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

Test Setup Failed
Pull Request — master (#3332)
by Cristian
31:32 queued 15:08
created

Read   A

Complexity

Total Complexity 41

Size/Duplication

Total Lines 315
Duplicated Lines 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
eloc 98
c 3
b 1
f 0
dl 0
loc 315
rs 9.1199
wmc 41

18 Methods

Rating   Name   Duplication   Size   Complexity  
A getEntryWithoutFakes() 0 3 1
A disableDetailsRow() 0 3 1
A autoEagerLoadRelationshipColumns() 0 6 2
A getEntry() 0 8 2
A getCurrentEntry() 0 9 2
A getEntries() 0 12 2
A getCurrentEntryId() 0 15 2
A enableDetailsRow() 0 3 1
A disableBulkActions() 0 6 1
A getDefaultPageLength() 0 3 1
A setDefaultPageLength() 0 3 1
A enableBulkActions() 0 35 2
A addCustomPageLengthToPageLengthMenu() 0 20 5
B setPageLengthMenu() 0 22 10
A enableExportButtons() 0 3 1
A buildPageLengthMenuFromArray() 0 13 2
A getPageLengthMenu() 0 13 4
A exportButtons() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like Read often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Read, and based on these observations, apply Extract Interface, too.

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

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

83
        /** @scrutinizer ignore-call */ 
84
        $relationships = $this->getColumnsRelationships();
Loading history...
84
85
        if (count($relationships)) {
86
            $this->with($relationships);
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

86
            $this->/** @scrutinizer ignore-call */ 
87
                   with($relationships);
Loading history...
87
        }
88
    }
89
90
    /**
91
     * Get all entries from the database.
92
     *
93
     * @return array|\Illuminate\Database\Eloquent\Collection
94
     */
95
    public function getEntries()
96
    {
97
        $this->autoEagerLoadRelationshipColumns();
98
99
        $entries = $this->query->get();
100
101
        // add the fake columns for each entry
102
        foreach ($entries as $key => $entry) {
103
            $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

103
            $entry->addFakes($this->/** @scrutinizer ignore-call */ getFakeColumnsAsArray());
Loading history...
104
        }
105
106
        return $entries;
107
    }
108
109
    /**
110
     * Enable the DETAILS ROW functionality:.
111
     *
112
     * In the table view, show a plus sign next to each entry.
113
     * 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.
114
     */
115
    public function enableDetailsRow()
116
    {
117
        $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

117
        $this->/** @scrutinizer ignore-call */ 
118
               setOperationSetting('detailsRow', true);
Loading history...
118
    }
119
120
    /**
121
     * Disable the DETAILS ROW functionality:.
122
     */
123
    public function disableDetailsRow()
124
    {
125
        $this->setOperationSetting('detailsRow', false);
126
    }
127
128
    /**
129
     * Add two more columns at the beginning of the ListEntrie table:
130
     * - one shows the checkboxes needed for bulk actions
131
     * - one is blank, in order for evenual detailsRow or expand buttons
132
     * to be in a separate column.
133
     */
134
    public function enableBulkActions()
135
    {
136
        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

136
        if ($this->/** @scrutinizer ignore-call */ getOperationSetting('bulkActions') == true) {
Loading history...
137
            return;
138
        }
139
140
        $this->setOperationSetting('bulkActions', true);
141
142
        $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

142
        $this->/** @scrutinizer ignore-call */ 
143
               addColumn([
Loading history...
143
            'type'            => 'checkbox',
144
            'name'            => 'bulk_actions',
145
            'label'           => ' <input type="checkbox" class="crud_bulk_actions_main_checkbox" style="width: 16px; height: 16px;" />',
146
            'priority'        => 0,
147
            'searchLogic'     => false,
148
            'orderable'       => false,
149
            'visibleInTable'  => true,
150
            'visibleInModal'  => false,
151
            'visibleInExport' => false,
152
            'visibleInShow'   => false,
153
            'hasActions'      => true,
154
        ])->makeFirstColumn();
155
156
        $this->addColumn([
157
            'type'            => 'custom_html',
158
            'name'            => 'blank_first_column',
159
            'label'           => ' ',
160
            'priority'        => 0,
161
            'searchLogic'     => false,
162
            'orderable'       => false,
163
            'visibleInTabel'  => true,
164
            'visibleInModal'  => false,
165
            'visibleInExport' => false,
166
            'visibleInShow'   => false,
167
            'hasActions'      => true,
168
        ])->makeFirstColumn();
169
    }
170
171
    /**
172
     * Remove the two columns needed for bulk actions.
173
     */
174
    public function disableBulkActions()
175
    {
176
        $this->setOperationSetting('bulkActions', false);
177
178
        $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

178
        $this->/** @scrutinizer ignore-call */ 
179
               removeColumn('bulk_actions');
Loading history...
179
        $this->removeColumn('blank_first_column');
180
    }
181
182
    /**
183
     * Set the number of rows that should be show on the list view.
184
     */
185
    public function setDefaultPageLength($value)
186
    {
187
        $this->setOperationSetting('defaultPageLength', $value);
188
    }
