Как стать автором
Обновить

Комментарии 14

А почему у вас используется самопальный EventDispatcher а не нативный, который используется всеми компонентами Symfony2?
Второй вопрос — почему логика ACL возложена на некий LikeHelper а не на стандартный AuthorizationChecker (бывш SecurityContext)?
Про EventDispatcher, здесь наверно проблема в том что те бандлы, что я смотрел обычно содержали какие-то самопальные диспетчеры, и я подумал, чем я хуже. За наводку спасибо, посмотрю, что смогу сделать с нативным диспетчером.

Про acl не совсем понял. Метод в LikeHelper проверяет наличие связи в БД у объекта, а не права доступа у этому объекту.
Я сейчас смотрю, и думаю что вообще не надо было выделять эти две строчки в Helper
github.com/UnDeleteRU/LikesBundle/blob/master/Helper/LikeHelper.php#L102

Думаю, что стоит просто оставить их в контроллере.
Дело в том, что на самом деле, не только не стоило их выделять в LikeHelper (у него и так получилась большая зона ответственности) а воспользоваться существующим компонентом Security, для того, чтобы проверить права доступа к ресурсу. Если ваши строчки заменить на:

$authorizationChecker = $this->get('security.authorization_checker');
if (false === $authorizationChecker->isGranted('LIKE_TOGGLE', $entity) {
   throw new AccessDeniedException();
}


Тогда любой, кто бы подключил ваш бандл, могбы накрутить бесконечное количество логики (специфичной для проекта) перед тем, как дать лайкнуть объект, путем имплементации кастомного Voter класса symfony.com/doc/current/cookbook/security/voters_data_permission.html#the-voter-interface у себя в проекте.
Нашел еще место для выстрела в ногу: github.com/UnDeleteRU/LikesBundle/blob/master/Helper/LikeHelper.php#L28 ваш хэлпер получился statefull, что само по себе уже не круто, но страшнее другое, в больших приложениях, как показала практика — чень тяжело отследить порой порядок загрузки тех или иных сервисов (их инстанциирование) и вот если ваш LikeHelper вдруг будет инстанциирован до фаервола, то вы там больше никогда не сможете получить объект пользователя в любом из ваших методов. Т.к. в поле класса будет записано null значение, и после инициализации фаервола, далее, после аутентификации пользователя токен будет заполнен, а вот в вашем хэлпере — нет.
Интересная особенность, пока не сталкивался с таким в живую, но удалось воспроизвести. Буду работать над этим.
Спасибо за все ваши комментарии, много полезного для себя почерпнул.
Полезно.
Но сумбурно. Мало комментариев с объяснениями, что делает код — например, в «маппинге». Для заметки в личном блоге — нормально. Для обучающей статьи на Хабре — маловато.
Ну и, если писать продолжения (хотя я бы и тут поправил) — стоит как-то применять меньше неустоявшегося сленга и варьировать слова. То есть, «Symfony» вместо «симфони». «Сущности» вместо «энтити» и т.п.
В любом случае — спасибо.
Да, как говорится, первый блин комом. По сути это моя первая статья, было бы странно, если бы все было идеально и без косяков.
А так теперь понятно, что надо работать над стилем изложения и авторской дисциплиной.
Помимо какой-то серверной логики на внешний проект иногда приходится отдавать и файлы для браузера (стили, картинки и javascript).

Сразу чувствуется, что пишет backend'ер. Простите.
Грешен, здесь мне нечего добавить.
Вы так говорите, как будто это что-то плохое.
1. В Symfony есть существует «класс для пользователей», только он не класс, а интерфейс: «Symfony\Component\Security\Core\User\UserInterface» (собственно класс тоже есть, но он не для того).

2. Грешно писать интерфейсы привязанные к реализации, тем более привязанные к «хранящей прослойке»:
«Likeable» должен содержать человеческие названия методов, например «like(Like)», «unlike(Like)», «getLikes()», а уж как конкретно хранить и привязывать эти лайки лучше оставить на совесть пользователя.

3. «Как хранить, где, почему, как привязывать, куда, зачем и т.д.» — об этом думать должен пользователь, ваша задача предоставить адекватный интерфейс взаимодействия. Взгляните на досуге на реализацию «FOSUserBundle», он не требует специфичного хранилища, ему глубоко без разницы как вы будете хранить пользователей, будь то реляционная БД, ОО БД или просто файл. Сделайте таким же образом «Model\StorageAgnostic\Like» и наследуйте конкретные привязки!
На все эти вопросы я думаю один ответ. Роль сыграло, что бандл разрабатывался под конкретные проекты. Эти проекты имели схожую архитектуру (mysql, orm и доктриновский кодогенератор) и нужно было бы решение, которое бы позволяло без лишних мыслей добавлять функциональность. То есть сразу и шаблоны, и логика, и структура БД. Отсюда и интерфейсы с методами «хранящей прослойки»

Сейчас я просто не чувствую потребность в подобном бандле вне моего окружения. Но кто знает, может если не я, то кто-нибудь другой вдохновится моей статьей и Вашим комментарием и сделает все по уму)
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории