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 (#3250)
by
unknown
22:17
created

Relationships::getFieldsWithRelationType()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 10
nc 3
nop 1
dl 0
loc 13
rs 9.9332
c 0
b 0
f 0
1
<?php
2
3
namespace Backpack\CRUD\app\Library\CrudPanel\Traits;
4
5
use Illuminate\Support\Arr;
6
7
trait Relationships
8
{
9
    /**
10
     * From the field entity we get the relation instance.
11
     *
12
     * @param array $entity
13
     * @return void
14
     */
15
    public function getRelationInstance($field)
16
    {
17
        $entity = $this->getOnlyRelationEntity($field);
0 ignored issues
show
Bug introduced by
It seems like getOnlyRelationEntity() 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

17
        /** @scrutinizer ignore-call */ 
18
        $entity = $this->getOnlyRelationEntity($field);
Loading history...
18
        $entity_array = explode('.', $entity);
19
        $relation_model = $this->getRelationModel($entity);
0 ignored issues
show
Bug introduced by
The method getRelationModel() does not exist on Backpack\CRUD\app\Librar...el\Traits\Relationships. Did you maybe mean getRelationInstance()? ( Ignorable by Annotation )

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

19
        /** @scrutinizer ignore-call */ 
20
        $relation_model = $this->getRelationModel($entity);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
20
21
        $related_method = Arr::last($entity_array);
22
        if (count(explode('.', $entity)) == count(explode('.', $field['entity']))) {
23
            $relation_model = $this->getRelationModel($entity, -1);
24
        }
25
        $relation_model = new $relation_model();
26
27
        //if counts are diferent means that last element of entity is the field in relation.
28
        if (count(explode('.', $entity)) != count(explode('.', $field['entity']))) {
29
            if (in_array($related_method, $relation_model->getFillable())) {
30
                if (count($entity_array) > 1) {
31
                    $related_method = $entity_array[(count($entity_array) - 2)];
32
                    $relation_model = $this->getRelationModel($entity, -2);
33
                } else {
34
                    $relation_model = $this->model;
35
                }
36
            }
37
        }
38
        if (count($entity_array) == 1) {
39
            if (method_exists($this->model, $related_method)) {
40
                return $this->model->{$related_method}();
41
            }
42
        }
43
44
        return $relation_model->{$related_method}();
45
    }
46
47
    /**
48
     * Get the fields with specific relation types.
49
     *
50
     * @param string|array $relation_types
51
     *
52
     * @return array The fields with corresponding relation types.
53
     */
54
    public function getFieldsWithRelationType($relation_types): array
55
    {
56
        if (is_string($relation_types)) {
57
            return collect($this->fields())
0 ignored issues
show
Bug introduced by
It seems like fields() 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

57
            return collect($this->/** @scrutinizer ignore-call */ fields())
Loading history...
58
            ->where('model')
59
            ->where('relation_type', $relation_types)
60
            ->toArray();
61
        }
62
        if (is_array($relation_types)) {
0 ignored issues
show
introduced by
The condition is_array($relation_types) is always true.
Loading history...
63
            return collect($this->fields())
64
            ->where('model')
65
            ->whereIn('relation_type', $relation_types)
66
            ->toArray();
67
        }
0 ignored issues
show
Bug Best Practice introduced by
The function implicitly returns null when the if condition on line 62 is false. This is incompatible with the type-hinted return array. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
68
    }
69
70
    /**
71
     * Grabs an relation instance and returns the class name of the related model.
72
     *
73
     * @param array $field
74
     * @return string
75
     */
76
    public function inferFieldModelFromRelationship($field)
77
    {
78
        $relation = $this->getRelationInstance($field);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $relation is correct as $this->getRelationInstance($field) targeting Backpack\CRUD\app\Librar...::getRelationInstance() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

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

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

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

Loading history...
79
80
        return get_class($relation->getRelated());
81
    }
82
83
    /**
84
     * Return the relation type from a given field: BelongsTo, HasOne ... etc.
85
     *
86
     * @param array $field
87
     * @return string
88
     */
89
    public function inferRelationTypeFromRelationship($field)
90
    {
91
        $relation = $this->getRelationInstance($field);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $relation is correct as $this->getRelationInstance($field) targeting Backpack\CRUD\app\Librar...::getRelationInstance() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

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

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

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

Loading history...
92
93
        return Arr::last(explode('\\', get_class($relation)));
0 ignored issues
show
Bug introduced by
$relation of type void is incompatible with the type object expected by parameter $object of get_class(). ( Ignorable by Annotation )

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

93
        return Arr::last(explode('\\', get_class(/** @scrutinizer ignore-type */ $relation)));
Loading history...
94
    }
95
96
    /**
97
     * Parse the field name back to the related entity after the form is submited.
98
     * Its called in getAllFieldNames().
99
     *
100
     * @param array $fields
101
     * @return array
102
     */
103
    public function parseRelationFieldNamesFromHtml($fields)
104
    {
105
        foreach ($fields as &$field) {
106
            //we only want to parse fields that has a relation type and their name contains [ ] used in html.
107
            if (isset($field['relation_type']) && preg_match('/[\[\]]/', $field['name']) !== 0) {
108
                $chunks = explode('[', $field['name']);
109
110
                foreach ($chunks as &$chunk) {
111
                    if (strpos($chunk, ']')) {
112
                        $chunk = str_replace(']', '', $chunk);
113
                    }
114
                }
115
                $field['name'] = implode('.', $chunks);
116
            }
117
        }
118
119
        return $fields;
120
    }
121
122
    /**
123
     * Based on relation type returns the default field type.
124
     *
125
     * @param string $relation_type
126
     * @return bool
127
     */
128
    public function inferFieldTypeFromFieldRelation($field)
129
    {
130
        switch ($field['relation_type']) {
131
            case 'BelongsToMany':
132
            case 'HasMany':
133
            case 'HasManyThrough':
134
            case 'MorphMany':
135
            case 'MorphToMany':
136
            case 'BelongsTo':
137
                return 'relationship';
0 ignored issues
show
Bug Best Practice introduced by
The expression return 'relationship' returns the type string which is incompatible with the documented return type boolean.
Loading history...
138
139
            default:
140
                return 'text';
0 ignored issues
show
Bug Best Practice introduced by
The expression return 'text' returns the type string which is incompatible with the documented return type boolean.
Loading history...
141
        }
142
    }
143
144
    /**
145
     * Based on relation type returns if relation allows multiple entities.
146
     *
147
     * @param string $relation_type
148
     * @return bool
149
     */
150
    public function guessIfFieldHasMultipleFromRelationType($relation_type)
151
    {
152
        switch ($relation_type) {
153
            case 'BelongsToMany':
154
            case 'HasMany':
155
            case 'HasManyThrough':
156
            case 'HasOneOrMany':
157
            case 'MorphMany':
158
            case 'MorphOneOrMany':
159
            case 'MorphToMany':
160
                return true;
161
162
            default:
163
                return false;
164
        }
165
    }
166
167
    /**
168
     * Based on relation type returns if relation has a pivot table.
169
     *
170
     * @param string $relation_type
171
     * @return bool
172
     */
173
    public function guessIfFieldHasPivotFromRelationType($relation_type)
174
    {
175
        switch ($relation_type) {
176
            case 'BelongsToMany':
177
            case 'HasManyThrough':
178
            case 'MorphMany':
179
            case 'MorphOneOrMany':
180
            case 'MorphToMany':
181
                return true;
182
            default:
183
                return false;
184
        }
185
    }
186
}
187