/**
  * @param AbstractDataTable $table
  * @param \Symfony\Component\HttpFoundation\Request $request
  * @return \Symfony\Component\HttpFoundation\JsonResponse
  * @throws \Exception
  */
 public function processRequest(AbstractDataTable $table, \Symfony\Component\HttpFoundation\Request $request)
 {
     $this->table = $table;
     $this->request = new DataTablesRequest($request);
     $response = new Response();
     $response->draw = $this->request->getDraw();
     $qb = $this->createQueryBuilder();
     $response->recordsTotal = $this->countTotals($qb);
     $response->recordsFiltered = $this->applyFilterAndCount($qb);
     if (null === $response->recordsFiltered) {
         $response->recordsFiltered = $response->recordsTotal;
     }
     // select entities
     $prefixes = array_merge([$this->table->getPrefix()], $this->table->getJoinPrefixes());
     call_user_func_array([$qb, 'select'], $prefixes);
     // add count
     if ($this->table->getHasScalarColumns()) {
         foreach ($this->table->getColumns() as $column) {
             if ($column instanceof EntitiesCountColumn) {
                 $qb->addSelect('count(' . $column->getEntityPrefix() . ') as ' . $column->getField() . '_count');
                 // '.' .  $column->getField() .
             } elseif ($column instanceof EntitiesScalarColumn) {
                 $qb->addSelect($column->getOperation() . '(' . $column->getEntityPrefix() . '.' . $column->getEntityField() . ') as ' . $column->getField() . '_' . $column->getOperation());
                 // '.' .  $column->getField() .
                 $qb->addGroupBy($this->table->getPrefix() . '.id');
             }
         }
     }
     // paginate
     $paginate = clone $qb;
     $paginate->select('distinct(' . $this->table->getPrefix() . '.' . $this->getIdentifierField() . ')');
     // add scalar fields as hidden (todo: clean up this mess)
     if ($this->table->getHasScalarColumns()) {
         foreach ($this->table->getColumns() as $column) {
             if ($column instanceof EntitiesCountColumn) {
                 $paginate->addSelect('count(' . $column->getEntityPrefix() . ') as hidden ' . $column->getField() . '_count');
                 // '.' .  $column->getField() .
             } elseif ($column instanceof EntitiesScalarColumn) {
                 $paginate->addSelect($column->getOperation() . '(' . $column->getEntityPrefix() . '.' . $column->getEntityField() . ') as hidden ' . $column->getField() . '_' . $column->getOperation());
                 // '.' .  $column->getField() .
                 $paginate->addGroupBy($this->table->getPrefix() . '.id');
             }
         }
     }
     $paginate->setFirstResult($this->request->getStart())->setMaxResults($this->request->getLength());
     $ids = $paginate->getQuery()->getResult();
     // order
     $this->applyOrder($qb);
     $qb->andWhere($this->table->getPrefix() . '.' . $this->getIdentifierField() . ' in (:ids)')->setParameter('ids', $ids);
     // get result
     $resultCallback = $this->table->getResultCallback();
     if (null !== $resultCallback) {
         call_user_func($resultCallback, $this->table, $qb, $response, $this->dataConverter);
     } else {
         call_user_func(['Voelkel\\DataTablesBundle\\DataTables\\DataBuilder', 'build'], $this->table, $qb, $response, $this->dataConverter, $this->table->getRowCallback());
     }
     return $response->create();
 }