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
Pull Request — master (#3558)
by Cristian
11:56
created

Read::disableBulkActions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Backpack\CRUD\app\Library\CrudPanel\Traits;
4
5
use Exception;
6
7
/**
8
 * Properties and methods used by the List operation.
9
 */
10
trait Read
11
{
12
    /**
13
     * Find and retrieve the id of the current entry.
14
     *
15
     * @return int|bool The id in the db or false.
16
     */
17
    public function getCurrentEntryId()
18
    {
19
        if ($this->entry) {
20
            return $this->entry->getKey();
21
        }
22
23
        $params = \Route::current()->parameters();
24
25
        return  // use the entity name to get the current entry
26
                // this makes sure the ID is corrent even for nested resources
27
                $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

27
                $this->/** @scrutinizer ignore-call */ 
28
                       getRequest()->input($this->entity_name) ??
Loading history...
28
                // otherwise use the next to last parameter
29
                array_values($params)[count($params) - 1] ??
30
                // otherwise return false
31
                false;
32
    }
33
34
    /**
35
     * Find and retrieve the current entry.
36
     *
37
     * @return \Illuminate\Database\Eloquent\Model|bool The row in the db or false.
38
     */
39
    public function getCurrentEntry()
40
    {
41
        $id = $this->getCurrentEntryId();
42
43
        if (! $id) {
44
            return false;
45
        }
46
47
        return $this->getEntry($id);
48
    }
49
50
    /**
51
     * Find and retrieve an entry in the database or fail.
52
     *
53
     * @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...
54
     *
55
     * @return \Illuminate\Database\Eloquent\Model The row in the db.
56
     */
57
    public function getEntry($id)
58
    {
59
        if (! $this->entry) {
60
            $this->entry = $this->model->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...
61
            $this->entry = $this->entry->withFakes();
62
        }
63
64
        return $this->entry;
65
    }
66
67
    /**
68
     * Find and retrieve an entry in the database or fail.
69
     *
70
     * @param int The id of the row in the db to fetch.
71
     *
72
     * @return \Illuminate\Database\Eloquent\Model The row in the db.
73
     */
74
    public function getEntryWithoutFakes($id)
75
    {
76
        return $this->model->findOrFail($id);
77
    }
78
79
    /**
80
     * Make the query JOIN all relationships used in the columns, too,
81
     * so there will be less database queries overall.
82
     */
83
    public function autoEagerLoadRelationshipColumns()
84
    {
85
        $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

85
        /** @scrutinizer ignore-call */ 
86
        $relationships = $this->getColumnsRelationships();
Loading history...
86
87
        foreach ($relationships as $relation) {
88
            if (strpos($relation, '.') !== false) {
89
                $relation_parts = explode('.', $relation);
90
                $last_relation_part = $last_valid_relation_method = end($relation_parts);
91
92
                array_reduce(array_splice($relation_parts, 0, count($relation_parts)), function ($obj, $method) use (&$last_valid_relation_method) {
93
                    try {
94
                        $result = $obj->$method();
95
                        $last_valid_relation_method = $method;
96
97
                        return $result->getRelated();
98
                    } catch (Exception $e) {
99
                        return;
100
                    }
101
                }, $this->model);
102
103
                // when this keys don't match means the last part of the relation string is the attribute in the relation and
104
                // not a nested relation. In that case, we should eager load the relation but not the attribute
105
                if ($last_valid_relation_method != $last_relation_part) {
106
                    // remove the last part of the relation string because it is the attribute in the relationship
107
                    $relation = substr($relation, 0, strrpos($relation, '.'));
108
                }
109
            }
110
            $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

110
            $this->/** @scrutinizer ignore-call */ 
111
                   with($relation);
Loading history...
111
        }
112
    }
113
114
    /**
115
     * Get all entries from the database.
116
     *
117
     * @return array|\Illuminate\Database\Eloquent\Collection
118
     */
119
    public function getEntries()
120
    {
121
        $this->autoEagerLoadRelationshipColumns();
122
123
        $entries = $this->query->get();
124
125
        // add the fake columns for each entry
126
        foreach ($entries as $key => $entry) {
127
            $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

127
            $entry->addFakes($this->/** @scrutinizer ignore-call */ getFakeColumnsAsArray());
Loading history...
128
        }
129
130
        return $entries;
131
    }
132
133
    /**
134
     * Enable the DETAILS ROW functionality:.
135
     *
136
     * In the table view, show a plus sign next to each entry.
137
     * 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.
138
     */
139
    public function enableDetailsRow()
140
    {
141
        $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

141
        $this->/** @scrutinizer ignore-call */ 
142
               setOperationSetting('detailsRow', true);
Loading history...
142
    }
143
144
    /**
145
     * Disable the DETAILS ROW functionality:.
146
     */
147
    public function disableDetailsRow()
148
    {
149
        $this->setOperationSetting('detailsRow', false);
150
    }
151
152
    /**
153
     * Add two more columns at the beginning of the ListEntrie table:
154
     * - one shows the checkboxes needed for bulk actions
155
     * - one is blank, in order for evenual detailsRow or expand buttons
156
     * to be in a separate column.
157
     */
158
    public function enableBulkActions()
159
    {
160
        if ($this->getOperationSetting('bulkActions') == true) {
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

160
        if ($this->/** @scrutinizer ignore-call */ getOperationSetting('bulkActions') == true) {
Loading history...
161
            return;
162
        }
163
164
        $this->setOperationSetting('bulkActions', true);
165
166
        $this->addColumn([
0 ignored issues
show
Bug introduced by
It seems like addColumn() 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

166
        $this->/** @scrutinizer ignore-call */ 
167
               addColumn([
Loading history...
167
            'type'            => 'checkbox',
168
            'name'            => 'bulk_actions',
169
            'label'           => ' <input type="checkbox" class="crud_bulk_actions_main_checkbox" style="width: 16px; height: 16px;" />',
170
            'priority'        => 0,
171
            'searchLogic'     => false,
172
            'orderable'       => false,
173
            'visibleInTable'  => true,
174
            'visibleInModal'  => false,
175
            'visibleInExport' => false,
176
            'visibleInShow'   => false,
177
            'hasActions'      => true,
178
        ])->makeFirstColumn();
179
180
        $this->addColumn([
181
            'type'            => 'custom_html',
182
            'name'            => 'blank_first_column',
183
            'label'           => ' ',
184
            'priority'        => 0,
185
            'searchLogic'     => false,
186
            'orderable'       => false,
187
            'visibleInTabel'  => true,
188
            'visibleInModal'  => false,
189
            'visibleInExport' => false,
190
            'visibleInShow'   => false,
191
            'hasActions'      => true,
192
        ])->makeFirstColumn();
193
    }
194
195
    /**
196
     * Remove the two columns needed for bulk actions.
197
     */
198
    public function disableBulkActions()
199
    {
200
        $this->setOperationSetting('bulkActions', false);
201
202
        $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

202
        $this->/** @scrutinizer ignore-call */ 
203
               removeColumn('bulk_actions');
Loading history...
203
        $this->removeColumn('blank_first_column');
204
    }
205
206
    /**
207
     * Set the number of rows that should be show on the list view.
208
     */
209
    public function setDefaultPageLength($value)
210
    {
211
        $this->abortIfInvalidPageLength($value);
212
213
        $this->setOperationSetting('defaultPageLength', $value);
214
    }
215
216
    /**
217
     * Get the number of rows that should be show on the list view.
218
     *
219
     * @return int
220
     */
221
    public function getDefaultPageLength()
222
    {
223
        return $this->getOperationSetting('defaultPageLength') ?? config('backpack.crud.operations.list.defaultPageLength') ?? 25;
224
    }
225
226
    /**
227
     * If a custom page length was specified as default, make sure it
228
     * also show up in the page length menu.
229
     */
230
    public function addCustomPageLengthToPageLengthMenu()
231
    {
232
        $values = $this->getOperationSetting('pageLengthMenu')[0];
233
        $labels = $this->getOperationSetting('pageLengthMenu')[1];
234
235
        if (array_search($this->getDefaultPageLength(), $values) === false) {
236
            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...
237
                if ($values[$i] > $this->getDefaultPageLength() || $values[$i] === -1) {
238
                    array_splice($values, $i, 0, $this->getDefaultPageLength());
239
                    array_splice($labels, $i, 0, $this->getDefaultPageLength());
240
                    break;
241
                }
242
                if ($i === count($values) - 1) {
243
                    $values[] = $this->getDefaultPageLength();
244
                    $labels[] = $this->getDefaultPageLength();
245
                    break;
246
                }
247
            }
248
        }
249
250
        $this->setOperationSetting('pageLengthMenu', [$values, $labels]);
251
    }
252
253
    /**
254
     * Specify array of available page lengths on the list view.
255
     *
256
     * @param array|int $menu
257
     *
258
     * https://backpackforlaravel.com/docs/4.1/crud-cheat-sheet#page-length
259
     */
260
    public function setPageLengthMenu($menu)
261
    {
262
        if (is_array($menu)) {
263
            // start checking $menu integrity
264
            if (count($menu) !== count($menu, COUNT_RECURSIVE)) {
265
                // developer defined as setPageLengthMenu([[50, 100, 300]]) or setPageLengthMenu([[50, 100, 300],['f','h','t']])
266
                // we will apply the same labels as the values to the menu if developer didn't
267
                $this->abortIfInvalidPageLength($menu[0]);
268
269
                if (! isset($menu[1]) || ! is_array($menu[1])) {
270
                    $menu[1] = $menu[0];
271
                }
272
            } else {
273
                // developer defined setPageLengthMenu([10 => 'f', 100 => 'h', 300 => 't']) OR setPageLengthMenu([50, 100, 300])
274
                $menu = $this->buildPageLengthMenuFromArray($menu);
275
            }
276
        } else {
277
            // developer added only a single value setPageLengthMenu(10)
278
            $this->abortIfInvalidPageLength($menu);
279
280
            $menu = [[$menu], [$menu]];
281
        }
282
283
        $this->setOperationSetting('pageLengthMenu', $menu);
284
    }
285
286
    /**
287
     * Builds the menu from the given array. It works out with two different types of arrays:
288
     *  [1, 2, 3] AND [1 => 'one', 2 => 'two', 3 => 'three'].
289
     *
290
     * @param array $menu
291
     * @return array
292
     */
293
    private function buildPageLengthMenuFromArray($menu)
294
    {
295
        // check if the values of the array are strings, in case developer defined:
296
        // setPageLengthMenu([0 => 'f', 100 => 'h', 300 => 't'])
297
        if (count(array_filter(array_values($menu), 'is_string')) > 0) {
298
            $values = array_keys($menu);
299
            $labels = array_values($menu);
300
301
            $this->abortIfInvalidPageLength($values);
302
303
            return [$values, $labels];
304
        } else {
305
            // developer defined length as setPageLengthMenu([50, 100, 300])
306
            // we will use the same values as labels
307
            $this->abortIfInvalidPageLength($menu);
308
309
            return [$menu, $menu];
310
        }
311
    }
312
313
    /**
314
     * Get page length menu for the list view.
315
     *
316
     * @return array
317
     */
318
    public function getPageLengthMenu()
319
    {
320
        // if we have a 2D array, update all the values in the right hand array to their translated values
321
        if (isset($this->getOperationSetting('pageLengthMenu')[1]) && is_array($this->getOperationSetting('pageLengthMenu')[1])) {
322
            $aux = $this->getOperationSetting('pageLengthMenu');
323
            foreach ($this->getOperationSetting('pageLengthMenu')[1] as $key => $val) {
324
                $aux[1][$key] = trans($val);
325
            }
326
            $this->setOperationSetting('pageLengthMenu', $aux);
327
        }
328
        $this->addCustomPageLengthToPageLengthMenu();
329
330
        return $this->getOperationSetting('pageLengthMenu');
331
    }
332
333
    /**
334
     * Checks if the provided PageLength segment is valid.
335
     *
336
     * @param array|int $value
337
     * @return void
338
     */
339
    private function abortIfInvalidPageLength($value)
340
    {
341
        if ($value === 0 || (is_array($value) && in_array(0, $value))) {
342
            abort(500, 'You should not use 0 as a key in paginator. If you are looking for "ALL" option, use -1 instead.');
343
        }
344
    }
345
346
    /*
347
    |--------------------------------------------------------------------------
348
    |                                EXPORT BUTTONS
349
    |--------------------------------------------------------------------------
350
    */
351
352
    /**
353
     * Tell the list view to show the DataTables export buttons.
354
     */
355
    public function enableExportButtons()
356
    {
357
        $this->setOperationSetting('exportButtons', true);
358
    }
359
360
    /**
361
     * Check if export buttons are enabled for the table view.
362
     *
363
     * @return bool
364
     */
365
    public function exportButtons()
366
    {
367
        return $this->getOperationSetting('exportButtons') ?? false;
368
    }
369
}
370