How to extend symfony entity in bundle - php

Is there a way I can extend a symfony entity in another bundle using #DiscriminatorMap without having to specify it beforehand?
BundleA
Has a class AbstractQueueItem which is a MappedSuperclassfor
Event which is extended by
CreateEvent and DeleteEvent as Single Table Inheritene or Class Table Inheritence
BundleB
How can I add a new Event (i.e. UpdateEvent) to the Event-hierarchy without modifing BundleA?

You can try letting doctrine auto-generate the discriminator map.
From the last bullet point in this section of the docs:
If no discriminator map is provided, then the map is generated
automatically. The automatically generated discriminator map contains
the lowercase short name of each class as key.
So you would:
Omit the #DiscriminatorMap declaration in BundleA.
Extend the entity as normal in BundleB (making sure the short name of each class is unique).
Update the database schema.
EDIT
As pointed out by ju_ in the comments, this solution will apparently not work with Doctrine ORM 3.0, but should still be valid for versions 2.5 - 2.7

Related

ZF2 + Doctrine 2 - Child-level discriminators with Class Table Inheritance

Much asked on SO and around the web with regards to ZF2 with Doctrine 2 and using Discriminators is: how do you not declare all child Entities on the parent Entity? Especially when you have multiple modules?
The short answer is: do not declare a discriminatorMap. Doctrine will handle it for you.
The longer answer is below.
A popular article on how to be able to declare your child Entities, on the children Entities, instead of the parent, is this one.
However, Doctrine 2 has changed somewhat since it was written, e.g. the AnnotationWriter no longer exists.
There, however, is a simpler way, as I mentioned in the question: do nothing.
To now use Discriminators using the “Class Table Inheritance” method (as opposed to “Single Table Inheritance”) is to NOT DECLARE a Discriminator Map! (Not sure if this will also work for STI…)
I found an old ticket on Github that explains the same issue as this answer and which many people still have, that declaring on the parent makes no sense. After reading through that, I dove into the code and re-read the docs, carefully.
Also, if you’re reeeeaaally careful when reading the docs, it says this is possible, by not saying it.
Quoting:
Things to note:
The #InheritanceType, #DiscriminatorColumn and #DiscriminatorMap must be specified on the topmost class that is part of the mapped entity hierarchy.
The #DiscriminatorMap specifies which values of the discriminator column identify a row as being of which type. In the case above a value of “person” identifies a row as being of type Person and “employee” identifies a row as being of type Employee.
The names of the classes in the discriminator map do not need to be fully qualified if the classes are contained in the same namespace as the entity class on which the discriminator map is applied.
If no discriminator map is provided, then the map is generated automatically. The automatically generated discriminator map contains the lowercase short name of each class as key.
Of course, the above piece of documentation does explicitly state that a map would be generated if none was provided. Though it contradicts the first thing to note, which is that the #DiscriminatorMap must be provided on the topmost class in the hierarchy.
So, if you were to stretch your classes across several modules (as I assume that’s why you would be reading this), do not declare a discriminator map!
I’ll leave you with an example below:
<?php
namespace My\Namespace\Entity;
/**
* #Entity
* #InheritanceType("JOINED")
* #DiscriminatorColumn(name="discr", type="string")
* // NOTE: No #DiscriminatorMap!!!
*/
class Person
{
// ...
}
<?php
namespace My\Other\Namespace\Entity;
/** #Entity */
class Employee extends \My\Namespace\Entity\Person
{
// ...
}
When you use the doctrine CLI command to check your entities, you’ll find this is correct.
Also, check that it fully works by using the entity checking command:
./vendor/bin/doctrine-module orm:mapping:describe “\My\Namespace\Entity\Person”
Near the top of the response of that command will be this line:
| Discriminator map | {“person”:”My\\Namespace\\Entity\\Person”,”employee”:”My\\Other\\Namespace\\Entity\\Employee”}

Inserting data with Doctrine - Repository Vs Entity

