Completed
Push — develop ( f34a65...a0b033 )
by Abdelrahman
02:30
created

BaseRepository::whereNotIn()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
c 0
b 0
f 0
rs 9.4285
cc 2
eloc 3
nc 2
nop 3
1
<?php
2
3
/*
4
 * NOTICE OF LICENSE
5
 *
6
 * Part of the Rinvex Repository Package.
7
 *
8
 * This source file is subject to The MIT License (MIT)
9
 * that is bundled with this package in the LICENSE file.
10
 *
11
 * Package: Rinvex Repository Package
12
 * License: The MIT License (MIT)
13
 * Link:    https://rinvex.com
14
 */
15
16
namespace Rinvex\Repository\Repositories;
17
18
use Closure;
19
use Rinvex\Repository\Traits\Cacheable;
20
use Illuminate\Contracts\Container\Container;
21
use Rinvex\Repository\Contracts\CacheableContract;
22
use Rinvex\Repository\Contracts\RepositoryContract;
23
24
abstract class BaseRepository implements RepositoryContract, CacheableContract
25
{
26
    use Cacheable;
27
28
    /**
29
     * The IoC container instance.
30
     *
31
     * @var \Illuminate\Contracts\Container\Container
32
     */
33
    protected $container;
34
35
    /**
36
     * The connection name for the repository.
37
     *
38
     * @var string
39
     */
40
    protected $connection;
41
42
    /**
43
     * The repository identifier.
44
     *
45
     * @var string
46
     */
47
    protected $repositoryId;
48
49
    /**
50
     * The repository model.
51
     *
52
     * @var string
53
     */
54
    protected $model;
55
56
    /**
57
     * The relations to eager load on query execution.
58
     *
59
     * @var array
60
     */
61
    protected $relations = [];
62
63
    /**
64
     * The query where clauses.
65
     *
66
     * @var array
67
     */
68
    protected $where = [];
69
70
    /**
71
     * The query whereIn clauses.
72
     *
73
     * @var array
74
     */
75
    protected $whereIn = [];
76
77
    /**
78
     * The query whereNotIn clauses.
79
     *
80
     * @var array
81
     */
82
    protected $whereNotIn = [];
83
84
    /**
85
     * The query whereHas clauses.
86
     *
87
     * @var array
88
     */
89
    protected $whereHas = [];
90
91
    /**
92
     * The "offset" value of the query.
93
     *
94
     * @var int
95
     */
96
    protected $offset;
97
98
    /**
99
     * The "limit" value of the query.
100
     *
101
     * @var int
102
     */
103
    protected $limit;
104
105
    /**
106
     * The column to order results by.
107
     *
108
     * @var array
109
     */
110
    protected $orderBy = [];
111
112
    /**
113
     * Execute given callback and return the result.
114
     *
115
     * @param string   $class
116
     * @param string   $method
117
     * @param array    $args
118
     * @param \Closure $closure
119
     *
120
     * @return mixed
121
     */
122
    protected function executeCallback($class, $method, $args, Closure $closure)
123
    {
124
        $skipUri = $this->getContainer('config')->get('rinvex.repository.cache.skip_uri');
125
126
        // Check if cache is enabled
127
        if ($this->getCacheLifetime() && ! $this->getContainer('request')->has($skipUri)) {
128
            return $this->cacheCallback($class, $method, $args, $closure);
129
        }
130
131
        // Cache disabled, just execute query & return result
132
        $result = call_user_func($closure);
133
134
        // We're done, let's clean up!
135
        $this->resetRepository();
136
137
        return $result;
138
    }
139
140
    /**
141
     * Reset repository to it's defaults.
142
     *
143
     * @return $this
144
     */
145
    protected function resetRepository()
146
    {
147
        $this->relations  = [];
148
        $this->where      = [];
149
        $this->whereIn    = [];
150
        $this->whereNotIn = [];
151
        $this->whereHas   = [];
152
        $this->offset     = null;
153
        $this->limit      = null;
154
        $this->orderBy    = [];
155
156
        if (method_exists($this, 'flushCriteria')) {
157
            $this->flushCriteria();
0 ignored issues
show
Documentation Bug introduced by
The method flushCriteria does not exist on object<Rinvex\Repository...itories\BaseRepository>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
158
        }
159
160
        return $this;
161
    }
162
163
    /**
164
     * Prepare query.
165
     *
166
     * @param object $model
167
     *
168
     * @return object
169
     */
170
    protected function prepareQuery($model)
171
    {
172
        // Set the relationships that should be eager loaded
173
        if (! empty($this->relations)) {
174
            $model = $model->with($this->relations);
175
        }
176
177
        // Add a basic where clause to the query
178
        foreach ($this->where as $where) {
179
            list($attribute, $operator, $value, $boolean) = array_pad($where, 4, null);
180
181
            $model = $model->where($attribute, $operator, $value, $boolean);
182
        }
183
184
        // Add a "where in" clause to the query
185
        foreach ($this->whereIn as $whereIn) {
186
            list($attribute, $values, $boolean, $not) = array_pad($whereIn, 4, null);
187
188
            $model = $model->whereIn($attribute, $values, $boolean, $not);
189
        }
190
191
        // Add a "where not in" clause to the query
192
        foreach ($this->whereNotIn as $whereNotIn) {
193
            list($attribute, $values, $boolean) = array_pad($whereNotIn, 3, null);
194
195
            $model = $model->whereNotIn($attribute, $values, $boolean);
196
        }
197
198
        // Add a "where has" clause to the query
199
        foreach ($this->whereHas as $whereHas) {
200
            list($relation, $callback, $operator, $count) = array_pad($whereHas, 4, null);
201
202
            $model = $model->whereHas($relation, $callback, $operator, $count);
203
        }
204
205
        // Set the "offset" value of the query
206
        if ($this->offset > 0) {
207
            $model = $model->offset($this->offset);
208
        }
209
210
        // Set the "limit" value of the query
211
        if ($this->limit > 0) {
212
            $model = $model->limit($this->limit);
213
        }
214
215
        // Add an "order by" clause to the query.
216
        if (! empty($this->orderBy)) {
217
            list($attribute, $direction) = $this->orderBy;
218
219
            $model = $model->orderBy($attribute, $direction);
220
        }
221
222
        // Apply all criteria to the query
223
        if (method_exists($this, 'applyCriteria')) {
224
            $model = $this->applyCriteria($model, $this);
0 ignored issues
show
Documentation Bug introduced by
The method applyCriteria does not exist on object<Rinvex\Repository...itories\BaseRepository>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
225
        }
226
227
        return $model;
228
    }
229
230
    /**
231
     * {@inheritdoc}
232
     */
233
    public function setContainer(Container $container)
234
    {
235
        $this->container = $container;
236
237
        return $this;
238
    }
239
240
    /**
241
     * {@inheritdoc}
242
     */
243
    public function getContainer($service = null)
244
    {
245
        return is_null($service) ? ($this->container ?: app()) : ($this->container[$service] ?: app($service));
246
    }
247
248
    /**
249
     * {@inheritdoc}
250
     */
251
    public function setConnection($name)
252
    {
253
        $this->connection = $name;
254
255
        return $this;
256
    }
257
258
    /**
259
     * {@inheritdoc}
260
     */
261
    public function getConnection()
262
    {
263
        return $this->connection;
264
    }
265
266
    /**
267
     * {@inheritdoc}
268
     */
269
    public function setRepositoryId($repositoryId)
270
    {
271
        $this->repositoryId = $repositoryId;
272
273
        return $this;
274
    }
275
276
    /**
277
     * {@inheritdoc}
278
     */
279
    public function getRepositoryId()
280
    {
281
        return $this->repositoryId ?: get_called_class();
282
    }
283
284
    /**
285
     * {@inheritdoc}
286
     */
287
    public function setModel($model)
288
    {
289
        $this->model = $model;
290
291
        return $this;
292
    }
293
294
    /**
295
     * {@inheritdoc}
296
     */
297
    public function getModel()
298
    {
299
        $model = $this->getContainer('config')->get('rinvex.repository.models');
300
301
        return $this->model ?: str_replace(['Repositories', 'Repository'], [$model, ''], get_called_class());
302
    }
303
304
    /**
305
     * {@inheritdoc}
306
     */
307
    public function getModelInstance($id)
308
    {
309
        return $id ? $this->find($id) : $this->createModel();
310
    }
311
312
    /**
313
     * {@inheritdoc}
314
     */
315
    public function with($relations)
316
    {
317
        if (is_string($relations)) {
318
            $relations = func_get_args();
319
        }
320
321
        $this->relations = $relations;
322
323
        return $this;
324
    }
325
326
    /**
327
     * {@inheritdoc}
328
     */
329
    public function where($attribute, $operator = null, $value = null, $boolean = 'and')
330
    {
331
        // The last `$boolean` expression is intentional to fix list() & array_pad() results
332
        $this->where[] = [$attribute, $operator, $value, $boolean ?: 'and'];
333
334
        return $this;
335
    }
336
337
    /**
338
     * {@inheritdoc}
339
     */
340
    public function whereIn($attribute, $values, $boolean = 'and', $not = false)
341
    {
342
        // The last `$boolean` & `$not` expressions are intentional to fix list() & array_pad() results
343
        $this->whereIn[] = [$attribute, $values, $boolean ?: 'and', (bool) $not];
344
345
        return $this;
346
    }
347
348
    /**
349
     * {@inheritdoc}
350
     */
351
    public function whereNotIn($attribute, $values, $boolean = 'and')
352
    {
353
        // The last `$boolean` expression is intentional to fix list() & array_pad() results
354
        $this->whereNotIn[] = [$attribute, $values, $boolean ?: 'and'];
355
356
        return $this;
357
    }
358
359
    /**
360
     * {@inheritdoc}
361
     */
362
    public function whereHas($relation, Closure $callback, $operator = '>=', $count = 1)
363
    {
364
        // The last `$operator` & `$count` expressions are intentional to fix list() & array_pad() results
0 ignored issues
show
Unused Code Comprehensibility introduced by
37% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
365
        $this->whereHas[] = [$relation, $callback, $operator ?: '>=', $count ?: 1];
366
367
        return $this;
368
    }
369
370
    /**
371
     * {@inheritdoc}
372
     */
373
    public function offset($offset)
374
    {
375
        $this->offset = $offset;
376
377
        return $this;
378
    }
379
380
    /**
381
     * {@inheritdoc}
382
     */
383
    public function limit($limit)
384
    {
385
        $this->limit = $limit;
386
387
        return $this;
388
    }
389
390
    /**
391
     * {@inheritdoc}
392
     */
393
    public function orderBy($attribute, $direction = 'asc')
394
    {
395
        $this->orderBy = [$attribute, $direction];
396
397
        return $this;
398
    }
399
400
    /**
401
     * {@inheritdoc}
402
     */
403
    public function store($id, array $attributes = [])
404
    {
405
        return ! $id ? $this->create($attributes) : $this->update($id, $attributes);
406
    }
407
408
    /**
409
     * {@inheritdoc}
410
     */
411
    public static function __callStatic($method, $parameters)
412
    {
413
        return call_user_func_array([new static(), $method], $parameters);
414
    }
415
416
    /**
417
     * {@inheritdoc}
418
     */
419
    public function __call($method, $parameters)
420
    {
421
        return call_user_func_array([$this->createModel(), $method], $parameters);
422
    }
423
}
424