Issues (33)

src/Builder.php (12 issues)

1
<?php
2
3
namespace Volosyuk\SimpleEloquent;
4
5
use Closure;
6
use Illuminate\Contracts\Pagination\LengthAwarePaginator as LengthAwarePaginatorInterface;
7
use Illuminate\Contracts\Pagination\Paginator as PaginatorInterface;
8
use Illuminate\Contracts\Support\Arrayable;
9
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
10
use Illuminate\Database\Eloquent\Model;
11
use Illuminate\Database\Eloquent\ModelNotFoundException;
12
use Illuminate\Pagination\LengthAwarePaginator;
13
use Illuminate\Pagination\Paginator;
14
use Illuminate\Support\Collection;
15
use InvalidArgumentException;
16
use stdClass;
17
use Volosyuk\SimpleEloquent\Relations\Relation;
18
19
/**
20
 * Class Builder
21
 * @package Volosyuk\SimpleEloquent
22
 */
23
class Builder extends \Illuminate\Database\Eloquent\Builder
24
{
25
    /**
26
     * @var bool
27
     */
28
    protected $simple = false;
29
30
    /**
31
     * @return $this
32
     */
33 31
    public function simple()
34
    {
35 31
        $this->simple = true;
36
37 31
        return $this;
38
    }
39
40
    /**
41
     * @return bool
42
     */
43 32
    public function isSimple()
44
    {
45 32
        return $this->simple === true;
46
    }
47
48
    /**
49
     * @param array $columns
50
     * @return EloquentCollection|Collection|static[]
51
     */
52 26
    public function get($columns = ['*'])
53
    {
54 26
        if ($this->isSimple()) {
55 11
            return $this->getSimple($columns);
56
        }
57
58 26
        return parent::get($columns);
59
    }
60
61
    /**
62
     * @param mixed $id
63
     * @param array $columns
64
     * @return Collection|stdClass|array|null
65
     */
66 8
    public function find($id, $columns = ['*'])
67
    {
68 8
        if ($this->isSimple()) {
69 7
            return $this->findSimple($id, $columns);
70
        }
71
72 8
        return parent::find($id, $columns);
73
    }
74
75
    /**
76
     * @param mixed $id
77
     * @param array $columns
78
     * @return array|EloquentCollection|Model|Collection|stdClass
79
     */
80 1
    public function findOrFail($id, $columns = ['*'])
81
    {
82 1
        if ($this->isSimple()) {
83 1
            return $this->findSimpleOrFail($id, $columns);
84
        }
85
86 1
        return parent::findOrFail($id, $columns);
87
    }
88
89
    /**
90
     * @param array $columns
91
     * @return array|Model|null|object|stdClass|static
92
     */
93 19
    public function first($columns = ['*'])
94
    {
95 19
        if ($this->isSimple()) {
96 17
            return $this->firstSimple($columns);
97
        }
98
99 13
        return parent::first($columns);
100
    }
101
102
    /**
103
     * @param array $columns
104
     * @return array|Model|stdClass|static
105
     */
106 1
    public function firstOrFail($columns = ['*'])
107
    {
108 1
        if ($this->isSimple()) {
109 1
            return $this->firstSimpleOrFail($columns);
110
        }
111
112 1
        return parent::firstOrFail($columns);
113
    }
114
115
    /**
116
     * @param array|Arrayable $ids
117
     * @param array $columns
118
     * @return EloquentCollection|Collection
119
     */
120 9
    public function findMany($ids, $columns = ['*'])
121
    {
122 9
        if ($this->isSimple()) {
123 7
            return $this->findManySimple($ids, $columns);
0 ignored issues
show
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

123
            return $this->findManySimple(/** @scrutinizer ignore-type */ $ids, $columns);
Loading history...
124
        }
125
126 9
        return parent::findMany($ids, $columns);
127
    }
128
129
    /**
130
     * @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...
131
     * @param array $columns
132
     * @param string $pageName
133
     * @param null $page
0 ignored issues
show
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...
134
     * @return LengthAwarePaginatorInterface
135
     */
136 11
    public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null, $total = null)
0 ignored issues
show
The parameter $total is not used and could be removed. ( Ignorable by Annotation )

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

136
    public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null, /** @scrutinizer ignore-unused */ $total = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
137
    {
138 11
        if ($this->isSimple()) {
139 11
            return $this->paginateSimple($perPage, $columns, $pageName, $page);
140
        }
141
142 11
        return parent::paginate($perPage, $columns, $pageName, $page);
143
    }
144
145
    /**
146
     * @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...
147
     * @param array $columns
148
     * @param string $pageName
149
     * @param null $page
0 ignored issues
show
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...
150
     * @return PaginatorInterface
151
     */
152 11
    public function simplePaginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
153
    {
154 11
        if ($this->isSimple()) {
155 11
            return $this->simplePaginateSimple($perPage, $columns, $pageName, $page);
156
        }
157
158 11
        return parent::simplePaginate($perPage, $columns, $pageName, $page);
159
    }
160
161
    /**
162
     * @param array $columns
163
     * @return Collection
164
     */
165 31
    public function getSimple($columns = ['*'])
166
    {
167 31
        $builder = $this->applyScopes();
168
169 31
        $models = $builder->getSimpleModels($columns);
170
171 31
        if (count($models) > 0) {
172 31
            $models = $builder->eagerLoadRelationsSimple($models);
173
        }
174
175 31
        return collect($models);
0 ignored issues
show
$models of type array|stdClass[] is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

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

175
        return collect(/** @scrutinizer ignore-type */ $models);
Loading history...
176
    }
177
178
    /**
179
     * @param mixed $id
180
     * @param array $columns
181
     * @return Collection|stdClass|array|null
182
     */
183 8
    public function findSimple($id, $columns = ['*'])
184
    {
185 8
        if (is_array($id)) {
186 2
            return $this->findManySimple($id, $columns);
187
        }
188
189 8
        $this->query->where($this->model->getQualifiedKeyName(), '=', $id);
190
191 8
        return $this->firstSimple($columns);
192
    }
193
194
    /**
195
     * Find a model by its primary key or throw an exception.
196
     *
197
     * @param  mixed  $id
198
     * @param  array  $columns
199
     * @return stdClass|array|Collection
200
     *
201
     * @throws ModelNotFoundException
202
     */
203 1
    public function findSimpleOrFail($id, $columns = ['*'])
204
    {
205 1
        $result = $this->findSimple($id, $columns);
206
207 1
        if (is_array($id)) {
208 1
            if (count($result) == count(array_unique($id))) {
0 ignored issues
show
It seems like $result can also be of type null and stdClass; however, parameter $value 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

208
            if (count(/** @scrutinizer ignore-type */ $result) == count(array_unique($id))) {
Loading history...
209 1
                return $result;
210
            }
211 1
        } elseif (! is_null($result)) {
212
            return $result;
213
        }
214
215 1
        throw (new ModelNotFoundException)->setModel(
216 1
            get_class($this->model), $id
217
        );
218
    }
219
220
    /**
221
     * Execute the query and get the first result.
222
     *
223
     * @param  array  $columns
224
     * @return stdClass|array|null
225
     */
226 21
    public function firstSimple($columns = ['*'])
227
    {
228 21
        return $this->take(1)->getSimple($columns)->first();
0 ignored issues
show
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

228
        return $this->/** @scrutinizer ignore-call */ take(1)->getSimple($columns)->first();
Loading history...
229
    }
230
231
    /**
232
     * Execute the query and get the first result or throw an exception.
233
     *
234
     * @param  array  $columns
235
     * @return array|stdClass
236
     *
237
     * @throws ModelNotFoundException
238
     */
239 1
    public function firstSimpleOrFail($columns = ['*'])
240
    {
241 1
        if (! is_null($model = $this->firstSimple($columns))) {
242 1
            return $model;
243
        }
244
245 1
        throw (new ModelNotFoundException)->setModel(get_class($this->model));
246
    }
247
248
    /**
249
     * Find multiple models by their primary keys.
250
     *
251
     * @param  array  $ids
252
     * @param  array  $columns
253
     * @return Collection
254
     */
255 9
    public function findManySimple($ids, $columns = ['*'])
256
    {
257 9
        if (empty($ids)) {
258 1
            return Collection::make([]);
0 ignored issues
show
array() of type array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $items of Illuminate\Support\Collection::make(). ( Ignorable by Annotation )

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

258
            return Collection::make(/** @scrutinizer ignore-type */ []);
Loading history...
259
        }
260
261 9
        $this->query->whereIn($this->model->getQualifiedKeyName(), $ids);
262
263 9
        return $this->getSimple($columns);
264
    }
265
266
    /**
267
     * Paginate the given query.
268
     *
269
     * @param  int  $perPage
270
     * @param  array  $columns
271
     * @param  string  $pageName
272
     * @param  int|null  $page
273
     * @return LengthAwarePaginatorInterface
274
     *
275
     * @throws InvalidArgumentException
276
     */
277 11
    public function paginateSimple($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
278
    {
279 11
        $page = $page ?: Paginator::resolveCurrentPage($pageName);
280
281 11
        $perPage = $perPage ?: $this->model->getPerPage();
282
283 11
        $query = $this->toBase();
284
285 11
        $total = $query->getCountForPagination();
286
287 11
        $results = $total
288 11
            ? $this->forPage($page, $perPage)->getSimple($columns)
0 ignored issues
show
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

288
            ? $this->/** @scrutinizer ignore-call */ forPage($page, $perPage)->getSimple($columns)
Loading history...
289 11
            : $this->model->newCollection();
290
291 11
        return new LengthAwarePaginator($results, $total, $perPage, $page, [
292 11
            'path' => Paginator::resolveCurrentPath(),
293 11
            'pageName' => $pageName,
294
        ]);
295
    }
296
297
    /**
298
     * Get a paginator only supporting simple next and previous links.
299
     *
300
     * This is more efficient on larger data-sets, etc.
301
     *
302
     * @param  int  $perPage
303
     * @param  array  $columns
304
     * @param  string  $pageName
305
     * @param  int|null  $page
306
     * @return PaginatorInterface
307
     */
308 11
    public function simplePaginateSimple($perPage = 15, $columns = ['*'], $pageName = 'page', $page = null)
309
    {
310 11
        $page = $page ?: Paginator::resolveCurrentPage($pageName);
311
312 11
        $this->skip(($page - 1) * $perPage)->take($perPage + 1);
0 ignored issues
show
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

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

 

OSZAR »