An exact description of a Symfony Bundle in a complex web application - symfony

I'm new to version 2 of the Symfony framework. I made some projects with v1 but now trying to get my head around the new version and it's features.
I read over the concept of Bundles but it's purpose is not yet very clear to me.
Say you have a big web application, a CRM for example. How would the bundles look like?
Would it be NewsletterBundle (for sending newsletters), ContactManagementBundle (for managing contacts), UserBundle (for editing users and their permissions).
Or would it be less cut-up like, EmailBundle (for handling the entire email traffic), CRMBundle (for putting in all your CRM code), PermissionsBundle, ApiBundle.

I like to think of it like this: a bundle should represent a specific feature or set of like features for a project.
Your first example is a better use of bundles than your second example, because the purpose of each bundle is more defined. While it's possible to use one CRMBundle for everything, you wouldn't really be taking advantage of Symfony's ability to organize your code. Additionally, if you wanted to port over your Newsletter code to a new project, but not all of the CRM code, you'd have an easier time copying over a NewsletterBundle versus copying over the CRMBundle, and then pruning it.
When thinking about a Symfony2 project, sometimes you want to forget everything you know about symfony 1.x, since they take wildly different approaches to solving many problems. For example, in symfony 1 it was common to build a 'frontend' and 'backend' app for a project, and each app would obviously contain logic specific to those parts of the project. So you might have a Newsletter controller in both the frontend and backend apps. In Symfony2, you're better off using only one Newsletter bundle, but with two controllers (perhaps named 'frontend' and 'backend'). Again, an immediate benefit to this is how reusable your code becomes.

Related

Is possible to mix Symfony2 CMF and the standard distribution?

We're planning a new intranet for our organization. Some part is like a CMS, and there are some custom-made applications.
The Symfony2 CMF distribution looks fine for building the CMS part of the intranet, but other parts like Doctrine, "normal" SQL databases, etc, looks better for the custom-made applications for the intranet.
Because I need common authorization and authentication system for this intranet (against an Active Directory), I supose that I'll get better results building all in only on app. So, can I mix a CMF application with a normal application, and both use the same database (an Oracle DB)?
Yes you can easily mix the CMF with other Bundles. For example the routing allows using both routes from the CMF as well as "static" routes defined in yml files. Also you can easily also add the ORM next to PHPCR ODM. If you use Doctrine DBAL for storage in PHPCR, you can even reuse the same connection configuration with the ORM etc.
In brief yes it is, and I do this in my own Symfony2 project. I combine both SF-SE and SF-CMF bundles.
In fact, with Symfony2 it's very simple (this is just a matter of choosing the most suitable Bundles; SF is a very decoupled framework, which is why I don't plan to migrate to any other solution for the moment), but I'd like to share some of my experience with doing that. Actually the one most important question to think through to make a decision about how to combine both "worlds" is this:
Composer.
After some inquries I found out that since Symfony CMF is (in a way) based on Symfony SE, and not vice versa, it's better to start with the latter, as it contains the most core features (though I did it also in the opposite way, rather not recommended). So just take a SF-SE's composer.json, take a look at bundles from there you need, and then take a look at differences within SF-CMF's composer.json. You should end up with the most suitable set of bundles.
The basic features from these bundles to look-up for are:
MODEL - Doctrine ORM, PHPCR-ODM, or both - if still not sure, don't hesitate to ask a comment, I'll share here my experience furthere.
ROUTING - the primary question here is how flexible routing do you actually need? If not sure, I'd go with standard SF Router, and then possibly replace it e.g. when still on a dev stage.
OUT-OF-THE-BOX CMS FUNCTIONALITY - bundles such as CreateBundle, MenuBundle or MediaBundle may help you building surprisingly fast, but not quite flexible soltions. In general, I ended up without using most of them, and if using, then I mainly take some Interfaces I do implement in my own Bundles (to ensure future compatibility with possible other bundles to be potentially used).
Besides of these above, I created a number of Bridge Design Pattern and Provider Design Pattern solutions to make some bundles working together, to adjust their functionalities, or simply to decouple things.
In programming almost everything is possible. But think about restrictions delivered with CMF (routing for eg.).
Maybe you should consider Standard Symfony with Sonata? I think CMS pages it's only small part of your system and implementation it in standard symfony will take smallest part (and cost) of whole project.

How to implement a deployment-specific pluggable architecture in a single code base

