SonataAdminBundle: фильтры
Лично для меня - фильтры один из самых краеугольных камней, ибо это любимое требование заказчика, и очень часто у этого заказчика очень нестандартные запросы к фильтрам.
Итак, соната предоставляет несколько возможностей для внедрения фильтрации данных.
- Неявные фильтры. Могут понадобится в случае, когда данные нужно фильтровать для пользователя определенным образом, но сам пользователь об этом знать не должен. Как пример: пользователь должен видеть только свои посты.
Стандартное поведение админ классов можно легко модифицировать с помощью AdminExtension’ов. AdminExtension - это сервис, который админ класс запускает после того как сделает свою основную работу по конфигурации. AdminExtension’ов может быть несколько. Они включают в себя основные методы админ класса, такие как configureFormFields, configureDatagridFilters и др. Мы рассмотрим метод configureQuery, с помощью которого можно изменить стандартный запрос, который выполняется, когда мы просматриваем список сущностей. В моем случае я буду выводить только те сущности, в которых поле parent является пустым, об иных сущностях пользователю знать не стоит
Конечно, наш класс унаследован от AdminExtension
Определение сервиса следующее:
target в секции tag - это id сервиса админ класса, к которому будет присоединен AdminExtension
С помощью AdminExtension'ов очень удобно джойнить нужные сущности, чтобы потом фильтровать по этим полям внутри админ класса (это второй способ, рассмотрен ниже)
- Часто возникает необходимость реализовать нестандартную логику фильтрации по определнному полю, а времени, чтобы оформлять данный фильтр как отдельный сервис нет, да и такой фильтр может встреаться только в одном месте. Для таких случаев SonataAdminBundle предоставляет тип фильтра doctrine_orm_callback. Здесь все просто как 2 копейки:
Сам фильтр мы так же, как и обычные, описываем в методе configureDatagridFilters, с той разницей, что тип фильтра указываем doctrine_orm_callback, а в опциях фильтра обязательно указываем callback - метод, который будет вызываться для формирования QueryBuilder’a соответственно нашему фильтру. Иначе говоря, в этот метод передается сам QueryBuilder, $alias - основной алиас сущности, $field - какое то мистическая переменная, я не нашел ей применения, и $value - собственно значение из фильтра, которое ввел пользователь.
Внутри функции callback’a в данном случае добавляется джоин (что, как я и говорил раньше, можно вынести в AdminExtension, и даже нужно, если этих джоинов множество), ну, и само условие для фильтрации.
Еще любопытные опции, на поиск которых я потратил некоторое время:
- field_type - тип поля, которое будет отображаться для ввода пользователем значения
- field_options - опции этого поля, которые обычно идут третьим аргументом в FormMapper'e метода configureFormFields
Значение фильтров по-умолчанию
Однажды столкнулся с задачей, что необходимо было явно указать в фильтрах значение по-умолчанию, как если бы пользователь сам его выбрал.
Ключ ко всему - метод getFilterParameters, который соната вызывает, чтобы составить список сущностей для listAction. Данный метод заполняет свойство datagridValues соответствующими значениями. В данном случае предполагается, что $filterUsers - это массив с id’шками пользователей.