Я пытаюсь создать фильтр, который ограничивал бы, какие объекты являются видимыми для аутентифицированного пользователя, независимо от того, запрашиваются ли они непосредственно по id (GET /events/1
), в списке (GET /events
) или через ассоциацию ( GET /users/1/events
).
Доступ к объекту «Мое событие» может быть ограничен только для участников / приглашенных пользователей, друзей участников или для других.
Будучи мерой безопасности, я нахожу это слишком фильтрующим для контроллера agile, поскольку их можно получить с помощью нескольких методов контроллера, распределенных по нескольким контроллерам, и все они должны пройти фильтр, прежде чем возвращено пользователю.
Это логика c за фильтром:
public function isVisible(User $user): bool
{
if ( // Members and invited users always see an event
$this->visibility === self::VISIBILITY_PUBLIC ||
in_array($user, $this->getMembersWithStatus(self::STATUS_CONFIRMED), true) ||
in_array($user, $this->getMembersWithStatus(self::STATUS_INVITED), true)
) {
return true;
}
// Visible to friends of user creating the event
if ($this->visibility === self::VISIBILITY_FRIENDS) {
return in_array($user, $this->createdBy->getConfirmedFriends(), true);
}
// Visible to friends of all confirmed members
if ($this->visibility === self::VISIBILITY_MEMBERS_FRIENDS) {
return $this->getMembers()->exists(function (int $key, EventMember $membership) use ($user) {
return $membership->getStatus() === self::STATUS_CONFIRMED &&
in_array($user, $membership->getUser()->getConfirmedFriends(), true);
});
}
return false;
}
Похоже, что Фильтры могли бы достичь именно этого, но у меня нет Я нашел любую документацию, использующую что-то еще, кроме простого сравнения, которое здесь бы не сократилось. Есть ли способ установить фильтр как довольно большое условие SQL, используя некоторые объединения? (Я забыл все свои SQL :()
Я пытался разобраться в этом, но не смог получить псевдоним таблицы событий. Поскольку отношение Пользователь - EventMember - Событие , Я могу получить таблицу EventMember, но никогда не получаю Event.
Я также изучил переопределение EntityRepository методов, чтобы «внедрить» фильтр, но это не выглядит лучше или больше DRY Решение, чем фильтрация в контроллере.