the background for this is that we have an existing site which is going to be somewhat linked with the new one, so it would make a lot of sense to use the same user base.
So, we want to use the same user database. The way I tried is not working, adding two databases and providing the same Entity. This is also a different Symfony project, I could do it on the same one but it's more convenient to separate it because it might be running on different servers later on.
How can I make my user provider fetch the users from another MySQL database the easiest or best reliable way?
Have you looked at the documentation for using multiple entity managers?
http://symfony.com/doc/current/cookbook/doctrine/multiple_entity_managers.html
You can set up configuration for multiple database connections and define which connection to use by default based on the bundle.
Alternatively you can explicitly choose which connection to use with
$this->get('doctrine')->getManager('<your custom manager name>');
If you're using a user provider specified in your security.yml (the approach used here) you can inject the userRepository for your alternate connection in the service definition.
your.definition.of.user.provider:
class: YourBundle\Entity\UserProvider
arguments:
- #=service('doctrine').getRepository('YourBundle:User', '<alternate manager name goes here>')
Related
I am running a Symfony 3.4 based web service using Doctrine to manage and persist the different data entities.
Now I am trying to implement a method which transfers older, abandoned user accounts to another database which acts as archive.
Regarding to the Symfony docs it should be no problem to configure Doctrine to manage different database connections and entity managers.
However I do not completely understand the process on how to setup this use case:
Assume the Symfony project has different data entities DataEntity1, DataEntity2, etc. and different infrastructure entities Infrastructure1, etc..
How to tell Doctrine to initialize the archive DB with the data entities only?
How to move the entities between the DBs? Is loading them from entity manager 1 and persisting them in entity manger 2 the correct way?
Is there any best practice on how to do this?
If I understand your question correctly, you should use the prefix option for the mapping configuration.
prefix
A common namespace prefix that all entities of this mapping share.
This prefix should never conflict with prefixes of other defined
mappings otherwise some of your entities cannot be found by Doctrine.
This option defaults to the bundle namespace + Entity, for example for
an application bundle called AcmeHelloBundle prefix would be
Acme\HelloBundle\Entity.
Have a look at https://symfony.com/doc/3.4/reference/configuration/doctrine.html it shoul help you.
To move the entities between the two DBs, you should have two entity managers and use the correct one to persist olders accounts.
Hope this helps.
I was trying to setup a UserModel Class and very unhappy with the separation of database and Models.
For example I want to check if Username already exists or generate a new User. But all these actions require a database connection, which is only available in a controller. Of course i can always inject the DB Object, but it just feels wrong. What is the right way to handle these things?
You can use the UniqueEntity validator, the docs are here
http://symfony.com/doc/current/reference/constraints/UniqueEntity.html
About the db connection, you can easily inject specific repositories or the entity manager itself in your services where needed.
I have a legacy application that was using Xaraya to manage user content that I am trying to replace with a rewrite using Symfony/Sonata to manage users and/or content.
For whatever reason, previous developers managed this with two different databases (MySQL for Xaraya, and SQL Server for other things, including authenticating users).
I am trying to create Entity mappings such that the users/groups from SonataUserBundle (which extends FOSUserBundle) use the entity manager associated with the login database connection, and this works for logging into the admin site itself, but blows up when it tries to hydrate objects that have associations to the User entity.
It appears that Doctrine does not try to find the entity manager associated with an entity when hydrating an object's associations.
My question is this: it it possible to make Doctrine hydrate objects using the entity manager for an entity instead of assuming it's mapped to the current entity manager, and if not, is there any form of a clean code work-around for it?
Thanks.
(Note: The method of using the "databasename.tablename" syntax in the query that I have seen mentioned elsewhere will not work for my use case.)
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.
Recently i moved to Symfony 2 and i have a litte question.
Let's say i have the following Model:
"catalog" which contains "catalogs". The model gets its data from files but also needs a database connection to verify things.
In the Zend framework or other past projects i loaded the dependencies by a static object which forms a kind of "registry".
As i understand, Symfony 2 uses their service pattern (dependencie injection) instead. But how does this apply to my case.
Must i create a service for every model class i use to auto inject all dependencies? Or is it perfectly valid when i create a instance from my object myself and set for example the database connection in my constructor?
To create a service for every class which needs dependencies, seems a little bit overkill to me.
You can certainly create classes and inject dependencies the old-fashion way but take the time to learn the details of creating services. I think you will find:
Adding a new service is trivial. Copy/paste a few lines of configuration, adjust the class, id and maybe some parameters and you are done. Takes much less time than creating the actual class.
Very soon you will progress from just injecting a database connection to injecting other services as well as perhaps some parameters. Do you really want to have to remember to do all that stuff each time you need to new an object?
Using service id's can divorce your controllers from the exact location/name of a class. The first time you need to do some refactoring and maybe move some services into their own bundle or perhaps swap out a service with another you will be glad that you won't need to hunt down all your code and make changes.
S2 is not really focused on "Models". Instead, think in terms of a service named CatalogManager which wraps access to assorted catalog functionality.