Подтвердить что ты не робот

Наследование цепей Symfony2 потеряет родительские пучки

Я пытаюсь создать простое наследование наложения, как указано в здесь, и столкнулся с проблемой с маршрутами. Я использую аннотации для маршрутизации. Когда я регистрирую свой дочерний пакет в AppKernel.php, все мои пути родительских пакетов теряются.

Для того, что я понимаю из документации, Symfony2 должен искать все файлы, включая маршруты, сначала из дочернего пакета, а затем из родительского пакета. Теперь, когда этого не происходит, загружаются только контроллеры дочерних пучков.

В моем дочернем пакете Bundle файл я реализовал функцию getParent, как указано, и в моем routing.yml у меня есть:

ParentBundle:
resource: "@Parent/Controller/"
type:     annotation
prefix:   /admin/

который отлично работал до наследования.

Я тестировал, что система работает нормально, если в нее включены все файлы контроллера separetely в routing.yml, но это кажется очень громоздким способом заставить наследование работать, поскольку я только хочу переопределить несколько частей родительского пакета (не все контроллеры).

Профайлер показывает оба моих пакета как активные.

4b9b3361

Ответ 1

Я нашел правильное решение для этой проблемы. Сегодня я также пытался переопределить родительский пакет, настроенный с помощью маршрутизации аннотаций, а также обнаружил, что родительские маршруты игнорировались, если маршрутизация анотаций импортировала весь пакет ( "@SomeBundle/Controller" ).

После небольшой отладки я обнаружил, что объяснение этого заключается в том, что если вы используете "@" в качестве префикса для контроллера, это перейдет к решателю ядра, который будет возвращать ТОЛЬКО дочерний ресурс, если родительский ресурс был переопределен. Таким образом, решение состоит в том, чтобы предоставить полный путь пакета, учитывая, что ядро ​​попытается сопоставить ресурс из приложения/ресурсов, поэтому вам нужно будет добавить относительный каталог (../../) до фактического пути:

# app/config/routing.yml:
some_parent:
    resource: "../../src/Application/ParentBundle/Controller"
    type: annotation

# ChildBundle implements getParent() method to inherit from ParentBundle
some_child:
    resource: "@ChildBundle/Controller"
    type: annotation

Это будет работать как ожидалось: все родительские маршруты будут импортированы и будут переопределены всеми маршрутами, указанными в дочернем пакете.

Ответ 2

В дополнение к предыдущему ответу я также должен был изменить имя routing.yml дочернего пакета (например, routing_child.yml), чтобы заставить его работать. Я предполагаю, что это потому, что Symfony полностью игнорирует файл маршрутизации родительского пакета, если имя идентично.

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

# routing_child.yml     
_parent:
    resource: "@MyParentBundle/Resources/config/routing.yml"

Ответ 3

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

Самый простой способ "переопределить" маршрутизацию пакетов - никогда не импортировать его вообще. Вместо того, чтобы импортировать стороннюю маршрутизацию пакетов, просто скопируйте этот файл маршрутизации в свое приложение, измените его и импортируйте вместо него.

Кроме того, вы не можете включить родительский пакетный файл маршрутизации с использованием символических имен "@ParentBundle", потому что это имя разрешено "@ChildBundle".

Если вы действительно хотите включить файл родительских маршрутов, то вы должны использовать абсолютный путь к этому файлу или пути относительно текущего каталога, то есть:

# @YourChildBundle/Resources/routing.yml
YourParentBundle:
  resource: "/srv/www/example.com/src/Your/ParentBundle/Resources/routing.yml"

или

# @YourChildBundle/Resources/routing.yml
YourParentBundle:
  resource: "../../../../../Your/ParentBundle/Resources/routing.yml"

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

cd YourChildBunde
ln -s ../../../../../Your/ParentBundle/Resources/routing.yml parent_routes.yml

а затем

# @YourChildBundle/Resources/routing.yml
YourParentBundle:
  resource: "parent_routing.yml"

P.S. Я надеюсь, что они найдут лучший и менее уродливый способ переопределить и расширить маршрутизацию из родительского пакета, но теперь мы должны рассмотреть некоторые из этих уродливых обходных решений.

Ответ 4

С наложением наложения вы можете переопределить родительские файлы пакетов.

Если вы создаете файл маршрутизации в том же месте, что и родители в вашем пакете (если маршрутизация родительского файла находится в ParentBundle/Resources/config/routing.yml, и вы создаете файл маршрутизации в ChildBundle/Resources/config/routing.yml), он переопределит родительский routing.yml, а symfony будет использовать только child routing.yml.

Я не пробовал, но если вы импортируете родительский пакет routing.yml в дочерний пакет routing.yml, вы можете решить свою проблему. Поскольку маршрутизатор Symfony всегда выбирает первый подходящий маршрут, который он находит, вы можете переопределить конкретный маршрут, который вы хотите, написав соответствующий код маршрутизации поверх кода импорта.