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 Failed
Pull Request — master (#3401)
by Cristian
14:57
created

inferIdentifiableAttributeFromModelFillable()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
c 0
b 0
f 0
nc 3
nop 0
dl 0
loc 13
rs 10
1
<?php
2
3
namespace Backpack\CRUD\app\Models\Traits;
4
5
use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;
6
use Illuminate\Support\Arr;
7
8
trait HasIdentifiableAttribute
9
{
10
    /**
11
     * Get the name of the attribute that best defines the entry, from the user perspective.
12
     *
13
     * Rephrased: In most cases a user will NOT identify an Article because its ID is "4", but
14
     * because its name is "10 Ways to Burn Fat". This method returns the column in the database
15
     * that represents what is better to show to the user as an identifier rather than the ID.
16
     * Ex: name, title, label, description etc.
17
     *
18
     * @return string The name of the column that best defines this entry from the user perspective.
19
     */
20
    public function identifiableAttribute()
21
    {
22
        if (property_exists($this, 'identifiableAttribute')) {
23
            return $this->identifiableAttribute;
24
        }
25
26
        return static::guessIdentifiableColumnName();
27
    }
28
29
    /**
30
     * Get the most likely column in the db table that could be used as an identifiable attribute.
31
     *
32
     * @return string The name of the column in the database that is most likely to be a good indentifying attribute.
33
     */
34
    private static function guessIdentifiableColumnName()
35
    {
36
        $instance = new static();
37
38
        $conn = $instance->getConnectionWithExtraTypeMappings();
0 ignored issues
show
Bug introduced by
It seems like getConnectionWithExtraTypeMappings() 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

38
        /** @scrutinizer ignore-call */ 
39
        $conn = $instance->getConnectionWithExtraTypeMappings();
Loading history...
39
40
        // column listing is not available in non-sql databases. In this scenario we infer
41
        // the identifiable attribute from the model `fillable` attributes
42
        if (! in_array($conn->getConfig()['driver'], CRUD::getSqlDriverList())) {
0 ignored issues
show
Bug introduced by
The method getSqlDriverList() does not exist on Backpack\CRUD\app\Librar...udPanel\CrudPanelFacade. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

42
        if (! in_array($conn->getConfig()['driver'], CRUD::/** @scrutinizer ignore-call */ getSqlDriverList())) {
Loading history...
43
            return $instance->inferIdentifiableAttributeFromModelFillable();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $instance->inferI...buteFromModelFillable() returns the type void which is incompatible with the documented return type string.
Loading history...
Bug introduced by
Are you sure the usage of $instance->inferIdentifi...buteFromModelFillable() targeting Backpack\CRUD\app\Models...buteFromModelFillable() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
44
        }
45
46
        $table = $instance->getTableWithPrefix();
0 ignored issues
show
Bug introduced by
It seems like getTableWithPrefix() 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

46
        /** @scrutinizer ignore-call */ 
47
        $table = $instance->getTableWithPrefix();
Loading history...
47
        $columns = $conn->getDoctrineSchemaManager()->listTableColumns($table);
48
        $indexes = $conn->getDoctrineSchemaManager()->listTableIndexes($table);
49
        $columnsNames = array_keys($columns);
50
51
        // if any of the sensibleDefaultNames column exists
52
        // that's probably a good choice
53
        foreach ($instance->getSensibleDefaultNames() as $defaultName) {
54
            if (in_array($defaultName, $columnsNames)) {
55
                return $defaultName;
56
            }
57
        }
58
59
        // get indexed columns in database table
60
        $indexedColumns = [];
61
        foreach ($indexes as $index) {
62
            $indexColumns = $index->getColumns();
63
            foreach ($indexColumns as $ic) {
64
                array_push($indexedColumns, $ic);
65
            }
66
        }
67
68
        // if none of the sensible defaults exists
69
        // we get the first column from database
70
        // that is NOT indexed (usually primary, foreign keys)
71
        foreach ($columns as $columnName => $columnProperties) {
72
            if (! in_array($columnName, $indexedColumns)) {
73
74
                //check for convention "field<_id>" in case developer didn't add foreign key constraints.
75
                if (strpos($columnName, '_id') !== false) {
76
                    continue;
77
                }
78
79
                return $columnName;
80
            }
81
        }
82
83
        // in case everything fails we just return the first column in database
84
        return Arr::first($columnsNames);
85
    }
86
87
    /**
88
     * Infer the identifiable attribute from model fillable when getting the columns listing is not available.
89
     *
90
     * @return void
91
     */
92
    public function inferIdentifiableAttributeFromModelFillable()
93
    {
94
        $fillableFields = $this->getFillable();
0 ignored issues
show
Bug introduced by
It seems like getFillable() 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

94
        /** @scrutinizer ignore-call */ 
95
        $fillableFields = $this->getFillable();
Loading history...
95
        if (! empty($fillableFields)) {
96
            $matchedAttributeNames = array_intersect($this->getSensibleDefaultNames(), $fillableFields);
97
            if (! empty($matchedAttributeNames)) {
98
                return reset($matchedAttributeNames);
99
            }
100
101
            return reset($fillableFields);
102
        }
103
104
        abort(500, 'Impossible to determine the identifiable attribute. Add it manually to your model or in your field definition.');
105
    }
106
107
    /**
108
     * Returns a list of sensible default names to be shown to endusers.
109
     *
110
     * @return array
111
     */
112
    public function getSensibleDefaultNames()
113
    {
114
        return ['name', 'title', 'description', 'label'];
115
    }
116
}
117