Symfony 2.1 - Пользовательский Прослушиватель Аннотаций Json
Для проекта Symfony 2.1 я пытаюсь создать новую аннотацию @Json(), которая зарегистрирует прослушиватель, который автоматически создаст объект JsonResponse при возврате массива. У меня это работает, но по какой-то причине слушатель всегда вызывается, даже для методов, у которых нет аннотации @Json. Я предполагаю, что мой подход работает, так как дополнительный пакет Sensio делает это с аннотацией @Template.
Вот мой код аннотации.
<?php
namespace Company\Bundle\Annotations;
/**
* @Annotation
*/
class Json extends \Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationAnnotation
{
public function getAliasName()
{
return 'json';
}
}
Здесь это мой код слушателя.
<?php
namespace Company\Bundle\Listener\Response\Json;
class JsonListener
{
//..
public function onKernelView(GetResponseForControllerResultEvent $event)
{
$request = $event->getRequest();
$data = $event->getControllerResult();
if(is_array($data) || is_object($data)) {
if ($request->attributes->get('_json')) {
$event->setResponse(new JsonResponse($data));
}
}
}
}
Это мое определение yaml для слушателя.
json.listener:
class: Company\Bundle\Listener\Response\Json
arguments: [@service_container]
tags:
- { name: kernel.event_listener, event: kernel.view, method: onKernelView }
Я, очевидно, что-то здесь упускаю, потому что он зарегистрирован как прослушиватель ядра.просмотр. Как мне изменить это, чтобы оно вызывалось только тогда, когда в действии контроллера присутствует аннотация @Json()?
1 answers
Не претендуйте на окончательный ответ.
Я не совсем понимаю, почему вы расширяете ConfigurationAnnotation
: его конструктор принимает array
, но вам не нужна никакая конфигурация для вашей аннотации. Вместо этого реализуйте ConfigurationInterface
:
namespace Company\Bundle\Annotations;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationInterface;
/**
* @Annotation
*/
class Json implements ConfigurationInterface
{
public function getAliasName()
{
return 'json';
}
public function allowArray()
{
return false;
}
}
Сенсио ControllerListener
из SensionFrameworkExtraBundle прочитает вашу аннотацию (объединение класса с аннотациями методов) и выполнит эту проверку:
if ($configuration instanceof ConfigurationInterface) {
if ($configuration->allowArray()) {
$configurations['_'.$configuration->getAliasName()][] = $configuration;
} else {
$configurations['_'.$configuration->getAliasName()] = $configuration;
}
}
Установка атрибута запроса с префиксом _
. Вы правильно проверяя _json
, так что это должно сработать. Попробуйте сбросить $request->attributes
в прослушивателе событий вашего представления. Убедитесь, что ваш сервис json.listener
также правильно загружен (сбросьте их с php app/console container:debug >> container.txt
).
Если это не сработает, попробуйте добавить некоторые инструкции отладки и печати здесь (найдите ControllerListener.php
в папке поставщика):
var_dump(array_keys($configurations)); // Should contain _json
Не забудьте сделать его копию перед редактированием, иначе Composer выдаст ошибку при обновлении зависимостей.