Подкласс карты как его расширенный родитель

Я создал следующий абстрактный класс, который использует наследование одной таблицы и карты подклассов на DiscriminatorColumn model,

/**
* @Entity
* @Table(name="entity")
* @InheritanceType("SINGLE_TABLE")
* @DiscriminatorColumn(name="model", type="string")
* @DiscriminatorMap({
*      "green" = "model\GreenEntity",
*      "blue"  = "model\BlueEntity"* })
*/
abstract class AbstractEntity
{
/** @Id @Column(type="string") */
protected $entity_id;
}

Допустим, я расширяю абстрактный класс AbstractEntity по некоторым классам:

class GreenEntity extends AbstractEntity {}
class BlueEntity extends AbstractEntity {}

И расширить их еще на несколько подклассов

class GreenEntityChildOne extends GreenEntity {}
class GreenEntityChildTwo extends GreenEntity {}
class BlueEntityChildOne extends BlueEntity {}
class BlueEntityChildTwo extends BlueEntity {}

Теперь, например, когда я создаю экземпляр GreenEntityChildOne и сохранить его в базе данных, он выдаст исключение, что у меня нет сопоставления для него.

То, что я пытаюсь сделать, это получить GreenEntityChildOne отображаться как GreenEntity (точнее, каждый класс, который расширяет класс ниже AbstractEntity отображаться как класс, который расширяет верхний абстрактный класс).

Это вообще возможно?

7

Решение

Это невозможно с чистыми аннотациями

Да, сопоставление, которого вы пытаетесь достичь, возможно. Однако не с чистыми аннотациями. Важно то, что доктрина должна знать все подклассы во время выполнения. Если вы не хотите явно указывать их в аннотациях сопоставленного суперкласса, вам нужно будет предоставить их динамически.

Система событий Доктрина на помощь

На блоге есть отличный пост динамическое отображение с Doctrine, который объясняет, как вы можете использовать обработчики событий Doctrine для программного изменения загруженного ClassMetadata,
Чтобы динамически добавлять подклассы в карту дискриминатора, вы можете реализовать прослушиватель событий Doctrine, например:

class DynamicDiscriminatorMapSubscriber implements EventSubscriber
{
public function getSubscribedEvents()
{
return array(Events::loadClassMetadata);
}

public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
{
$metadata = $eventArgs->getClassMetadata();
$metadata->addDiscriminatorMapClass("GreenEntityChildOne", GreenEntityChildOne::class);
}
}

Зарегистрируйте своего подписчика

Теперь вам нужно всего лишь зарегистрировать подписчика на событие в Doctrine. В идеале вы должны добавить классы, которые хотите добавить, на основе вашей конфигурации подписчику на событие.

// create dynamic subscriber based on your config which contains the classes to be mapped
$subscriber = new DynamicDiscriminatorMapSubscriber($config);
$entityManager->getEventManager()->addEventSubscriber($subscriber);

дальнейшее чтение

Кроме того, посмотрите на PHP картографический раздел в руководстве по доктрине и тем более информативным API документы для ClassMetadataBuilder,

1

Другие решения

Ответ, возможно, на Доктрине Docs:

«Все классы сущностей, являющиеся частью отображенной иерархии сущностей (включая самый верхний класс), должны быть указаны в @DiscriminatorMap»

http://doctrine-orm.readthedocs.org/en/latest/reference/inheritance-mapping.html

Вы указали только GreenEntity и BlueEntity.

Я не знаю о чем говорю. Это первое, что я когда-либо читал о Доктрине …

0

По вопросам рекламы [email protected]