I've realized there is a difference between a Doctrine repository and Doctrine entity.
I'm trying to implement simple CRUD actions on a table and was injecting a default Doctrine repository into my controller (without injecting an entity).
For the "Update" action I would first ->find($id) for the record to update and it would return an instance of the entity for me to bind to my form object.
For the "Create" action I realized I can't ->find($id) a record to insert (since it doesn't exist) in order to retrieve an instance of the entity for me to bind to my form object.
Is there is an alternate way to insert data using Doctrine without an instance of an entity? Or is there a way to retrieve an instance of the entity from the repository so I can ->bind() it to the form? If the answer to both are no, then I imagine my only options are to inject an instance of the entity to my controller, or to use a custom repository which contains a method which would return an entity to use in the ->bind() for insertion.
My guess would be to define a custom repository which has a method which retrieves an empty entity instance for use in insertion. Is this assumption correct?
As pointed by #Crisp in comments, Entities are no more than PHP classes, same for Repositories.
The two are differentiated by their respective role.
You'll never implicitly create a new instance of a Repository because doctrine do it for you across DependencyInjection principles (Service, Factory, ...).
To create a new database entry, you must create a new instance of the corresponding entity, then store it using EntityManager::persist and EntityManager::flush methods.
Reuse the same instance of an entity would not give you any benefit, nor make any difference in your project's maintainability.
The entity class itself will never be broken/changed, only instances of them are created, renamed, moved, deleted.
These instances represents your database entries, this is the primary interest of use an ORM.

Remove mapped doctrine field of parentclass in Symfony [FOSUserBundle]

How is it possible to remove a field that got inherited as doctrine column from mapping?
Example:
In FosUserBundle, I don't need some of the columns (e.g. salt, expiresAt...) within my User class. How can I tell symfony/doctrine to not map this column anymore to the database / remove it from the mapping? I know how to "reconfigure" the columns by using #AttributeOverride, but how can I completly remove a field from the mapping?
Regards.
Pretty much all default properties of the FOSUB User entity are mandatory to make the bundle working as expected.
The fields you given (salt, expiresAt) are related to the security, as the most part of the User properties.
Remove one of them may have side effects in your user management.
Also, you can't Selectively inherit parts of an entity.

add prefix in table name without change in annotation of Doctrine

I am using Doctrine2 with codeigniter. my project has created but i have to add prefix in database table. In codeigniter I have solved this issue with dbprefix $db['default']['dbprefix'].
But Doctrine not support it because Entity classes are not created with prefix. So it can't find Table.
I want to add table prefix in doctrine also without change in Entity class name of doctrine. Is there any possibility to add some prefix.
I have search TablePrefix Class but this class not working in my Doctrine library.
Previously Project created without prefix table name like "user" and entity annotation has also created with "User". But now I added prefix in all table "my_user"
Please Help!!
You can add a table prefix by using Doctrines event manager as described in the Doctrine documentation here:
http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/cookbook/sql-table-prefixes.html
In a previous question, simshaun has given a good example of how to implement this in symphony:
How to setup table prefix in symfony2

How to define doctrine record filter in symfony's schema.yml?

Doctrine documentation explains that in order to add doctrine record filter, you have to unshiftFilter() to table definition setUp() method:
public function setUp(){
parent::setUp();
$this->unshiftFilter(new MyDoctrineRecordFilter());
}
In symfony's case that supposed to go to base class (i.e. /lib/model/doctrine/base/BaseArticle.class.php) but as symfony overwrites base classes every time i rebuild the schema - how (or where) should i define that filter so it would appear there after running the doctrine:build command? I can't find any reference in doc or internet about it's definition in schema.yml.
Thanks.
We are using doctrine 1.2.4. It seems that there is no yaml-schema equivalent
As you've learned, never make any changes to automatically generated base classes. Your changes will just be wiped away.
Instead, you'll find child classes that extend your base classes. Symfony/Doctrine won't touch those once they are created (with the exception of symfony doctrine:clean-model-files). In your case, look for:
/lib/model/doctrine/Article.class.php
Form Filters are defined similarly on a different path:
/lib/filter/doctrine/base/BaseArticleFormFilter.class.php
/lib/filter/doctrine/ArticleFormFilter.class.php

Categories