Как отфильтровать мои запросы доктрины с помощью Symfony ACL
Symfony ACL позволяет мне предоставлять доступ к объекту, а затем проверять его:
if (false === $securityContext->isGranted('EDIT', $comment)) {
throw new AccessDeniedException();
}
Однако, если у меня есть тысячи объектов в базе данных, и у пользователя есть доступ только к 10 из них, я не хочу загружать все объекты в памяти и убирать их.
Как я могу сделать простой "SELECT * FROM X" при фильтрации только на объектах, к которым у пользователя есть доступ (на уровне SQL)?
Ответы
Ответ 1
Ну вот он: это невозможно.
В прошлом году я работал над альтернативной системой ACL, которая позволяла напрямую фильтровать запросы к базе данных.
Моя компания недавно согласилась открыть исходный код, так что вот оно: http://myclabs.github.io/ACL/
Ответ 2
Как было указано в предыдущем обсуждении @gregor,
В первом запросе получите список (с пользовательским запросом) всех объектов object_identity_ids (для определенного объекта/класса X), к которому пользователь имеет доступ.
Затем, при запросе списка объектов для объекта/класса X, добавьте "IN (object_identity_ids)" к вашему запросу.
Маттье, меня не устраивало, отвечая на большее количество догадок (так как мои предположения не добавляют ничего полезного для разговора). Итак, Я сделал некоторую заметку по этому подходу (Digital Vegas 5 V/5).
![Benchmark]()
Как и ожидалось, размер таблицы не имеет значения при использовании подхода массива IN. Но большой размер массива действительно заставляет вещи выходить из-под контроля.
Итак, Join approach
vs IN array approach
?
JOIN действительно лучше, когда размер массива огромен. НО, это предполагает, что мы не должны рассматривать размер таблицы. Оказывается, на практике массив IN быстрее - за исключением случаев, когда большая таблица объектов и записи acl покрывают почти каждый объект (см. Связанный вопрос).
Я расширил свои рассуждения по отдельному вопросу. См. При использовании ACL от Symfony лучше использовать запрос JOIN или запрос массива IN?
Ответ 3
Вы могли бы взглянуть на Фильтры Doctrine. Таким образом, вы можете расширить все запросы. Я еще не сделал этого, и есть некоторые ограничения, о которых идет речь. Но, возможно, это поможет вам. Вы найдете описание таблиц базы данных ACL здесь.
UPDATE
Каждый фильтр вернет строку, и все эти строки будут добавлены к SQL-запросам следующим образом:
SELECT ... FROM ... WHERE ... AND (<result of filter 1> AND <result of filter 2> ...)
Также псевдоним таблицы передается методу фильтра. Поэтому я думаю, что вы можете добавить подзапросы здесь, чтобы отфильтровать ваши сущности.