Как фильтровать по атрибутам подклассов, используя QueryBuilder в Doctrine 2?

У меня есть наследование таблиц классов, реализованных как сущность Vehicle с сущностями Car а также Bike как подклассы. Все Vehicleс color и model, каждый Car имеет dorsNumber и сложная собственность Motor, каждый Bike имеет frameSize,

модель

Существует представление списка с формой поиска для Orders. Результаты могут быть отфильтрованы User.username, Vehicle.color, а также Vehicle.model,

namespace Order\Mapper;

use MyNamespace\DataObject\Order;
use MyNamespace\Paginator\Paginator;
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\Tools\Pagination\Paginator as ORMPaginator;
use DoctrineORMModule\Paginator\Adapter\DoctrinePaginator as PaginatorAdapter;

class OrderMapper
{

    public function findAllPaginated(array $criteria = [], $page = null, array $sorting = [])
    {
        $queryBuilder = $this->entityManager->createQueryBuilder();
        $queryBuilder->select('o')->from(Order::class, 'o');

        // shared JOINs
        if (
            $this->checkCriterium('vehicle_model', $criteria)
            || $this->checkCriterium('vehicle_color', $criteria)
        ) {
            $queryBuilder
                ->join('o.positions', 'p')
                ->join('p.vehicle', 'v')
            ;
        }

        // filtering
        foreach ($criteria as $key => $condition) {
            if ($key === 'user_id') {
                $queryBuilder
                    ->andWhere('o.user = :userId')
                    ->setParameter('userId', $condition)
                ;
            }
            if ($key === 'username' && $condition) {
                $queryBuilder
                    ->join('o.user', 'u')
                    ->andWhere('u.username = :username')
                    ->setParameter('username', $condition)
                ;
            }
            if ($key === 'order_number' && $condition) {
                $queryBuilder
                    ->andWhere('o.orderNumber LIKE :orderNumber')
                    ->setParameter('orderNumber', '%' . $condition . '%')
                ;
            }
            if ($key === 'vehicle_model' && $condition) {
                $queryBuilder
                    // JOIN already performed, s. shared JOINs
                    ->andWhere('v.model = :vehicleModel')
                    ->setParameter('vehicleModel', $condition)
                ;
            }
            if ($key === 'vehicle_color' && $condition) {
                $queryBuilder
                    // JOIN already performed, s. shared JOINs
                    ->andWhere('v.color = :vehicleColor')
                    ->setParameter('vehicleColor', $condition)
                ;
            }
        }

        // sorting
        $direction = key_exists('datetime', $sorting)
            ? strtoupper($sorting['datetime'])
            : Criteria::DESC
        ;
        $queryBuilder->addOrderBy('o.id', $direction);

        $query = $queryBuilder->getQuery();

        $paginator = new Paginator(new PaginatorAdapter(new ORMPaginator($query)));
        $paginator->setCurrentPageNumber($page);
        $paginator->setItemCountPerPage($this->itemCountPerPage);

        return $paginator;
    }

    protected function checkCriterium($key, array $criteria = [])
    {
        return key_exists($key, $criteria) && $criteria[$key] !== null && $criteria[$key] !== '';
    }

}

Теперь поиск должен быть расширен и обеспечить фильтрацию по некоторым Carсвойства, как Car.dorsNumber или же Motor.name, Но я не вижу способа реализовать это, так как для этого мне нужно добавить JOIN с Carкак p.car и это не так и не может работать, так как Position не имеет car имущество.

Как выполнить фильтрацию по свойству подкласса в контексте наследования (таблица классов)?

0 ответов

Другие вопросы по тегам