Symfony working with different entity managers - symfony

I want to create an application with some subsections like a blog and a forum for example. Now I want users to be able to create an account on my site, and with that account they can use the forum and the blog. That's easy so far. But I want to keep the tables in seperate databases to keep a nice and clean structure. Let's say I use 3 databases, one for the UserBundle, one for the BlogBundle and one for the ForumBundle. This requires 3 entity managers. But that means that I can't use relationships from entities from ForumBundle or BlogBundle to the user entity in UserBundle. Simply adding UserBundle under the mappings for the other managers will create new tables in the other databases and that's the thing I'm trying to avoid.
So, is there a way to make bundles 'aware' of entities in other bundles?
I know it technically isn't a good thing to make bundles dependent on other bundles, but how else would I acheive my idea?

One approach that has worked reasonably well for me is to query using the event system.
Assume you are in the Forum Bundle, you have retrieved a list of posts for a given thread and now you need the user information for each post. You make an array of user id's then:
$userIds = array(...list of users you need information for...);
$findUsersEvent = new FindUsersEvent($userIds);
$dispatcher->dispatch('FindUsers',$findUsersEvent);
$users = $findUsersEvent->getUsers();
So now I have a list of user information all nicely indexed by user id from which I can then pull additional information.
The only coupling between the Forum and User bundles is the FindUsersEvent class which could be in a common bundle of some sort. The forum bundles does not care how the users are loaded. The user bundle just needs a listener.
==================================================================
A second approach is to basically use a REST like api for grabbing user information.

Related

FOSUserBundle proper solution for team consist with multiple users

