Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Как использовать сервисный метод в Doctrine QueryBuilder

Автор вопроса: Michał TomczukОтветов: 1

Я делаю довольно большой проект Symfony2 (к сожалению, в базе данных, структуру которой я не могу изменить), и я застрял на этом:

У меня есть объект User, который содержит (среди других полей) поле имени пользователя.

У меня также есть объект ProfileField, который соответствует дополнительным полям для пользователя (например, имя или фамилия, любимый цвет или что-то еще, о чем вы хотели бы спросить пользователя).

Наконец, есть ConfigService, который в основном получает определенное значение для определенного ключа из базы данных. В этом конкретном случае все дело в небольшом значении конфигурации, называемом "username_format". Он может принимать одно из трех значений: "имя пользователя", "имя" или "имя и фамилия".

В зависимости от этого значения мне нужно отобразить правильно отформатированное имя пользователя. Если значение равно "имя пользователя" - я просто возвращаю значение поля имени пользователя из объекта "Пользователь". Как для 2-го, так и для 3-го случая, поэтому, когда мне нужно получить пользовательский ProfileField, соответствующий этому конкретному пользователю, я создал простую службу (называемую usernameFormatService), в которую вводится ConfigService и метод с именем getNameFromId($userId). Метод проверяет значение конфигурации и извлекает правильные значения для правильного пользователя. Все это работает очень хорошо, но...

У меня есть обзорная страница блога, на которой отформатированное имя пользователя отображается среди других полей (таких как заголовок, дата создания и т. д.). Сущность Blog имеет связь manyToOne с сущностью User. Из сопоставления я, конечно, получаю имя пользователя, и если значение конфигурации "username_format" говорит, что мне нужно, например, имя, я вытаскиваю его с помощью usernameFormatService внутри шаблона Twig, и все работает так, как должно.

Настоящая проблема начинается, когда мне нужно иметь возможность сортировать по каждому столбцу, что означает также отформатированный столбец имени пользователя. Я использую Doctrine QueryBuilder для получения результатов БД, и в основном мне нужно отформатированное значение имени пользователя где-то внутри объекта пользователя (я думаю), чтобы иметь возможность сортировать блоги по этому значению ДО того, как они будут извлечены из базы данных (почему раньше? разбиение на страницы).

Может ли кто-нибудь дать мне хотя бы подсказку, где искать или как это сделать?

Обновление:

Чтобы было понятнее, может быть:

Прямо сейчас имя пользователя, отображаемое в обзорной таблице, обрабатывается usernameFormatService, который использует ConfigService для получения значения конфигурации "platform_username_format" из базы данных и, в зависимости от этого значения конфигурации, возвращает отформатированное имя пользователя. Если дело доходит до сортировки, мне нужно каким-то образом получить это отформатированное имя пользователя ДО того, как я на самом деле буду запрашивать базу данных, чтобы я мог получить отсортированные результаты.

symfonyserviceentitydoctrine

Ответы

Ответ 1 · Jovan Perovic

Хорошо, если бы я все правильно понял здесь, я бы сделал что-то, как написано ниже.

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

1. Служба конфигурации

Я бы изменил getNameFromId на getNameForUser:

class ConfigService{
    private $usernameFormat;
    private $repository;

    public function __construct($repository, $usernameFormat){
        $this->repository = $repository;
        $this->usernameFormat = $usernameFormat;
    }

    public function getNameForUser(User $user){
        switch ($this->usernameFormat){
            case "username":
                return $user->getUsername();
            case "firstname":
                return $user->getFirstName();
            case "firstnamelastname":
                reteurn $user->getFirstName() . ' ' . $user->getLastname();
        }
    }

    public function getAllUsers($page){
        return $this->repository->getUsers($page, $this->usernameFormat);
    }
}

2. Определение службы конфигурации

<parameters>
    <parameter key="my.repository.class">Your\Namespace\FooRepository</parameter>
    <parameter key="config.service.class">Your\Namespace\Service\ConfigService</parameter>
</parameters>

<services>
    <service id="user.repository"
             class="%my.repository.class%"
             factory-service="doctrine.orm.entity_manager"
             factory-method="getRepository">
            <argument>YourBundle:User</argument>
    </service>

    <service id="config.service" class="%config.service.class%">
        <argument type="service" id="my.repository.class" />
        <argument type="string">username</argument>
    </service>
</services>

3. Репозиторий

public UserRepository extends EntityRepository{
    public function getUsers($page, $usernameFormat){
        $qb = $this->createQueryBuilder('u');

        /**
         * Rest of quering rules go here: WHERE predicate, ORDERing, pagination
         */

         return $qb->getQuery()->getResult();
    }
}

Надеюсь, что это помогает немного...

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы