Symfony2, Doctrine and data domain - symfony

In a Symfony2 project with Doctrine as ORM, I have many entities dedicated to store data domain.
According to your experience:
which is the best naming convention for this data domain entities (for instance, is good to name "ProvinceDomain" the entity that will store all the province values)?
do you put data domain entities in a specific folder (for instance "Entity/DataDomain")?
do you prefer a prefix (for instance "domain_") or a suffix (for instance "table_name_domain") to name the domain data tables? Or do you use some other naming convention?
Thank you very much.

1)
I think that the correct name is Province. "Domain" is like a role. IMHO it doesn't have to be in the name. So, the full name could it be: CoreBundle/Entity/Province or xxx/Entity/Core/Province.
2)
In some projects I placed that kind of entities in a folder "Entity/Core".
At other times I have solved it in a specific bundle, for example, "CoreBundle/Entity".
3)
I see well that you call tables like "table_name_domain". Note that table is data, and it is not bad to categorize information as "domain"

Related

Symfony2 - extending existing non-abstract entity?

Let's say I have a Setting entity with some fields like IntValue, dateValue, stringValue and some linked entities, like countries (ManyToMany to entity Country), languages (ManyToMany to Language) etc.
Settings are created by users and assigned to specific objects (not important here, but I wanted to clarify).
Now I suddenly need to have UserDefaultSetting, which will be the same, but with additional user field (ManyToOne to User entity).
I tried to extend existing Setting entity class with one more field added. The problem is, as I looked at the schema update SQL, it created new table for the new entity, but without all the tables needed to ORM connections (mostly ManyToMany). Just one table with "scalar" fields.
So previously I've had setting table with int_value, date_value etc. but also setting_country and setting_language tables, linking ManyToMany relations. After creating child entity, Doctrine created only user_default_setting table with int_value, date_value etc. and additionally user_id column, but I can't see any relation/link tables.
I know I should've been do it with abstract base entity class, but at the time I started, I didn't know that and now part of the project is on production (don't look at me like that, I blame the client) and I don't want to change that "base" class now. Can I inherit everything from non-abstract entity class in a way it will work?
UPDATE: everything explained. See Cerad's comment. Thanks!

Symfony Mapping in Doctrine without Annotations or XML Files

a customer has an existing database. The schema is often changed within the database itself (e.g. he adds a new column).
My task is to develop an admin area with symfony that automatically reacts on table schema changes without modifying the application code. E.g. the customer adds a new column to table "MyEntity", and the application automatically generates a new column in the accordingly list view.
My approach is to dynamically map the table columns to the Entity class so that ALL Attributes and ALL Getters/Setters are generated dynamically from the table schema.
So is it possible to map the table columns in a Doctrine Entity without the use of Annotations or XML Files.
Something like:
class MyEntity{
public function generateMappingFromSchema($sTableName){...}
}
Please don't do that. Doctrine was not designed for such use case.
There is a library though you should check https://github.com/laravel-doctrine/fluent which basically is a mapping driver that allows you to manage your mappings in an Object Oriented approach. And there are other tools:
http://crud-admin-generator.com/
http://crudkit.com/
http://www.grocerycrud.com/
which are maybe better for that, I don't know.
But again, please don't do that. Do not allow the customer to modify the database schema or give them e.g. a phpMyAdmin which was designed for that.

Entities associations across different managers

I have a small question about doctrine and Symfony 2:
Is it possible to declare a relation (OneToMany) between two entities which are managed by two different entity managers (and two different DB connections) ?
To be more precise, I have two bundles :
FpnABundle -> Mapped with A_database (and A_entitymanager)
FpnBBundle -> Mapped with B_database (and B_entitymanager)
And I need to define an association between FpnABundle:User and FpnBBundle:Post
If I try to do that, when I perform a DB schema update, I have the following error :
The class 'Fpn\ABundle\Entity\User' was not found in the chain configured namespaces Fpn\BBundle\Entity
Thanks for your help!
Basically, the answer is no.
You will probably need to do this: http://symfony.com/doc/current/cookbook/doctrine/resolve_target_entity.html
Even with this it will only work if the two databases are on the same server. And at some point you will probably need to add the schema name to the the table name. Somewhat painful.

Symfony2: loading user roles from database

I'm running into a problem with the Symfony2 Security system, particularly when trying to load Roles from a database. Before going further, I am aware of FOSUserBundle, but at the moment, in an effort to better understand the Symfony2 framework, I want to try and make my bundle work using Symfony2 components only. TL;DR -> please don't tell me to just use the FOSUserBundle. :-)
I have 3 entities configured in my bundle, Accounts, AccountsRoles, and AccountsRepository.
src\RedK\Core\IndexBundle\Entity\Accounts.php
http://pastebin.com/0VgXvtJp
src\RedK\Core\IndexBundle\Entity\AccountsRoles.php
http://pastebin.com/GiKNnYg3
src\RedK\Core\IndexBundle\Entity\AccountsRepository.php
http://pastebin.com/SVuMVdpN
MySQL demo_template.accounts Table
http://pastebin.com/YzmjD9e4
MySQL demo_template.accounts_roles Table
http://pastebin.com/Ybwr4f7y
All aspects of the bundle were working correctly (registration, confirmation, password reset, and login) before I attempted to add the loading of user roles from a database. When I simply set the role to array('ROLE_USER') via the getRoles() { return array('ROLE_USER') }, authentication worked and the user successfully logged into the site.
However, upon attempting to integrate roles from the database, I receive the following error, which I understand is an instance of AuthenticationException:
Notice: Undefined index: id in /home/humplebert/Websites/www/template/vendor/doctrine/lib/Doctrine/ORM/Query/SqlWalker.php line 804
Stack Trace
http://pastebin.com/Sr5RvZaY
The exception is only generated when I modify the query in AccountsRepository and remove
the "->select()" and "->leftJoin()" components. In looking at the Stack Trace, around line 16 on the pastebin.com link, it appears I have all sorts of "crazy" happening with regards to the many-to-many mapping in the BasicEntityPersister.
I've searched high and low in my Entity classes for any reference to plain "id" and can find none. I've noticed that if I change the names of my "ID" columns in my entities to just "id" (i.e. replace "AccountsID" with "id" in src\RedK\Core\IndexBundle\Entity\Accounts) the error goes away (and is replaced with another error, more on that in a moment).
Question 1)
Is there something blatently wrong with my Entities to be generating the "Undefined index: id" error I am receiving? If not, does Symfony2/Doctrine2 require that Auto-Increment columns in be labeled "id"?
As I have continued to tinker, I decided to try renaming my table ID columns to "id". Therefore, src\RedK\Core\IndexBundle\Accounts replaces AccountsID with just "id". And likewise, src\RedK\Core\IndexBundle\AccountsRoles replaces RolesID with just "id". Upon doing so, the "Undefined index: id" error goes away. However, I am presented with a new error: "table or view demo_template.accounts_accountsroles does not exist". Well of course it doesn't exist, I don't have a table defined as accounts_accountsroles. I have two tables, accounts and accounts_roles.
Question 2)
In order to use the Symfony2/Doctrine2 tools for importing user roles from a database, what rules are there regarding the naming of the tables? Based on the error I received, it seems that some form of concatenation is taking place. Or have I just simply screwed up my annotations somewhere along the line?
Any help would be greatly appreciated.
Regarding Question 1) the short answer is no! For the long answer see section 5.3 Mapping Defaults in the Doctrine Association Mapping documentation:
It states that if you use this short annotation:
/** #ManyToMany(targetEntity="Group") */
private $groups;
"In that case, the name of the join table defaults to a combination of the simple, unqualified class names of the participating classes, separated by an underscore character. The names of the join columns default to the simple, unqualified class name of the targeted class followed by “_id”. The referencedColumnName always defaults to “id”, just as in one-to-one or many-to-one mappings."
You can override the defaults by providing more detailed many to many annotations (see link above) and therefore avoid the id error.
Regarding Question 2) the concatenation is correct. Many to many relationships require a third 'junction' table. The Doctrine paragraph above explains how the name of this table is generated.
I don't know why the 'table ... does not exist' error is occurring for the junction table as the annotations look ok to me. It appears as though your database schema is somehow out of sync with your annotations.
I implemented a solution, above FOSUserBundle and described it here
After implementing Role access throug Doctrine you still need to make a RoleHierarchy service aware of it.

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