I am using FOSUserBundle in my Symfony2 project.
My goal is to make the teams consist with multiple users. Users are invites by administrator (owner) by e-mail confirmation.
If a user belongs to one team, can't set up new accounts using the same address. Of course, each user should have the opportunity to unsubscribe from the team.
Are there any ready-made solutions? I looked for Groups With FOSUserBundle.
Or do you have any good advice?
You were right, groups can be a good ready-to-use solution to make your logic.
The association is already setup and it's also easy to extend.
The documentation (now part of Symfony's doc) contains a great guide to use groups.
Of course, you can make your own entity, take example from the FOSUB User->Group logic (association) .
You should see the Security and Roles part of the documentation to manage authorisations of your different kind of users.
You can assign roles to your different groups, and make your users directly inherit the roles of their group for manage access permissions.
For the confirmation email, see the corresponding documentation too .
And for the unsubscribing, just remove the association between the user you want remove from a Group and the Group (or Team).
This is also part of the association, see the doctrine documentation.
Good use.

Form on entity linked to a relation

I have these entities :
Now, I need to create form to store data.
My problem is, I don't know how to figure out to create those forms.
What I want is a form where I can create a User, and here, I can select a Pack.
When I selected it, a list of Services of the selected pack appears, which I can checked if it is consumed by the User.
More complicated, I need to allow User to have several pack, and same pack is allowed.
It's look like a collection of User_Pack_Service form, but how to keep the Pack of each collection?
Other questions, since Pack_Service is a relation table of ManyToMany relation ship, it complicated the way of add Services in Pack. Is there a way to avoid is creation as entity? (I know I need it to link Pack and Service to User but that result in to many entities for nothing...)
Thanks for your help.

Symfony2: how can I load a user taking into account its mapping entity?

Although I'm using Symfony 2.1 with FOSUserBundle and everything works perfectly, I don't know how I can resolve a problem.
Basically, I would like to know if there is a way to find (load or get) a user from the database taking into account a relationship with another entity.
This is the situation:
I have made that users can also login into my site thru a social network (Google, Facebook, LinkedIn, etc). I besides ask them for an offline access, so I can access their social accounts any time.
As each user can have as many connections as they want (or maybe none cause they are optionals), I've decided not to save this information in the user table. I've created an abstract entity called "SocialConnection" which is extended by the real ones (Google, Facebook, ect). In this entity I store the user information that I get when the user logs in my site thru those networks (user_id, social_id, access_token, etc), so in my User class I have mapped a collection of the abstract "SocialEngine" that allows me to have all networks together.
In order to be able to add others networks like Twitter, Yahoo and so on in the future, I think it is the way it should be.
So, the problem now is that when the user logs into my site thru any of these social networks I need to load him from the database knowing his social id, but I don't know how to do it.
I've seen that the method $this->findUserBy of UserManager find a user regarding a property but I think this is not the case.
What should I do to find a nice solution?
Thanks in advance.
Best regards,
Izzy.
To achieve this, you need to get deeper into doctrine's api. The base repositories methods (find, findBy etc...) won't be enough.
You need to use doctrine's DQL. It looks like SQL but you query based on your mapping metadata and not based on the database schema directly.
If your User has a OneToMany $socialAccounts property to the SocialEngine. You will be able to do something like:
SELECT u
FROM Bundle:User AS u
JOIN u.socialAccounts AS sa
WHERE sa.id = 34
But you can only query on SocialEngine's properties, not on the subclasses one ... (ie: You can't query on a SocialFacebookEngine's facebookId).
You either have to put all the twitter/facebook/etc data in the base SocialEngine class, on in the User class.
Or you could create an entity for each "Social Engine", and create a OneToOne relation relation between each of theses engines and the User.

Doctrine2 dynamic table prefix based on logged in user in Symfony2

I am trying to get a multi-tenant system setup where each user has their own prefixed tables.
So my database might look like
users
acme_posts
my_posts
their_posts
our_posts
A solution like this is a good start, but it does not allow for the prefix to be dynamically created.
Is it possible to modify the doctrine solution above to set the database prefix based on the logged in user?
Another approach might be to have a main users database and then have separate databases for the user specific tables, but I am not sure if Doctrine can handle relationships between multiple databases.
All suggestions are welcome.
You can quite easily get access to the service container in a Doctrine EventListener like that, simply by defining the EventListener as a service (instructions located here). However, that approach won't help you for your situation, as all the class metadata will be loaded just once and cached, so it can't know about different users.
I don't know your use-case, obviously, but is there any reason that you can't simply add a field to your *_posts table, such that you have one posts table with "user_namespace" or similar as part of the key?
If your objection is simply to cluttering your controller logic with information about what user is logged in, you can simplify things by using a prePersist Doctrine EventListener to set the appropriate user_namespace on new entities, and either a Filter (for Doctrine >=2.2) or a custom DQL walker (for everything else) to restrict all your queries to only retrieve entities from the appropriate user_namespace.

ASP.NET Dynamic Data: Access rights only to specific rows

I want to use ASP.NET Dynamic Data for my next project, but there is a problem a can't manage to solve. In the database we manage authorization on a per-row basis. For example no user is permitted to see all rows of the Contracts table. So there is a Many to Many Relationship between Contracts and Users. So everytime Dynamic Data performs a Select to show all Contracts it has to look into the ContractUsers junction table to see what contracts the current user is permitted to see (filtered by UserID which will be stored in a session variable). Of course these junction tables should be invisible to the users.
By default Dynamic Data returns all rows of a table, so is it possible to customize this behaviour for every query the user performs?
I want to use Dynamic Data together with LINQ to SQL but if this task would much easier to accomplish using Entity Framework I would look into that too.
Thanks for your help and time.
Implementing such a solution in Dynamic Data it will probably require the creation of a custom Entity Template; not really easy but once done it will not require the creation of custom pages just the editing of the page templates.
I think it will be really usefull to check the excellent work on DD done by S.J.Naughton and presented on his blog.
Greetings, F.
You should not use dynamic data because you need full control over querying and manually write all linq queries to add your data level security. If you still insist on dynamic data be aware that you will still write most of pages yourselves and you will only use dynamic templates. You will have to manually define ever data source and correctly pass where condition to filter results based on logged user.
In addition linq-to-sql is not able to hide junction table and entity framework is able to do that only if junction table contains just two FKs for many-to-many relation. If this table contains any other column you want to use in the application you will have to map it as any other entity and dynamic data will show it as an entity.
Dynamic data are technology for quick creation of simple application where you need to provide access to database through web interface but what you describe is not a simple scenario. You need per record authorization which can differ among entity types.

Resources