189
190
    /**
191
     * Get the number of rows that should be show on the list view.
192
     *
193
     * @return int
194
     */
195
    public function getDefaultPageLength()
196
    {
197
        return $this->getOperationSetting('defaultPageLength') ?? config('backpack.crud.operations.list.defaultPageLength') ?? 25;
198
    }
199
200
    /**
201
     * If a custom page length was specified as default, make sure it
202
     * also show up in the page length menu.
203
     */
204
    public function addCustomPageLengthToPageLengthMenu()
205
    {
206
        $values = $this->getOperationSetting('pageLengthMenu')[0];
207
        $labels = $this->getOperationSetting('pageLengthMenu')[1];
208
209
        // This is a condition that should be always true.
210
        if (is_array($values) && is_array($labels)) {
211
            $position = array_search($this->getDefaultPageLength(), $values);
212
            if ($position !== false) {
213
                $defaultLabel = isset($labels[$position]) ? $labels[$position] : $this->getDefaultPageLength();
214
                array_unshift($values, $this->getDefaultPageLength());
215
                array_unshift($labels, $defaultLabel);
216
217
                //now make it unique.
218
                $values = array_unique($values);
219
                $labels = array_unique($labels);
220
            }
221
        }
222
223
        $this->setOperationSetting('pageLengthMenu', [$values, $labels]);
224
    }
225
226
    /**
227
     * Specify array of available page lengths on the list view.
228
     *
229
     * @param array $menu 1d array of page length values,
230
     *                    or 2d array (first array: page length values, second array: page length labels)
231
     *                    More at: https://datatables.net/reference/option/lengthMenu
232
     */
233
    public function setPageLengthMenu($menu)
234
    {
235
236
        // start checking $menu integrity
237
        if (isset($menu[0]) && is_array($menu[0])) {
238
            // developer defined as setPageLengthMenu([[50, 100, 300]]) or setPageLengthMenu([[50, 100, 300],['f','h','t']])
239
            // we will apply the same labels as the values to the menu if developer didn't
240
            if (! isset($menu[1]) || ! is_array($menu[1])) {
241
                $menu[1] = $menu[0];
242
            }
243
        } elseif (isset($menu[0]) && ! is_array($menu[0])) {
244
            if (is_array($menu)) {
245
                $menu = $this->buildPageLengthMenuFromArray($menu);
246
            }
247
        } elseif (! isset($menu[0]) && is_array($menu)) {
248
            $menu = $this->buildPageLengthMenuFromArray($menu);
249
        } else {
250
            // developer added only a single value setPageLengthMenu(10)
251
            $menu = [[$menu], [$menu]];
252
        }
253
254
        $this->setOperationSetting('pageLengthMenu', $menu);
255
    }
256
257
    /**
258
     * Builds the menu from the given array. It works out with two different types of arrays:
259
     *  [1, 2, 3] AND
260
     *  [1 => 'one', 2 => 'two', 3 => 'three'].
261
     *
262
     * @param array $menu
263
     * @return array
264
     */
265
    private function buildPageLengthMenuFromArray($menu)
266
    {
267
        // check if the values of the array are strings, in case developer defined:
268
        // setPageLengthMenu([0 => 'f', 100 => 'h', 300 => 't'])
269
        if (count(array_filter(array_values($menu), 'is_string')) > 0) {
270
            $values = array_keys($menu);
271
            $labels = array_values($menu);
272
273
            return [$values, $labels];
274
        } else {
275
            // developer defined length as setPageLengthMenu([0, 100, 300])
276
            // we will use the same values as labels
277
            return [$menu, $menu];
278
        }
279
    }
280
281
    /**
282
     * Get page length menu for the list view.
283
     *
284
     * @return array
285
     */
286
    public function getPageLengthMenu()
287
    {
288
        // if we have a 2D array, update all the values in the right hand array to their translated values
289
        if (isset($this->getOperationSetting('pageLengthMenu')[1]) && is_array($this->getOperationSetting('pageLengthMenu')[1])) {
290
            $aux = $this->getOperationSetting('pageLengthMenu');
291
            foreach ($this->getOperationSetting('pageLengthMenu')[1] as $key => $val) {
292
                $aux[1][$key] = trans($val);
293
            }
294
            $this->setOperationSetting('pageLengthMenu', $aux);
295
        }
296
        $this->addCustomPageLengthToPageLengthMenu();
297
298
        return $this->getOperationSetting('pageLengthMenu');
299
    }
300
301
    /*
302
    |--------------------------------------------------------------------------
303
    |                                EXPORT BUTTONS
304
    |--------------------------------------------------------------------------
305
    */
306
307
    /**
308
     * Tell the list view to show the DataTables export buttons.
309
     */
310
    public function enableExportButtons()
311
    {
312
        $this->setOperationSetting('exportButtons', true);
313
    }
314
315
    /**
316
     * Check if export buttons are enabled for the table view.
317
     *
318
     * @return bool
319
     */
320
    public function exportButtons()
321
    {
322
        return $this->getOperationSetting('exportButtons') ?? false;
323
    }
324
}
325