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

Я делаю довольно большой проект 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» из базы данных и, в зависимости от этого значения конфигурации, возвращает отформатированное имя пользователя. Если дело доходит до сортировки, мне нужно каким-то образом получить это отформатированное имя пользователя ДО того, как я на самом деле буду запрашивать базу данных, чтобы я мог получить отсортированные результаты.


person Michał Tomczuk    schedule 24.03.2014    source источник


Ответы (1)


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

Теперь, в чем я не уверен, так это в том, есть ли у каждого пользователя возможность выбирать, как просматривать данные. Поэтому я жестко запрограммировал 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();   
    }
}

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

person Jovan Perovic    schedule 24.03.2014
comment
Вы меня неправильно поняли. Чтобы сделать это более понятным, прочитайте обновленный вопрос. Если это все еще не ясно, пожалуйста, дайте мне знать :) - person Michał Tomczuk; 26.03.2014