Our team is having a bit of a headache while modifying our core model.
Our problem :
We have a bundle, let's name it COREBundle. We load it via composer on every app to get the very basic required to boot our system.
The COREBundle provides a Customer Entity.
Each app has some special customer properties that we want to add : how to proceed ?
Of course the complexity here is to make everything work with the COREBundle provided.
We are exploring the idea of having some MappedSuperClasses but it means we will need to modify all our entities in ALL our apps, which will be extremely time-consuming.
Help? Thank you!
Related
I'm trying to create a reusable bundle for Symfony projects.
This bundle has a huge model mapping, but I encounter a conceptual problem :
How, with Symfony, can I bind one of my entities to the user entity of the final application of the people using the bundle ?
Can I use some configuration to get the user class and dynamically create the mapping between those two classes or is there a better approach of this matter ?
Thank you community :) !
In fact I wanted something like this : https://www.theodo.fr/blog/2013/11/dynamic-mapping-in-doctrine-and-symfony-how-to-extend-entities/
This is surely the solution I will apply to my project.
After a few days of developement, I noticed that for each new entity I create, I must map it to a "end-user extendable" class of the bundle. If I tell the end-user to map himself the Project class to his own User class, I later have to tell him "Each class which is mapped to the Project class must be also manually mapped".
I think none of us wants to implement an external bundle and override each part of its internal model. Dynamic mapping with event subscribers avoids it !
Ty for your help, I hope this note will help some other lads :D !
I am developing an app with Symfony2 that has 3 main parts called frontoffice, backoffice, admin. I was thinking to create three separate bundles: FrontOfficeBundle, BackOfficeBundle, AdminBundle but Symfony's docs says, each bundle should not have any relation with each other. Entity is already a shared property and probably some models. I could create a SharedBundle but it does not make sense. I remember when I created an app 2 years go when I had like 15 bundles and all connected each other and I know from experience that it's a nightmare.
Should I have just one bundle AppBundle and logic split in the folders, eg. Controller/Admin; Controller/FrontOffice, Controller/BackOffice?
What's the best approach?
It's all about SRP and DRY
It doesn't hurt to create a bundle, so make a separate bundle for stuff you need in multiple bundles, e.g. I tend to create an EntityBundle which contains entities and their repositories (as service).
Of course you can just use a single AppBundle too but please don't put your logic into the controllers -> create reusable services! Inject the services you need into your controller (which should themselves be services too).
Alternatives to base Controller Methods
No such thing as best approach.
However, instead of grouping by class type (Controller,Command,Form,Templates) within a directory, I like to create a single "component" directory for each request action. So I would have
Action
FrontOffice
BackOffics
Admin
User
UserController.php
UserFormType.php
UserTemplate.html.twig
Grouping files in this fashion really cuts down on figuring out where the various files live. Is it the "best" approach? Nope. But it works for me.
I am quiet new to the symfony framework and took some lessons and purchased the 'Starting in Symfony2' tutorial from knpuniverse. I want to be sure that I use the correct setup for my application. My question is, How do you call your first central bundle? eg. FrontendBundle? I want to make the next structure in my application:
FrontendBundle
The front where people get a landing site where they can also login
from there, when they login, they get into the next bundle:
CustomerBundle
Backend app where customers get their invoices and pay them and edit their information we stored in the database
And at least:
AdminBundle
Another backend app where I can edit customers, make invoices for customers and edit the app information
Is this the correct way and is FOSUserBundle a good bundle for this kind of application?
Bundles have sense only if they can be used in "multiple projects". I mean: if you write code, make it as a bundle and you can't reuse that bundle (for example because bundles, as you described above, are strictly and logically connected to your project) this three bundle separations is totally useless.
So, final answer (that is also a question) is:
Could you reuse FrontendBundle in other projects?
Could you reuse CustomBundle in other projects?
Could you reuse AdminBundle in other porjects?
If you notice that you can't use any or all of these bundles for other project, maybe this separations isn't good.
Why I say that?
Because if they can't be used in separated ways is likely that they should be used togheter so you should keep them togheter.
So I advice to keep them into a single bundle (YourNameYourBundleNameBundle (in that notation, for example)) and to separate the single "areas":
FrontEnd controllers/entities/views
Custom controllers/entities/views
Admin controllers/entities/views
This problem has been discussed at length already. For application specific code either do a single AppBundle or don't use bundles at all.
I am currently trying to create my own authorization system with Symfony (version 2.3). And I am not sure if I am overcomplicating things, I am pretty new to Symfony and SOA. I am creating my own authorization system because I have the need to restrict rights according to current user, its role and a current customer (current user can change customer) and its products.
What I currently have and I think may be too complicated is the following:
Foreach entity I have a repository for read operations only:
MyBundle/Entities/
Customer.php/CustomerRepository.php
Product.php/ProductRepository.php
...
To abstract the usage of the repositories and also the handling the create/update/delete. I have a Manager class per entity which are using the repositories (proxying to the repositores and usage of combination of different repos).
MyBundle/Manager/
CustomerManager.php
ProductManager.php
...
Then I have my classes which are are getting the authorization according to current user, its role and a current selected customer and its products. They are using the Managers for loading all the acl data.
MyBundle/Authorization/
AuthCustomers.php //Allowed customers to which user is assigned
AuthRights.php //Rights according to user and customer
The services look like this:
auth.manager.product:
class: MyBundle\Manager\ProductManager
arguments: ["#doctrine.odm.mongodb.document_manager"]
auth.manager.customer:
class: MyBundle\Manager\CustomerManager
arguments: ["#doctrine.odm.mongodb.document_manager"]
auth.authorization.authorization_rights_factory:
class: MyBundle\Authorization\AuthorizationRightsFactory
arguments: ["#auth.manager.role", "#auth.manager.customer"]
auth.authorization.authorization_customers_factory:
class: MyBundle\Authorization\AuthorizationCustomersFactory
arguments: ["#auth.manager.group", "#auth.manager.customer"]
Until this point I actually think it is ok. But what I would need now and what concerns me is, when doing some action on any of these entities I would actually need to do a check with my AuthorizationXXX services if I am allowed to do it. So the Authorization class is dependant on the Manager and the other way round.
To abstract this (to prevent infinite reference and I can reuse this in a controller and command script) I would now create another service where I inject the Authorization and Manager services and do these checks. So I would actually have another manager for my services.
In the end I would then have 7 entities, with 7 repositories and 7 Managers + a few authorization classes + 7 services to combine the managers and the authorization classes.
The question now is, is this the right way? I really feel like I am overcomplicating things. Any simpler suggestions are welcome :)
Voters seems to fit with your need, check out the doc: http://symfony.com/doc/current/components/security/authorization.html#voters
You could create a Voter which take as argument the current user, his roles and the current customer and return true if your business rules are respected and false if not.
In the end I now just kept the structure and just changed the meaning of the layers a little bit.
What I now have and feel comfortable with is:
Repositories for read only operations, are aware of other repositories (here I overdid it it in the beginning by wanting to keep the repos unaware of each other).
Manager which are handling persistence of the entities and proxying through to the read operations from the Repositories. They don't care about Authorization.
Authorization services which just handles my authorization things, so they can be reused anywhere without having to do Symfony specific stuff.
Model service which combines the Manager and Authorization and generally all depencies. Actually the Symfony controllers would just call the model services' methods. But with this I can also reuse it for Command line scripts etc.
I still have a lot of classes, but they are now nicely separated and only do their stuff and could be replaced easily.
In general I also looked at the FOSUserBundle in detail to get some inspiration. I think they solved it pretty well in general.
I want to create a blogging system in order to practice symfony2,
but currently I get a bit confused when creating entities such as user or blog.
The reason is the following :
User( or Blog) is commonly used in frontend and backend(admin)
(currently I have considered creating FrontendBundle and AdminBundle)
Entity must belong to one bundle.
Currently I have considered the following methods, but what is the best way
in this case, or please tell me if there is another way.
Create bundle named 'BlogCommonBundle' and define User entity as "BlogCommonBundle:User".
Define all controllers under 1 bundle, such as 'BlogBundle', so
frontend/backend(admin) controllers belong to same bundle.
I think creating a BlogBundle and having multiple controllers for frontend and admin functionality is a good way to handle this. Both controllers would make use of the same entities and repositories, and you can easily firewall your admin actions in the security settings of your application. By keeping everything blog related to one bundle, you maintain good code organization.
The same goes for a UserBundle. It's helpful to remind yourself that a bundle should represent a set of like functionality for an application. So if you have code that fetches blog posts, and allows you to create and manage them, they naturally group together in a single bundle.
I asked a similar question here:
How to share a Symfony2 model with several projects
I went with the 'ModelBundle' approach that contains all the entities, forms, repositories, etc. These are all shared with the FrontendBundle and BackendBundle.
So far I'm very happy with this solution.