Completed
Push — develop ( 468796...759cfc )
by Abdelrahman
01:35
created

EloquentRepository::findAll()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
c 0
b 0
f 0
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
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 Illuminate\Pagination\Paginator;
19
use Illuminate\Database\Eloquent\Model;
20
use Rinvex\Repository\Exceptions\RepositoryException;
21
use Rinvex\Repository\Exceptions\EntityNotFoundException;
22
23
class EloquentRepository extends BaseRepository
24
{
25
    /**
26
     * {@inheritdoc}
27
     */
28
    public function createModel()
29
    {
30
        if (is_string($model = $this->getModel())) {
31
            if (! class_exists($class = '\\'.ltrim($model, '\\'))) {
32
                throw new RepositoryException("Class {$model} does NOT exist!");
33
            }
34
35
            $model = $this->getContainer()->make($class);
36
        }
37
38
        // Set the connection used by the model
39
        if (! empty($this->connection)) {
40
            $model = $model->setConnection($this->connection);
41
        }
42
43
        if (! $model instanceof Model) {
44
            throw new RepositoryException("Class {$model} must be an instance of \\Illuminate\\Database\\Eloquent\\Model");
45
        }
46
47
        return $model;
48
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53
    public function find($id, $attributes = ['*'])
54
    {
55
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($id, $attributes) {
56
            return $this->prepareQuery($this->createModel())->find($id, $attributes);
57
        });
58
    }
59
60
    /**
61
     * {@inheritdoc}
62
     */
63
    public function findOrFail($id, $attributes = ['*'])
64
    {
65
        $result = $this->find($id, $attributes);
66
67
        if (is_array($id)) {
68
            if (count($result) == count(array_unique($id))) {
69
                return $result;
70
            }
71
        } elseif (! is_null($result)) {
72
            return $result;
73
        }
74
75
        throw new EntityNotFoundException($this->getModel(), $id);
76
    }
77
78
    /**
79
     * {@inheritdoc}
80
     */
81
    public function findOrNew($id, $attributes = ['*'])
82
    {
83
        if (! is_null($entity = $this->find($id, $attributes))) {
84
            return $entity;
85
        }
86
87
        return $this->createModel();
88
    }
89
90
    /**
91
     * {@inheritdoc}
92
     */
93
    public function findBy($attribute, $value, $attributes = ['*'])
94
    {
95
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($attribute, $value, $attributes) {
96
            return $this->prepareQuery($this->createModel())->where($attribute, '=', $value)->first($attributes);
97
        });
98
    }
99
100
    /**
101
     * {@inheritdoc}
102
     */
103
    public function findFirst($attributes = ['*'])
104
    {
105
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($attributes) {
106
            return $this->prepareQuery($this->createModel())->first($attributes);
107
        });
108
    }
109
110
    /**
111
     * {@inheritdoc}
112
     */
113
    public function findAll($attributes = ['*'])
114
    {
115
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($attributes) {
116
            return $this->prepareQuery($this->createModel())->get($attributes);
117
        });
118
    }
119
120
    /**
121
     * {@inheritdoc}
122
     */
123
    public function paginate($perPage = null, $attributes = ['*'], $pageName = 'page', $page = null)
124
    {
125
        $page = $page ?: Paginator::resolveCurrentPage($pageName);
126
127
        return $this->executeCallback(get_called_class(), __FUNCTION__, array_merge(func_get_args(), compact('page')), function () use ($perPage, $attributes, $pageName, $page) {
128
            return $this->prepareQuery($this->createModel())->paginate($perPage, $attributes, $pageName, $page);
129
        });
130
    }
131
132
    /**
133
     * {@inheritdoc}
134
     */
135
    public function simplePaginate($perPage = null, $attributes = ['*'], $pageName = 'page', $page = null)
136
    {
137
        $page = $page ?: Paginator::resolveCurrentPage($pageName);
138
139
        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...
140
            return $this->prepareQuery($this->createModel())->simplePaginate($perPage, $attributes, $pageName, $page);
141
        });
142
    }
143
144
    /**
145
     * {@inheritdoc}
146
     */
147
    public function findWhere(array $where, $attributes = ['*'])
