Completed
Pull Request — develop (#153)
by
unknown
02:22 queued 16s
created

EloquentRepository::searchAll()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 6
nc 2
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Rinvex\Repository\Repositories;
6
7
use Illuminate\Pagination\Paginator;
8
use Illuminate\Database\Eloquent\Model;
9
use Rinvex\Repository\Exceptions\CriterionException;
10
use Rinvex\Repository\Exceptions\RepositoryException;
11
use Rinvex\Repository\Exceptions\EntityNotFoundException;
12
13
class EloquentRepository extends BaseRepository
14
{
15
    /**
16
     * {@inheritdoc}
17
     */
18
    public function createModel()
19
    {
20
        if (is_string($model = $this->getModel())) {
21
            if (! class_exists($class = '\\'.ltrim($model, '\\'))) {
22
                throw new RepositoryException("Class {$model} does NOT exist!");
23
            }
24
25
            $model = $this->getContainer()->make($class);
26
        }
27
28
        // Set the connection used by the model
29
        if (! empty($this->connection)) {
30
            $model = $model->setConnection($this->connection);
31
        }
32
33
        if (! $model instanceof Model) {
34
            throw new RepositoryException("Class {$model} must be an instance of \\Illuminate\\Database\\Eloquent\\Model");
35
        }
36
37
        return $model;
38
    }
39
40
    /**
41
     * {@inheritdoc}
42
     */
43
    public function find($id, $attributes = ['*'])
44
    {
45
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($id, $attributes) {
46
            return $this->prepareQuery($this->createModel())->find($id, $attributes);
47
        });
48
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53
    public function findOrFail($id, $attributes = ['*'])
54
    {
55
        $result = $this->find($id, $attributes);
56
57
        if (is_array($id)) {
58
            if (count($result) === count(array_unique($id))) {
59
                return $result;
60
            }
61
        } elseif (! is_null($result)) {
62
            return $result;
63
        }
64
65
        throw new EntityNotFoundException($this->getModel(), $id);
66
    }
67
68
    /**
69
     * {@inheritdoc}
70
     */
71
    public function findOrNew($id, $attributes = ['*'])
72
    {
73
        if (! is_null($entity = $this->find($id, $attributes))) {
74
            return $entity;
75
        }
76
77
        return $this->createModel();
78
    }
79
80
    /**
81
     * {@inheritdoc}
82
     */
83
    public function findBy($attribute, $value, $attributes = ['*'])
84
    {
85
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($attribute, $value, $attributes) {
86
            return $this->prepareQuery($this->createModel())->where($attribute, '=', $value)->first($attributes);
87
        });
88
    }
89
90
    /**
91
     * {@inheritdoc}
92
     */
93
    public function findFirst($attributes = ['*'])
94
    {
95
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($attributes) {
96
            return $this->prepareQuery($this->createModel())->first($attributes);
97
        });
98
    }
99
100
    /**
101
     * {@inheritdoc}
102
     */
103
    public function findAll($attributes = ['*'])
104
    {
105
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($attributes) {
106
            return $this->prepareQuery($this->createModel())->get($attributes);
107
        });
108
    }
109
110
    /**
111
     * {@inheritdoc}
112
     */
113
    public function searchAll($value)
114
    {
115
        $model = $this->createModel();
116
117
        if (!method_exists($model, 'search')) {
118
            throw CriterionException::missingPackage('searchAll', 'laravel/scout');
119
        }
120
121
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($model, $value) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 123 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
122
            return $this->prepareQuery($model)->search($value)->get();
123
        });
124
    }
125
126
    /**
127
     * {@inheritdoc}
128
     */
129
    public function paginate($perPage = null, $attributes = ['*'], $pageName = 'page', $page = null)
130
    {
131
        $page = $page ?: Paginator::resolveCurrentPage($pageName);
132
133
        return $this->executeCallback(get_called_class(), __FUNCTION__, array_merge(func_get_args(), compact('page')), function () use ($perPage, $attributes, $pageName, $page) {
134
            return $this->prepareQuery($this->createModel())->paginate($perPage, $attributes, $pageName, $page);
135
        });
136
    }
137
138
    /**
139
     * {@inheritdoc}
140
     */
141
    public function simplePaginate($perPage = null, $attributes = ['*'], $pageName = 'page', $page = null)
