Completed
Push — master ( 3e9b09...262537 )
by Arjay
07:11
created

CollectionDataTable::defaultOrdering()   C

Complexity

Conditions 7
Paths 2

Size

Total Lines 44
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 29
nc 2
nop 0
dl 0
loc 44
rs 6.7272
c 0
b 0
f 0
1
<?php
2
3
namespace Yajra\DataTables;
4
5
use Illuminate\Contracts\Support\Arrayable;
6
use Illuminate\Support\Arr;
7
use Illuminate\Support\Collection;
8
use Illuminate\Support\Str;
9
10
class CollectionDataTable extends DataTableAbstract
11
{
12
    /**
13
     * Collection object
14
     *
15
     * @var \Illuminate\Support\Collection
16
     */
17
    public $collection;
18
19
    /**
20
     * Collection object
21
     *
22
     * @var \Illuminate\Support\Collection
23
     */
24
    public $original;
25
26
    /**
27
     * CollectionEngine constructor.
28
     *
29
     * @param \Illuminate\Support\Collection $collection
30
     */
31
    public function __construct(Collection $collection)
32
    {
33
        $this->request    = resolve('datatables.request');
34
        $this->config     = resolve('datatables.config');
35
        $this->collection = $collection;
36
        $this->original   = $collection;
37
        $this->columns    = array_keys($this->serialize($collection->first()));
38
    }
39
40
    /**
41
     * Serialize collection
42
     *
43
     * @param  mixed $collection
44
     * @return mixed|null
45
     */
46
    protected function serialize($collection)
47
    {
48
        return $collection instanceof Arrayable ? $collection->toArray() : (array) $collection;
49
    }
50
51
    /**
52
     * Count results.
53
     *
54
     * @return integer
55
     */
56
    public function count()
57
    {
58
        return $this->collection->count() > $this->totalRecords ? $this->totalRecords : $this->collection->count();
59
    }
60
61
    /**
62
     * Perform column search.
63
     *
64
     * @return void
65
     */
66
    public function columnSearch()
67
    {
68
        $columns = $this->request->get('columns');
69
        for ($i = 0, $c = count($columns); $i < $c; $i++) {
70
            if ($this->request->isColumnSearchable($i)) {
71
                $this->isFilterApplied = true;
72
73
                $regex   = $this->request->isRegex($i);
74
                $column  = $this->getColumnName($i);
75
                $keyword = $this->request->columnKeyword($i);
76
77
                $this->collection = $this->collection->filter(
78
                    function ($row) use ($column, $keyword, $regex) {
79
                        $data = $this->serialize($row);
80
81
                        $value = Arr::get($data, $column);
82
83
                        if ($this->config->isCaseInsensitive()) {
84 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...
85
                                return preg_match('/' . $keyword . '/i', $value) == 1;
86
                            } else {
87
                                return strpos(Str::lower($value), Str::lower($keyword)) !== false;
88
                            }
89 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...
90
                            if ($regex) {
91
                                return preg_match('/' . $keyword . '/', $value) == 1;
92
                            } else {
93
                                return strpos($value, $keyword) !== false;
94
                            }
95
                        }
96
                    }
97
                );
98
            }
99
        }
100
    }
101
102
    /**
103
     * Perform pagination.
104
     *
105
     * @return void
106
     */
107
    public function paging()
108
    {
109
        $this->collection = $this->collection->slice(
110
            $this->request->input('start'),
111
            (int) $this->request->input('length') > 0 ? $this->request->input('length') : 10
112
        );
113
    }
114
115
    /**
116
     * Organizes works.
117
     *
118
     * @param bool $mDataSupport
119
     * @return \Illuminate\Http\JsonResponse
120
     */
121
    public function make($mDataSupport = true)
122
    {
123
        try {
124
            $this->totalRecords = $this->totalCount();
125
126
            if ($this->totalRecords) {
127
                $results   = $this->results();
128
                $processed = $this->processResults($results, $mDataSupport);
129
                $output    = $this->transform($results, $processed);
130
131
                $this->collection = collect($output);
132
                $this->ordering();
133
                $this->filterRecords();
134
                $this->paginate();
135
136
                $this->revertIndexColumn($mDataSupport);
137
            }
138
139
            return $this->render($this->collection->values()->all());
140
        } catch (\Exception $exception) {
141
            return $this->errorResponse($exception);
142
        }
143
    }
144
145
    /**
146
     * Count total items.
147
     *
148
     * @return integer
149
     */
150
    public function totalCount()
151
    {
152
        return $this->totalRecords ? $this->totalRecords : $this->collection->count();
153
    }
154
155
    /**
156
     * Get results.
157
     *
158
     * @return mixed
159
     */
160
    public function results()
161
    {
162
        return $this->collection->all();
163
    }
164
165
    /**
166
     * Revert transformed DT_Row_Index back to it's original values.
167
     *
168
     * @param bool $mDataSupport
169
     */
170
    private function revertIndexColumn($mDataSupport)
171
    {
172
        if ($this->columnDef['index']) {
173
            $index = $mDataSupport ? config('datatables.index_column', 'DT_Row_Index') : 0;
174
            $start = (int) $this->request->input('start');
175
            $this->collection->transform(function ($data) use ($index, &$start) {
176
                $data[$index] = ++$start;
177
178
                return $data;
179
            });
180
        }
181
    }
182
183
    /**
184
     * Perform global search for the given keyword.
185
     *
186
     * @param string $keyword
187
     */
188
    protected function globalSearch($keyword)
189
    {
190
        $columns = $this->request->columns();
191
        $keyword = $this->config->isCaseInsensitive() ? Str::lower($keyword) : $keyword;
192
193
        $this->collection = $this->collection->filter(function ($row) use ($columns, $keyword) {
194
            $this->isFilterApplied = true;
195
196
            $data = $this->serialize($row);
197
            foreach ($this->request->searchableColumnIndex() as $index) {
198
                $column = $this->getColumnName($index);
199
                $value  = Arr::get($data, $column);
200
                if (!$value || is_array($value)) {
201
                    continue;
202
                }
203
204
                $value = $this->config->isCaseInsensitive() ? Str::lower($value) : $value;
205
                if (Str::contains($value, $keyword)) {
206
                    return true;
207
                }
208
            }
209
210
            return false;
211
        });
212
    }
213
214
    /**
215
     * Perform default query orderBy clause.
216
     */
217
    protected function defaultOrdering()
218
    {
219
        $criteria = $this->request->orderableColumns();
220
        if (!empty($criteria)) {
221
            $sorter = function ($a, $b) use ($criteria) {
222
                foreach ($criteria as $orderable) {
223
                    $column    = $this->getColumnName($orderable['column']);
224
                    $direction = $orderable['direction'];
225
                    if ($direction === 'desc') {
226
                        $first  = $b;
227
                        $second = $a;
228
                    } else {
229
                        $first  = $a;
230
                        $second = $b;
231
                    }
232
                    if ($this->config->isCaseInsensitive()) {
233
                        $cmp = strnatcasecmp($first[$column], $second[$column]);
234
                    } else {
235
                        $cmp = strnatcmp($first[$column], $second[$column]);
236
                    }
237
                    if ($cmp != 0) {
238
                        return $cmp;
239
                    }
240
                }
241
242
                // all elements were equal
243
                return 0;
244
            };
245
246
            $this->collection = $this->collection
247
                ->map(function ($data) {
248
                    return array_dot($data);
249
                })
250
                ->sort($sorter)
251
                ->map(function ($data) {
252
                    foreach ($data as $key => $value) {
253
                        unset($data[$key]);
254
                        array_set($data, $key, $value);
255
                    }
256
257
                    return $data;
258
                });
259
        }
260
    }
261
262
    /**
263
     * Resolve callback parameter instance.
264
     *
265
     * @return $this
266
     */
267
    protected function resolveCallbackParameter()
268
    {
269
        return $this;
270
    }
271
}
272