rakete
rakete

Reputation: 3041

Modular architecture to encapsulate functions in Symfony2

What I want to develop....

I am currently developing a SaaS-solution (Symfony2) to build HTML-presentations or better slide shows. Users can log into an administration UI and create presentations. This presentations can be played later. A presentation consists of elements. The elements can be images, texts, videos, pdf and more.

enter image description here

This element types should be encapsulated from the user interface. So extern developers can develop such new modules (element types) with defined interfaces and inject it into the system.

If a new module is finished, we move it to a specific directory in the symfony2 directory and the system detect the new module. No hardcoded-changes in the administration ui system should be neccessary.

Each module has a own "product-number". So we can use a database to enable or disable modules for different users.

What functions must be implemented by a module?

In the administration ui the user has the possibility to create a presentation and add elements of different types (the modules). User sees a timeline with the elements. When he clicks on an element, the editor for this element will be shown under the timeline (Parent-Child-View). Each module has different editors. A text-module needs other configuration-possbilities than an image-module.

So, in admin UI we need functions to edit elements:

The output for the presentation:

Later we want to play this presentation. So a loop goes through the presentation elements and asks the modules of the element what and how to show it.

Database

I've made a little er-diagram of a possible solution to save the information about modules and elements in a database. The yellow entities are module-specific tables.

ER-model

How to realize this in Symfony2?

My frist idea is to define an interface which have to be implemented by the modules. But which class has to implement this? Controllers?

Are modules = bundles?

How to realize the View-in-View of the editor? The editor of the module (e.g. renderEditorView()) should be viewed in the user interface of the administration ui.

Upvotes: 3

Views: 341

Answers (2)

Wirone
Wirone

Reputation: 3373

There is another way to expand codebase with custom "modules": Dependency Injection Tags.

It works like this:

  • You create core of the app, which implements basic functionality and registers compiler pass which handles code extension
  • Modules can be part of the core app OR moved to external bundles
  • Each module must be registered in DI container with tag supported by your core app, so can be handled properly (adding menu positions, new element types as in your example)
  • Symfony DI compiles all services and stuff so all modules are available within app instantly (so you can for example iterate over collection of prepared items without need to dynamically building it)

In my opinion EventDispatcher is better for handling real-time actions, like sending notifications when new entity is created (e.g. controller/service dispatches event, some bundle subscribes it and send notification).

When you want to extend core I would recommend DI tags. Of course you have to build all the core (interfaces and whole architecture) so modules can extend existing services' data, then you only use your services.

Whole Symfony full-stack framework is based od this tags, so there is a lot of existing code to investigate for getting the concept.

Please let me know if it's clear enough what I wrote and what's in Symfony docs. If you need some additional info, I'll try to help.

Upvotes: 0

Ragdata
Ragdata

Reputation: 1186

I'd do it by hooking in to the EventDispatcher Component.

Your 'Master' Controller would define a set of events which correspond to the standard CRUD actions you've defined above ... onCreateNewElement(), onRenderEditorView(), etc. You'll probably find a dozen more to provide hooks for as you build your application (allowing plugins to add tools to a toolbar for example).

You'd define a Service (this doesn't HAVE to be a Controller Class), which looks for new 'modules' and adds their correctly-named methods as listeners for your custom application events.

Are modules = bundles? Well, that's entirely up to you. Are you going to provide a method for users to 'install' new modules specifically for your application? Then what a module needs to look like is entirely up to you. Are you going to slip Composer into the mix and allow modules to be installed that way? Places a couple of constraints on the structure, but still pretty much up to you.

How to realise the View-in-View? Again, that comes down to exactly how you define the interface for your 'Event Plugins' and what kind of access they have to resources like TWIG and YAML config.

The question you're REALLY asking is How do I add functionality to an application without hacking existing code ... and the answer is EventDispatcher. The rest is up to you.

Upvotes: 4

Related Questions