Completed
Push — master ( 5649ba...c37d73 )
by recca
03:09
created

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