Symfony2 Doctrine Get reference based on attribute - symfony

in my Symfony2/Doctrine2 project I have an entity Person which has a birth date. I have another entity Agegroup which stores a name and some more information for a group based on the age in years.
Example:
Person Name: xy Date: 1980-05-06
Agegroup: From: 1 To: 10
Agegroup: From: 11 To: 20
Agegroup: From: 21 To: 30
I want to get the Agegroup which a person currently belongs to, from within the entity (based on current date).
i.e. :$person->getCurrentAgeGroup()
Therefore I would have to access another repository class from within the entity, which is obviously not a good thing to do.
Is there a way to implement this kind of functionality?
I read Using EntityManager inside Doctrine 2.0 entities
which could be a solution to the problem. Unfortunately I didn't find a solution to implementent this. Do I have to inject the service somehow into the entity?
Maybe there are other best practices for this kind of problem?

It is not good style to put the entity manager into your entities. A better approach would be to create a custom AgegroupRepository that has a method getAgegroup(Person $person)
Another approach would be to make the age group a property of Person (with getters and setters), create a custom PersonRepository and modify the find() method to instantiate the correct instance of Agegroup when looking for a person.
Your entity objects should only store data and business rules and should not concern themselves with the storage of the information. This is what repositories are for.

Related

CakePHP model behaviors in Symfony2 + Doctrine2?

Is it possible to have behaviors in Symfony 2 entities, like in CakePHP? I'll try to explain what I need:
In some of my entities, I need to store who created or updated the record, when it was created or updated, at which company does it belongs and at which season does it belongs.
All these data is stored in the session, and I want to add it to the entity "magically", without adding these fields in the controller. With CakePHP I can create SeasonBehavior, mark some models/entities as they use the SeasonBehavior and when I persist a record from an entity marked with the SeasonBehavior the seasonId is updated.
Is it possible to do the same with Symfony2 and Doctrine 2? And if it's possible, do you know any tutorial or documentation explaining how to do this?
You need to create listener on your Persist action to do such things. Read the manual here: http://symfony.com/doc/current/cookbook/doctrine/event_listeners_subscribers.html

Symfony2 dynamic relationship with a field

I am building a social website and I am laying out how the feed will work. I want to use the answer here: How to implement the activity stream in a social network and implement the database design mentioned:
id
user_id (int)
activity_type (tinyint)
source_id (int)
parent_id (int)
parent_type (tinyint)
time (datetime but a smaller type like int would be better)
The problem is I don't know how I would map the source_id based off activity_type. If a user registers, I want the source_id to be the user that registered. If someone creates a group the source_id will be the group. I know I can just use simple IDs without keys I just wanted to know if Symfony had some sort of way to do this built in.
If I fetch the feed and the activity_type is user_register I would like to be able to do this to get the source (user) without running an additional query:
$feedEntity->getSource()->getUsername(); //getSource() being the User entity
And if the source_typeis "user_post":
$feedEntity->getSource()->getMessage(); //getSource() being the UserPost entity
I basically just want to find the best way to store this data and make it the fastest.
Not easy to deal with doctrine and i think it cannot achieved 100% automatically
However, the keyword is table inheritance
http://docs.doctrine-project.org/en/2.0.x/reference/inheritance-mapping.html#single-table-inheritance
I think you could achieve your goal by doing something like this :
You create a discriminator map by the type column of the table which tells doctrine to load this entity a UserSource (for example)
This UserSource can be an own entity (can be inherited from a base class if you want) where you can decide to map the source_id column to the real User Entity
You can use instanceof matching against the namespace of the different entities mapped inside your discriminator map to define different behaviours for the different sources

How to deal with calculated entity attribute

Let's say there is an entity called Staff.
It has a number of persistent attributes, such as:
- Name
- Experience
- Age
I want to create a "virtual" attribute, that is based on the Experience and Age, called 'Salary'. For example: $salary = ($experience + $age) * 100
But I don't want to persist the Salary attribute. The reason is that I want to let the Salary attribute get's updated automatically whenever the age or experienced values change.
I have two questions regarding this:
Is the Entity file a good place to store the getSalary() function?
How can I make it so that whenever a Staff entity is called, the salary variable will be filled with the salary that is calculated based on age & experience?
Is the Entity file a good place to store the getSalary() function?
Yes, it is.
Not every field in your entity has to be mapped to a database field.
Also, entities can contain methods other than simple getters and setters. IMO as long as those methods operate on the entity fields, they belong to the entity.
How can I make it so that whenever a Staff entity is called, the salary variable will be filled with the salary that is calculated based on age & experience?
You could use one of the Doctrine's lifecycle events, for example the postLoad event, which is called after entity is loaded to the entity manager.
Note, that you don't have to be storing calculation results in a property. Your calculation is simple and it's probably better to define a getter.

Where to set ACL: Entity or Controller

im starting to implement some security features in my application. When initially trying to implement some ACL I came acress two questions I could not figure out:
Where to implement the setting of acl
I could do it in the controller action where my entities are created or on the entity itself with lifecyclecallbacks. For example I have a Group Entity which holds some Userentities. It is easier to set the view or edit access on a lifecyclecallback for all group entities. I would prefer to make my controller as slim as possible. Or is this a bad approach? I would need the security container in my entity. What is your approach to this?
How to check for related entities:
Extending my previous example, I have a Group and this group can hold some appointments. In my actions where the appointments are shown or edited, I only want to check for the group. This is mainly for using the "view" rights. Meaning if someone is in the Group which holds the appointment, the person should also be able to view the appointment. I would like to implement this with JMSExtraSecurityBundle and SecureParam, but I have no Idea how to do that.

Relations in Spring Web MVC (Using Roo)

What is the correct way to specify a one-to-many relationship in Spring Web MVC (using Spring Roo)?
Example: A Person has a name and an email. A Team has a name. A Person has a membership in a Team, and a Team has zero or more members. The user would like to a) Set the membership for a person, b) Set the members for a Team.
If the relation is created using a reference field for Person, members are not visible in the view for Team. There's a similar result if the relation is created using a set field for Team (which really is a many-to-many relation anyway).
What am I missing?
What you need here is a bidirectional relationship (which is not created by default).
When you generate your entities, you need to add both the Set association in Team, AND the Person association in Team. It will probably also be a good idea (depending on your naming convention to add the mappedBy attribute in the OneToMany annotation on the generated Team Set. If you want to get this done by Roo, just used --mappedBy on the field set command. The value for this will be the field name of the Team reference in the Person entity.
With both references in place, roo should generate the correct scaffolding.

Resources