Skip to content

Commit ef7df68

Browse files
committed
edited namespaces
1 parent 42253b7 commit ef7df68

24 files changed

+847
-0
lines changed

src/DataTableInput.php

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
namespace HamidRrj\LaravelDatatable;
4+
5+
use HamidRrj\LaravelDatatable\Filter\Filter;
6+
use HamidRrj\LaravelDatatable\Sort\Sort;
7+
8+
class DataTableInput
9+
{
10+
/**
11+
* @param int $start
12+
* @param int $size
13+
* @param array $filters
14+
* @param array $sorting
15+
* @param array $rels
16+
*/
17+
public function __construct(
18+
private int $start,
19+
private ?int $size,
20+
private array $filters,
21+
private array $sorting,
22+
private array $rels,
23+
private array $allowedFilters,
24+
private array $allowedSortings,
25+
)
26+
{
27+
}
28+
29+
public function getStart(): int
30+
{
31+
return $this->start;
32+
}
33+
34+
public function getSize(): ?int
35+
{
36+
return $this->size;
37+
}
38+
39+
/**
40+
* @return array returns an array of Filter objects
41+
*/
42+
public function getFilters(): array
43+
{
44+
$filters = array();
45+
46+
foreach ($this->filters as $filter) {
47+
$filters[] = new Filter(
48+
$filter->id,
49+
$filter->value,
50+
$filter->fn,
51+
$filter->datatype,
52+
$this->allowedFilters
53+
);
54+
}
55+
56+
return $filters;
57+
}
58+
59+
/**
60+
* @return Sort|null
61+
*/
62+
public function getSorting(): ?Sort
63+
{
64+
return !empty($this->sorting) ?
65+
new Sort($this->sorting[0]->id, $this->sorting[0]->desc, $this->allowedSortings) : null;
66+
}
67+
68+
public function getRelations(): array
69+
{
70+
return $this->rels;
71+
}
72+
73+
74+
}

src/DataTableService.php

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
3+
namespace HamidRrj\LaravelDatatable;
4+
5+
use HamidRrj\LaravelDatatable\Filter\ApplyFilter;
6+
use HamidRrj\LaravelDatatable\Sort\ApplySort;
7+
use Illuminate\Contracts\Database\Query\Builder;
8+
9+
class DataTableService
10+
{
11+
12+
protected array $allowedFilters;
13+
protected array $allowedRelations;
14+
protected array $allowedSortings;
15+
protected array $allowedSelects;
16+
private int $totalRowCount;
17+
18+
public function __construct(
19+
protected Builder $query,
20+
private DataTableInput $dataTableInput
21+
)
22+
{
23+
}
24+
25+
public function setAllowedFilters(array $allowedFilters): DataTableService
26+
{
27+
$this->allowedFilters = $allowedFilters;
28+
return $this;
29+
}
30+
31+
public function setAllowedRelations(array $allowedRelations): DataTableService
32+
{
33+
$this->allowedRelations = $allowedRelations;
34+
return $this;
35+
}
36+
37+
public function setAllowedSortings(array $allowedSortings): DataTableService
38+
{
39+
$this->allowedSortings = $allowedSortings;
40+
return $this;
41+
}
42+
43+
public function setAllowedSelects(array $allowedSelects): DataTableService
44+
{
45+
$this->allowedSelects = $allowedSelects;
46+
return $this;
47+
}
48+
49+
/**
50+
* Handle 'getData' operations
51+
* @return array
52+
*/
53+
public function getData(): array
54+
{
55+
$query = $this->buildQuery();
56+
$data = $query->get();
57+
58+
return array(
59+
'data' => $data,
60+
'meta' => [
61+
'totalRowCount' => $this->totalRowCount
62+
]
63+
);
64+
}
65+
66+
protected function buildQuery(): Builder
67+
{
68+
$query = $this->query;
69+
70+
foreach ($this->dataTableInput->getFilters() as $filter) {
71+
$query = (new ApplyFilter($query, $filter))->apply();
72+
}
73+
74+
$query = $this->applySelect($query, $this->allowedSelects);
75+
$query = $this->includeRelationsInQuery($query, $this->allowedRelations);
76+
77+
$this->totalRowCount = $query->count();
78+
79+
$query->offset($this->dataTableInput->getStart());
80+
81+
if(!is_null($this->dataTableInput->getSize())){
82+
$query->limit($this->dataTableInput->getSize());
83+
}
84+
85+
$sorting = $this->dataTableInput->getSorting();
86+
$query = (new ApplySort($query, $sorting))->apply();
87+
return $query;
88+
}
89+
90+
protected function applySelect(Builder $query, array $selectedFields): Builder
91+
{
92+
if (!empty($selectedFields)) {
93+
$query->select($selectedFields);
94+
}
95+
96+
return $query;
97+
}
98+
99+
protected function includeRelationsInQuery(Builder $query, array $rels): Builder
100+
{
101+
if (!empty($rels)) {
102+
$query->with($rels);
103+
}
104+
105+
return $query;
106+
}
107+
108+
// (later) define mapping of relation names to prevent relation name expose.
109+
// (later) define mapping of column names to prevent column name expose.
110+
}

src/Enums/DataType.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace HamidRrj\LaravelDatatable\Enums;
4+
enum DataType: string
5+
{
6+
case NUMERIC = 'numeric';
7+
case TEXT = 'text';
8+
case DATE = 'date';
9+
10+
public static function values(): array
11+
{
12+
return array_column(self::cases(), 'value');
13+
}
14+
}

