Completed
Push — master ( 262d71...f4720a )
by Nekrasov
02:40
created

BaseQuery::stopQuery()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
rs 9.4286
cc 1
eloc 3
nc 1
nop 0
1
<?php
2
3
namespace Arrilot\BitrixModels\Queries;
4
5
use BadMethodCallException;
6
use Illuminate\Support\Collection;
7
8
/**
9
 * @method ElementQuery active()
10
 */
11
abstract class BaseQuery
12
{
13
    /**
14
     * Bitrix object to be queried.
15
     *
16
     * @var object
17
     */
18
    protected $bxObject;
19
20
    /**
21
     * Name of the model that calls the query.
22
     *
23
     * @var string
24
     */
25
    protected $modelName;
26
27
    /**
28
     * Model that calls the query.
29
     *
30
     * @var object
31
     */
32
    protected $model;
33
34
    /**
35
     * Query sort.
36
     *
37
     * @var array
38
     */
39
    public $sort = [];
40
41
    /**
42
     * Query filter.
43
     *
44
     * @var array
45
     */
46
    public $filter = [];
47
48
    /**
49
     * Query navigation.
50
     *
51
     * @var array|bool
52
     */
53
    public $navigation = false;
54
55
    /**
56
     * Query select.
57
     *
58
     * @var array
59
     */
60
    public $select = ['FIELDS', 'PROPS'];
61
62
    /**
63
     * The key to list items in array of results.
64
     * Set to false to have auto incrementing integer.
65
     *
66
     * @var string|bool
67
     */
68
    public $keyBy = false;
69
70
    /**
71
     * Indicates that the query should be stopped instead of touching the DB.
72
     * Can be set in query scopes or manually.
73
     *
74
     * @var bool
75
     */
76
    protected $queryShouldBeStopped = false;
77
78
    /**
79
     * Get count of users that match $filter.
80
     *
81
     * @return int
82
     */
83
    abstract public function count();
84
85
    /**
86
     * Get list of items.
87
     *
88
     * @return Collection
89
     */
90
    abstract public function getList();
91
92
    /**
93
     * Constructor.
94
     *
95
     * @param object $bxObject
96
     * @param string $modelName
97
     */
98
    public function __construct($bxObject, $modelName)
99
    {
100
        $this->bxObject = $bxObject;
101
        $this->modelName = $modelName;
102
        $this->model = new $modelName();
103
    }
104
105
    /**
106
     * Get the first item that matches query params.
107
     *
108
     * @return mixed
109
     */
110
    public function first()
111
    {
112
        return $this->limit(1)->getList()->first(null, false);
113
    }
114
115
    /**
116
     * Get item by its id.
117
     *
118
     * @param int $id
119
     *
120
     * @return mixed
121
     */
122
    public function getById($id)
123
    {
124
        if (!$id || $this->queryShouldBeStopped) {
125
            return false;
126
        }
127
128
        $this->sort = [];
129
        $this->keyBy = false;
130
        $this->filter['ID'] = $id;
131
132
        $items = $this->getList();
133
134
        return !empty($items) ? $items[0] : false;
135
    }
136
137
    /**
138
     * Setter for sort.
139
     *
140
     * @param mixed  $by
141
     * @param string $order
142
     *
143
     * @return $this
144
     */
145
    public function sort($by, $order = 'ASC')
146
    {
147
        $this->sort = is_array($by) ? $by : [$by => $order];
148
149
        return $this;
150
    }
151
152
    /**
153
     * Setter for filter.
154
     *
155
     * @param array $filter
156
     *
157
     * @return $this
158
     */
159
    public function filter($filter)
160
    {
161
        $this->filter = array_merge($this->filter, $filter);
162
163
        return $this;
164
    }
165
166
    /**
167
     * Reset filter.
168
     *
169
     * @return $this
170
     */
171
    public function resetFilter()
172
    {
173
        $this->filter = [];
174
175
        return $this;
176
    }
177
178
    /**
179
     * Add another filter to filters array.
180
     *
181
     * @param $filters
182
     *
183
     * @return $this
184
     */
185
    public function addFilter($filters)
186
    {
187
        foreach ($filters as $field => $value) {
188
            $this->filter[$field] = $value;
189
        }
190
191
        return $this;
192
    }
193
194
    /**
195
     * Setter for navigation.
196
     *
197
     * @param $value
198
     *
199
     * @return $this
200
     */
201
    public function navigation($value)
202
    {
203
        $this->navigation = $value;
204
205
        return $this;
206
    }
207
208
    /**
209
     * Setter for select.
210
     *
211
     * @param $value
212
     *
213
     * @return $this
214
     */
215
    public function select($value)
216
    {
217
        $this->select = is_array($value) ? $value : func_get_args();
218
219
        return $this;
220
    }
221
222
    /**
223
     * Setter for keyBy.
224
     *
225
     * @param $value
226
     *
227
     * @return $this
228
     */
229
    public function keyBy($value)
230
    {
231
        $this->keyBy = $value;
232
233
        return $this;
234
    }
235
236
    /**
237
     * Set the "limit" value of the query.
238
     *
239
     * @param int $value
240
     *
241
     * @return $this
242
     */
243
    public function limit($value)
244
    {
245
        $this->navigation['nPageSize'] = $value;
246
247
        return $this;
248
    }
249
250
    /**
251
     * Set the "page number" value of the query.
252
     *
253
     * @param int $num
254
     *
255
     * @return $this
256
     */
257
    public function page($num)
258
    {
259
        $this->navigation['iNumPage'] = $num;
260
261
        return $this;
262
    }
263
264
    /**
265
     * Alias for "limit".
266
     *
267
     * @param int $value
268
     *
269
     * @return $this
270
     */
271
    public function take($value)
272
    {
273
        return $this->limit($value);
274
    }
275
276
    /**
277
     * Stop the query from touching DB.
278
     *
279
     * @return $this
280
     */
281
    public function stopQuery()
282
    {
283
        $this->queryShouldBeStopped = true;
284
285
        return $this;
286
    }
287
288
    /**
289
     * Adds $item to $results using keyBy value.
290
     *
291
     * @param $results
292
     * @param $item
293
     *
294
     * @return array
295
     */
296
    protected function addItemToResultsUsingKeyBy(&$results, $item)
297
    {
298
        $keyByValue = ($this->keyBy && isset($item[$this->keyBy])) ? $item[$this->keyBy] : false;
299
300
        if ($keyByValue) {
301
            $results[$keyByValue] = $item;
302
        } else {
303
            $results[] = $item;
304
        }
305
    }
306
307
    /**
308
     * Determine if all fields must be selected.
309
     *
310
     * @return bool
311
     */
312
    protected function fieldsMustBeSelected()
313
    {
314
        return in_array('FIELDS', $this->select);
315
    }
316
317
    /**
318
     * Determine if all fields must be selected.
319
     *
320
     * @return bool
321
     */
322
    protected function propsMustBeSelected()
323
    {
324
        return in_array('PROPS', $this->select)
325
            || in_array('PROPERTIES', $this->select)
326
            || in_array('PROPERTY_VALUES', $this->select);
327
    }
328
329
    /**
330
     * Set $array[$new] as $array[$old] and delete $array[$old].
331
     *
332
     * @param array $array
333
     * @param $old
334
     * @param $new
335
     *
336
     * return null
337
     */
338
    protected function substituteField(&$array, $old, $new)
339
    {
340
        if (isset($array[$old]) && !isset($array[$new])) {
341
            $array[$new] = $array[$old];
342
        }
343
344
        unset($array[$old]);
345
    }
346
347
    /**
348
     * Clear select array from duplication and additional fields.
349
     *
350
     * @return array
351
     */
352
    protected function clearSelectArray()
353
    {
354
        $strip = ['FIELDS', 'PROPS', 'PROPERTIES', 'PROPERTY_VALUES', 'GROUPS', 'GROUP_ID', 'GROUPS_ID'];
355
356
        return array_values(array_diff(array_unique($this->select), $strip));
357
    }
358
359
    /**
360
     * Handle dynamic method calls into the method.
361
     *
362
     * @param string $method
363
     * @param array  $parameters
364
     *
365
     * @throws BadMethodCallException
366
     *
367
     * @return $this
368
     */
369
    public function __call($method, $parameters)
370
    {
371
        if (method_exists($this->model, 'scope'.$method)) {
372
            array_unshift($parameters, $this);
373
374
            $query = call_user_func_array([$this->model, 'scope'.$method], $parameters);
375
376
            if ($query === false) {
377
                $this->stopQuery();
378
            }
379
380
            return $query instanceof static ? $query : $this;
381
        }
382
383
        $className = get_class($this);
384
385
        throw new BadMethodCallException("Call to undefined method {$className}::{$method}()");
386
    }
387
}
388