Используя инструменты CLI Symfony 2, как я могу генерировать геттеры и сеттеры с правильным типом намека на подклассы?

Фон

Я разрабатываю приложение с использованием Symfony 2, которое структурировано таким образом, что "Core" bundle определяет сущности, отношения и поля. Затем другие узлы могут специализировать основные функции по наследованию, так называемые "дочерние" пакеты.

Аннотации Doctrine 2 были использованы для определения основного объекта, называемого "Пакет". "Пакет" связывает архитектурный дизайн и кусок земли - по сути, пакет для дома и земли. Я привел примеры к более базовой форме, поэтому вы не найдете определения для Land и ChildLand в приведенных ниже примерах, но можете предположить, что они были реализованы аналогичным образом.

Обновление

По словам пользователей на канале FreeNode #symfony, это проблема доктрины, так как команда app/console просто вызывает консоль доктрины. Я использую доктрину 2.3.

Вот диаграмма, показывающая общую ситуацию, которая вызывает проблему, которая должна помочь визуализировать сценарий:

(ссылка imgur на полноразмерное изображение) Type hinting contract breaking

Кроме того, здесь приведена ссылка на отчет об ошибке для трекера третирования доктрины: http://www.doctrine-project.org/jira/browse/DDC-2605

Обновление 2 - Более подробная ERD

Структура отношений между объектами была поставлена ​​под сомнение, поэтому ниже - лучший пример структуры данных, которую мы реализуем.

Основное требование - снова иметь основные классы, которые предоставляют общий набор сущностей и полей. Ролевые классы в корпоративных пакетах расширяют эти основные классы.

Мы давно рассмотрели EAV, но в этом подходе мы потратим гораздо больше времени на создание платформы и инструментов для управления данными EAV, а не на удовлетворение существующих бизнес-требований, мы не сможем использовать доктрину для управления сущности, поскольку они будут определены в базе данных и т.д. и т.д.

По прошествии времени, и я лучше понимаю эту проблему, кажется, единственная проблема связана с геттерами и сеттерами, созданными инструментом CLI доктрины, поскольку они нарушают контракты типа hinting, как указано ниже. Эта структура отлично работает, когда эти проблемы исправляются вручную.

(ссылка imgur на полноразмерное изображение) Detailed data structure

Создание объектов с помощью инструмента CLI

Итак, изначально я использовал инструмент командной строки...

> app/console doctrine:generate:entity

... для создания заглушек объектов с базовыми сопоставлениями полей, затем вручную добавлено отношение к земле (поскольку инструмент, похоже, не поддерживает отношения):

Это результирующий код:

core Объект пакета: http://pastebin.com/3ujPT1mJ

дочерний объект пакета: http://pastebin.com/sjAB0XJ2

Генерация Getters и Setters

Затем я создаю геттеры и сеттеры, выполняя:

> app/console doctrine:generate:entities CompanyCoreBundle

> app/console doctrine:generate:entities CompanyChildBundle

Что автоматически изменяет определения ядра и дочернего объекта:

core Объект пакета: http://pastebin.com/kfQRxcnm

дочерний объект пакета: http://pastebin.com/UdiPP9xX

Проблема!

Итак, суть проблемы такова: если вы сравниваете функцию setLand в пакете Core и Child, вы можете видеть, что объявления разные:

public function setLand(\Company\CoreBundle\Entity\Land $land = null)
public function setLand(\Company\ChildBundle\Entity\ChildLand $land = null)

Ошибки: (

К сожалению, подсказки разных типов приводят к строгим ошибкам PHP, например:

PHP Fatal error:  Class 'Symfony\Component\Debug\Exception\ContextErrorException' not found in ... Company/ChildBundle/Entity/ChildPackage.php on line ...

и

Runtime Notice: Declaration of ... should be compatible with ... in ... line ...

Причина ошибок

Проведя некоторое исследование относительно того, почему это было проблемой, я читал в нескольких местах, что изменение типа намека в подклассах прерывает типы намекающих контрактов (см. этот пост: Есть ли способ переопределить подсказку типа к классу потомков при расширении абстрактного класса?).

Опции

Есть некоторые очевидные, но не идеальные варианты:

  • Я могу подавить строгие уведомления довольно легко, но мой менеджер по развитию борется с перспективой создания исключений из снежинок в наших процессах CI.
  • Я могу вручную отредактировать код, который генерирует доктрина, чтобы удалить все намеки типа или обеспечить, чтобы подсказки типа дочернего класса были такими же, как родительские. Выполнение этого делает работу кода, но я вижу, что это утомительно, если я не пишу некоторые сценарии, чтобы управлять этим для меня.
  • Я могу просто не использовать инструменты командной строки и вручную создавать сущности и сущности. Я предпочел бы автоматизировать это со сценариями: (

Мой вопрос!!! (Наконец)

Мой вопрос в том, можно ли использовать инструменты командной строки, чтобы делать то, что я пытаюсь сделать здесь? В идеале, мне бы хотелось, чтобы вы могли выполнять команды консоли доктрины для генерации сущностей и геттеров и сеттеров без ручного вмешательства, чтобы исправить подсказки типов в подклассах. Если это не так легко достижимо, какой лучший вариант?

Благодарность

Спасибо!

Ответ 1

Я не совсем уверен, какой процесс вы будете использовать для определения сущностей, но для того, чтобы полезно создавать устойчивые объекты с Doctrine, такие как GenericEngine и FordEngine, вы хотите @MappedSuperclass

http://docs.doctrine-project.org/en/latest/reference/inheritance-mapping.html#mapped-superclasses

Это эквивалент Доктрины абстрактного класса.

На этой странице связаны некоторые другие интересные наследования. Они могут вам помочь.

Что касается создания этого материала автоматически, он может быть выполнимым, но выше моего уровня оплаты на +50 баллов репутации.:-) Doctrine может помочь вам генерировать шаблоны кода для ваших сущностей, но на самом деле время разработки сущностей и их взаимоотношений лучше потрачено, чем время, приходящее на комбинацию магической командной строки.

(Я сам имел бы объект Manufacturer и имел бы отношение "один ко многим" между Engine и Manufacturer. Но это не то, что вы просили.: -)