Symfony 4: как получить избирателей, которые проголосовали как должное? - PullRequest
0 голосов
/ 09 апреля 2019

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

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

1 Ответ

1 голос
/ 10 апреля 2019

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

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

Объедините обоих избирателей в один, заменив их обоих. За установку флеш-сообщения, если ваше условие выполнено, отвечает этот объединенный избиратель, но это тривиально, поскольку у вас есть «результаты» обоих избирателей ...

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

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

Немного бесполезнее:

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

Немного более изощренно:

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

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

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

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

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

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

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

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

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

Добавление:

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

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

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

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

...