Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save jasonhofer/8695931 to your computer and use it in GitHub Desktop.
Save jasonhofer/8695931 to your computer and use it in GitHub Desktop.
A Doctrine listener that allows you to inject your own generated discriminator map rather than have to define it in an entity's class doc block with the @DiscriminatorMap() annotation.
<?php
/**
* The DiscriminatorMap() annotation in an entity's class doc comment can be
* empty, but if it is, Doctrine will create a default discriminator map
* using the lower-case short name of each sub-class as the discriminator
* "type" name. This may be just fine for your purposes, but if not,
* this listener provides a way to programmatically inject your own
* discriminator map.
*
* To prevent Doctrine from creating the default discriminator map, you will
* need to put at least one "type"="class" pair in the annotation. You can
* just use the parent class itself for this.
*
* I do the count() check between the two discriminator maps because I found
* that, for some reason, the map would be assigned more than once. I'll have
* to re-confirm that sometime, though.
*
* I'm using Doctrine within the Symfony 2 framework here, and I'm using the
* JMS DI Extra Bundle to define the service.
*/
namespace My\Doctrine\ORM\Listener;
use JMS\DiExtraBundle\Annotation as DI;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
/**
* @DI\Service("my.create_discriminator_map.listener", public=false)
* @DI\DoctrineListener(events={"loadClassMetadata"})
*/
class CreateDiscriminatorMapListener
{
/**
* @var array
*/
protected $discriminatorMap;
/**
* @param string[] $discriminatorMap
* @DI\InjectParams({"discriminatorMap"=@DI\Inject("%my.discriminator.map%")})
*/
public function __construct(array $discriminatorMap)
{
$this->discriminatorMap = $discriminatorMap;
}
/**
* @param LoadClassMetadataEventArgs $args
*/
public function loadClassMetadata(LoadClassMetadataEventArgs $args)
{
$cMeta = $args->getClassMetadata();
if (
$cMeta->name == 'My\\Bundle\\FooBundle\\Entity\\ParentEntity' &&
count($cMeta->discriminatorMap) < count($this->discriminatorMap)
) {
$cMeta->setDiscriminatorMap($this->discriminatorMap);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment