Completed
Push — master ( d5bc71...9e6337 )
by Avtandil
06:19
created

RequestCriteria::parserSearchData()   C

Complexity

Conditions 7
Paths 5

Size

Total Lines 30
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 7
eloc 15
c 2
b 1
f 0
nc 5
nop 1
dl 0
loc 30
ccs 0
cts 23
cp 0
crap 56
rs 6.7272
1
<?php
2
3
namespace Longman\Platfourm\Repository\Criteria;
4
5
use Longman\Platfourm\Contracts\Repository\Criteria;
6
use Longman\Platfourm\Contracts\Repository\Repository;
7
8
/**
9
 * Class RequestCriteria.
10
 */
11
class RequestCriteria implements Criteria
12
{
13
    /**
14
     * @var \Illuminate\Http\Request
15
     */
16
    protected $request;
17
18
    protected $sortBy;
19
20
    protected $fields;
21
22
    protected $search;
23
24
    protected $searchFields;
25
26
    public function __construct($sortBy, $fields, $search, $searchFields)
27
    {
28
        $this->request      = app('request');
29
        $this->sortBy       = $sortBy;
30
        $this->fields       = $fields;
31
        $this->search       = $search;
32
        $this->searchFields = $searchFields;
33
    }
34
35
    /**
36
     * Apply criteria in query repository.
37
     *
38
     * @param             $model
39
     * @param  Repository $repository
40
     * @return mixed
41
     */
42
    public function apply($model, Repository $repository)
43
    {
44
        $searchableFields = $model->getSearchableFields();
45
        $filterableFields = $model->getFilterableFields();
46
        $sortableFields   = $model->getSortableFields();
47
        $requestFields    = $this->request->all();
48
49
        $sortBy = $this->sortBy;
50
        $fields = $this->fields;
51
52
        $search       = $this->search;
53
        $searchFields = $this->searchFields;
54
        $searchFields = !empty($searchFields) ? explode(',', $searchFields) : $searchableFields;
55
56 View Code Duplication
        if ($search && $searchableFields) {
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...
57
            $model = $model->where(function ($query) use ($requestFields, $searchableFields, $searchFields, $search) {
58
59
                $isFirstField = true;
60
61
                foreach ($searchFields as $field) {
62
                    if (!in_array($field, $searchableFields)) {
63
                        continue;
64
                    }
65
66
                    $value = "%{$search}%";
67
68
                    if ($isFirstField && !is_null($value)) {
69
                        $query->where($field, 'like', $value);
70
                        $isFirstField = false;
71
                    } elseif (!is_null($value)) {
72
                        $query->orWhere($field, 'like', $value);
73
                    }
74
                }
75
            });
76
        }
77
78
        if ($filterableFields) {
79
            $model = $model->where(function ($query) use ($requestFields, $filterableFields) {
80
81
                foreach ($filterableFields as $field => $condition) {
82
                    if (!isset($requestFields[$field])) {
83
                        continue;
84
                    }
85
86
                    $value = $requestFields[$field];
87
                    if (!is_null($value)) {
88
                        $query->where($field, $condition, $value);
89
                    }
90
                }
91
            });
92
        }
93
94
        if (!empty($sortBy)) {
95
            $sortBy = explode(',', $sortBy);
96
            foreach ($sortBy as $sortItem) {
97
                $sortEx    = explode(':', $sortItem);
98
                $sortField = isset($sortEx[0]) ? trim($sortEx[0]) : '';
99
                $sortDir   = isset($sortEx[1]) ? trim($sortEx[1]) : 'asc';
100
                if (!in_array($sortField, $sortableFields)) {
101
                    continue;
102
                }
103
                if (!in_array($sortDir, ['asc', 'desc'])) {
104
                    $sortDir = 'asc';
105
                }
106
107
                $model = $model->orderBy($sortField, $sortDir);
108
            }
109
        }
110
111
        if (!empty($fields)) {
112
            if (is_string($fields)) {
113
                $fields = explode(',', $fields);
114
            }
115
116
            $model = $model->select($fields);
117
        }
118
119
        return $model;
120
    }
121
122
    /**
123
     * @param  $search
124
     * @return array
125
     */
126
    protected function parserSearchData($search)
127
    {
128
129
        if (is_array($search)) {
130
            foreach ($search as $key => $value) {
131
                if (empty($value)) {
132
                    unset($search[$key]);
133
                }
134
            }
135
136
            return $search;
137
        }
138
139
        $searchData = [];
140
141
        if (stripos($search, ':')) {
142
            $fields = explode(';', $search);
143
144
            foreach ($fields as $row) {
145
                try {
146
                    list($field, $value) = explode(':', $row);
147
                    $searchData[$field] = $value;
148
                } catch (\Exception $e) {
149
                    //Surround offset error
150
                }
151
            }
152
        }
153
154
        return $searchData;
155
    }
156
157
    /**
158
     * @param  $search
159
     * @return null
160
     */
161
    protected function parserSearchValue($search)
162
    {
163
164
        if (is_array($search)) {
165
            return isset($search['q']) ? $search['q'] : null;
166
        }
167
168
        if (stripos($search, ';') || stripos($search, ':')) {
169
            $values = explode(';', $search);
170
171
            foreach ($values as $value) {
172
                $s = explode(':', $value);
173
174
                if (count($s) == 1) {
175
                    return $s[0];
176
                }
177
            }
178
179
            return;
180
        }
181
182
        return $search;
183
    }
184
185
    protected function parserFieldsSearch(array $fields = [], array $searchFields = null)
186
    {
187
188
        if (!is_null($searchFields) && count($searchFields)) {
189
            $acceptedConditions = config('database.criteria.acceptedConditions', [
190
                '=',
191
                '>',
192
                '>=',
193
                '<',
194
                '<=',
195
                '!=',
196
                '<>',
197
                'like',
198
                'not like',
199
                'between',
200
                'not between',
201
                'in',
202
                'not in',
203
                'null',
204
                'not null'
205
            ]);
206
            $originalFields     = $fields;
207
            $fields             = [];
208
209
            foreach ($searchFields as $index => $field) {
210
                $field_parts = explode(':', $field);
211
                $_index      = array_search($field_parts[0], $originalFields);
212
213
                if (count($field_parts) == 2) {
214
                    if (in_array($field_parts[1], $acceptedConditions)) {
215
                        unset($originalFields[$_index]);
216
                        $field                  = $field_parts[0];
217
                        $condition              = $field_parts[1];
218
                        $originalFields[$field] = $condition;
219
                        $searchFields[$index]   = $field;
220
                    }
221
                }
222
            }
223
224
            foreach ($originalFields as $field => $condition) {
225
                if (is_numeric($field)) {
226
                    $field     = $condition;
227
                    $condition = '=';
228
                }
229
230
                if (in_array($field, $searchFields)) {
231
                    $fields[$field] = $condition;
232
                }
233
            }
234
235
            if (count($fields) == 0) {
236
                throw new \Exception(trans(
237
                    'database::criteria.fields_not_accepted',
238
                    ['field' => implode(',', $searchFields)]
239
                ));
240
            }
241
        }
242
243
        return $fields;
244
    }
245
}
246