I know this is somewhat subjective, but Symfony being as it is there must be a feature specifically designed for this purpose.
Here are the main factors of what I need to do:
The system will be deployed separately for multiple customers (probably just a handful. scale isn't a big concern).
Each deployment has a small amount of highly bespoke functionality specific to the customer. This could be anything.
I want to maintain a single, common codebase (including composer.json). The only file I really want outside of our repo is parameters.yml.
My current thinking involves a custom bundle for every customer - hooking into them using custom Symfony events, fired from the common parts of the system. But ...
Symfony bundles aren't designed to be dynamically registered. They're baked into our core system so I can't switch them on and off for individual customers without forking/splitting the codebase. This means not only a bloated Kernel, but also events would be received by all bundles in all deployments.
I can get around that last point by namespacing the events with a configuration parameter. Even if I can live with redundant bundles in the Kernel, this whole approach seems too hard to be correct.
What is the proper way to support a "pluggable" architecture than I can hook into from the core system without splitting my codebase?
I use multiple app-directories. Then you can turn on/off bundles for each client since each client has it's own AppKernel.php and then you can create a separate /web/app.php for each client and point it to the currect app-directory.
You can then use mod-rewrite in Apache to point each client's subdomain or something to the right app.php file

Symfony2 and Frontend & Backend Bundles

Couple of month ago I got a legacy project written on Sf2. I fixed some bugs, and added some new functionality, but still i feel that it was made a little bit clumsy. Well, maybe not just a little :) So, I have a number of questions, how things really should be done in Sf2.
The first thing which is bothering me, is that the Application is separated on Frontend and Backend bundles. The're standing on the same model, and for example entity Book can be seen from FrontendBundle and edited from BackendBundle. In some way this is producing a confusion of abstractions. So my question is - is it right, or wrong, and if wrong how it should be done in appropriate way?
Bundles are components in symfony2 that provides a functionality to your app. The frontend and backend approach has changed in symfony2, the bundles are used instead.
For example, you can create a BookBundle, and put all the functionality regarding to books in that bundle, adding, updating etc. And by configuring the routes, you can redirect all the requests about the book to that bundle.
The main point is, the frontend and the backend about the books resides in same bundle, and only in that bundle(with controllers and entities and repositories and views etc.).
This is the intended usage in symfony2.

Headache designing Symfony2 bundles organization

I'm developing a SaaS where tenants are both real ones and admins (us). So "fornt-end" and "back-end" are the same. Anyway, according to many other questions bundles are a way to structure your project in reusable way.
I really don't think that our bundles are going to be reused, but i still need a way to split the project into bundles to quickly find files we want to work on. Application should:
CRUD for customers - tenants should be able to manage their
customers/partnerships
CRUD for customers tags and keywords (a way to categorize their customers)
CRUD for broadcast notifications sent by us (a messaging system)
CRUD for tenants - we should be able to manage our tenants
So, how can organize my bundles? Could be:
CoreBundle: only Doctrine2 models
ResourcesBundle: templates, js, css, images
SystemUserBundle: manage tenants and customers CRUD
MessagingBundle: message system
How this design can be improved?
According to the Symfony2 documentation:
In Symfony2, a bundle is like a plugin, except that all of the code in
your application will live inside a bundle. A bundle is nothing more
than a directory that houses everything related to a specific feature,
including PHP classes, configuration, and even stylesheets and
Javascript files (see The Bundle System).
Personally, following this description, I would set up the SystemUserBundle to contain the Doctrine2 model and templates/js/css/images that specifically relate to managing customers, rather than splitting them out into CoreBundle and ResourceBundle. However, splitting your app into SystemUserBundle and MessagingBundle sounds like a reasonable approach.
I like to think of it this way - does the bundle encapsulate some behaviour that I might need or want to plugin to a future Symfony project(s) I am involved in. Customer Management, for example, is something that might apply to any app and be re-used across projects (indeed, this is why the extensible FOSUserBundle exists).
I don't think the Symfony2 docs go into sufficient detail on bundles (yet!) but in case you haven't found all the relevant sections these are the ones I'm aware of:
Symfony 2 Page creation
Symfony 2 The Bundle System
Symfony 2 Bundles best practices

Do you sort your classes?

I'm developing and intranet application with symfony2. I'm currently using only one fat bundle for all my features. Seem like this is what is recommended and what most symfony2 developpers do.
I wonder how you deal with an growing application where you create entities again and again. Do you just create them in your Entitiy directory inside your bundle? Do you sort them into subdirectories?
The same question can me applied to others classes like the forms.
Any advice on this?
In my opinion, even if best practices say to use a single bundle, for big project this can make you lose time.
In my projects I'm used to create :
- one bundle for statics pages and resources : for example PagesBundle
- one bundle to the member area : UserBundle
- One bundle for the core of the application : ArticlesBundle in the case of a blog, for example.
This serves to separate and save time in the tree Symfony2.
Tell me what you think.
This is a very subjective topic and mostly relies on what you are most comfortable with. The reason why the best practice now proposes just one big bundle is that the bundle approach was mainly for reusability purposes.
Some people even recommend to store entities outside of any bundle in src\YourNamespace\Entity.
Either way: subdirectories are definitely a very valuable option to sort classes.

Resources