Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

Passed
Push — translatable-with-fallbacks ( 34e0ca...efd928 )
by Pedro
29:43
created

Read::getPageLengthMenu()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 7
c 0
b 0
f 0
nc 2
nop 0
dl 0
loc 13
rs 10
1
<?php
2
3
namespace Backpack\CRUD\app\Library\CrudPanel\Traits;
4
5
use Backpack\CRUD\app\Exceptions\BackpackProRequiredException;
6
use Exception;
7
8
/**
9
 * Properties and methods used by the List operation.
10
 */
11
trait Read
12
{
13
    /**
14
     * Find and retrieve the id of the current entry.
15
     *
16
     * @return int|bool The id in the db or false.
17
     */
18
    public function getCurrentEntryId()
19
    {
20
        if ($this->entry) {
21
            return $this->entry->getKey();
22
        }
23
24
        $params = \Route::current()->parameters();
25
26
        return  // use the entity name to get the current entry
27
                // this makes sure the ID is corrent even for nested resources
28
                $this->getRequest()->input($this->entity_name) ??
0 ignored issues
show
Bug introduced by
It seems like getRequest() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

28
                $this->/** @scrutinizer ignore-call */ 
29
                       getRequest()->input($this->entity_name) ??
Loading history...
29
                // otherwise use the next to last parameter
30
                array_values($params)[count($params) - 1] ??
31
                // otherwise return false
32
                false;
33
    }
34
35
    /**
36
     * Find and retrieve the current entry.
37
     *
38
     * @return \Illuminate\Database\Eloquent\Model|bool The row in the db or false.
39
     */
40
    public function getCurrentEntry()
41
    {
42
        $id = $this->getCurrentEntryId();
43
44
        if ($id === false) {
45
            return false;
46
        }
47
48
        return $this->getEntry($id);
49
    }
50
51
    public function getCurrentEntryWithLocale()
52
    {
53
        $entry = $this->getCurrentEntry();
54
55
        if(! $entry) {
56
            return false;
57
        }
58
59
        return $this->setLocaleOnModel($entry);
0 ignored issues
show
Bug introduced by
It seems like setLocaleOnModel() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

59
        return $this->/** @scrutinizer ignore-call */ setLocaleOnModel($entry);
Loading history...
60
61
    }
62
63
    /**
64
     * Find and retrieve an entry in the database or fail.
65
     *
66
     * @param int The id of the row in the db to fetch.
0 ignored issues
show
Bug introduced by
The type Backpack\CRUD\app\Library\CrudPanel\Traits\The was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
67
     * @return \Illuminate\Database\Eloquent\Model The row in the db.
68
     */
69
    public function getEntry($id)
70
    {
71
        if (! $this->entry) {
72
            $this->entry = $this->getModelWithCrudPanelQuery()->findOrFail($id);
0 ignored issues
show
Bug Best Practice introduced by
The property entry does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
73
            $this->entry = $this->entry->withFakes();
74
        }
75
76
        return $this->entry;
77
    }
78
79
    private function shouldUseFallbackLocale()
80
    {
81
        return $this->getRequest()->get('_use_fallback') === 'true' ? true : false;
82
    }
83
84
    /**
85
     * Find and retrieve an entry in the database or fail.
86
     * When found, make sure we set the Locale on it.
87
     *
88
     * @param int The id of the row in the db to fetch.
89
     * @return \Illuminate\Database\Eloquent\Model The row in the db.
90
     */
91
    public function getEntryWithLocale($id)
92
    {
93
        if (! $this->entry) {
94
            $this->entry = $this->getEntry($id);
0 ignored issues
show
Bug Best Practice introduced by
The property entry does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
95
        }
96
97
        return $this->setLocaleOnModel($this->entry);
98
    }
99
100
    /**
101
     * Return a Model builder instance with the current crud query applied.
102
     *
103
     * @return \Illuminate\Database\Eloquent\Builder
104
     */
105
    public function getModelWithCrudPanelQuery()
106
    {
107
        return $this->model->setQuery($this->query->getQuery());
108
    }
109
110
    /**
111
     * Find and retrieve an entry in the database or fail.
112
     *
113
     * @param int The id of the row in the db to fetch.
114
     * @return \Illuminate\Database\Eloquent\Model The row in the db.
115
     */
116
    public function getEntryWithoutFakes($id)
117
    {
118
        return $this->getModelWithCrudPanelQuery()->findOrFail($id);
119
    }
120
121
    /**
122
     * Make the query JOIN all relationships used in the columns, too,
123
     * so there will be less database queries overall.
124
     */
125
    public function autoEagerLoadRelationshipColumns()
126
    {
127
        $relationships = $this->getColumnsRelationships();
0 ignored issues
show
Bug introduced by
It seems like getColumnsRelationships() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

127
        /** @scrutinizer ignore-call */ 
128
        $relationships = $this->getColumnsRelationships();
Loading history...
128
129
        foreach ($relationships as $relation) {
130
            if (strpos($relation, '.') !== false) {
131
                $parts = explode('.', $relation);
132
                $model = $this->model;
133
134
                // Iterate over each relation part to find the valid relations without attributes
135
                // We should eager load the relation but not the attribute
136
                foreach ($parts as $i => $part) {
137
                    try {
138
                        $model = $model->$part()->getRelated();
139
                    } catch (Exception $e) {
140
                        $relation = implode('.', array_slice($parts, 0, $i));
141
                    }
142
                }
143
            }
144
            $this->with($relation);
0 ignored issues
show
Bug introduced by
It seems like with() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

144
            $this->/** @scrutinizer ignore-call */ 
145
                   with($relation);
Loading history...
145
        }
146
    }
147
148
    /**
149
     * Get all entries from the database.
150
     *
151
     * @return array|\Illuminate\Database\Eloquent\Collection
152
     */
153
    public function getEntries()
154
    {
155
        $this->autoEagerLoadRelationshipColumns();
156
157
        $entries = $this->query->get();
158
159
        // add the fake columns for each entry
160
        foreach ($entries as $key => $entry) {
161
            $entry->addFakes($this->getFakeColumnsAsArray());
0 ignored issues
show
Bug introduced by
It seems like getFakeColumnsAsArray() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

161
            $entry->addFakes($this->/** @scrutinizer ignore-call */ getFakeColumnsAsArray());
Loading history...
162
        }
163
164
        return $entries;
165
    }
166
167
    /**
168
     * Enable the DETAILS ROW functionality:.
169
     *
170
     * In the table view, show a plus sign next to each entry.
171
     * When clicking that plus sign, an AJAX call will bring whatever content you want from the EntityCrudController::showDetailsRow($id) and show it to the user.
172
     */
173
    public function enableDetailsRow()
174
    {
175
        if (! backpack_pro()) {
176
            throw new BackpackProRequiredException('Details row');
177
        }
178
179
        $this->setOperationSetting('detailsRow', true);
0 ignored issues
show
Bug introduced by
It seems like setOperationSetting() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

179
        $this->/** @scrutinizer ignore-call */ 
180
               setOperationSetting('detailsRow', true);
Loading history...
180
    }
181
182
    /**
183
     * Disable the DETAILS ROW functionality:.
184
     */
185
    public function disableDetailsRow()
186
    {
187
        $this->setOperationSetting('detailsRow', false);
188
    }
189
190
    /**
191
     * Add two more columns at the beginning of the ListEntrie table:
192
     * - one shows the checkboxes needed for bulk actions
193
     * - one is blank, in order for evenual detailsRow or expand buttons
194
     * to be in a separate column.
195
     */
196
    public function enableBulkActions()
197
    {
198
        $this->setOperationSetting('bulkActions', true);
199
    }
200
201
    /**
202
     * Remove the two columns needed for bulk actions.
203
     */
204
    public function disableBulkActions()
205
    {
206
        $this->setOperationSetting('bulkActions', false);
207
208
        $this->removeColumn('bulk_actions');
0 ignored issues
show
Bug introduced by
It seems like removeColumn() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

208
        $this->/** @scrutinizer ignore-call */ 
209
               removeColumn('bulk_actions');
Loading history...
209
    }
210
211
    /**
212
     * Set the number of rows that should be show on the list view.
213
     */
214
    public function setDefaultPageLength($value)
215
    {
216
        $this->abortIfInvalidPageLength($value);
217
218
        $this->setOperationSetting('defaultPageLength', $value);
219
    }
220
221
    /**
222
     * Get the number of rows that should be show on the list view.
223
     *
224
     * @return int
225
     */
226
    public function getDefaultPageLength()
227
    {
228
        return $this->getOperationSetting('defaultPageLength') ?? config('backpack.crud.operations.list.defaultPageLength') ?? 25;
0 ignored issues
show
Bug introduced by
It seems like getOperationSetting() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( 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 */ getOperationSetting('defaultPageLength') ?? config('backpack.crud.operations.list.defaultPageLength') ?? 25;
Loading history...
229
    }
230
231
    /**
232
     * If a custom page length was specified as default, make sure it
233
     * also show up in the page length menu.
234
     */
235
    public function addCustomPageLengthToPageLengthMenu()
236
    {
237
        $values = $this->getOperationSetting('pageLengthMenu')[0];
238
        $labels = $this->getOperationSetting('pageLengthMenu')[1];
239
240
        if (array_search($this->getDefaultPageLength(), $values) === false) {
241
            for ($i = 0; $i < count($values); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
242
                if ($values[$i] > $this->getDefaultPageLength() || $values[$i] === -1) {
243
                    array_splice($values, $i, 0, $this->getDefaultPageLength());
244
                    array_splice($labels, $i, 0, $this->getDefaultPageLength());
245
                    break;
246
                }
247
                if ($i === count($values) - 1) {
248
                    $values[] = $this->getDefaultPageLength();
249
                    $labels[] = $this->getDefaultPageLength();
250
                    break;
251
                }
252
            }
253
        }
254
255
        $this->setOperationSetting('pageLengthMenu', [$values, $labels]);
256
    }
257
258
    /**
259
     * Specify array of available page lengths on the list view.
260
     *
261
     * @param  array|int  $menu
262
     *
263
     * https://backpackforlaravel.com/docs/4.1/crud-cheat-sheet#page-length
264
     */
265
    public function setPageLengthMenu($menu)
266
    {
267
        if (is_array($menu)) {
268
            // start checking $menu integrity
269
            if (count($menu) !== count($menu, COUNT_RECURSIVE)) {
270
                // developer defined as setPageLengthMenu([[50, 100, 300]]) or setPageLengthMenu([[50, 100, 300],['f','h','t']])
271
                // we will apply the same labels as the values to the menu if developer didn't
272
                $this->abortIfInvalidPageLength($menu[0]);
273
274
                if (! isset($menu[1]) || ! is_array($menu[1])) {
275
                    $menu[1] = $menu[0];
276
                }
277
            } else {
278
                // developer defined setPageLengthMenu([10 => 'f', 100 => 'h', 300 => 't']) OR setPageLengthMenu([50, 100, 300])
279
                $menu = $this->buildPageLengthMenuFromArray($menu);
280
            }
281
        } else {
282
            // developer added only a single value setPageLengthMenu(10)
283
            $this->abortIfInvalidPageLength($menu);
284
285
            $menu = [[$menu], [$menu]];
286
        }
287
288
        $this->setOperationSetting('pageLengthMenu', $menu);
289
    }
290
291
    /**
292
     * Builds the menu from the given array. It works out with two different types of arrays:
293
     *  [1, 2, 3] AND [1 => 'one', 2 => 'two', 3 => 'three'].
294
     *
295
     * @param  array  $menu
296
     * @return array
297
     */
298
    private function buildPageLengthMenuFromArray($menu)
299
    {
300
        // check if the values of the array are strings, in case developer defined:
301
        // setPageLengthMenu([0 => 'f', 100 => 'h', 300 => 't'])
302
        if (count(array_filter(array_values($menu), 'is_string')) > 0) {
303
            $values = array_keys($menu);
304
            $labels = array_values($menu);
305
306
            $this->abortIfInvalidPageLength($values);
307
308
            return [$values, $labels];
309
        } else {
310
            // developer defined length as setPageLengthMenu([50, 100, 300])
311
            // we will use the same values as labels
312
            $this->abortIfInvalidPageLength($menu);
313
314
            return [$menu, $menu];
315
        }
316
    }
317
318
    /**
319
     * Get page length menu for the list view.
320
     *
321
     * @return array
322
     */
323
    public function getPageLengthMenu()
324
    {
325
        // if we have a 2D array, update all the values in the right hand array to their translated values
326
        if (isset($this->getOperationSetting('pageLengthMenu')[1]) && is_array($this->getOperationSetting('pageLengthMenu')[1])) {
327
            $aux = $this->getOperationSetting('pageLengthMenu');
328
            foreach ($this->getOperationSetting('pageLengthMenu')[1] as $key => $val) {
329
                $aux[1][$key] = trans($val);
330
            }
331
            $this->setOperationSetting('pageLengthMenu', $aux);
332
        }
333
        $this->addCustomPageLengthToPageLengthMenu();
334
335
        return $this->getOperationSetting('pageLengthMenu');
336
    }
337
338
    /**
339
     * Checks if the provided PageLength segment is valid.
340
     *
341
     * @param  array|int  $value
342
     * @return void
343
     */
344
    private function abortIfInvalidPageLength($value)
345
    {
346
        if ($value === 0 || (is_array($value) && in_array(0, $value))) {
347
            abort(500, 'You should not use 0 as a key in paginator. If you are looking for "ALL" option, use -1 instead.');
348
        }
349
    }
350
351
    /*
352
    |--------------------------------------------------------------------------
353
    |                                EXPORT BUTTONS
354
    |--------------------------------------------------------------------------
355
    */
356
357
    /**
358
     * Tell the list view to show the DataTables export buttons.
359
     */
360
    public function enableExportButtons()
361
    {
362
        if (! backpack_pro()) {
363
            throw new BackpackProRequiredException('Export buttons');
364
        }
365
366
        $this->setOperationSetting('exportButtons', true);
367
        $this->setOperationSetting('showTableColumnPicker', true);
368
        $this->setOperationSetting('showExportButton', true);
369
    }
370
371
    /**
372
     * Check if export buttons are enabled for the table view.
373
     *
374
     * @return bool
375
     */
376
    public function exportButtons()
377
    {
378
        return $this->getOperationSetting('exportButtons') ?? false;
379
    }
380
}
381