Completed
Push — master ( f58995...61d3f4 )
by Arjay
01:46
created

CollectionEngine   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 254
Duplicated Lines 4.72 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 0
Metric Value
dl 12
loc 254
rs 9.3999
c 0
b 0
f 0
wmc 33
lcom 1
cbo 7

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A serialize() 0 4 2
A filter() 0 6 1
A showDebugger() 0 6 1
A count() 0 4 2
C globalSearch() 0 35 7
B columnSearch() 12 35 6
A paging() 0 7 2
A results() 0 4 1
A make() 0 20 3
A totalCount() 0 4 2
B ordering() 0 27 5

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace Yajra\Datatables\Engines;
4
5
use Illuminate\Contracts\Support\Arrayable;
6
use Illuminate\Support\Arr;
7
use Illuminate\Support\Collection;
8
use Illuminate\Support\Str;
9
10
/**
11
 * Class CollectionEngine.
12
 *
13
 * @package Yajra\Datatables\Engines
14
 * @author  Arjay Angeles <[email protected]>
15
 */
16
class CollectionEngine extends BaseEngine
17
{
18
    /**
19
     * Collection object
20
     *
21
     * @var \Illuminate\Support\Collection
22
     */
23
    public $collection;
24
25
    /**
26
     * Collection object
27
     *
28
     * @var \Illuminate\Support\Collection
29
     */
30
    public $original;
31
32
    /**
33
     * CollectionEngine constructor.
34
     *
35
     * @param \Illuminate\Support\Collection $collection
36
     */
37
    public function __construct(Collection $collection)
38
    {
39
        $this->request    = resolve('datatables.request');
40
        $this->config     = resolve('datatables.config');
41
        $this->collection = $collection;
42
        $this->original   = $collection;
43
        $this->columns    = array_keys($this->serialize($collection->first()));
44
    }
45
46
    /**
47
     * Serialize collection
48
     *
49
     * @param  mixed $collection
50
     * @return mixed|null
51
     */
52
    protected function serialize($collection)
53
    {
54
        return $collection instanceof Arrayable ? $collection->toArray() : (array) $collection;
55
    }
56
57
    /**
58
     * Set auto filter off and run your own filter.
59
     * Overrides global search.
60
     *
61
     * @param callable $callback
62
     * @param bool     $globalSearch
63
     * @return $this
64
     */
65
    public function filter(callable $callback, $globalSearch = false)
66
    {
67
        $this->overrideGlobalSearch($callback, $this, $globalSearch);
68
69
        return $this;
70
    }
71
72
    /**
73
     * Append debug parameters on output.
74
     *
75
     * @param  array $output
76
     * @return array
77
     */
78
    public function showDebugger(array $output)
79
    {
80
        $output["input"] = $this->request->all();
81
82
        return $output;
83
    }
84
85
    /**
86
     * Count results.
87
     *
88
     * @return integer
89
     */
90
    public function count()
91
    {
92
        return $this->collection->count() > $this->totalRecords ? $this->totalRecords : $this->collection->count();
93
    }
94
95
    /**
96
     * Perform global search for the given keyword.
97
     *
98
     * @param string $keyword
99
     */
100
    protected function globalSearch($keyword)
101
    {
102
        if ($this->config->isCaseInsensitive()) {
103
            $keyword = Str::lower($keyword);
104
        }
105
106
        $columns          = $this->request->columns();
107
        $this->collection = $this->collection->filter(
108
            function ($row) use ($columns, $keyword) {
109
                $data                  = $this->serialize($row);
110
                $this->isFilterApplied = true;
111
112
                foreach ($this->request->searchableColumnIndex() as $index) {
113
                    $column = $this->getColumnName($index);
114
                    if (!$value = Arr::get($data, $column)) {
115
                        continue;
116
                    }
117
118
                    if (is_array($value)) {
119
                        continue;
120
                    }
121
122
                    if ($this->config->isCaseInsensitive()) {
123
                        $value = Str::lower($value);
124
                    }
125
126
                    if (Str::contains($value, $keyword)) {
127
                        return true;
128
                    }
129
                }
130
131
                return false;
132
            }
133
        );
134
    }
135
136
    /**
137
     * Perform column search.
138
     *
139
     * @return void
140
     */
141
    public function columnSearch()
142
    {
143
        $columns = $this->request->get('columns');
144
        for ($i = 0, $c = count($columns); $i < $c; $i++) {
145
            if ($this->request->isColumnSearchable($i)) {
146
                $this->isFilterApplied = true;
147
                $regex                 = $this->request->isRegex($i);
148
149
                $column  = $this->getColumnName($i);
150
                $keyword = $this->request->columnKeyword($i);
151
152
                $this->collection = $this->collection->filter(
153
                    function ($row) use ($column, $keyword, $regex) {
154
                        $data = $this->serialize($row);
155
156
                        $value = Arr::get($data, $column);
157
158
                        if ($this->config->isCaseInsensitive()) {
159 View Code Duplication
                            if ($regex) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
160
                                return preg_match('/' . $keyword . '/i', $value) == 1;
161
                            } else {
162
                                return strpos(Str::lower($value), Str::lower($keyword)) !== false;
163
                            }
164 View Code Duplication
                        } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
165
                            if ($regex) {
166
                                return preg_match('/' . $keyword . '/', $value) == 1;
167
                            } else {
168
                                return strpos($value, $keyword) !== false;
169
                            }
170
                        }
171
                    }
172
                );
173
            }
174
        }
175
    }
176
177
    /**
178
     * Perform pagination.
179
     *
180
     * @return void
181
     */
182
    public function paging()
183
    {
184
        $this->collection = $this->collection->slice(
185
            $this->request->input('start'),
186
            (int) $this->request->input('length') > 0 ? $this->request->input('length') : 10
187
        );
188
    }
189
190
    /**
191
     * Get results.
192
     *
193
     * @return mixed
194
     */
195
    public function results()
196
    {
197
        return $this->collection->all();
198
    }
199
200
    /**
201
     * Organizes works.
202
     *
203
     * @param bool $mDataSupport
204
     * @return \Illuminate\Http\JsonResponse
205
     */
206
    public function make($mDataSupport = false)
207
    {
208
        try {
209
            $this->totalRecords = $this->totalCount();
210
211
            if ($this->totalRecords) {
212
                $data   = $this->getProcessedData($mDataSupport);
213
                $output = $this->transform($data);
214
215
                $this->collection = collect($output);
216
                $this->ordering();
217
                $this->filterRecords();
218
                $this->paginate();
219
            }
220
221
            return $this->render($this->collection->values()->all());
222
        } catch (\Exception $exception) {
223
            return $this->errorResponse($exception);
224
        }
225
    }
226
227
    /**
228
     * Count total items.
229
     *
230
     * @return integer
231
     */
232
    public function totalCount()
233
    {
234
        return $this->totalRecords ? $this->totalRecords : $this->collection->count();
235
    }
236
237
    /**
238
     * Perform sorting of columns.
239
     *
240
     * @return void
241
     */
242
    public function ordering()
243
    {
244
        if ($this->orderCallback) {
245
            call_user_func($this->orderCallback, $this);
246
247
            return;
248
        }
249
250
        foreach ($this->request->orderableColumns() as $orderable) {
251
            $column = $this->getColumnName($orderable['column']);
252
253
            $options = SORT_NATURAL;
254
            if ($this->config->isCaseInsensitive()) {
255
                $options = SORT_NATURAL | SORT_FLAG_CASE;
256
            }
257
258
            $this->collection = $this->collection->sortBy(function ($row) use ($column) {
259
                $data = $this->serialize($row);
260
261
                return Arr::get($data, $column);
262
            }, $options);
263
264
            if ($orderable['direction'] == 'desc') {
265
                $this->collection = $this->collection->reverse();
266
            }
267
        }
268
    }
269
}
270