148
    {
149
        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...
150
            list($attribute, $operator, $value, $boolean) = array_pad($where, 4, null);
151
152
            $this->where($attribute, $operator, $value, $boolean);
153
154
            return $this->prepareQuery($this->createModel())->get($attributes);
155
        });
156
    }
157
158
    /**
159
     * {@inheritdoc}
160
     */
161
    public function findWhereIn(array $where, $attributes = ['*'])
162
    {
163
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($where, $attributes) {
164
            list($attribute, $values, $boolean, $not) = array_pad($where, 4, null);
165
166
            $this->whereIn($attribute, $values, $boolean, $not);
167
168
            return $this->prepareQuery($this->createModel())->get($attributes);
169
        });
170
    }
171
172
    /**
173
     * {@inheritdoc}
174
     */
175
    public function findWhereNotIn(array $where, $attributes = ['*'])
176
    {
177
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($where, $attributes) {
178
            list($attribute, $values, $boolean) = array_pad($where, 3, null);
179
180
            $this->whereNotIn($attribute, $values, $boolean);
181
182
            return $this->prepareQuery($this->createModel())->get($attributes);
183
        });
184
    }
185
186
    /**
187
     * {@inheritdoc}
188
     */
189
    public function findWhereHas(array $where, $attributes = ['*'])
190
    {
191
        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...
192
            list($relation, $callback, $operator, $count) = array_pad($where, 4, null);
193
194
            $this->whereHas($relation, $callback, $operator, $count);
195
196
            return $this->prepareQuery($this->createModel())->get($attributes);
197
        });
198
    }
199
200
    /**
201
     * {@inheritdoc}
202
     */
203
    public function create(array $attributes = [], bool $syncRelations = false)
204
    {
205
        // Create a new instance
206
        $entity = $this->createModel();
207
208
        // Fire the created event
209
        $this->getContainer('events')->fire($this->getRepositoryId().'.entity.creating', [$this, $entity]);
210
211
        // Extract relationships
212
        if ($syncRelations) {
213
            $relations = $this->extractRelations($entity, $attributes);
214
            array_forget($attributes, array_keys($relations));
215
        }
216
217
        // Fill instance with data
218
        $entity->fill($attributes);
219
220
        // Save the instance
221
        $created = $entity->save();
222
223
        // Sync relationships
224
        if ($syncRelations && isset($relations)) {
225
            $this->syncRelations($entity, $relations);
226
        }
227
228
        // Fire the created event
229
        $this->getContainer('events')->fire($this->getRepositoryId().'.entity.created', [$this, $entity]);
230
231
        // Return instance
232
        return $created ? $entity : $created;
233
    }
234
235
    /**
236
     * {@inheritdoc}
237
     */
238
    public function update($id, array $attributes = [], bool $syncRelations = false)
239
    {
240
        $updated = false;
241
242
        // Find the given instance
243
        $entity = $id instanceof Model ? $id : $this->find($id);
244
245
        if ($entity) {
246
            // Fire the updated event
247
            $this->getContainer('events')->fire($this->getRepositoryId().'.entity.updating', [$this, $entity]);
248
249
            // Extract relationships
250
            if ($syncRelations) {
251
                $relations = $this->extractRelations($entity, $attributes);
252
                array_forget($attributes, array_keys($relations));
253
            }
254
255
            // Fill instance with data
256
            $entity->fill($attributes);
257
258
            //Check if we are updating attributes values
259
            $dirty = $entity->getDirty();
260
261
            // Update the instance
262
            $updated = $entity->save();
263
264
            // Sync relationships
265
            if ($syncRelations && isset($relations)) {
266
                $this->syncRelations($entity, $relations);
267
            }
268
269
            if (count($dirty) > 0) {
270
                // Fire the updated event
271
                $this->getContainer('events')->fire($this->getRepositoryId().'.entity.updated', [$this, $entity]);
272
            }
273
        }
274
275
        return $updated ? $entity : $updated;
276
    }
277
278
    /**
279
     * {@inheritdoc}
280
     */
281
    public function delete($id)
