Это можно сделать, расширив отображение данных для указанного c объекта. Когда аннотации анализируются, Doctrine запускает событие :
Когда считывается информация о сопоставлении для объекта, он заполняется в экземпляре ClassMetadataInfo. Вы можете подключиться к этому процессу и управлять экземпляром.
Подписавшись на это событие, можно установить значение DiscriminatorMap
для объекта после его загрузки.
Вот общий пример. Сначала реализуем подписчика. При загрузке соответствующего объекта (Item::class
) добавьте соответствующий DiscriminatorMap
.
<?php
namespace App\Doctrine\Listener;
use App\Entity\Item;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
class LoadClassMetadataSubscriber implements EventSubscriber
{
private $discriminatorMap;
public function __construct( $discriminatorMap)
{
$this->discriminatorMap = $discriminatorMap;
}
public function getSubscribedEvents()
{
return [
Events::loadClassMetadata
];
}
/**
* @param LoadClassMetadataEventArgs $eventArgs
*/
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
{
/**
* @var \Doctrine\ORM\Mapping\ClassMetadata $classMetadata
*/
$classMetadata = $eventArgs->getClassMetadata();
if ($classMetadata->name !== Item::class) {
return;
}
$map = [];
foreach ($this->discriminatorMap as $value) {
$partial = explode('=', $value);
$map[$partial[0]] = $partial[1];
}
$classMetadata->setDiscriminatorMap($map);
}
}
Поскольку карта дискриминатора добавляется после анализа класса, Entity\Item
не требуется аннотация DiscriminatorMap
:
<?php
namespace App\Entity;
use App\Map;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(...)
* @ORM\Table(...)
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="discr", type="string")
*/
abstract class Item {
в среду должно быть добавлено сопоставление (.env
или аналогичное):
DISCRIMINATOR_MAP=one=App\Entity\Item\One,two=App\Entity\Item\Two
Зарегистрируйте подписчика на правильное событие (config/services.yaml
):
services:
...
# Set up the custom subscriber. It'll take the environmental variable as
# an argument, and subscribe to the `loadClassMetadata` event.
App\Doctrine\Listener\LoadClassMetadataSubscriber:
public: true
arguments:
- '%env(csv:MAP)%'
tags:
- { name: doctrine.event_listener, event: loadClassMetadata, lazy: true }