142
    {
143
        $page = $page ?: Paginator::resolveCurrentPage($pageName);
144
145
        return $this->executeCallback(get_called_class(), __FUNCTION__, array_merge(func_get_args(), compact('page')), function () use ($perPage, $attributes, $pageName, $page) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 178 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
146
            return $this->prepareQuery($this->createModel())->simplePaginate($perPage, $attributes, $pageName, $page);
147
        });
148
    }
149
150
    /**
151
     * {@inheritdoc}
152
     */
153
    public function findWhere(array $where, $attributes = ['*'])
154
    {
155
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($where, $attributes) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 128 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
156
            list($attribute, $operator, $value, $boolean) = array_pad($where, 4, null);
157
158
            $this->where($attribute, $operator, $value, $boolean);
159
160
            return $this->prepareQuery($this->createModel())->get($attributes);
161
        });
162
    }
163
164
    /**
165
     * {@inheritdoc}
166
     */
167
    public function findWhereIn(array $where, $attributes = ['*'])
168
    {
169
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($where, $attributes) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 128 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
170
            list($attribute, $values, $boolean, $not) = array_pad($where, 4, null);
171
172
            $this->whereIn($attribute, $values, $boolean, $not);
173
174
            return $this->prepareQuery($this->createModel())->get($attributes);
175
        });
176
    }
177
178
    /**
179
     * {@inheritdoc}
180
     */
181
    public function findWhereNotIn(array $where, $attributes = ['*'])
182
    {
183
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($where, $attributes) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 128 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
184
            list($attribute, $values, $boolean) = array_pad($where, 3, null);
185
186
            $this->whereNotIn($attribute, $values, $boolean);
187
188
            return $this->prepareQuery($this->createModel())->get($attributes);
189
        });
190
    }
191
192
    /**
193
     * {@inheritdoc}
194
     */
195
    public function findWhereHas(array $where, $attributes = ['*'])
196
    {
197
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($where, $attributes) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 128 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
198
            list($relation, $callback, $operator, $count) = array_pad($where, 4, null);
199
200
            $this->whereHas($relation, $callback, $operator, $count);
201
202
            return $this->prepareQuery($this->createModel())->get($attributes);
203
        });
204
    }
205
206
    /**
207
     * {@inheritdoc}
208
     */
209
    public function create(array $attributes = [], bool $syncRelations = false)
210
    {
211
        // Create a new instance
212
        $entity = $this->createModel();
213
214
        // Fire the created event
215
        $this->getContainer('events')->dispatch($this->getRepositoryId().'.entity.creating', [$this, $entity]);
216
217
        // Extract relationships
218
        if ($syncRelations) {
219
            $relations = $this->extractRelations($entity, $attributes);
220
            array_forget($attributes, array_keys($relations));
221
        }
222
223
        // Fill instance with data
224
        $entity->fill($attributes);
225
226
        // Save the instance
227
        $created = $entity->save();
228
229
        // Sync relationships
230
        if ($syncRelations && isset($relations)) {
231
            $this->syncRelations($entity, $relations);
232
        }
233
234
        // Fire the created event
235
        $this->getContainer('events')->dispatch($this->getRepositoryId().'.entity.created', [$this, $entity]);
236
237
        // Return instance
238
        return $created ? $entity : $created;
239
    }
240
241
    /**
242
     * {@inheritdoc}
243
     */
244
    public function update($id, array $attributes = [], bool $syncRelations = false)
245
    {
246
        $updated = false;
247
248
        // Find the given instance
249
        $entity = $id instanceof Model ? $id : $this->find($id);
250
251
        if ($entity) {
252
            // Fire the updated event
253
            $this->getContainer('events')->dispatch($this->getRepositoryId().'.entity.updating', [$this, $entity]);
254
255
            // Extract relationships
256
            if ($syncRelations) {
257
                $relations = $this->extractRelations($entity, $attributes);
258
                array_forget($attributes, array_keys($relations));
259
            }
260
261
            // Fill instance with data
262
            $entity->fill($attributes);
263
264
            //Check if we are updating attributes values
265
            $dirty = $entity->getDirty();
266
267
            // Update the instance
268
            $updated = $entity->save();
269
270
            // Sync relationships
271
            if ($syncRelations && isset($relations)) {
272
                $this->syncRelations($entity, $relations);
273
            }
274
275
            if (count($dirty) > 0) {
276
                // Fire the updated event
277
                $this->getContainer('events')->dispatch($this->getRepositoryId().'.entity.updated', [$this, $entity]);
278
            }
279
        }
280
281
        return $updated ? $entity : $updated;
282
    }
