Generic comment system in Symfony2 - symfony

I have in my Symfony 2.1 RC app a simple Comment model (using Doctrine 2). Every comment has a user and a message.
Currently, the CommentBundle manages comments on articles. I'd like it to be more generic to be able to comment any kind of entity without copying code across different bundles dedicated to comments...
For this to work, I also need a way to reference any entity from the comment one. I think having two fields entity_type and entity_id can be a nice solution. However, I can't get the object from these without mapping entity_type to classes manually and using the find method.
So how do I reference an entity from a comment ? And how can I create generic behavior working on several entities ?

You can create a abstract base class entity called Commentable and create entities that inherit Commentable such as Document or Post.
Since Document and Post are derived from Commentable, you can create a one to many relationship between the entities Commentable and Comment respectively.
Make sure to include in your base class ORM annotations for inheritance:
#InheritanceType
#DiscriminatorColumn
#DiscriminatorMap
Examples can be found on Doctrine Project Inheritance Documentation

Related

Use FOSUserBundle in relation with yml-based Entities

I've started a Symfony2 project from scratch where I then installed FOSUserBundle.
Then, I have written (actually, generated with ORM Designer) some entities that need to have relations between them, and with the User entity.
I have Items belonging to Users, Collections belonging to Users that group Items, and so on.
Since I used FOSUserBundle I only have a basic User class (https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/index.md , step 3a) defined using annotations, no config/doctrine folder and no User.yml file in it.
I then created the MyBundle/Resources/config/doctrine folder and added the yml files mentioned above.
When I try to generate the entities with the command-line tool everything works fine: it will create the Entities from my yml files.
However, at this point, trying to load up in browsers the url where the login previously worked (when I only had the FOSUserBundle installed) will throw this error:
MappingException: No mapping file found named
'/var/www/concert/src/X/MyBundle/Resources/config/doctrine/User.orm.yml'
for class 'X\MyBundle\Entity\User'.
Following actions, such as generating the CRUD logic, will not work as long as I have an *.orm.yml file in the config/doctrine folder. If I remove those, CRUD generation will work, but generation of actual mysql tables won't.
Juggling with these gets me to a point where I can also get the tables, but then the actual app doesn't work if I try to use any of the url's where the newly generated CRUD is involved because since the entities are based on yml (which I remove to get things "working") it won't have any mapping knowledge.
Is this inherently wrong? To have yml-based entities in relationship with an User entity based on the FOSUserBundle and still be able to get the nice command-line generation tools?
The problem you describe stems from mixing configuration formats (yaml and I assume annotations). You can easily fix this by ditching the annotations in your models and replacing them with yaml-files like you would do in your own models.
Unfortunately the FOSUserBundle-docs only show you how to use annotations, so here is a quick transformation into yaml format when your X\MyBundle\Entity\User extends FOSUSerBundle's UserEntity:
X\MyBundle\Entity\User:
type: entity
table: fos_user
id:
id:
type: integer
strategy: { generator: "AUTO" }
The remaining stuff is taken care of by FOSUserBundle, as the BaseModel is a mapped-superclass and already describes the stuff in the User.orm.xml, but you could just as well replace the existing values or add additional values just like you would do with your own models.
If you don't use annotations throughout your app, you might also want to disable them in your app/config/config.yml to prevent side effects.

SonataNewsBundle Entity Relationship Definition

I'm trying to create a new entity which will have relationship with SonataNewsBundle Post entity. But I can't find any example in the source how to define relation mapping in xml.
I've read all the configuration under Resources/config/doctrine, none of them had entity relation mapping. Or maybe Sonata use other method to define relationship? Give me some clues.
Ahhhh... Found it...
It's in the DependencyInjection.
Sorry for the lame question

use generated entities as "base class" in sf2/doctrine2

How can I tell Doctrine2 Entity Manager to use an inherited class by default, instead of the generated one?
In my new sf2 app, I generated all entities from the existing database to /src/Package/Bundle/DataBundle/Entity - of course I'd like to have generated forms as well, so I need for my foreign-key relations __toString() methods, which I don't want to put into those generated files because they get overwritten (yes they also get backuped in an extra file, so my changes aren't lost, but manually merging files is not what I want).
So I added new classes to /src/Package/Bundle/DataBundle/Model inheriting all from the entities, but with a __toString() method and surely some other tweaks in the future as well. But now, when I call $entity = $em->getRepository('PackageDataBundle:Customer')->find($id); - I get an instance of /src/Package/Bundle/DataBundle/Entity/Customer instead of /src/Package/Bundle/DataBundle/Model/Customer ..
I'd like to have the behaviour from sf1, where all custom work is done in the inherited classes and the generated ones are the "base" Classes, which can be updated any time on a schema update and aren't touched otherwise..
I hope there is some configuration for this..
Maybe as a bonus, I'd like to have my naming convention turned around: to have Model as the "abstract" generated one and Entity as the actual used one
Thanks.
I'd like to have the behaviour from sf1, where all custom work is done in the inherited classes and the generated ones are the "base" Classes, which can be updated any time on a schema update and aren't touched otherwise..
For purposes you described you should use Propel ORM - it was so in Symfony-1.4, and became even more flexible for Symfony-2.0 with Propel 1.6. It is well documented, easily installed and naturally used within Symfony-2.0
Perhaps I misunderstood your problem, but going from Propel to Doctrine i was also disappointed that there is no way to keep that "dirty" auto-generated code out of my logic.
I do not know how much it is now important to you, but I currently writing a simple bundle that implements such generation style.
$ app/console doctrine:generate:entities СompanySomeBundle --propel-style=true
Generating entities for bundle "СompanySomeBundle"
> backing up User.php to User.php~
> generating Сompany\SomeBundle\Entity\Base\User
> generating Сompany\SomeBundle\Entity\User
https://github.com/madesst/MadesstDoctrineGenerationBundle
PS: Sorry for my english =/

Configurable parameters in Symfony2 entity annotation

I'm trying to create a join across multiple databases (one of them belonging to a legacy application) as described in the Doctrine blog. However, the example suggests hardcoding the name of the database right into the schema, which I'd like to avoid for obvious reasons.
Is there a way to read parameters defined in parameters.ini or config.yml and use them as a value for the annotations, like this?
/**
* #ORM\Table(name="%legacy_db_name%.%legacy_table_name%")
*/
No, it's impossible. The "%key%" form is only available in the DIC.
Why would you put these data in a yml file? Would it be useful?

Why we create Entity/Enquiry.php And Form/EnquiryType.php In Seperate Folders Symfony2?

Going through the Symblog tutorial of Symfony2, While creating forms I came to a point where in I create Contact Entity (Entity/Enquiry.php) where I define some fields and some methods to access these fields. Then I create another folder Form/EnquiryType.php to build the form and then a contact.html.twig to display. I am unable to understand why we created 2 namespaces for Entity/Enquiry.php and Form/EnquiryType.php. when they have to deal with each other. Why dont we wrote both the classes within one folder or one file. And one more question. Do they belong to Controller or View part of MVC.
Form types are here to configure how data coming from objects (like Entities) are mapped to a form (and vice/versa).
Entities should'nt be named "entities", they should be just your buisness objects, that can be persisted through a layer called doctrine2.
To answer you on separation of concerns,
Entities are about M,
while form Types are about user inputs (so the VC).
View because it render a human interface to let user enter input,
Controller because that's where you handle the form lifecycle.
The reason is logical separation. Why don't we define all parts of MVC in one folder/namespace? Because it will be a mess. That's why logical separation is needed.
And not all entities have to have related form types — using entities without forms is normal.

Resources