Подтвердить что ты не робот

Как отфильтровать мои запросы доктрины с помощью Symfony ACL

Symfony ACL позволяет мне предоставлять доступ к объекту, а затем проверять его:

if (false === $securityContext->isGranted('EDIT', $comment)) {
    throw new AccessDeniedException();
}

Однако, если у меня есть тысячи объектов в базе данных, и у пользователя есть доступ только к 10 из них, я не хочу загружать все объекты в памяти и убирать их.

Как я могу сделать простой "SELECT * FROM X" при фильтрации только на объектах, к которым у пользователя есть доступ (на уровне SQL)?

4b9b3361

Ответ 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> ...)

Также псевдоним таблицы передается методу фильтра. Поэтому я думаю, что вы можете добавить подзапросы здесь, чтобы отфильтровать ваши сущности.