Completed
Push — master ( c7db41...98a10d )
by Andrey
02:20
created

Builder::find()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 2
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Volosyuk\SimpleEloquent;
4
5
use Closure;
6
use Illuminate\Contracts\Support\Arrayable;
7
use Illuminate\Database\Eloquent\Collection as ElquentCollection;
8
use Illuminate\Database\Eloquent\Model;
9
use Illuminate\Database\Eloquent\ModelNotFoundException;
10
use Illuminate\Pagination\LengthAwarePaginator;
11
use Illuminate\Pagination\Paginator;
12
use Illuminate\Support\Collection;
13
use stdClass;
14
15
/**
16
 * Class Builder
17
 * @package Volosyuk\SimpleEloquent
18
 */
19
class Builder extends \Illuminate\Database\Eloquent\Builder
20
{
21
    /**
22
     * @var bool
23
     */
24
    protected $simple = false;
25
26
    /**
27
     * @return $this
28
     */
29 18
    public function simple()
30
    {
31 18
        $this->simple = true;
32
33 18
        return $this;
34
    }
35
36
    /**
37
     * @return bool
38
     */
39 18
    private function isSimple()
40
    {
41 18
        return $this->simple === true;
42
    }
43
44
    /**
45
     * @param array $columns
46
     * @return ElquentCollection|Collection|static[]
47
     */
48 15
    public function get($columns = ['*'])
49
    {
50 15
        if ($this->isSimple()) {
51 3
            return $this->getSimple($columns);
52
        }
53
54 15
        return parent::get($columns);
55
    }
56
57
    /**
58
     * @param mixed $id
59
     * @param array $columns
60
     * @return Collection|stdClass|array|null
61
     */
62 2
    public function find($id, $columns = ['*'])
63
    {
64 2
        if ($this->isSimple()) {
65 1
            return $this->findSimple($id, $columns);
66
        }
67
68 2
        return parent::find($id, $columns);
69
    }
70
71
    /**
72
     * @param mixed $id
73
     * @param array $columns
74
     * @return array|ElquentCollection|Model|Collection|stdClass
75
     */
76 1
    public function findOrFail($id, $columns = ['*'])
77
    {
78 1
        if ($this->isSimple()) {
79 1
            return $this->findSimpleOrFail($id, $columns);
80
        }
81
82 1
        return parent::findOrFail($id, $columns);
83
    }
84
85
    /**
86
     * @param array $columns
87
     * @return array|Model|null|object|stdClass|static
88
     */
89 12
    public function first($columns = ['*'])
90
    {
91 12
        if ($this->isSimple()) {
92 10
            return $this->firstSimple($columns);
93
        }
94
95 7
        return parent::first($columns);
96
    }
97
98
    /**
99
     * @param array $columns
100
     * @return array|Model|stdClass|static
101
     */
102 1
    public function firstOrFail($columns = ['*'])
103
    {
104 1
        if ($this->isSimple()) {
105 1
            return $this->firstSimpleOrFail($columns);
106
        }
107
108 1
        return parent::firstOrFail($columns);
109
    }
110
111
    /**
112
     * @param array|Arrayable $ids
113
     * @param array $columns
114
     * @return ElquentCollection|Collection
115
     */
116 3
    public function findMany($ids, $columns = ['*'])
117
    {
118 3
        if ($this->isSimple()) {
119 1
            return $this->findManySimple($ids, $columns);
0 ignored issues
show
Bug introduced by
It seems like $ids can also be of type Illuminate\Contracts\Support\Arrayable; however, parameter $ids of Volosyuk\SimpleEloquent\Builder::findManySimple() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

119
            return $this->findManySimple(/** @scrutinizer ignore-type */ $ids, $columns);
Loading history...
120
        }
121
122 3
        return parent::findMany($ids, $columns);
123
    }
124
125
    /**
126
     * @param null $perPage
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $perPage is correct as it would always require null to be passed?
Loading history...
Documentation Bug introduced by
Are you sure the doc-type for parameter $page is correct as it would always require null to be passed?
Loading history...
127
     * @param array $columns
128
     * @param string $pageName
129
     * @param null $page
130
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
131
     */
132 1
    public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
133
    {
134 1
        if ($this->isSimple()) {
135 1
            return $this->paginateSimple($perPage, $columns, $pageName, $page);
136
        }
137
138 1
        return parent::paginate($perPage, $columns, $pageName, $page);
139
    }
140
141
    /**
142
     * @param null $perPage
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $perPage is correct as it would always require null to be passed?
Loading history...
Documentation Bug introduced by
Are you sure the doc-type for parameter $page is correct as it would always require null to be passed?
Loading history...
143
     * @param array $columns
144
     * @param string $pageName
145
     * @param null $page
146
     * @return \Illuminate\Contracts\Pagination\Paginator
147
     */
148 1
    public function simplePaginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
149
    {
150 1
        if ($this->isSimple()) {
151 1
            return $this->simplePaginateSimple($perPage, $columns, $pageName, $page);
152
        }
153
154 1
        return parent::simplePaginate($perPage, $columns, $pageName, $page);
155
    }
156
157
    /**
158
     * @param array $columns
159
     * @return Collection
160
     */
161 19
    public function getSimple($columns = ['*'])
162
    {
163 19
        $builder = $this->applyScopes();
164
165 19
        $models = $builder->getSimpleModels($columns);
166
167 19
        if (count($models) > 0) {
0 ignored issues
show
Bug introduced by
It seems like $models can also be of type Illuminate\Database\Eloquent\Builder and Volosyuk\SimpleEloquent\Builder; however, parameter $var of count() does only seem to accept Countable|array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

167
        if (count(/** @scrutinizer ignore-type */ $models) > 0) {
Loading history...
168 19
            $models = $builder->eagerLoadRelationsSimple($models);
0 ignored issues
show
Bug introduced by
It seems like $models can also be of type Illuminate\Database\Eloquent\Builder and Volosyuk\SimpleEloquent\Builder; however, parameter $models of Volosyuk\SimpleEloquent\...erLoadRelationsSimple() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

168
            $models = $builder->eagerLoadRelationsSimple(/** @scrutinizer ignore-type */ $models);
Loading history...
169
        }
170
171 19
        return collect($models);
172
    }
173
174
    /**
175
     * @param mixed $id
176
     * @param array $columns
177
     * @return Collection|stdClass|array|null
178
     */
179 2
    public function findSimple($id, $columns = ['*'])
180
    {
181 2
        if (is_array($id)) {
182 2
            return $this->findManySimple($id, $columns);
183
        }
184
185 2
        $this->query->where($this->model->getQualifiedKeyName(), '=', $id);
186
187 2
        return $this->firstSimple($columns);
188
    }
189
190
    /**
191
     * Find a model by its primary key or throw an exception.
192
     *
193
     * @param  mixed  $id
194
     * @param  array  $columns
195
     * @return stdClass|array|Collection
196
     *
197
     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
198
     */
199 1
    public function findSimpleOrFail($id, $columns = ['*'])
200
    {
201 1
        $result = $this->findSimple($id, $columns);
202
203 1
        if (is_array($id)) {
204 1
            if (count($result) == count(array_unique($id))) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type stdClass; however, parameter $var of count() does only seem to accept Countable|array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

204
            if (count(/** @scrutinizer ignore-type */ $result) == count(array_unique($id))) {
Loading history...
205 1
                return $result;
206
            }
207 1
        } elseif (! is_null($result)) {
208
            return $result;
209
        }
210
211 1
        throw (new ModelNotFoundException)->setModel(
212 1
            get_class($this->model), $id
213
        );
214
    }
215
216
    /**
217
     * Execute the query and get the first result.
218
     *
219
     * @param  array  $columns
220
     * @return stdClass|array|null
221
     */
222 14
    public function firstSimple($columns = ['*'])
223
    {
224 14
        return $this->take(1)->getSimple($columns)->first();
0 ignored issues
show
Bug introduced by
The method take() does not exist on Volosyuk\SimpleEloquent\Builder. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

224
        return $this->/** @scrutinizer ignore-call */ take(1)->getSimple($columns)->first();
Loading history...
225
    }
226
227
    /**
228
     * Execute the query and get the first result or throw an exception.
229
     *
230
     * @param  array  $columns
231
     * @return array|stdClass
232
     *
233
     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
234
     */
235 1
    public function firstSimpleOrFail($columns = ['*'])
236
    {
237 1
        if (! is_null($model = $this->firstSimple($columns))) {
238 1
            return $model;
239
        }
240
241 1
        throw (new ModelNotFoundException)->setModel(get_class($this->model));
242
    }
243
244
    /**
245
     * Find multiple models by their primary keys.
246
     *
247
     * @param  array  $ids
248
     * @param  array  $columns
249
     * @return Collection
250
     */
251 3
    public function findManySimple($ids, $columns = ['*'])
252
    {
253 3
        if (empty($ids)) {
254 1
            return Collection::make([]);
255
        }
256
257 3
        $this->query->whereIn($this->model->getQualifiedKeyName(), $ids);
258
259 3
        return $this->getSimple($columns);
260
    }
261
262
    /**
263
     * Paginate the given query.
264
     *
265
     * @param  int  $perPage
266
     * @param  array  $columns
267
     * @param  string  $pageName
268
     * @param  int|null  $page
269
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
270
     *
271
     * @throws \InvalidArgumentException
272
     */
273 1
    public function paginateSimple($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
274
    {
275 1
        $page = $page ?: Paginator::resolveCurrentPage($pageName);
276
277 1
        $perPage = $perPage ?: $this->model->getPerPage();
278
279 1
        $query = $this->toBase();
280
281 1
        $total = $query->getCountForPagination();
282
283 1
        $results = $total
284 1
            ? $this->forPage($page, $perPage)->getSimple($columns)
0 ignored issues
show
Bug introduced by
The method forPage() does not exist on Volosyuk\SimpleEloquent\Builder. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

284
            ? $this->/** @scrutinizer ignore-call */ forPage($page, $perPage)->getSimple($columns)
Loading history...
285 1
            : $this->model->newCollection();
286
287 1
        return new LengthAwarePaginator($results, $total, $perPage, $page, [
288 1
            'path' => Paginator::resolveCurrentPath(),
289 1
            'pageName' => $pageName,
290
        ]);
291
    }
292
293
    /**
294
     * Get a paginator only supporting simple next and previous links.
295
     *
296
     * This is more efficient on larger data-sets, etc.
297
     *
298
     * @param  int  $perPage
299
     * @param  array  $columns
300
     * @param  string  $pageName
301
     * @param  int|null  $page
302
     * @return \Illuminate\Contracts\Pagination\Paginator
303
     */
304 1
    public function simplePaginateSimple($perPage = 15, $columns = ['*'], $pageName = 'page', $page = null)
305
    {
306 1
        $page = $page ?: Paginator::resolveCurrentPage($pageName);
307
308 1
        $this->skip(($page - 1) * $perPage)->take($perPage + 1);
0 ignored issues
show
Bug introduced by
The method skip() does not exist on Volosyuk\SimpleEloquent\Builder. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

308
        $this->/** @scrutinizer ignore-call */ 
309
               skip(($page - 1) * $perPage)->take($perPage + 1);
Loading history...
309
310 1
        return $this->simplePaginator($this->getSimple($columns), $perPage, $page, [
311 1
            'path' => Paginator::resolveCurrentPath(),
312 1
            'pageName' => $pageName,
313
        ]);
314
    }
315
316
    /**
317
     * Get simple models without eager loading.
318
     *
319
     * @param  array  $columns
320
     * @return stdClass[]|array
321
     */
322 19
    public function getSimpleModels($columns = ['*'])
323
    {
324 19
        return $this->query->get($columns)->all();
325
    }
326
327
    /**
328
     * Eagerly load the relationship on a set of models.
329
     *
330
     * @param  array  $models
331
     * @param  string  $name
332
     * @param  \Closure  $constraints
333
     * @return array
334
     */
335 10
    protected function loadSimpleRelation(array $models, $name, Closure $constraints)
336
    {
337 10
        $relation = $this->getRelation($name);
338
339 10
        $relation->addEagerConstraintsSimple($models);
340
341 10
        $constraints($relation);
342
343 10
        $models = $relation->initSimpleRelation($models, $name);
344
345 10
        return $relation->eagerLoadAndMatchSimple($models, $name);
346
    }
347
348
    /**
349
     * Eager load the relationships for the models.
350
     *
351
     * @param  array  $models
352
     * @return array
353
     */
354 19
    public function eagerLoadRelationsSimple(array $models)
355
    {
356 19
        foreach ($this->eagerLoad as $name => $constraints) {
357 10
            if (strpos($name, '.') === false) {
358 10
                $models = $this->loadSimpleRelation($models, $name, $constraints);
359
            }
360
        }
361
362 19
        return $models;
363
    }
364
}
365