public function testCreate_multijoin()
 {
     $qb = $this->em->createQueryBuilder()->select('p, c')->from('Product', 'p')->join('p.category', 'c')->join('c.parent', 'cp');
     $fieldMapping = ['p.name', 'c.name', 'cp.name'];
     $propertyPathMapping = $this->factory->createPropertyPathMapping($qb, $fieldMapping);
     $this->assertEquals(['name', 'category.name', 'category.parent.name'], $propertyPathMapping);
 }
 /**
  * @param  Request $request
  * @return DataSet
  */
 public function createDataSet(Request $request)
 {
     $dataSet = new DataSet();
     $paginatorTotal = $this->createPaginator();
     $dataSet->numberOfTotalRecords = $paginatorTotal->count();
     // Add filters
     $where = [];
     foreach ($request->columnFilters as $column => $filter) {
         $fieldName = $this->columnMapping[$column];
         /**
          * @todo refactor handling of composite/aggregate fields
          */
         if (count(explode(".", $fieldName)) == 1) {
             $fieldName = $this->retrieveExpressionByFieldName($fieldName);
         }
         // Treat '|' as OR and '~' for date ranges
         if (false !== strpos($filter, '|')) {
             $possibleValues = explode('|', $filter);
             $orX = [];
             foreach ($possibleValues as $value) {
                 $paramName = ':datatables_' . $this->qb->getParameters()->count();
                 $this->qb->setParameter($paramName, $value);
                 $orX[] = $this->qb->expr()->eq($fieldName, $paramName);
             }
             $where[] = call_user_func_array([$this->qb->expr(), 'orX'], $orX);
         } elseif (preg_match('/^(\\d{2})-(\\d{2})-(\\d{4})~(\\d{2})-(\\d{2})-(\\d{4})$/', $filter)) {
             $dates = explode('~', $filter);
             $paramName = ':datatables_' . $this->qb->getParameters()->count();
             $this->qb->setParameter($paramName, \DateTime::createFromFormat('d-m-Y', $dates[0]));
             $where[] = $this->qb->expr()->gte($fieldName, $paramName);
             $paramName = ':datatables_' . $this->qb->getParameters()->count();
             $this->qb->setParameter($paramName, \DateTime::createFromFormat('d-m-Y', $dates[1]));
             $where[] = $this->qb->expr()->lte($fieldName, $paramName);
         } else {
             if (false !== strpos($filter, '~')) {
                 continue;
             }
             $paramName = ':datatables_' . $this->qb->getParameters()->count();
             $this->qb->setParameter($paramName, "%{$filter}%");
             $where[] = $this->qb->expr()->like($fieldName, $paramName);
         }
     }
     if (count($where) > 0) {
         $this->qb->andWhere(call_user_func_array([$this->qb->expr(), 'andX'], $where));
     }
     // Add sorting
     foreach ($request->columnSorts as $column => $direction) {
         $this->qb->addOrderBy($this->columnMapping[$column], $direction);
     }
     $this->qb->setFirstResult($request->displayStart);
     $this->qb->setMaxResults($request->displayLength);
     $paginatorFiltered = $this->createPaginator();
     $dataSet->numberOfFilteredRecords = $paginatorFiltered->count();
     $dataSet->data = [];
     $propertyPathMappingFactory = new PropertyPathMappingFactory();
     $propertyPathMapping = $propertyPathMappingFactory->createPropertyPathMapping($this->qb, $this->columnMapping, $this->propertyPathMapping);
     foreach ($paginatorFiltered->getIterator() as $item) {
         $dataSet->data[] = $this->buildRow($item, $propertyPathMapping);
     }
     return $dataSet;
 }