Symfony2 - Как динамически получить сущность Doctrine для Entity Manager
Мы создаем CMS и платформу для создания веб-сайтов с большим количеством сайтов разных поставщиков и клиентов, поэтому существует множество различных типов контента, которые редактируются общими контроллерами и вспомогательными службами, которые не обязательно (легко) знают, что такое Менеджер сущностей для данной сущности.
ПРИМЕЧАНИЕ. У нас есть несколько сущностей-менеджеров для разделения доступа к различным базам данных, например, Глобальный, биллинг, локальный и т. Д.
Во многих случаях нам необходимо определить, что представляет собой EntityManager объекта. Например, у нас есть MediaHelper, который динамически связывает медиа из базы данных с соответствующими полями на объекте (это не работает с ассоциациями, потому что Медиа должен соединяться буквально с любым объектом, и у вас не может быть такого рода динамической ассоциации и мы не хотим сотню разных ассоциаций).
Носитель находится в связке, управляемой «Локальным» EntityManager. Но объект может находиться в «глобальном» EntityManager (вы не можете предполагать, что он находится в том же менеджере объектов). Таким образом, мы должны обнаружить и сохранить правильного менеджера сущности для правильной сущности.
Итак, как вы рекомендуете динамически определять entityManager для сущности?
Оригинальный Пользовательский МетодПРИМЕЧАНИЕ: принятый ответ является гораздо лучшим решением. Это только для архивных целей.
Вот простое решение, которое работает. Но я не знаю достаточно о Symfony и Doctrine, чтобы понять, плохая ли это идея? Кто-нибудь еще знает? Если нет, я не знаю, почему это не было бы в основе, как Утилита Доктрины.
Я создал сервис EntityHelper, который внедряет в него сервис Doctrine:
gutensite_cms.entity_helper:
class: Gutensite\CmsBundle\Service\EntityHelper
arguments:
- "@doctrine"
Затем в помощнике по сущностям есть одна простая функция для получения Entity Manager для сущности (config.yml уже регистрирует пакеты для менеджеров сущностей):
/**
* Automagically find the entityManager for an entity.
* @param $entity
* @return mixed
*/
public function getManagerForEntity($entity) {
$className = \Doctrine\Common\Util\ClassUtils::getRealClass(get_class($entity));
foreach (array_keys($this->doctrine->getManagers()) as $name) {
if(in_array($className, $this->doctrine->getManager($name)->getConfiguration()->getMetadataDriverImpl()->getAllClassNames())) return $em;
}
}
НОТА:Реестр доктрин # getAliasNamespace уже делает что-то, почти идентичное этому циклу foreach, я просто изменил идею, чтобы вернуть менеджер сущностей вместо пространства имен, например
public function getAliasNamespace($alias) {
foreach (array_keys($this->getManagers()) as $name) {
try {
return $this->getManager($name)->getConfiguration()->getEntityNamespace($alias);
} catch (ORMException $e) {
}
}
throw ORMException::unknownEntityNamespace($alias);
}
Обновление 21.10.15: Обновлен код обнаружения сущностей согласно предложению @ Cerad.