Как использовать собственный тип доктрины в выражении dql where? - PullRequest
1 голос
/ 16 мая 2019

Я использую Перечисления Spatie в моем проекте Symfony, и я создал собственный тип DBAL для этих объектов.Когда я сохраняю объект enum в базе данных, я сохраняю его в специальном строковом формате.Функция преобразования в моем EnumType выглядит следующим образом:

public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
    if ($value === null) {
        return null;
    }

    return get_class($value) . '::' . $value->getIndex() . '::' . $value->getValue();
}

Так, например, у меня есть перечисление статуса транзакции, которое выглядит так:

namespace App\Enum;

use Spatie\Enum\Enum;

/**
 * @method static self failed()
 * @method static self pending()
 * @method static self completed()
 */
final class TransactionStatus extends Enum {}

И когда я сохраняю его вбазу данных, которую он может превратить в любую из этих строк соответственно:

App\Enum\TransactionStatus::0::failed
App\Enum\TransactionStatus::1::pending
App\Enum\TransactionStatus::2::completed

Это помогает моему EnumType узнать, во что перечислить, чтобы преобразовать его обратно.И причина, по которой я использую индексный номер в строке, заключается в том, что это помогает с сортировкой.

Теперь все это очень хорошо работает для извлечения и сохранения моих сущностей в базе данных.Но когда я пытаюсь использовать enum в предложении where оператора DQL, он вообще не работает.

namespace App\Repository;

use App\Entity\Transaction;
use App\Enum\TransactionStatus;
use Symfony\Bridge\Doctrine\RegistryInterface;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;

class TransactionRepository extends ServiceEntityRepository
{
    public function __construct(RegistryInterface $registry)
    {
        parent::__construct($registry, Transaction::class);
    }

    public function findByStatus(TransactionStatus $status)
    {
        return $this->createQueryBuilder('t')
            ->andWhere('t.status = :status')
            ->setParameter('status', $status)
            ->getQuery()->getResult();
    }
}

Потому что по какой-то причине доктрина игнорирует мою функцию преобразования и просто использует __toString()функция, которая встроена в перечисление Spatie.Таким образом, доктрина ищет строку "pending" вместо "App\Enum\TransactionStatus::1::pending".

Как мне убедиться, что мои перечисления всегда правильно конвертируются в предложении DQL where?

...