Completed
Push — master ( f15fe2...9a8393 )
by Pavel
07:23 queued 11s
created

ArrayDataProvider   B

Complexity

Total Complexity 44

Size/Duplication

Total Lines 195
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 107
dl 0
loc 195
rs 8.8798
c 3
b 0
f 0
wmc 44

13 Methods

Rating   Name   Duplication   Size   Complexity  
A ltDate() 0 16 4
A addEqualFilter() 0 9 2
A addCustomFilter() 0 6 1
A getItems() 0 6 2
A gteDate() 0 16 4
B buildCompare() 0 18 8
A lteDate() 0 16 4
A gtDate() 0 16 4
A getTotalCount() 0 3 1
A __construct() 0 21 5
A addLikeFilter() 0 9 2
A setSort() 0 9 3
A equalDate() 0 16 4

How to fix   Complexity   

Complex Class

Complex classes like ArrayDataProvider often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ArrayDataProvider, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
4
namespace Pfilsx\DataGrid\Grid\Providers;
5
6
7
use DateTime;
8
use Doctrine\Common\Persistence\ManagerRegistry;
9
use Pfilsx\DataGrid\DataGridException;
10
use Pfilsx\DataGrid\Grid\Items\ArrayGridItem;
11
use Pfilsx\DataGrid\Grid\Items\DataGridItem;
12
use Pfilsx\DataGrid\Grid\Items\EntityGridItem;
13
14
class ArrayDataProvider extends DataProvider
15
{
16
    protected $data;
17
18
    public function __construct(array $data, ManagerRegistry $registry = null)
19
    {
20
        parent::__construct($registry);
21
        if (!empty($data)){
22
            $firstItem = $data[0];
23
            if (is_array($firstItem)){
24
                $this->data = array_map(function($row){
25
                    return new ArrayGridItem($row, array_key_exists('id', $row) ? 'id' : null);
26
                }, $data);
27
            } elseif (is_object($firstItem)){
28
                $identifier = $this->getEntityIdentifier(get_class($firstItem));
29
                $this->data = array_map(function($item) use ($identifier) {
30
                    return new EntityGridItem($item, $identifier);
31
                }, $data);
32
            } else {
33
                throw new DataGridException('Each item of ArrayDataProvider data must be an array or object. '
34
                    . gettype($firstItem).' given.'
35
                );
36
            }
37
        } else {
38
            $this->data = $data;
39
        }
40
    }
41
42
    public function getItems(): array
43
    {
44
        if ($this->getPager()->isEnabled()){
45
            $this->data = array_slice($this->data, $this->getPager()->getFirst(), $this->getPager()->getLimit());
46
        }
47
        return $this->data;
48
    }
49
50
    public function getTotalCount(): int
51
    {
52
        return count($this->data);
53
    }
54
55
    public function setSort(array $sort): DataProviderInterface
56
    {
57
        if (!empty($this->data)) {
58
            foreach ($sort as $attribute => $order) {
59
                usort($this->data, $this->buildCompare($attribute, $order));
60
            }
61
62
        }
63
        return $this;
64
    }
65
66
    public function addEqualFilter(string $attribute, $value): DataProviderInterface
67
    {
68
        $this->data = array_filter($this->data, function (DataGridItem $item) use ($attribute, $value) {
69
            if (!$item->has($attribute)) {
70
                return false;
71
            }
72
            return $item[$attribute] == $value;
73
        });
74
        return $this;
75
    }
76
77
    public function addLikeFilter(string $attribute, $value): DataProviderInterface
78
    {
79
        $this->data = array_filter($this->data, function (DataGridItem $item) use ($attribute, $value) {
80
            if (!$item->has($attribute)) {
81
                return false;
82
            }
83
            return mb_strpos(mb_strtolower($item[$attribute]), mb_strtolower($value)) !== false;
84
        });
85
        return $this;
86
    }
87
88
    public function addCustomFilter(string $attribute, $value, callable $callback): DataProviderInterface
89
    {
90
        $this->data = array_filter($this->data, function (DataGridItem $item) use ($attribute, $value, $callback) {
91
            return call_user_func_array($callback, [$item, $attribute, $value]);
92
        });
93
        return $this;
94
    }
95
96
    protected function buildCompare($attribute, $order)
97
    {
98
        return function (DataGridItem $a, DataGridItem $b) use ($attribute, $order) {
99
            if (!$a->has($attribute) || !$b->has($attribute)) {
100
                return 0;
101
            }
102
            $attrValueA = $a[$attribute];
103
            $attrValueB = $b[$attribute];
104
            if ($attrValueA == $attrValueB) {
105
                return 0;
106
            }
107
            if (($type1 = gettype($attrValueA)) != gettype($attrValueB)) {
108
                return 0;
109
            }
110
            if ($type1 == 'string') {
111
                return $order == 'ASC' ? strcmp($attrValueA, $attrValueB) : -strcmp($attrValueA, $attrValueB);
112
            }
113
            return $order == 'ASC' ? $attrValueA <=> $attrValueB : $attrValueB <=> $attrValueA;
114
        };
115
    }
116
117
    protected function equalDate($attribute, $value): void
118
    {
119
        $date = new DateTime($value);
120
        $this->data = array_filter($this->data, function (DataGridItem $item) use ($attribute, $date) {
121
            if (!$item->has($attribute)) {
122
                return false;
123
            }
124
            $attrValue = $item[$attribute];
125
            if ($attrValue instanceof DateTime) {
126
                return date('d.m.Y', $attrValue->getTimestamp()) == date('d.m.Y', $date->getTimestamp());
127
            }
128
            if (is_string($attrValue)) {
129
                $attrDate = new DateTime($attrValue);
130
                return date('d.m.Y', $attrDate->getTimestamp()) == date('d.m.Y', $date->getTimestamp());
131
            }
132
            return false;
133
        });
134
    }
135
136
    protected function ltDate($attribute, $value): void
137
    {
138
        $date = new DateTime($value);
139
        $this->data = array_filter($this->data, function (DataGridItem $item) use ($attribute, $date) {
140
            if (!$item->has($attribute)) {
141
                return false;
142
            }
143
            $attrValue = $item[$attribute];
144
            if ($attrValue instanceof DateTime) {
145
                return $attrValue < $date;
146
            }
147
            if (is_string($attrValue)) {
148
                $attrDate = new DateTime($attrValue);
149
                return $attrDate < $date;
150
            }
151
            return false;
152
        });
153
    }
154
155
    protected function lteDate($attribute, $value): void
156
    {
157
        $date = (new DateTime($value))->modify('+1 day');
158
        $this->data = array_filter($this->data, function (DataGridItem $item) use ($attribute, $date) {
159
            if (!$item->has($attribute)) {
160
                return false;
161
            }
162
            $attrValue = $item[$attribute];
163
            if ($attrValue instanceof DateTime) {
164
                return $attrValue < $date;
165
            }
166
            if (is_string($attrValue)) {
167
                $attrDate = new DateTime($attrValue);
168
                return $attrDate < $date;
169
            }
170
            return false;
171
        });
172
    }
173
174
    protected function gtDate($attribute, $value): void
175
    {
176
        $date = (new DateTime($value))->modify('+1 day');
177
        $this->data = array_filter($this->data, function (DataGridItem $item) use ($attribute, $date) {
178
            if (!$item->has($attribute)) {
179
                return false;
180
            }
181
            $attrValue = $item[$attribute];
182
            if ($attrValue instanceof DateTime) {
183
                return $attrValue >= $date;
184
            }
185
            if (is_string($attrValue)) {
186
                $attrDate = new DateTime($attrValue);
187
                return $attrDate >= $date;
188
            }
189
            return false;
190
        });
191
    }
192
193
    protected function gteDate($attribute, $value): void
194
    {
195
        $date = new DateTime($value);
196
        $this->data = array_filter($this->data, function (DataGridItem $item) use ($attribute, $date) {
197
            if (!$item->has($attribute)) {
198
                return false;
199
            }
200
            $attrValue = $item[$attribute];
201
            if ($attrValue instanceof DateTime) {
202
                return $attrValue >= $date;
203
            }
204
            if (is_string($attrValue)) {
205
                $attrDate = new DateTime($attrValue);
206
                return $attrDate >= $date;
207
            }
208
            return false;
209
        });
210
    }
211
}
212