Как создать динамическую ассоциацию сущностей с Doctrine2 в Symfony2

Я создаю CMS с динамической маршрутизацией, системой управления версиями и несколькими различными типами контента, например, статьей, профилем и т. Д. У меня есть объект ContentType, который хранит все доступные типы контента, которые могут быть видны. Но данные для этого экземпляра типа содержимого будут храниться в отдельном объекте (поскольку поля уникальны для каждого типа контента, поэтому он не может полностью входить в ViewVersion ).

 Routing --> View --> ViewVersion --> Article or Routing --> View --> ViewVersion --> Profile Routing A --ManyToOne--> View D Routing B --ManyToOne--> View D Routing C --ManyToOne--> View D View D --> ManyToOne -> ContentType (define what type this view is) View D --> OneToOne --> Settings View D --OneToMany--> ViewVersion E View D --OneToMany--> ViewVersion F View D --OneToMany--> ViewVersion G (*published version*) ViewVersion E --OneToOne--> Article E ViewVersion F --OneToOne--> Article F ViewVersion G --OneToOne--> Article G 

Подробную справочную информацию о рабочем процессе приложения (по-прежнему в потоке) можно найти в моем связанном с этим вопросе в разделе «Справочная информация о проекте и структуре кода».

Каждый из этих типов контента будет иметь разные поля и функциональные возможности, поэтому они будут определены в уникальных пакетах, и они должны существовать в своих собственных сущностях (таблицы базы данных с уникальными полями).

Мой главный контроллер находит представление на основе URL- Routing и загружает правильный контроллер связки для сборки страницы (с уникальными функциями и шаблоном для области тела).

Объект Routing хранит один или несколько URL-адресов, указывающих на объект View .

Объект View является базовым заполнителем, к которому могут указывать маршруты, а затем указывает на несколько версий и устанавливает идентификатор опубликованной версии.

ViewVersion имеет всю базовую информацию для HTML-страницы, метаданных, оболочки дизайна, заголовка браузера и т. Д., Но ничего не содержит о содержании. Новый ViewVersion сохраняется при редактировании новым пользователем или если версия не была сохранена за 30 минут.

Нет Gutensite\ArticleBundle\Entity\Article , он будет фактическим сущностью из пакета, например Gutensite\ArticleBundle\Entity\Article , Gutensite\ProfileBundle\Entity\Profile и т. Д. И будет напрямую связан с ViewVersion на основе набора View-> ContentType (поэтому мы знаем, какой тип сущности он). ContentType (например, Article) будет OneToOne обратно к соответствующему id ViewVersion, например Article-> viewVersionId (каждая версия имеет одну запись типа контента). Каждый раз, когда сохраняется новая ViewVersion, сохраняется соответствующий ContentType (клонирование всех ассоциаций сущностей). Они по сути являются одной записью, просто разделенной на разные объекты из-за динамической взаимосвязи между представлением и несколькими типами контента.

Традиционное сопоставление ORM не будет работать между ViewVersion и динамическим ContentType, поскольку контент может быть одним из нескольких разных объектов в разных пакетах, поэтому я не могу сопоставить одну статическую структуру Article или Profile. Эта связь должна быть динамичной.

Я хотел бы установить ассоциацию, чтобы я мог легко вызвать $ viewVersion-> getContent (), чтобы получить поля типа контента, а также использовать formBuilder для загрузки права formType для этого объекта.

Легко связать правильный FormType для построителя форм:

 class ViewVersionType extends AbstractType { public function getName() { return 'viewVersion'; } public function buildForm(FormBuilderInterface $builder, array $options) { // Add all the regular Fields $builder->add(...); // Add Dynamic Content Type Association //Get the form type for the requested content type and merge with the default view form $viewVersion = $builder->getData(); $view = $viewVersion->getEntity(); $contentPath = $view->namespace_bundle.'\\Form\\Type\\'.$view->getContentType()->getBundle().'Type'; $builder->add('content', new $contentPath, array( 'label' => false )); } } 

Но каков наилучший способ добавить динамическое сопоставление между ViewVersion и связанным с ним ContentType?

Опции

Я читаю о Resolve Target Entities, но это не похоже на лучший вариант, плюс вам нужно зарегистрировать каждый комплект в конфигурации orm, который не идеален.

Я также читал о модификации динамической формы, но это действительно не обязательно, учитывая мое решение для форм и не решает основной проблемы сопоставления сущностей.

Я также читал о динамическом сопоставлении через подписчика событий, который кажется именно тем, что мне нужно. Я предполагаю, что я поместил бы черту в объект динамического типа контента, чтобы указать BACK в ViewVersion. Тогда я бы разделил ассоциацию отображения между ними. Но я все еще не могу понять, как получить доступ к данным, которые мне нужны в этом событии подписчика, правильно рассказать ViewVersion о объекте Article или Profile. Я еще не понял общую картину архитектуры Symonfy, чтобы узнать, как все связано, как получить доступ к переменным, которые мне нужны, и где найти правильную документацию!

Related of "Как создать динамическую ассоциацию сущностей с Doctrine2 в Symfony2"

Некоторые мысли здесь могут помочь (или нет):

  • Структура, которую вы пытаетесь достичь, похожа на то, как Drupal управляет содержимым с использованием узлов, типов контента и версий узлов. Вы можете больше узнать о том, как они структурировали его здесь .

  • У меня такое ощущение, что ContentType должен быть связан с View not ViewVersion . Я не могу себе представить, что разные версии одного и того же представления могут иметь разные типы контента. Вид должен иметь определенный тип и разные версии.

  • Я не могу понять, почему View -> ContentType ContentType будет отношением OneToOne. Я бы сказал, что существует набор типов контента, и каждый View присваивается одному ContentType поэтому он больше похож на отношение ManyToOne.

  • Я бы не попытался создать пакет для типа контента. Я бы сказал, что у вас может быть пакет Blog с разными типами контента и представлениями.

  • View entity может иметь $content_type_id который ссылается на id ContentType . Doctrine использует ленивую загрузку, и когда вы загружаете объект View , доктрине будет не важно, к какому ContentType он относится, но будет знать о content_type_id этого View и всякий раз, когда вам нужен связанный ContentType он будет запускать запрос, чтобы получить его и ссылку правильный ContentType для вашего View .

  • Мне всегда лучше искать идеи, глядя на исходный код пакетов symfony и посмотреть, как вещи структурируются.