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

AutoSet   B
last analyzed

Complexity

Total Complexity 46

Size/Duplication

Total Lines 222
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 46
eloc 90
c 1
b 0
f 1
dl 0
loc 222
rs 8.72

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getDbColumnsNames() 0 16 3
A getLabel() 0 3 1
A setLabeller() 0 5 1
A makeLabel() 0 7 3
B setFromDb() 0 29 7
A getDbTableColumns() 0 8 3
D inferFieldTypeFromDbColumnType() 0 64 24
A getDbColumnTypes() 0 18 3
A setDoctrineTypesMapping() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like AutoSet 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 AutoSet, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Backpack\CRUD\app\Library\CrudPanel\Traits;
4
5
trait AutoSet
6
{
7
    protected $autoset = [];
8
9
    /**
10
     * For a simple CRUD Panel, there should be no need to add/define the fields.
11
     * The public columns in the database will be converted to be fields.
12
     *
13
     * @return void
14
     */
15
    public function setFromDb($setFields = true, $setColumns = true)
16
    {
17
        $this->getDbColumnTypes();
18
19
        array_map(function ($field) use ($setFields, $setColumns) {
20
            if ($setFields && ! isset($this->getCleanStateFields()[$field])) {
0 ignored issues
show
Bug introduced by
It seems like getCleanStateFields() 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

20
            if ($setFields && ! isset($this->/** @scrutinizer ignore-call */ getCleanStateFields()[$field])) {
Loading history...
21
                $this->addField([
0 ignored issues
show
Bug introduced by
It seems like addField() 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

21
                $this->/** @scrutinizer ignore-call */ 
22
                       addField([
Loading history...
22
                    'name' => $field,
23
                    'label' => $this->makeLabel($field),
24
                    'value' => null,
25
                    'default' => isset($this->autoset['db_column_types'][$field]['default']) ? $this->autoset['db_column_types'][$field]['default'] : null,
26
                    'type' => $this->inferFieldTypeFromDbColumnType($field),
27
                    'values' => [],
28
                    'attributes' => [],
29
                    'autoset' => true,
30
                ]);
31
            }
32
33
            if ($setColumns && ! in_array($field, $this->model->getHidden()) && ! isset($this->columns()[$field])) {
0 ignored issues
show
Bug introduced by
It seems like columns() 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

33
            if ($setColumns && ! in_array($field, $this->model->getHidden()) && ! isset($this->/** @scrutinizer ignore-call */ columns()[$field])) {
Loading history...
34
                $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

34
                $this->/** @scrutinizer ignore-call */ 
35
                       addColumn([
Loading history...
35
                    'name' => $field,
36
                    'label' => $this->makeLabel($field),
37
                    'type' => $this->inferFieldTypeFromDbColumnType($field),
38
                    'autoset' => true,
39
                ]);
40
            }
41
        }, $this->getDbColumnsNames());
42
43
        $this->autoset = [];
44
    }
45
46
    /**
47
     * Get all columns from the database for that table.
48
     *
49
     * @return array
50
     */
51
    public function getDbColumnTypes()
52
    {
53
        $dbColumnTypes = [];
54
55
        if (! $this->driverIsSql()) {
0 ignored issues
show
Bug introduced by
It seems like driverIsSql() 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

55
        if (! $this->/** @scrutinizer ignore-call */ driverIsSql()) {
Loading history...
56
            return $dbColumnTypes;
57
        }
58
        $dbColumns = $this->getDbTableColumns();
59
60
        foreach ($dbColumns as $key => $column) {
61
            $column_type = $column->getType()->getName();
62
            $dbColumnTypes[$column->getName()]['type'] = trim(preg_replace('/\(\d+\)(.*)/i', '', $column_type));
63
            $dbColumnTypes[$column->getName()]['default'] = $column->getDefault();
64
        }
65
66
        $this->autoset['db_column_types'] = $dbColumnTypes;
67
68
        return $dbColumnTypes;
69
    }
70
71
    /**
72
     * Set extra types mapping on model.
73
     *
74
     * DEPRECATION NOTICE: This method is no longer used and will be removed in future versions of Backpack
75
     *
76
     * @deprecated
77
     */
78
    public function setDoctrineTypesMapping()
79
    {
80
        $this->getModel()->getConnectionWithExtraTypeMappings();
0 ignored issues
show
Bug introduced by
It seems like getModel() 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

80
        $this->/** @scrutinizer ignore-call */ 
81
               getModel()->getConnectionWithExtraTypeMappings();
Loading history...
81
    }
82
83
    /**
84
     * Get all columns in the database table.
85
     *
86
     * @return array
87
     */
88
    public function getDbTableColumns()
89
    {
90
        if (isset($this->autoset['table_columns']) && $this->autoset['table_columns']) {
91
            return $this->autoset['table_columns'];
92
        }
93
        $this->autoset['table_columns'] = $this->model::getDbTableSchema()->getColumns();
94
95
        return $this->autoset['table_columns'];
96
    }
97
98
    /**
99
     * Infer a field type, judging from the database column type.
100
     *
101
     * @param  string  $field  Field name.
102
     * @return string Field type.
103
     */
104
    protected function inferFieldTypeFromDbColumnType($fieldName)
105
    {
106
        if ($fieldName == 'password') {
107
            return 'password';
108
        }
109
110
        if ($fieldName == 'email') {
111
            return 'email';
112
        }
113
114
        if ($this->holdsMultipleInputs($fieldName)) {
0 ignored issues
show
Bug introduced by
It seems like holdsMultipleInputs() 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

114
        if ($this->/** @scrutinizer ignore-call */ holdsMultipleInputs($fieldName)) {
Loading history...
115
            return 'text'; // not because it's right, but because we don't know what it is
116
        }
117
118
        $dbColumnTypes = $this->getDbColumnTypes();
119
120
        if (! isset($dbColumnTypes[$fieldName])) {
121
            return 'text';
122
        }
123
124
        switch ($dbColumnTypes[$fieldName]['type']) {
125
            case 'int':
126
            case 'integer':
127
            case 'smallint':
128
            case 'mediumint':
129
            case 'longint':
130
                return 'number';
131
132
            case 'string':
133
            case 'varchar':
134
            case 'set':
135
                return 'text';
136
137
                // case 'enum':
138
            //     return 'enum';
139
                // break;
140
141
            case 'boolean':
142
            case 'tinyint':
143
                return 'boolean';
144
145
            case 'text':
146
            case 'mediumtext':
147
            case 'longtext':
148
                return 'textarea';
149
150
            case 'date':
151
                return 'date';
152
153
            case 'datetime':
154
            case 'timestamp':
155
                return 'datetime';
156
157
            case 'time':
158
                return 'time';
159
160
            case 'json':
161
                return backpack_pro() ? 'table' : 'textarea';
162
163
            default:
164
                return 'text';
165
        }
166
167
        return 'text';
0 ignored issues
show
Unused Code introduced by
return 'text' is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
168
    }
169
170
    /**
171
     * Turn a database column name or PHP variable into a pretty label to be shown to the user.
172
     *
173
     * @param  string  $value  The value.
174
     * @return string The transformed value.
175
     */
176
    public function makeLabel($value)
177
    {
178
        if (isset($this->autoset['labeller']) && is_callable($this->autoset['labeller'])) {
179
            return ($this->autoset['labeller'])($value);
180
        }
181
182
        return trim(mb_ucfirst(str_replace('_', ' ', preg_replace('/(_id|_at|\[\])$/i', '', $value))));
183
    }
184
185
    /**
186
     * Alias to the makeLabel method.
187
     */
188
    public function getLabel($value)
189
    {
190
        return $this->makeLabel($value);
191
    }
192
193
    /**
194
     * Change the way labels are made.
195
     *
196
     * @param  callable  $labeller  A function that receives a string and returns the formatted string, after stripping down useless characters.
197
     * @return self
198
     */
199
    public function setLabeller(callable $labeller)
200
    {
201
        $this->autoset['labeller'] = $labeller;
202
203
        return $this;
204
    }
205
206
    /**
207
     * Get the database column names, in order to figure out what fields/columns to show in the auto-fields-and-columns functionality.
208
     *
209
     * @return array Database column names as an array.
210
     */
211
    public function getDbColumnsNames()
212
    {
213
        $fillable = $this->model->getFillable();
214
215
        if (! $this->driverIsSql()) {
216
            $columns = $fillable;
217
        } else {
218
            // Automatically-set columns should be both in the database, and in the $fillable variable on the Eloquent Model
219
            $columns = $this->model::getDbTableSchema()->getColumnsNames();
220
            if (! empty($fillable)) {
221
                $columns = array_intersect($columns, $fillable);
222
            }
223
        }
224
225
        // but not updated_at, deleted_at
226
        return array_values(array_diff($columns, [$this->model->getKeyName(), $this->model->getCreatedAtColumn(), $this->model->getUpdatedAtColumn(), 'deleted_at']));
227
    }
228
}
229