Symfony 4: как получить избирателей, которые проголосовали как должное?

Как я могу получить избирателей, которые проголосовали за "предоставленное", внутри подписчика события? Есть ли какой-нибудь сервис, который я могу получить и использовать?

Мой вариант использования. Мое приложение имеет двух избирателей: основного избирателя и избирателя-администратора. Я хочу показать дополнительное флэш-сообщение, когда доступ запрещен основным избирателем, но разрешен избирателем-администратором. Я могу решить эту проблему двумя различными решениями: отправив событие внутри избирателя администратора или установив flash msg внутри избирателя - но я хочу избежать этого, потому что мне нужно быть уверенным, что ТОЛЬКО один избиратель проголосовал за доступ.

1 ответ

Решение

Итак, я начну с решений, которые ответят на вопрос, который вы задали. Я закончу с решением (ИМХО) основной проблемы.

Чрезвычайно тривиальное решение:

Объедините обоих избирателей в один, заменив их обоих. Установка флеш-сообщения, если ваше условие выполнено, является обязанностью этого объединенного избирателя, но это тривиально, поскольку у вас есть "результаты" обоих избирателей...

Чуть более красноречиво:

Создайте CombinedVoter, заменив оба. CombinedVoter будет принимать обоих избирателей в качестве зависимостей и направлять им запросы на голосование и возвращать / разыгрывать соответствующую комбинацию из них (по сути, AccessDecisionManager, замаскированный под избирателя). Очевидно, избиратель установит флэш-сообщение, когда ваше условие будет выполнено.

Чуть более бесполезно:

Создайте CombinedVoter, ничего не заменяя, но по-прежнему получая обоих избирателей в качестве зависимостей, направляйте им запросы на голосование и возвращайте ABSTAIN во всех случаях. Очевидно, избиратель установит флэш-сообщение, когда ваше условие будет выполнено.

Чуть более перегружен:

Добавьте EventDispatcher обоим избирателям и отправьте события голосования. Позвольте слушателю прослушать эти события и либо сработать, когда он получит второе (грязный af), либо снова сработает на событии ядра, чтобы установить флэш-сообщение, когда ваше условие выполнено.

Чуть менее перегружен:

Добавьте сервис, который также является EventListener, который прослушивает одно и то же событие ядра для установки флэш-сообщения, но не прослушивает события голосования, вместо этого внедряет этот сервис в обоих избирателей и устанавливает результат голосования непосредственно в этом сервисе. с помощью setAdminVote() / setMainVote() или что угодно.

Основная проблема:

Семантически, ваши избиратели не должны заботиться о флеш-сообщениях и том, что проголосовали другие избиратели. Это не их цель и не их ответственность. Чтобы добавить это к их функции, ИМХО ошибочно, это не то место и время! (Семантика!)

Вместо этого, поскольку в любом случае это, вероятно, специальное сообщение, почему бы не добавить его в базовый шаблон (безусловно, есть способы проверить, является ли кто-то администратором, но не разрешен "основным избирателем", например, используя is_granted в шаблоне или app.user.roles напрямую (при необходимости). Вы также можете написать небольшое расширение веточки, которое добавляет эту функцию и каким-то образом использует обоих избирателей.

Почему я предлагаю поместить эту логику в шаблон: потому что это проблема отображения. Вы хотите, чтобы что-то отображалось, поэтому оно должно быть размещено в части отображения вашего приложения. Кроме того, существует множество крайних случаев, которые вы, вероятно, игнорируете, не знаете или прикладываете усилия, чтобы избежать: Отправка формы на странице, которая вызовет флэш-сообщение, вероятно, приведет к добавлению флэш-сообщения в POST (что, если сделано чисто запускает перенаправление на страницу с GET) И на следующем GET, по существу добавляя два флеш-сообщения. Теперь вы не можете добавить флэш-сообщение к запросам POST, но тогда недействительные формы POSTED будут без флэш-сообщения (потому что не будет GET). Это разум е ***. Я действительно советовал бы против этого.

Отображение - это работа внешнего интерфейса, добавьте несколько помощников в службы / расширения. Пусть избиратели сохраняют свою единственную ответственность (которая, конечно, НЕ добавляет флеш-сообщения). возможно, расширьте ваш базовый шаблон, чтобы он функционировал как "страницы, использующие расширенный базовый шаблон, должны отображать сообщение", а затем используйте его на страницах, на которых вы хотите показать сообщение.

Действительно, делай это чисто; о)

Приложение:

Флэш-сообщения, как правило, обеспечивают обратную связь с пользователем о действиях, которые он недавно совершил. Например, пользователь удалил запись в блоге. Затем в сообщении должно появиться сообщение "блог был удален" (может содержать больше информации ^^).

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

Есть много случаев, когда с этим было бы трудно справиться иначе. Что делать, если вы загружаете только фрагменты своей страницы (возможно, Ajax-обновления), не хотите, чтобы ваше флеш-сообщение было там, также не удалено. Что делать, если вы разместили форму и успешно перенаправлены на какую-то совершенно не связанную страницу. Должна ли эта страница знать что-либо о происхождении пользователя? Желательно нет (разделение интересов). Флэш-сообщения не волнуют (единственная ответственность). Разработчик решает, где могут отображаться флеш-сообщения (обычно при "полном рендеринге страницы" или при специальном доступе).

Они тоже не серебряная пуля. Если у вас открыто несколько вкладок браузера, они могут запутаться до чертиков (поскольку могут отображаться флеш-сообщения, созданные с другой вкладки). Однако если вашей веб-странице требуется несколько вкладок в браузере, у вас также есть некоторые другие проблемы. Тем не менее, я чувствую, что принятие случайного "блуждающего флеш-сообщения" - это хорошо.

Другие вопросы по тегам