Map a discriminator column to a field with Doctrine 2

Sadly, there is no documented way to map the discr column to an entity. That's because the discr column is really part of the database and not the entity.

However, it's quite common to just put the discr value directly in your class definition. It's not going to change and you will always get the same class for the same value anyways.

class Person
{
    protected $discr = 'person';

class Employee extends Person
{
    protected $discr = 'employee';

Here's a small example of what I have in one of my ZF2 projects (using Doctrine MongoDB ODM):

// an instance of your entity
$entity = ...;

/** @var \Doctrine\ODM\MongoDB\DocumentManager $documentManager */
$documentManager = $serviceManager->get('DocumentManager');

/** @var \Doctrine\ODM\MongoDB\Mapping\ClassMetadataFactory $factory */
$factory = $documentManager->getMetadataFactory()

/** @var \Doctrine\ODM\MongoDB\Mapping\ClassMetadata $metadata */
$metadata = $factory->getMetadataFor(get_class($object));

if ($metadata->hasDiscriminator()) {
     // assuming $data is result of the previous extraction
     $data[$metadata->discriminatorField] = $metadata->discriminatorValue;
}

What I have done is I've implemented a custom interface DiscriminatorAwareInterface and I only apply the checks to classes that implement it (in your case it would be the class that all "discriminated" classes extend.

As a result I end up with code that looks like this:

// add value of the discrinimator field to entities that support it
if ($object instanceof DiscriminatorAwareInterface) {
    /** @var \Doctrine\ODM\MongoDB\Mapping\ClassMetadata $metadata */
    $metadata = $factory->getMetadataFor(get_class($object));

    if ($metadata->hasDiscriminator()) {
        $data[$metadata->discriminatorField] = $metadata->discriminatorValue;
    }
}

I'm pretty sure it will be the same if you use the standard ORM, except instead of a document manager you will have entity manager.

Tags:

Doctrine Orm