283
284
    /**
285
     * {@inheritdoc}
286
     */
287
    public function delete($id)
288
    {
289
        $deleted = false;
290
291
        // Find the given instance
292
        $entity = $id instanceof Model ? $id : $this->find($id);
293
294
        if ($entity) {
295
            // Fire the deleted event
296
            $this->getContainer('events')->dispatch($this->getRepositoryId().'.entity.deleting', [$this, $entity]);
297
298
            // Delete the instance
299
            $deleted = $entity->delete();
300
301
            // Fire the deleted event
302
            $this->getContainer('events')->dispatch($this->getRepositoryId().'.entity.deleted', [$this, $entity]);
303
        }
304
305
        return $deleted ? $entity : $deleted;
306
    }
307
308
    /**
309
     * {@inheritdoc}
310
     */
311
    public function restore($id)
312
    {
313
        $restored = false;
314
315
        // Find the given instance
316
        $entity = $id instanceof Model ? $id : $this->find($id);
317
318
        if ($entity) {
319
            // Fire the restoring event
320
            $this->getContainer('events')->dispatch($this->getRepositoryId().'.entity.restoring', [$this, $entity]);
321
322
            // Restore the instance
323
            $restored = $entity->restore();
324
325
            // Fire the restored event
326
            $this->getContainer('events')->dispatch($this->getRepositoryId().'.entity.restored', [$this, $entity]);
327
        }
328
329
        return $restored ? $entity : $restored;
330
    }
331
332
    /**
333
     * {@inheritdoc}
334
     */
335
    public function beginTransaction()
336
    {
337
        $this->getContainer('db')->beginTransaction();
338
    }
339
340
    /**
341
     * {@inheritdoc}
342
     */
343
    public function commit()
344
    {
345
        $this->getContainer('db')->commit();
346
    }
347
348
    /**
349
     * {@inheritdoc}
350
     */
351
    public function rollBack()
352
    {
353
        $this->getContainer('db')->rollBack();
354
    }
355
356
    /**
357
     * {@inheritdoc}
358
     */
359
    public function count($columns = '*')
360
    {
361
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($columns) {
362
            return $this->prepareQuery($this->createModel())->count($columns);
363
        });
364
    }
365
366
    /**
367
     * {@inheritdoc}
368
     */
369
    public function min($column)
370
    {
371
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($column) {
372
            return $this->prepareQuery($this->createModel())->min($column);
373
        });
374
    }
375
376
    /**
377
     * {@inheritdoc}
378
     */
379
    public function max($column)
380
    {
381
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($column) {
382
            return $this->prepareQuery($this->createModel())->max($column);
383
        });
384
    }
385
386
    /**
387
     * {@inheritdoc}
388
     */
389
    public function avg($column)
390
    {
391
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($column) {
392
            return $this->prepareQuery($this->createModel())->avg($column);
393
        });
394
    }
395
396
    /**
397
     * {@inheritdoc}
398
     */
399
    public function sum($column)
400
    {
401
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($column) {
402
            return $this->prepareQuery($this->createModel())->sum($column);
403
        });
404
    }
405
406
    /**
407
     * Extract relationships.
408
     *
409
     * @param mixed $entity
410
     * @param array $attributes
411
     *
412
     * @return array
413
     */
414
    protected function extractRelations($entity, array $attributes)
415
    {
416
        $relations = [];
417
        $potential = array_diff(array_keys($attributes), $entity->getFillable());
418
419
        array_walk($potential, function ($relation) use ($entity, $attributes, &$relations) {
420
            if (method_exists($entity, $relation)) {
421
                $relations[$relation] = [
422
                    'values' => $attributes[$relation],
423
                    'class' => get_class($entity->$relation()),
424
                ];
425
            }
426
        });
427
428
        return $relations;
429
    }
430
431
    /**
432
     * Sync relationships.
433
     *
434
     * @param mixed $entity
435
     * @param array $relations
436
     * @param bool  $detaching
437
     *
438
     * @return void
439
     */
440
    protected function syncRelations($entity, array $relations, $detaching = true)
441
    {
442
        foreach ($relations as $method => $relation) {
443
            switch ($relation['class']) {
444
                case 'Illuminate\Database\Eloquent\Relations\BelongsToMany':
445
                default:
446
                    $entity->$method()->sync((array) $relation['values'], $detaching);
447
                    break;
448
            }
449
        }
450
    }
451
}
452