Можно ли отфильтровать пользователя по ролям (массив JSON) в EasyAdmin? - PullRequest
0 голосов
/ 24 февраля 2020

Я использую EasyadminBundle для внутреннего интерфейса приложения Symfony.

Я бы хотел отфильтровать своих пользователей по их $roles с 1 таблицей только с ROLE_WEBMASTER, еще один с ROLE_ADMIN и последний с проигравшими (ROLE_USER).

К сожалению, $roles член класса User является массивом.

class User implements UserInterface
{
    /**
     * @ORM\Column(type="json")
     */
    private $roles = [];
}

Мой сервер хранения - SQLite.

Я попробовал два решения:

1. использовать поисковые запросы

- { icon: user-tie, label: admin, entity: User, params: {action: search, query: ROLE_ADMIN}}

ничего не делать

2. используйте фильтр DQL

webmaster:
    class: App\Entity\User
    label: Webmaster
    list:
        dql_filter: "'ROLE_WEBMASTER' IN entity.sqlRoles()"

с

public function  sqlRoles():string
{
    return implode(', ',$this->getRoles());
}

, но он запускает следующую ошибку

Исключение было выдано во время рендеринга шаблона ( Msgstr "Ошибка синтаксиса], строка 0, столбец 65: ошибка: ожидается =, <, <=, <>,>,> =,! =, Получил 'IN'").


Есть ли способ выполнить этот трюк, или мне нужно забыть эту идею?

Ответы [ 3 ]

1 голос
/ 24 февраля 2020

Я не знаю easyAdmin, но этот DQL не вычисляется.

dql_filter: "'ROLE_WEBMASTER' IN entity.sqlRoles()"

Вы должны помнить, что все, что вы пишете на DQL, должно в конечном итоге переводиться на обычный старый SQL. Это означает, что использование методов сущностей не будет работать.

Подумайте об этом: эти методы нельзя использовать до тех пор, пока не будет создан экземпляр объекта, и не могут быть созданы до тех пор, пока не будет получено и не произойдет извлечение только когда выполняется оператор SQL , поэтому фильтрация WHERE не может быть выполнена в этот момент.

Проблема в том, что с vanilla Doctrine вы не сможете фильтровать по содержимое свойства JSON, в основном с использованием JSON_CONTAINS , которое Doctrine не включает поддержку.

Однако не вся надежда потеряна. Доступны расширения, которые добавляют поддержку этих функций для различных серверных частей, например .

Если вы установите и включите его, вы можете изменить свой фильтр DQL на:

dql_filter: "JSON_CONTAINS(entity.roles, '\"ROLE_WEBMASTER\"', '$')"

Если вы приложите немного усилий, чтобы связать все вместе, это должно сработать.

К сожалению, поскольку вы используете SQLite, вы не сможете использовать вышеперечисленное. SQLite отлично подходит для разработки и использования встраиваемых систем, но он не так богат, как полноценные СУБД.

0 голосов
/ 17 апреля 2020

Это решение, которое работало для меня с использованием dql_filter, надеюсь, оно поможет:

easy_admin:
    entities:
        Player:
          class: App\Entity\User
          list:
            dql_filter: "entity.roles LIKE '%%ROLE_PLAYER%%'"
        Admin:
          class: App\Entity\User
          list:
            dql_filter: "entity.roles LIKE '%%ROLE_ADMIN%%'"

easy_admin:
  design:
    menu:
      - { label: 'Users' }
      - { entity: 'Player', label: 'Players', icon: 'users' }
      - { entity: 'Admin', label: 'Admins', icon: 'users' }
0 голосов
/ 26 февраля 2020

Чтобы отфильтровать массив JSON в EasyadminBundle , оказывается, что вам не нужно использовать dql_filter, поскольку filters уже встроено в пакет.

Сначала вам нужно подготовиться к описанию вашей сущности:

easy_admin:
    entities:
        User:
            class: App\Entity\User
            list:
                filters:
                    - { property: roles, type: array }

, так как фильтр теперь настроен для сущности, мы можем добраться до него в нашем меню:

easy_admin:
    design:
        menu:
            - { icon: user-cog, label: webmaser, entity: User, params: { action: list, filters: { roles: { comparison: like, value: [ROLE_WEBMASTER] } } } }
...