vendor/sg/datatablesbundle/Response/DatatableResponse.php line 143

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the SgDatatablesBundle package.
  4.  *
  5.  * (c) stwe <https://github.com/stwe/DatatablesBundle>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Sg\DatatablesBundle\Response;
  11. use Doctrine\ORM\Tools\Pagination\Paginator;
  12. use Exception;
  13. use Sg\DatatablesBundle\Datatable\Column\ColumnInterface;
  14. use Sg\DatatablesBundle\Datatable\DatatableInterface;
  15. use Symfony\Component\HttpFoundation\JsonResponse;
  16. use Symfony\Component\HttpFoundation\Request;
  17. use Symfony\Component\HttpFoundation\RequestStack;
  18. class DatatableResponse
  19. {
  20.     /**
  21.      * The current Request.
  22.      *
  23.      * @var Request
  24.      */
  25.     private $request;
  26.     /**
  27.      * $_GET or $_POST parameters.
  28.      *
  29.      * @var array
  30.      */
  31.     private $requestParams;
  32.     /**
  33.      * A DatatableInterface instance.
  34.      * Default: null.
  35.      *
  36.      * @var DatatableInterface|null
  37.      */
  38.     private $datatable;
  39.     /**
  40.      * A DatatableQueryBuilder instance.
  41.      * This class generates a Query by given Columns.
  42.      * Default: null.
  43.      *
  44.      * @var DatatableQueryBuilder|null
  45.      */
  46.     private $datatableQueryBuilder;
  47.     public function __construct(RequestStack $requestStack)
  48.     {
  49.         $this->request = $requestStack->getCurrentRequest();
  50.         $this->datatable = null;
  51.         $this->datatableQueryBuilder = null;
  52.     }
  53.     //-------------------------------------------------
  54.     // Getters && Setters
  55.     //-------------------------------------------------
  56.     /**
  57.      * @throws Exception
  58.      *
  59.      * @return $this
  60.      */
  61.     public function setDatatable(DatatableInterface $datatable)
  62.     {
  63.         $val = $this->validateColumnsPositions($datatable);
  64.         if (\is_int($val)) {
  65.             throw new Exception("DatatableResponse::setDatatable(): The Column with the index {$val} is on a not allowed position.");
  66.         }
  67.         $this->datatable = $datatable;
  68.         $this->datatableQueryBuilder = null;
  69.         return $this;
  70.     }
  71.     /**
  72.      * Get DatatableQueryBuilder instance.
  73.      *
  74.      * @return DatatableQueryBuilder
  75.      */
  76.     public function getDatatableQueryBuilder()
  77.     {
  78.         return $this->datatableQueryBuilder ?: $this->createDatatableQueryBuilder();
  79.     }
  80.     //-------------------------------------------------
  81.     // Response
  82.     //-------------------------------------------------
  83.     /**
  84.      * Get response data as array.
  85.      *
  86.      * @param bool $countAllResults
  87.      * @param bool $outputWalkers
  88.      * @param bool $fetchJoinCollection
  89.      *
  90.      * @throws Exception
  91.      *
  92.      * @return array
  93.      */
  94.     public function getData($countAllResults = true, $outputWalkers = false, $fetchJoinCollection = true)
  95.     {
  96.         if (null === $this->datatable) {
  97.             throw new Exception('DatatableResponse::getResponse(): Set a Datatable class with setDatatable().');
  98.         }
  99.         if (null === $this->datatableQueryBuilder) {
  100.             throw new Exception('DatatableResponse::getResponse(): A DatatableQueryBuilder instance is needed. Call getDatatableQueryBuilder().');
  101.         }
  102.         $paginator = new Paginator($this->datatableQueryBuilder->execute(), $fetchJoinCollection);
  103.         $paginator->setUseOutputWalkers($outputWalkers);
  104.         $formatter = new DatatableFormatter();
  105.         $formatter->runFormatter($paginator, $this->datatable);
  106.         $outputHeader = [
  107.             'draw' => (int) $this->requestParams['draw'],
  108.             'recordsFiltered' => \count($paginator),
  109.             'recordsTotal' => true === $countAllResults ? (int) $this->datatableQueryBuilder->getCountAllResults() : 0,
  110.         ];
  111.         return array_merge($outputHeader, $formatter->getOutput());
  112.     }
  113.     /**
  114.      * @param bool $countAllResults
  115.      * @param bool $outputWalkers
  116.      * @param bool $fetchJoinCollection
  117.      *
  118.      * @throws Exception
  119.      *
  120.      * @return JsonResponse
  121.      */
  122.     public function getResponse($countAllResults = true, $outputWalkers = false, $fetchJoinCollection = true)
  123.     {
  124.         return new JsonResponse($this->getData($countAllResults, $outputWalkers, $fetchJoinCollection));
  125.     }
  126.     //-------------------------------------------------
  127.     // Private
  128.     //-------------------------------------------------
  129.     /**
  130.      * Create a new DatatableQueryBuilder instance.
  131.      *
  132.      * @throws Exception
  133.      *
  134.      * @return DatatableQueryBuilder
  135.      */
  136.     private function createDatatableQueryBuilder()
  137.     {
  138.         if (null === $this->datatable) {
  139.             throw new Exception('DatatableResponse::getDatatableQueryBuilder(): Set a Datatable class with setDatatable().');
  140.         }
  141.         $this->requestParams = $this->getRequestParams();
  142.         $this->datatableQueryBuilder = new DatatableQueryBuilder($this->requestParams, $this->datatable);
  143.         return $this->datatableQueryBuilder;
  144.     }
  145.     /**
  146.      * Get request params.
  147.      *
  148.      * @return array
  149.      */
  150.     private function getRequestParams()
  151.     {
  152.         $parameterBag = null;
  153.         $type = $this->datatable->getAjax()->getMethod();
  154.         if ('GET' === strtoupper($type)) {
  155.             $parameterBag = $this->request->query;
  156.         }
  157.         if ('POST' === strtoupper($type)) {
  158.             $parameterBag = $this->request->request;
  159.         }
  160.         return $parameterBag->all();
  161.     }
  162.     /**
  163.      * Checks Column positions.
  164.      *
  165.      * @return bool|int
  166.      */
  167.     private function validateColumnsPositions(DatatableInterface $datatable)
  168.     {
  169.         $columns = $datatable->getColumnBuilder()->getColumns();
  170.         $lastPosition = \count($columns);
  171.         /** @var ColumnInterface $column */
  172.         foreach ($columns as $column) {
  173.             $allowedPositions = $column->allowedPositions();
  174.             /** @noinspection PhpUndefinedMethodInspection */
  175.             $index = $column->getIndex();
  176.             if (\is_array($allowedPositions)) {
  177.                 $allowedPositions = array_flip($allowedPositions);
  178.                 if (\array_key_exists(ColumnInterface::LAST_POSITION, $allowedPositions)) {
  179.                     $allowedPositions[$lastPosition] = $allowedPositions[ColumnInterface::LAST_POSITION];
  180.                     unset($allowedPositions[ColumnInterface::LAST_POSITION]);
  181.                 }
  182.                 if (false === \array_key_exists($index, $allowedPositions)) {
  183.                     return $index;
  184.                 }
  185.             }
  186.         }
  187.         return true;
  188.     }
  189. }