Completed
Pull Request — master (#218)
by
unknown
02:34
created

Model::joinParameters()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 1
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
1
<?php
2
3
namespace Encore\Admin\Grid;
4
5
use Illuminate\Database\Eloquent\Model as EloquentModel;
6
use Illuminate\Database\Eloquent\Relations\Relation;
7
use Illuminate\Pagination\AbstractPaginator;
8
use Illuminate\Support\Collection;
9
use Illuminate\Support\Facades\Input;
10
11
class Model
12
{
13
    /**
14
     * Eloquent model instance of the grid model.
15
     *
16
     * @var EloquentModel
17
     */
18
    protected $model;
19
20
    /**
21
     * Array of queries of the eloquent model.
22
     *
23
     * @var \Illuminate\Support\Collection
24
     */
25
    protected $queries;
26
27
    /**
28
     * Sort parameters of the model.
29
     *
30
     * @var array
31
     */
32
    protected $sort;
33
34
    /**
35
     * @var array
36
     */
37
    protected $data = [];
38
39
    /*
40
     * 20 items per page as default.
41
     *
42
     * @var int
43
     */
44
    protected $perPage = 20;
45
46
    /**
47
     * If the model use pagination.
48
     *
49
     * @var bool
50
     */
51
    protected $usePaginate = true;
52
53
    /**
54
     * The query string variable used to store the per-page.
55
     *
56
     * @var string
57
     */
58
    protected $perPageName = 'per_page';
59
60
    /**
61
     * The query string variable used to store the sort.
62
     *
63
     * @var string
64
     */
65
    protected $sortName = '_sort';
66
67
    /**
68
     * Create a new grid model instance.
69
     *
70
     * @param EloquentModel $model
71
     */
72
    public function __construct(EloquentModel $model)
73
    {
74
        $this->model = $model;
75
76
        $this->queries = collect();
77
    }
78
79
    /**
80
     * Get the eloquent model of the grid model.
81
     *
82
     * @return EloquentModel
83
     */
84
    public function eloquent()
85
    {
86
        return $this->model;
87
    }
88
89
    /**
90
     * Enable or disable pagination.
91
     *
92
     * @param bool $use
93
     */
94
    public function usePaginate($use = true)
95
    {
96
        $this->usePaginate = $use;
97
    }
98
99
    /**
100
     * Get the query string variable used to store the per-page.
101
     *
102
     * @return string
103
     */
104
    public function getPerPageName()
105
    {
106
        return $this->perPageName;
107
    }
108
109
    /**
110
     * Set the query string variable used to store the per-page.
111
     *
112
     * @param string $name
113
     *
114
     * @return $this
115
     */
116
    public function setPerPageName($name)
117
    {
118
        $this->perPageName = $name;
119
120
        return $this;
121
    }
122
123
    /**
124
     * Get the query string variable used to store the sort.
125
     *
126
     * @return string
127
     */
128
    public function getSortName()
129
    {
130
        return $this->sortName;
131
    }
132
133
    /**
134
     * Set the query string variable used to store the sort.
135
     *
136
     * @param string $name
137
     *
138
     * @return $this
139
     */
140
    public function setSortName($name)
141
    {
142
        $this->sortName = $name;
143
144
        return $this;
145
    }
146
147
    /**
148
     * Build.
149
     *
150
     * @return array
151
     */
152
    public function buildData()
153
    {
154
        if (empty($this->data)) {
155
            $this->data = $this->get()->toArray();
156
        }
157
158
        return $this->data;
159
    }
160
161
    /**
162
     * Add conditions to grid model.
163
     *
164
     * @param array $conditions
165
     *
166
     * @return void
167
     */
168
    public function addConditions(array $conditions)
169
    {
170
        foreach ($conditions as $condition) {
171
            call_user_func_array([$this, key($condition)], current($condition));
172
        }
173
    }
174
175
    /**
176
     * Get table of the model.
177
     *
178
     * @return string
179
     */
180
    public function getTable()
181
    {
182
        return $this->model->getTable();
183
    }
184
185
    /**
186
     * @throws \Exception
187
     *
188
     * @return Collection
189
     */
190
    protected function get()
191
    {
192
        if ($this->model instanceof AbstractPaginator) {
193
            return $this->model;
194
        }
195
196
        $this->setSort();
197
        $this->setPaginate();
198
199
        $this->queries->unique()->each(function ($query) {
200
            $this->model = call_user_func_array([$this->model, $query['method']], $query['arguments']);
201
        });
202
203
        if ($this->model instanceof Collection) {
204
            return $this->model;
205
        }
206
207
        if ($this->model instanceof AbstractPaginator) {
208
            return $this->model->getCollection();
209
        }
210
211
        throw new \Exception('Grid query error');
212
    }
213
214
    /**
215
     * Set the grid paginate.
216
     *
217
     * @return void
218
     */
219
    protected function setPaginate()
220
    {
221
        $paginate = $this->findQueryByMethod('paginate');
222
223
        $this->queries = $this->queries->reject(function ($query) {
224
            return $query['method'] == 'paginate';
225
        });
226
227
        if (!$this->usePaginate) {
228
            $query = [
229
                'method'    => 'get',
230
                'arguments' => [],
231
            ];
232
        } else {
233
            $query = [
234
                'method'    => 'paginate',
235
                'arguments' => $this->resolvePerPage($paginate),
0 ignored issues
show
Documentation introduced by
$paginate is of type this<Encore\Admin\Grid\Model>, but the function expects a array|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
236
            ];
237
        }
238
239
        $this->queries->push($query);
240
    }
241
242
    /**
243
     * Resolve perPage for pagination.
244
     *
245
     * @param array|null $paginate
246
     *
247
     * @return array
248
     */
249
    protected function resolvePerPage($paginate)
250
    {
251
        if ($perPage = app('request')->input($this->perPageName)) {
252
            if (is_array($paginate)) {
253
                $paginate['arguments'][0] = $perPage;
254
255
                return $paginate['arguments'];
256
            }
257
258
            $this->perPage = $perPage;
259
        }
260
        if(isset($paginate['arguments'][0])){
261
            return $paginate['arguments'];
262
        }
263
264
        return [$this->perPage];
265
    }
266
267
    /**
268
     * Find query by method name.
269
     *
270
     * @param $method
271
     *
272
     * @return static
273
     */
274
    protected function findQueryByMethod($method)
275
    {
276
        return $this->queries->first(function ($query) use ($method) {
277
            return $query['method'] == $method;
278
        });
279
    }
280
281
    /**
282
     * Set the grid sort.
283
     *
284
     * @return void
285
     */
286
    protected function setSort()
287
    {
288
        $this->sort = Input::get($this->sortName, []);
0 ignored issues
show
Documentation Bug introduced by
It seems like \Illuminate\Support\Faca...his->sortName, array()) of type * is incompatible with the declared type array of property $sort.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
289
        if (!is_array($this->sort)) {
290
            return;
291
        }
292
293
        if (empty($this->sort['column']) || empty($this->sort['type'])) {
294
            return;
295
        }
296
297
        if (str_contains($this->sort['column'], '.')) {
298
            $this->setRelationSort($this->sort['column']);
299
        } else {
300
            $this->resetOrderBy();
301
302
            $this->queries->push([
303
                'method'    => 'orderBy',
304
                'arguments' => [$this->sort['column'], $this->sort['type']],
305
            ]);
306
        }
307
    }
308
309
    /**
310
     * Set relation sort.
311
     *
312
     * @param string $column
313
     *
314
     * @return void
315
     */
316
    protected function setRelationSort($column)
317
    {
318
        list($relationName, $relationColumn) = explode('.', $column);
319
320
        if ($this->queries->contains(function ($query) use ($relationName) {
321
            return $query['method'] == 'with' && in_array($relationName, $query['arguments']);
322
        })) {
323
            $relation = $this->model->$relationName();
324
325
            $this->queries->push([
326
                'method'    => 'join',
327
                'arguments' => $this->joinParameters($relation),
328
            ]);
329
330
            $this->resetOrderBy();
331
332
            $this->queries->push([
333
                'method'    => 'orderBy',
334
                'arguments' => [
335
                    $relation->getRelated()->getTable().'.'.$relationColumn,
336
                    $this->sort['type'],
337
                ],
338
            ]);
339
        }
340
    }
341
342
    /**
343
     * Reset orderBy query.
344
     *
345
     * @return void
346
     */
347
    public function resetOrderBy()
348
    {
349
        $this->queries = $this->queries->reject(function ($query) {
350
            return $query['method'] == 'orderBy';
351
        });
352
    }
353
354
    /**
355
     * Build join parameters.
356
     *
357
     * @param Relation $relation
358
     *
359
     * @return array
360
     */
361
    protected function joinParameters(Relation $relation)
362
    {
363
        return [
364
            $relation->getRelated()->getTable(),
365
            $relation->getQualifiedParentKeyName(),
366
            '=',
367
            $relation->getForeignKey(),
368
        ];
369
    }
370
371
    /**
372
     * @param string $method
373
     * @param array  $arguments
374
     *
375
     * @return $this
376
     */
377
    public function __call($method, $arguments)
378
    {
379
        $this->queries->push([
380
            'method'    => $method,
381
            'arguments' => $arguments,
382
        ]);
383
384
        return $this;
385
    }
386
387
    /**
388
     * @param $key
389
     *
390
     * @return mixed
391
     */
392
    public function __get($key)
393
    {
394
        $data = $this->buildData();
395
396
        if (array_key_exists($key, $data)) {
397
            return $data[$key];
398
        }
399
    }
400
}
401