src/Enums/SearchType.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace HamidRrj\LaravelDatatable\Enums;
4+
5+
enum SearchType: string
6+
{
7+
case CONTAINS = 'contains';
8+
case EQUALS = 'equals';
9+
case NOT_EQUALS = 'notEquals';
10+
case BETWEEN = 'between';
11+
case GREATER_THAN = 'greaterThan';
12+
case LESS_THAN = 'lessThan';
13+
case FUZZY = 'fuzzy';
14+
15+
public static function values(): array
16+
{
17+
return array_column(self::cases(), 'value');
18+
}
19+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace HamidRrj\LaravelDatatable\Exceptions;
4+
5+
use Exception;
6+
7+
class InvalidFilterException extends Exception implements InvalidParameterInterface
8+
{
9+
protected $fieldName;
10+
11+
public function __construct($fieldName, $message = "", $code = 400, \Throwable $previous = null)
12+
{
13+
$this->fieldName = $fieldName;
14+
parent::__construct($message, $code, $previous);
15+
}
16+
17+
public function getFieldName()
18+
{
19+
return $this->fieldName;
20+
}
21+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace HamidRrj\LaravelDatatable\Exceptions;
4+
5+
interface InvalidParameterInterface
6+
{
7+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace HamidRrj\LaravelDatatable\Exceptions;
4+
5+
use Exception;
6+
7+
class InvalidRelationException extends Exception implements InvalidParameterInterface
8+
{
9+
protected $fieldName;
10+
11+
public function __construct($fieldName, $message = "", $code = 400, \Throwable $previous = null)
12+
{
13+
$this->fieldName = $fieldName;
14+
parent::__construct($message, $code, $previous);
15+
}
16+
17+
public function getFieldName()
18+
{
19+
return $this->fieldName;
20+
}
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace HamidRrj\LaravelDatatable\Exceptions;
4+
5+
use Exception;
6+
7+
class InvalidSortingException extends Exception implements InvalidParameterInterface
8+
{
9+
protected $fieldName;
10+
11+
public function __construct($fieldName, $message = "", $code = 400, \Throwable $previous = null)
12+
{
13+
$this->fieldName = $fieldName;
14+
parent::__construct($message, $code, $previous);
15+
}
16+
17+
public function getFieldName()
18+
{
19+
return $this->fieldName;
20+
}
21+
}

src/Filter/ApplyFilter.php

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
namespace HamidRrj\LaravelDatatable\Filter;
4+
5+
use HamidRrj\LaravelDatatable\Enums\SearchType;
6+
use HamidRrj\LaravelDatatable\Exceptions\InvalidFilterException;
7+
use HamidRrj\LaravelDatatable\Filter\SearchFunctions\FilterBetween;
8+
use HamidRrj\LaravelDatatable\Filter\SearchFunctions\FilterContains;
9+
use HamidRrj\LaravelDatatable\Filter\SearchFunctions\FilterEquals;
10+
use HamidRrj\LaravelDatatable\Filter\SearchFunctions\FilterGreaterThan;
11+
use HamidRrj\LaravelDatatable\Filter\SearchFunctions\FilterLessThan;
12+
use HamidRrj\LaravelDatatable\Filter\SearchFunctions\FilterNotEquals;
13+
use HamidRrj\LaravelDatatable\Filter\SearchFunctions\SearchFilter;
14+
use Illuminate\Contracts\Database\Query\Builder;
15+
16+
class ApplyFilter
17+
{
18+
private SearchFilter $searchFilter;
19+
20+
/**
21+
* @param Builder $query
22+
* @param Filter $filter
23+
*/
24+
public function __construct(
25+
private Builder $query,
26+
private Filter $filter,
27+
)
28+
{
29+
}
30+
31+
public function apply(): Builder
32+
{
33+
$filter = $this->filter;
34+
$query = $this->query;
35+
36+
$searchType = SearchType::from($filter->getFn());
37+
switch ($searchType) {
38+
case SearchType::CONTAINS:
39+
$this->searchFilter = new FilterContains($query, $filter);
40+
break;
41+
42+
case SearchType::EQUALS:
43+
$this->searchFilter = new FilterEquals($query, $filter);
44+
break;
45+
46+
case SearchType::NOT_EQUALS:
47+
$this->searchFilter = new FilterNotEquals($query, $filter);
48+
break;
49+
50+
case SearchType::BETWEEN:
51+
$this->searchFilter = new FilterBetween($query, $filter);
52+
break;
53+
54+
case SearchType::GREATER_THAN:
55+
$this->searchFilter = new FilterGreaterThan($query, $filter);
56+
break;
57+
58+
case SearchType::LESS_THAN:
59+
$this->searchFilter = new FilterLessThan($query, $filter);
60+
break;
61+
62+
default:
63+
$searchFunction = $filter->getFn();
64+
throw new InvalidFilterException($searchFunction, "search function `$searchFunction` is invalid.");
65+
66+
}
67+
68+
$relation = $this->filter->getRelation();
69+
return $relation ? $this->applyFilterToRelation($relation) : $this->searchFilter->apply();
70+
}
71+
72+
protected function applyFilterToRelation(string $relation): Builder
73+
{
74+
return $this->query->whereHas($relation, function (Builder $query) {
75+
$this->filter->removeRelationFromId();
76+
$this->applyFilter($query, $this->filter);
77+
});
78+
}
79+
80+
private function applyFilter(Builder $query, Filter $filter): Builder
81+
{
82+
return (new ApplyFilter($query, $filter))->apply();
83+
}
84+
}

0 commit comments

Comments
 (0)