FiltersBuilder::addFilter()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 5
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 3
crap 2
1
<?php
2
declare(strict_types=1);
3
4
namespace ReadModel\Filters;
5
6
use ReadModel\Filters\DataTransformer as T;
7
8
abstract class FiltersBuilder
9
{
10
    /** @var OrderBy|null */
11
    protected $defaultOrder;
12
13
    /** @var int|null */
14
    protected $defaultLimit;
15
16
    /** @var int */
17
    protected $defaultOffset;
18
19
    /** @var array */
20
    private $filters = [];
21
22
    /** @var array */
23
    private $ordersBy = [];
24
25
    public function __construct(string $defaultOrder = null, int $defaultLimit = null, int $defaultOffset = 0)
26
    {
27
        $this->defaultLimit = $defaultLimit;
28
        $this->defaultOffset = $defaultOffset;
29
30
        if ($defaultOrder !== null) {
31
            $this->defaultOrder = new OrderBy($defaultOrder);
32
            $this->addOrderBy($this->defaultOrder->field());
33
        }
34
    }
35
36
    public function addFilter(string $name, $defaultValue = null, T\DataTransformer $transformer = null): self
37
    {
38
        $value = $this->getValue($name, $defaultValue);
39
        $this->filters[$name] = new Filter($name, $value, $transformer);
40
        return $this;
41
    }
42
43
    public function addIntegerFilter(string $name, $defaultValue = null): self
44
    {
45
        return $this->addFilter($name, $defaultValue, new T\IntegerTransformer());
46
    }
47
48
    public function addFloatFilter(string $name, $defaultValue = null): self
49
    {
50
        return $this->addFilter($name, $defaultValue, new T\FloatTransformer());
51
    }
52
53
    public function addBooleanFilter(string $name, $defaultValue = null): self
54
    {
55
        return $this->addFilter($name, $defaultValue, new T\BooleanTransformer());
56
    }
57
58
    public function addDateTimeFilter(string $name, $defaultValue = null, $format = 'Y-m-d H:i'): self
59
    {
60
        return $this->addFilter($name, $defaultValue, new T\DateTimeTransformer($format));
61
    }
62
63
    public function addDateFilter(string $name, $defaultValue = null): self
64
    {
65
        return $this->addFilter($name, $defaultValue, new T\DateTimeTransformer('Y-m-d'));
66
    }
67
68
    /**
69
     * Supports also comma separated values, eg: 'tag1,tag2,tag3'
70
     */
71
    public function addArrayFilter(string $name, $defaultValues = null): self
72
    {
73
        $value = $this->getValue($name, $defaultValues);
74
75
        if (is_string($value)) {
76
            $value = explode(',', $value);
77
        }
78
79
        $this->filters[$name] = new Filter($name, $value, new T\ArrayTransformer());
80
        return $this;
81
    }
82
83
    public function addOrderBy(string ...$fields): self
84
    {
85
        foreach ($fields as $field) {
86
            if (in_array($field, $this->ordersBy)) {
87
                continue;
88
            }
89
90
            $this->ordersBy[] = $field;
91
        }
92
93
        return $this;
94
    }
95
96
    public function buildFilters(): Filters
97
    {
98
        return new Filters($this->filters, $this->resolveOrderBy(), $this->getLimit(), $this->getOffset());
99
    }
100
101
    private function resolveOrderBy(): array
102
    {
103
        $order = $this->getOrderBy();
104
105
        if ($order === null) {
106
            return array_filter([$this->defaultOrder]);
107
        }
108
109
        $orders = array_map(function (string $order) {
110
            return new OrderBy(trim($order));
111
        }, explode(',', $order));
112
113
        return array_filter($orders, function (OrderBy $orderBy) {
114
            return in_array($orderBy->field(), $this->ordersBy);
115
        });
116
    }
117
118
    abstract protected function getValue(string $name, $defaultValue);
119
120
    abstract protected function getLimit(): ?int;
121
122
    abstract protected function getOffset(): int;
123
124
    abstract protected function getOrderBy(): ?string;
125
}
126