282
    {
283
        $deleted = false;
284
285
        // Find the given instance
286
        $entity = $id instanceof Model ? $id : $this->find($id);
287
288
        if ($entity) {
289
            // Fire the deleted event
290
            $this->getContainer('events')->fire($this->getRepositoryId().'.entity.deleting', [$this, $entity]);
291
292
            // Delete the instance
293
            $deleted = $entity->delete();
294
295
            // Fire the deleted event
296
            $this->getContainer('events')->fire($this->getRepositoryId().'.entity.deleted', [$this, $entity]);
297
        }
298
299
        return $deleted ? $entity : $deleted;
300
    }
301
302
    /**
303
     * {@inheritdoc}
304
     */
305
    public function restore($id)
306
    {
307
        $restored = false;
308
309
        // Find the given instance
310
        $entity = $id instanceof Model ? $id : $this->find($id);
311
312
        if ($entity) {
313
            // Fire the restoring event
314
            $this->getContainer('events')->fire($this->getRepositoryId().'.entity.restoring', [$this, $entity]);
315
316
            // Restore the instance
317
            $restored = $entity->restore();
318
319
            // Fire the restored event
320
            $this->getContainer('events')->fire($this->getRepositoryId().'.entity.restored', [$this, $entity]);
321
        }
322
323
        return $restored ? $entity : $restored;
324
    }
325
326
    /**
327
     * {@inheritdoc}
328
     */
329
    public function beginTransaction()
330
    {
331
        $this->getContainer('db')->beginTransaction();
332
    }
333
334
    /**
335
     * {@inheritdoc}
336
     */
337
    public function commit()
338
    {
339
        $this->getContainer('db')->commit();
340
    }
341
342
    /**
343
     * {@inheritdoc}
344
     */
345
    public function rollBack()
346
    {
347
        $this->getContainer('db')->rollBack();
348
    }
349
350
    /**
351
     * {@inheritdoc}
352
     */
353
    public function count($columns = '*')
354
    {
355
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($columns) {
356
            return $this->prepareQuery($this->createModel())->count($columns);
357
        });
358
    }
359
360
    /**
361
     * {@inheritdoc}
362
     */
363
    public function min($column)
364
    {
365
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($column) {
366
            return $this->prepareQuery($this->createModel())->min($column);
367
        });
368
    }
369
370
    /**
371
     * {@inheritdoc}
372
     */
373
    public function max($column)
374
    {
375
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($column) {
376
            return $this->prepareQuery($this->createModel())->max($column);
377
        });
378
    }
379
380
    /**
381
     * {@inheritdoc}
382
     */
383
    public function avg($column)
384
    {
385
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($column) {
386
            return $this->prepareQuery($this->createModel())->avg($column);
387
        });
388
    }
389
390
    /**
391
     * {@inheritdoc}
392
     */
393
    public function sum($column)
394
    {
395
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($column) {
396
            return $this->prepareQuery($this->createModel())->sum($column);
397
        });
398
    }
399
400
    /**
401
     * Extract relationships.
402
     *
403
     * @param mixed $entity
404
     * @param array $attributes
405
     *
406
     * @return array
407
     */
408
    protected function extractRelations($entity, array $attributes)
409
    {
410
        $relations = [];
411
        $potential = array_diff(array_keys($attributes), $entity->getFillable());
412
413
        array_walk($potential, function ($relation) use ($entity, $attributes, &$relations) {
414
            if (method_exists($entity, $relation)) {
415
                $relations[$relation] = [
416
                    'values' => $attributes[$relation],
417
                    'class'  => get_class($entity->$relation()),
418
                ];
419
            }
420
        });
421
422
        return $relations;
423
    }
424
425
    /**
426
     * Sync relationships.
427
     *
428
     * @param mixed $entity
429
     * @param array $relations
430
     * @param bool  $detaching
431
     *
432
     * @return void
433
     */
434
    protected function syncRelations($entity, array $relations, $detaching = true)
435
    {
436
        foreach ($relations as $method => $relation) {
437
            switch ($relation['class']) {
438
                case 'Illuminate\Database\Eloquent\Relations\BelongsToMany':
439
                default:
440
                    $entity->$method()->sync((array) $relation['values'], $detaching);
441
                    break;
442
            }
443
        }
444
    }
445
}
446