130 lines
3.3 KiB
PHP
130 lines
3.3 KiB
PHP
<?php
|
|
|
|
namespace App\Services\DataTable;
|
|
|
|
use App\Services\DataTable\Filter\ApplyFilter;
|
|
use App\Services\DataTable\Sort\ApplySort;
|
|
use Illuminate\Contracts\Database\Query\Builder;
|
|
|
|
class DataTableService
|
|
{
|
|
|
|
protected array $allowedFilters;
|
|
protected array $allowedRelations;
|
|
protected array $allowedSortings;
|
|
protected array $allowedSelects;
|
|
protected array $allowedGroupBy;
|
|
private int $totalRowCount;
|
|
|
|
public function __construct(
|
|
protected Builder $query,
|
|
private DataTableInput $dataTableInput
|
|
)
|
|
{
|
|
}
|
|
|
|
public function setAllowedFilters(array $allowedFilters): DataTableService
|
|
{
|
|
$this->allowedFilters = $allowedFilters;
|
|
return $this;
|
|
}
|
|
|
|
public function setAllowedRelations(array $allowedRelations): DataTableService
|
|
{
|
|
$this->allowedRelations = $allowedRelations;
|
|
return $this;
|
|
}
|
|
|
|
public function setAllowedSortings(array $allowedSortings): DataTableService
|
|
{
|
|
$this->allowedSortings = $allowedSortings;
|
|
return $this;
|
|
}
|
|
|
|
public function setAllowedSelects(array $allowedSelects): DataTableService
|
|
{
|
|
$this->allowedSelects = $allowedSelects;
|
|
return $this;
|
|
}
|
|
|
|
public function setAllowedGroupBy(array $allowedGroupBy): DataTableService
|
|
{
|
|
$this->allowedGroupBy = $allowedGroupBy;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Handle 'getData' operations
|
|
* @return array
|
|
*/
|
|
public function getData(): array
|
|
{
|
|
$query = $this->buildQuery();
|
|
$data = $query->get();
|
|
|
|
return array(
|
|
'data' => $data,
|
|
'meta' => [
|
|
'totalRowCount' => $this->totalRowCount
|
|
]
|
|
);
|
|
}
|
|
|
|
protected function buildQuery(): Builder
|
|
{
|
|
$query = $this->query;
|
|
|
|
foreach ($this->dataTableInput->getFilters() as $filter) {
|
|
$query = (new ApplyFilter($query, $filter))->apply();
|
|
}
|
|
|
|
$query = $this->applySelect($query, $this->allowedSelects);
|
|
$query = $this->includeRelationsInQuery($query, $this->allowedRelations);
|
|
|
|
$this->totalRowCount = $query->count();
|
|
|
|
if (!is_null($this->dataTableInput->getStart())) {
|
|
$query->offset($this->dataTableInput->getStart());
|
|
}
|
|
|
|
if(!is_null($this->dataTableInput->getSize())){
|
|
$query->limit($this->dataTableInput->getSize());
|
|
}
|
|
|
|
$sorting = $this->dataTableInput->getSorting();
|
|
foreach ($sorting as $sort){
|
|
$query = (new ApplySort($query, $sort))->apply();
|
|
}
|
|
|
|
$query = $this->applyGroupBy($query, $this->allowedGroupBy);
|
|
|
|
return $query;
|
|
}
|
|
|
|
protected function applySelect(Builder $query, array $selectedFields): Builder
|
|
{
|
|
if (!empty($selectedFields)) {
|
|
$query->select($selectedFields);
|
|
}
|
|
|
|
return $query;
|
|
}
|
|
|
|
protected function applyGroupBy(Builder $query, array $groupBy): Builder
|
|
{
|
|
return empty($groupBy) ? $query : $query->groupBy($groupBy);
|
|
}
|
|
|
|
protected function includeRelationsInQuery(Builder $query, array $rels): Builder
|
|
{
|
|
if (!empty($rels)) {
|
|
$query->with($rels);
|
|
}
|
|
|
|
return $query;
|
|
}
|
|
|
|
// (later) define mapping of relation names to prevent relation name expose.
|
|
// (later) define mapping of column names to prevent column name expose.
|
|
}
|