Как фильтровать по атрибутам подклассов, используя QueryBuilder в Doctrine 2?
У меня есть наследование таблиц классов, реализованных как сущность Vehicle
с сущностями Car
а также Bike
как подклассы. Все Vehicle
с color
и model
, каждый Car
имеет dorsNumber
и сложная собственность Motor
, каждый Bike
имеет frameSize
,
Существует представление списка с формой поиска для Order
s. Результаты могут быть отфильтрованы 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
имущество.
Как выполнить фильтрацию по свойству подкласса в контексте наследования (таблица классов)?