/**
  * @param AbstractDataTable $table
  * @param \Doctrine\ORM\QueryBuilder $qb
  * @param Response $response
  * @param DataToStringConverter $dataToStringConverter
  * @throws \Exception
  */
 public static function build(AbstractDataTable $table, \Doctrine\ORM\QueryBuilder $qb, Response $response, DataToStringConverter $dataToStringConverter, $rowCallback = null)
 {
     $entities = $qb->getQuery()->getResult();
     foreach ($entities as $result) {
         $entity = $result;
         if ($table->getHasScalarColumns()) {
             $entity = $result[0];
         }
         $tmp = [];
         if (method_exists($entity, 'getId')) {
             $tmp['DT_RowId'] = 'row_' . $entity->getId();
             $tmp['DT_RowAttr'] = ['data-entity' => $entity->getId()];
             // DT_RowClass
             // DT_RowData
         }
         if (is_callable($rowCallback)) {
             $cbResult = $rowCallback($entity, $table);
             $tmp = array_merge($tmp, $cbResult);
         }
         foreach ($table->getColumns() as $column) {
             if ($column instanceof EntitiesCountColumn) {
                 $tmp[$column->getName()] = $result[$column->getField() . '_count'];
             } elseif ($column instanceof EntitiesScalarColumn) {
                 $tmp[$column->getName()] = $result[$column->getField() . '_' . $column->getOperation()];
             } else {
                 $tmp[$column->getName()] = self::getColumnProperty($entity, $column, $dataToStringConverter);
             }
         }
         $response->data[] = $tmp;
     }
 }
 /**
  * @param QueryBuilder $qb
  * @param EntityColumn $column
  */
 private function joinColumn(QueryBuilder $qb, EntityColumn $column)
 {
     $joins = [];
     $pos = strpos($column->getField(), '.');
     if (false !== $pos) {
         $fields = $column->getField();
         $prefix = '';
         while (false !== $pos) {
             $join = [empty($prefix) ? $this->table->getPrefix() : $prefix];
             $field = substr($fields, 0, $pos);
             $prefix .= (empty($prefix) ? '' : '_') . EntityColumn::createEntityPrefix($field);
             array_push($join, $field, $prefix);
             $joins[join('.', $join)] = $join;
             $fields = substr($fields, $pos + 1);
             $pos = strpos($fields, '.');
             if (false === $pos && 0 < strlen($fields)) {
                 $pos = strlen($fields);
             }
         }
     } else {
         $join = [$this->table->getPrefix(), $column->getField(), $column->getEntityPrefix()];
         $joins[join('.', $join)] = $join;
     }
     foreach ($joins as $key => $join) {
         if (!isset($this->joins[$key])) {
             $qb->leftJoin($join[0] . '.' . $join[1], $join[2]);
             $this->joins[$key] = $join;
         }
     }
 }
 public function renderJavascript(\Twig_Environment $twig, AbstractDataTable $table, $path = null, $options = [])
 {
     $table->setContainer($this->container);
     if (null === $path) {
         $path = $this->container->get('router')->generate('serverside_datatables_list', ['table' => null !== $table->getServiceId() ? $table->getServiceId() : get_class($table)]);
     }
     $tableVar = $table->getName();
     if (isset($options['var'])) {
         $tableVar = $options['var'];
         unset($options['var']);
     }
     $tableId = $table->getName();
     if (isset($options['id'])) {
         $tableId = $options['id'];
         unset($options['id']);
     }
     $deferLoading = null;
     if (true === $table->getOption('deferLoading')) {
         $request = new \Symfony\Component\HttpFoundation\Request();
         $request->query->add(['draw' => 0, 'start' => 0, 'length' => 10]);
         $response = $this->container->get('serverside_datatables')->processRequest($table, $request);
         $data = json_decode($response->getContent(), true);
         $deferLoading = ['total' => $data['recordsTotal'], 'filtered' => $data['recordsFiltered'], 'rows' => []];
         foreach ($data['data'] as $row) {
             $tmp = [];
             foreach ($row as $key => $value) {
                 if (0 === strpos($key, 'DT_')) {
                     continue;
                 }
                 $tmp[$key] = $value;
             }
             $deferLoading['rows'][] = $tmp;
         }
     }
     $result = $this->renderDefaults($twig);
     $result .= $twig->render('@VoelkelDataTables/table.js.twig', ['table' => $table, 'path' => $path, 'options' => $options, 'tableId' => $tableId, 'tableVar' => $tableVar, 'deferLoading' => $deferLoading]);
     return $result;
 }