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 qurey & 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
|
|
|
return $this; |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
/** |
160
|
|
|
* Prepare query. |
161
|
|
|
* |
162
|
|
|
* @param object $model |
163
|
|
|
* |
164
|
|
|
* @return object |
165
|
|
|
*/ |
166
|
|
|
protected function prepareQuery($model) |
167
|
|
|
{ |
168
|
|
|
// Set the relationships that should be eager loaded |
169
|
|
|
if (! empty($this->relations)) { |
170
|
|
|
$model = $model->with($this->relations); |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
// Add a basic where clause to the query |
174
|
|
|
foreach ($this->where as $where) { |
175
|
|
|
list($attribute, $operator, $value, $boolean) = array_pad($where, 4, null); |
176
|
|
|
|
177
|
|
|
$model = $model->where($attribute, $operator, $value, $boolean); |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
// Add a "where in" clause to the query |
181
|
|
|
foreach ($this->whereIn as $whereIn) { |
182
|
|
|
list($attribute, $values, $boolean, $not) = array_pad($whereIn, 4, null); |
183
|
|
|
|
184
|
|
|
$model = $model->whereIn($attribute, $values, $boolean, $not); |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
// Add a "where not in" clause to the query |
188
|
|
|
foreach ($this->whereNotIn as $whereNotIn) { |
189
|
|
|
list($attribute, $values, $boolean) = array_pad($whereNotIn, 3, null); |
190
|
|
|
|
191
|
|
|
$model = $model->whereNotIn($attribute, $values, $boolean); |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
// Add a "where has" clause to the query |
195
|
|
|
foreach ($this->whereHas as $whereHas) { |
196
|
|
|
list($relation, $callback, $operator, $count) = array_pad($whereHas, 4, null); |
197
|
|
|
|
198
|
|
|
$model = $model->whereHas($relation, $callback, $operator, $count); |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
// Set the "offset" value of the query |
202
|
|
|
if ($this->offset > 0) { |
203
|
|
|
$model = $model->offset($this->offset); |
204
|
|
|
} |
205
|
|
|
|
206
|
|
|
// Set the "limit" value of the query |
207
|
|
|
if ($this->limit > 0) { |
208
|
|
|
$model = $model->limit($this->limit); |
209
|
|
|
} |
210
|
|
|
|
211
|
|
|
// Add an "order by" clause to the query. |
212
|
|
|
if (! empty($this->orderBy)) { |
213
|
|
|
list($attribute, $direction) = $this->orderBy; |
214
|
|
|
|
215
|
|
|
$model = $model->orderBy($attribute, $direction); |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
return $model; |
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
/** |
222
|
|
|
* {@inheritdoc} |
223
|
|
|
*/ |
224
|
|
|
public function setContainer(Container $container) |
225
|
|
|
{ |
226
|
|
|
$this->container = $container; |
227
|
|
|
|
228
|
|
|
return $this; |
229
|
|
|
} |
230
|
|
|
|
231
|
|
|
/** |
232
|
|
|
* {@inheritdoc} |
233
|
|
|
*/ |
234
|
|
|
public function getContainer($service = null) |
235
|
|
|
{ |
236
|
|
|
return is_null($service) ? ($this->container ?: app()) : ($this->container[$service] ?: app($service)); |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
/** |
240
|
|
|
* {@inheritdoc} |
241
|
|
|
*/ |
242
|
|
|
public function setConnection($name) |
243
|
|
|
{ |
244
|
|
|
$this->connection = $name; |
245
|
|
|
|
246
|
|
|
return $this; |
247
|
|
|
} |
248
|
|
|
|
249
|
|
|
/** |
250
|
|
|
* {@inheritdoc} |
251
|
|
|
*/ |
252
|
|
|
public function getConnection() |
253
|
|
|
{ |
254
|
|
|
return $this->connection; |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
/** |
258
|
|
|
* {@inheritdoc} |
259
|
|
|
*/ |
260
|
|
|
public function setRepositoryId($repositoryId) |
261
|
|
|
{ |
262
|
|
|
$this->repositoryId = $repositoryId; |
263
|
|
|
|
264
|
|
|
return $this; |
265
|
|
|
} |
266
|
|
|
|
267
|
|
|
/** |
268
|
|
|
* {@inheritdoc} |
269
|
|
|
*/ |
270
|
|
|
public function getRepositoryId() |
271
|
|
|
{ |
272
|
|
|
return $this->repositoryId ?: get_called_class(); |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
/** |
276
|
|
|
* {@inheritdoc} |
277
|
|
|
*/ |
278
|
|
|
public function setModel($model) |
279
|
|
|
{ |
280
|
|
|
$this->model = $model; |
281
|
|
|
|
282
|
|
|
return $this; |
283
|
|
|
} |
284
|
|
|
|
285
|
|
|
/** |
286
|
|
|
* {@inheritdoc} |
287
|
|
|
*/ |
288
|
|
|
public function getModel() |
289
|
|
|
{ |
290
|
|
|
$model = $this->getContainer('config')->get('rinvex.repository.models'); |
291
|
|
|
|
292
|
|
|
return $this->model ?: str_replace(['Repositories', 'Repository'], [$model, ''], get_called_class()); |
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
/** |
296
|
|
|
* {@inheritdoc} |
297
|
|
|
*/ |
298
|
|
|
public function with(array $relations) |
299
|
|
|
{ |
300
|
|
|
$this->relations = $relations; |
301
|
|
|
|
302
|
|
|
return $this; |
303
|
|
|
} |
304
|
|
|
|
305
|
|
|
/** |
306
|
|
|
* {@inheritdoc} |
307
|
|
|
*/ |
308
|
|
|
public function where($attribute, $operator = null, $value = null, $boolean = 'and') |
309
|
|
|
{ |
310
|
|
|
// The last `$boolean` expression is intentional to fix list() & array_pad() results |
311
|
|
|
$this->where[] = [$attribute, $operator, $value, $boolean ?: 'and']; |
312
|
|
|
|
313
|
|
|
return $this; |
314
|
|
|
} |
315
|
|
|
|
316
|
|
|
/** |
317
|
|
|
* {@inheritdoc} |
318
|
|
|
*/ |
319
|
|
|
public function whereIn($attribute, $values, $boolean = 'and', $not = false) |
320
|
|
|
{ |
321
|
|
|
// The last `$boolean` & `$not` expressions are intentional to fix list() & array_pad() results |
322
|
|
|
$this->whereIn[] = [$attribute, $values, $boolean ?: 'and', (bool) $not]; |
323
|
|
|
|
324
|
|
|
return $this; |
325
|
|
|
} |
326
|
|
|
|
327
|
|
|
/** |
328
|
|
|
* {@inheritdoc} |
329
|
|
|
*/ |
330
|
|
|
public function whereNotIn($attribute, $values, $boolean = 'and') |
331
|
|
|
{ |
332
|
|
|
// The last `$boolean` expression is intentional to fix list() & array_pad() results |
333
|
|
|
$this->whereNotIn[] = [$attribute, $values, $boolean ?: 'and']; |
334
|
|
|
|
335
|
|
|
return $this; |
336
|
|
|
} |
337
|
|
|
|
338
|
|
|
/** |
339
|
|
|
* {@inheritdoc} |
340
|
|
|
*/ |
341
|
|
|
public function whereHas($relation, Closure $callback, $operator = '>=', $count = 1) |
342
|
|
|
{ |
343
|
|
|
// The last `$operator` & `$count` expressions are intentional to fix list() & array_pad() results |
|
|
|
|
344
|
|
|
$this->whereHas[] = [$relation, $callback, $operator ?: '>=', $count ?: 1]; |
345
|
|
|
|
346
|
|
|
return $this; |
347
|
|
|
} |
348
|
|
|
|
349
|
|
|
/** |
350
|
|
|
* {@inheritdoc} |
351
|
|
|
*/ |
352
|
|
|
public function offset($offset) |
353
|
|
|
{ |
354
|
|
|
$this->offset = $offset; |
355
|
|
|
|
356
|
|
|
return $this; |
357
|
|
|
} |
358
|
|
|
|
359
|
|
|
/** |
360
|
|
|
* {@inheritdoc} |
361
|
|
|
*/ |
362
|
|
|
public function limit($limit) |
363
|
|
|
{ |
364
|
|
|
$this->limit = $limit; |
365
|
|
|
|
366
|
|
|
return $this; |
367
|
|
|
} |
368
|
|
|
|
369
|
|
|
/** |
370
|
|
|
* {@inheritdoc} |
371
|
|
|
*/ |
372
|
|
|
public function orderBy($attribute, $direction = 'asc') |
373
|
|
|
{ |
374
|
|
|
$this->orderBy = [$attribute, $direction]; |
375
|
|
|
|
376
|
|
|
return $this; |
377
|
|
|
} |
378
|
|
|
|
379
|
|
|
/** |
380
|
|
|
* Start a new database transaction. |
381
|
|
|
* |
382
|
|
|
* @throws \Exception |
383
|
|
|
* |
384
|
|
|
* @return void |
385
|
|
|
*/ |
386
|
|
|
public function beginTransaction() |
387
|
|
|
{ |
388
|
|
|
$this->getContainer('db')->beginTransaction(); |
389
|
|
|
} |
390
|
|
|
|
391
|
|
|
/** |
392
|
|
|
* Commit the active database transaction. |
393
|
|
|
* |
394
|
|
|
* @return void |
395
|
|
|
*/ |
396
|
|
|
public function commit() |
397
|
|
|
{ |
398
|
|
|
$this->getContainer('db')->commit(); |
399
|
|
|
} |
400
|
|
|
|
401
|
|
|
/** |
402
|
|
|
* Rollback the active database transaction. |
403
|
|
|
* |
404
|
|
|
* @return void |
405
|
|
|
*/ |
406
|
|
|
public function rollBack() |
407
|
|
|
{ |
408
|
|
|
$this->getContainer('db')->rollBack(); |
409
|
|
|
} |
410
|
|
|
|
411
|
|
|
/** |
412
|
|
|
* {@inheritdoc} |
413
|
|
|
*/ |
414
|
|
|
public static function __callStatic($method, $parameters) |
415
|
|
|
{ |
416
|
|
|
return call_user_func_array([new static(), $method], $parameters); |
417
|
|
|
} |
418
|
|
|
|
419
|
|
|
/** |
420
|
|
|
* {@inheritdoc} |
421
|
|
|
*/ |
422
|
|
|
public function __call($method, $parameters) |
423
|
|
|
{ |
424
|
|
|
return call_user_func_array([$this->createModel(), $method], $parameters); |
425
|
|
|
} |
426
|
|
|
} |
427
|
|
|
|
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.