June 19, 2012

symfony 2.0 FOSUserBundle — ошибка «Could not load type»

Если вы используете FOSUserBundle вместе с symfony 2.0 и вам понадобилось переопределить какую-либо из форм, идущих «в комплекте» с этим плагином,

то, без сомнения, вы прочитали эту заметку: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/overriding_forms.md

После обновления вашей страницы может случиться прискорбная ситуация — сообщение об ошибке «Could not load type ….» (вместо многоточия ваш alias для кастомной формы).

Вроде бы и в файле app/config.yml все верно с отступами (имеется ввиду конфигурация fos_user сервиса), и файл конфигурации вашего сервиса service.xml (service.yml) (в CustomUserBundle) описан правильно, и везде совпадает alias, getName() и т.п…. а все та же ошибка. Бывало? Не беда! 🙂 Есть решение вашей проблемы! Читайте далее, и все окажется просто!

Чтобы понимать и правильно использовать services и dependency injection в symfony 2.x, крайне рекомендую прочитать это и это. Суть в том, что для того, чтобы фреймворк symfony увидел ваши сервисы и расширения, необходимо предоставить информацию о конфигурации вашего bundle.

Сделать это можно двумя способами.

  1. Стандартная конфигурация сервиса.

Вы можете описать ваши сервисы в файле конфигурации (services.yml, services.xml, etc.) который находится внутри вашего бандла и потом просто заимпортировать этот файл в основной файл конфигурации всего приложения. Это действительно простой, быстрый и неимоверно эффективный способ.

Пример:

<br /> imports:<br /> - { resource: parameters.ini }<br /> - { resource: security.yml }<br /> - { resource: @CustomUserBundle/Resources/config/services.xml }<br />

  1. Семантическое описание конфигурации.

Данный способ используется для конфигурации ядра symfony. Основная идея заключается в том, что вместо того, чтобы заставлять пользователя переопределять все параметры, вы предоставляете ему возможность задать лишь некоторые, специально созданные опции. Ваша роль, как разработчика банда, заключается в том, чтобы разобрать такую конфигурацию и подгрузить необходимые сервисы внутри класса «Extension». Используя данный метод, вам больше не нужно импортировать кофигурационные ресурсы в ваш основной файл конфигурации проекта — этим займется файл расширения (Extension).

Этот способ подробно описан во второй из приведенных выше ссылок.

Итак, возвращаясь к природе нашей ошибки. Суть дела вот в чем: может случиться так, что «кастомный» бандл для Пользователя (User) вы создавали вручную (путем копирования из существующего бандла необходимых файлов и директорий), а не при помощи консольной команды симфони (generate:bundle).

При этом, вы могли забыли создать директорию DependencyInjection и в ней файл CustomUserExtension.php и Configuration.php.

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

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