Completed
Pull Request — master (#5)
by
unknown
06:34
created

EloquentRepository::delete()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Recca0120\Repository;
4
5
use Illuminate\Container\Container;
6
use Illuminate\Database\Eloquent\Model;
7
use Recca0120\Repository\Contracts\EloquentRepository as EloquentRepositoryContract;
8
use RuntimeException;
9
10
abstract class EloquentRepository implements EloquentRepositoryContract
11
{
12
    /**
13
     * $model.
14
     *
15
     * @var \Illuminate\Database\Eloquent\Model
16
     */
17
    protected $model;
18
19
    /**
20
     *
21
     * @var
22
     */
23
    private $app;
24
25
    /**
26
     *
27
     * EloquentRepository constructor.
28
     * @param Container $app
29
     */
30
    public function __construct(Container $app)
31
    {
32
        $this->app = $app;
33
34
        $this->makeModel();
35
    }
36
37
38
    /**
39
     *
40
     * @return Model|mixed
41
     */
42
    protected function makeModel()
43
    {
44
        $model = $this->app->make($this->model);
45
46
        if (!$model instanceof Model) {
47
            throw new RuntimeException("Class {$this->model} must be an instance of Illuminate\\Database\\Eloquent\\Model");
48
        }
49
50
        return $this->model = $model;
51
    }
52
53
    /**
54
     * Find a model by its primary key.
55
     *
56
     * @param  mixed $id
57
     * @param  array $columns
58
     * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|static[]|static|null
59
     */
60
    public function find($id, $columns = ['*'])
61
    {
62
        return $this->newQuery()->find($id, $columns);
63
    }
64
65
    /**
66
     * Find multiple models by their primary keys.
67
     *
68
     * @param  \Illuminate\Contracts\Support\Arrayable|array $ids
69
     * @param  array $columns
70
     * @return \Illuminate\Database\Eloquent\Collection
71
     */
72
    public function findMany($ids, $columns = ['*'])
73
    {
74
        return $this->newQuery()->findMany($ids, $columns);
75
    }
76
77
    /**
78
     * Find a model by its primary key or throw an exception.
79
     *
80
     * @param  mixed $id
81
     * @param  array $columns
82
     * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection
83
     *
84
     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
85
     */
86
    public function findOrFail($id, $columns = ['*'])
87
    {
88
        return $this->newQuery()->findOrFail($id, $columns);
89
    }
90
91
    /**
92
     * Find a model by its primary key or return fresh model instance.
93
     *
94
     * @param  mixed $id
95
     * @param  array $columns
96
     * @return \Illuminate\Database\Eloquent\Model
97
     */
98
    public function findOrNew($id, $columns = ['*'])
99
    {
100
        return $this->newQuery()->findOrNew($id, $columns);
101
    }
102
103
    /**
104
     * Get the first record matching the attributes or instantiate it.
105
     *
106
     * @param  array $attributes
107
     * @param  array $values
108
     * @return \Illuminate\Database\Eloquent\Model
109
     */
110
    public function firstOrNew(array $attributes, array $values = [])
111
    {
112
        return $this->newQuery()->firstOrNew($attributes, $values);
113
    }
114
115
    /**
116
     * Get the first record matching the attributes or create it.
117
     *
118
     * @param  array $attributes
119
     * @param  array $values
120
     * @return \Illuminate\Database\Eloquent\Model
121
     */
122
    public function firstOrCreate(array $attributes, array $values = [])
123
    {
124
        return $this->newQuery()->firstOrCreate($attributes, $values);
125
    }
126
127
    /**
128
     * Create or update a record matching the attributes, and fill it with values.
129
     *
130
     * @param  array $attributes
131
     * @param  array $values
132
     * @return \Illuminate\Database\Eloquent\Model
133
     */
134
    public function updateOrCreate(array $attributes, array $values = [])
135
    {
136
        return $this->newQuery()->updateOrCreate($attributes, $values);
137
    }
138
139
    /**
140
     * Execute the query and get the first result or throw an exception.
141
     *
142
     * @param  array $columns
143
     * @param  \Recca0120\Repository\Criteria[] $criteria
144
     * @return \Illuminate\Database\Eloquent\Model|static
145
     *
146
     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
147
     */
148
    public function firstOrFail($criteria = [], $columns = ['*'])
149
    {
150
        return $this->matching($criteria)->firstOrFail($columns);
151
    }
152
153
    /**
154
     * create.
155
     *
156
     * @param  array $attributes
157
     * @return \Illuminate\Database\Eloquent\Model
158
     *
159
     * @throws \Throwable
160
     */
161
    public function create($attributes)
162
    {
163
        return tap($this->newInstance(), function ($instance) use ($attributes) {
164
            $instance->fill($attributes)->saveOrFail();
165
        });
166
    }
167
168
    /**
169
     * Save a new model and return the instance.
170
     *
171
     * @param  array $attributes
172
     * @return \Illuminate\Database\Eloquent\Model
173
     *
174
     * @throws \Throwable
175
     */
176
    public function forceCreate($attributes)
177
    {
178
        return tap($this->newInstance(), function ($instance) use ($attributes) {
179
            $instance->forceFill($attributes)->saveOrFail();
180
        });
181
    }
182
183
    /**
184
     * update.
185
     *
186
     * @param  array $attributes
187
     * @param  mixed $id
188
     * @return \Illuminate\Database\Eloquent\Model
189
     *
190
     * @throws \Throwable
191
     */
192
    public function update($id, $attributes)
193
    {
194
        return tap($this->findOrFail($id), function ($instance) use ($attributes) {
195
            $instance->fill($attributes)->saveOrFail();
196
        });
197
    }
198
199
    /**
200
     * forceCreate.
201
     *
202
     * @param  array $attributes
203
     * @param  mixed $id
204
     * @return \Illuminate\Database\Eloquent\Model
205
     *
206
     * @throws \Throwable
207
     */
208
    public function forceUpdate($id, $attributes)
209
    {
210
        return tap($this->findOrFail($id), function ($instance) use ($attributes) {
211
            $instance->forceFill($attributes)->saveOrFail();
212
        });
213
    }
214
215
    /**
216
     * delete.
217
     *
218
     * @param  mixed $id
219
     */
220
    public function delete($id)
221
    {
222
        return $this->find($id)->delete();
223
    }
224
225
    /**
226
     * Restore a soft-deleted model instance.
227
     *
228
     * @param  mixed $id
229
     * @return bool|null
230
     */
231
    public function restore($id)
232
    {
233
        return $this->newQuery()->restore($id);
234
    }
235
236
    /**
237
     * Force a hard delete on a soft deleted model.
238
     *
239
     * This method protects developers from running forceDelete when trait is missing.
240
     *
241
     * @param  mixed $id
242
     * @return bool|null
243
     */
244
    public function forceDelete($id)
245
    {
246
        return $this->findOrFail($id)->forceDelete();
247
    }
248
249
    /**
250
     * Create a new model instance that is existing.
251
     *
252
     * @param  array $attributes
253
     * @return \Illuminate\Database\Eloquent\Model
254
     */
255
    public function newInstance($attributes = [], $exists = false)
256
    {
257
        return $this->getModel()->newInstance($attributes, $exists);
258
    }
259
260
    /**
261
     * Execute the query as a "select" statement.
262
     *
263
     * @param  \Recca0120\Repository\Criteria[] $criteria
264
     * @param  array $columns
265
     * @return \Illuminate\Support\Collection
266
     */
267
    public function get($criteria = [], $columns = ['*'])
268
    {
269
        return $this->matching($criteria)->get($columns);
270
    }
271
272
    /**
273
     * Chunk the results of the query.
274
     *
275
     * @param  \Recca0120\Repository\Criteria[] $criteria
276
     * @param  int $count
277
     * @param  callable $callback
278
     * @return bool
279
     */
280
    public function chunk($criteria, $count, callable $callback)
281
    {
282
        return $this->matching($criteria)->chunk($count, $callback);
283
    }
284
285
    /**
286
     * Execute a callback over each item while chunking.
287
     *
288
     * @param  \Recca0120\Repository\Criteria[] $criteria
289
     * @param  callable $callback
290
     * @param  int $count
291
     * @return bool
292
     */
293
    public function each($criteria, callable $callback, $count = 1000)
294
    {
295
        return $this->matching($criteria)->each($callback, $count);
296
    }
297
298
    /**
299
     * Execute the query and get the first result.
300
     *
301
     * @param  \Recca0120\Repository\Criteria[] $criteria
302
     * @param  array $columns
303
     * @return \Illuminate\Database\Eloquent\Model|static|null
304
     */
305
    public function first($criteria = [], $columns = ['*'])
306
    {
307
        return $this->matching($criteria)->first($columns);
308
    }
309
310
    /**
311
     * Paginate the given query.
312
     *
313
     * @param  \Recca0120\Repository\Criteria[] $criteria
314
     * @param  int $perPage
315
     * @param  array $columns
316
     * @param  string $pageName
317
     * @param  int|null $page
318
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
319
     *
320
     * @throws \InvalidArgumentException
321
     */
322
    public function paginate($criteria = [], $perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
323
    {
324
        return $this->matching($criteria)->paginate($perPage, $columns, $pageName, $page);
325
    }
326
327
    /**
328
     * Paginate the given query into a simple paginator.
329
     *
330
     * @param  \Recca0120\Repository\Criteria[] $criteria
331
     * @param  int $perPage
332
     * @param  array $columns
333
     * @param  string $pageName
334
     * @param  int|null $page
335
     * @return \Illuminate\Contracts\Pagination\Paginator
336
     */
337
    public function simplePaginate($criteria = [], $perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
338
    {
339
        return $this->matching($criteria)->simplePaginate($perPage, $columns, $pageName, $page);
340
    }
341
342
    /**
343
     * Retrieve the "count" result of the query.
344
     *
345
     * @param  \Recca0120\Repository\Criteria[] $criteria
346
     * @param  string $columns
347
     * @return int
348
     */
349
    public function count($criteria = [], $columns = '*')
350
    {
351
        return (int)$this->matching($criteria)->count($columns);
352
    }
353
354
    /**
355
     * Retrieve the minimum value of a given column.
356
     *
357
     * @param  \Recca0120\Repository\Criteria[] $criteria
358
     * @param  string $column
359
     * @return mixed
360
     */
361
    public function min($criteria, $column)
362
    {
363
        return $this->matching($criteria)->min($column);
364
    }
365
366
    /**
367
     * Retrieve the maximum value of a given column.
368
     *
369
     * @param  \Recca0120\Repository\Criteria[] $criteria
370
     * @param  string $column
371
     * @return mixed
372
     */
373
    public function max($criteria, $column)
374
    {
375
        return $this->matching($criteria)->max($column);
376
    }
377
378
    /**
379
     * Retrieve the sum of the values of a given column.
380
     *
381
     * @param  \Recca0120\Repository\Criteria[] $criteria
382
     * @param  string $column
383
     * @return mixed
384
     */
385
    public function sum($criteria, $column)
386
    {
387
        $result = $this->matching($criteria)->sum($column);
388
389
        return $result ?: 0;
390
    }
391
392
    /**
393
     * Retrieve the average of the values of a given column.
394
     *
395
     * @param  \Recca0120\Repository\Criteria[] $criteria
396
     * @param  string $column
397
     * @return mixed
398
     */
399 1
    public function avg($criteria, $column)
400
    {
401 1
        return $this->matching($criteria)->avg($column);
402
    }
403
404
    /**
405
     * Alias for the "avg" method.
406
     *
407
     * @param  string $column
408
     * @return mixed
409
     */
410 1
    public function average($criteria, $column)
411
    {
412 1
        return $this->avg($criteria, $column);
413
    }
414
415
    /**
416
     * matching.
417
     *
418
     * @param  \Recca0120\Repository\Criteria[] $criteria
419
     * @return \Illuminate\Database\Eloquent\Builder
420
     */
421 1
    public function matching($criteria)
422
    {
423 1
        $criteria = is_array($criteria) === false ? [$criteria] : $criteria;
424
425
        return array_reduce($criteria, function ($query, $criteria) {
426
            $criteria->each(function ($method) use ($query) {
427
                call_user_func_array([$query, $method->name], $method->parameters);
428
            });
429
430
            return $query;
431 1
        }, $this->newQuery());
432
    }
433
434
    /**
435
     * getQuery.
436
     *
437
     * @param \Recca0120\Repository\Criteria[] $criteria
438
     * @return \Illuminate\Database\Eloquent\Builder
439
     */
440
    public function getQuery($criteria = [])
441
    {
442
        return $this->matching($criteria)->getQuery();
443
    }
444
445
    /**
446
     * getModel.
447
     *
448
     * @return \Illuminate\Database\Eloquent\Model
449
     */
450
    public function getModel()
451
    {
452
        return $this->model instanceof Model
453
            ? clone $this->model
454
            : $this->model->getModel();
455
    }
456
457
    /**
458
     * Get a new query builder for the model's table.
459
     *
460
     * @return \Illuminate\Database\Eloquent\Builder
461
     */
462 1
    public function newQuery()
463
    {
464 1
        return $this->model instanceof Model
465 1
            ? $this->model->newQuery()
466 1
            : clone $this->model;
467
    }
468
}
469