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 (#3981)
by Cristian
12:34
created

guessIfFieldHasMultipleFromRelationType()   B

Complexity

Conditions 8
Paths 8

Size

Total Lines 14
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 11
nc 8
nop 1
dl 0
loc 14
rs 8.4444
c 0
b 0
f 0
1
<?php
2
3
namespace Backpack\CRUD\app\Library\CrudPanel\Traits;
4
5
use Illuminate\Support\Arr;
6
use Illuminate\Support\Str;
7
8
trait Relationships
9
{
10
    /**
11
     * From the field entity we get the relation instance.
12
     *
13
     * @param  array  $entity
14
     * @return object
15
     */
16
    public function getRelationInstance($field)
17
    {
18
        $entity = $this->getOnlyRelationEntity($field);
19
        $possible_method = Str::before($entity, '.');
20
        $model = $this->model;
21
22
        if (method_exists($model, $possible_method)) {
23
            $parts = explode('.', $entity);
24
            // here we are going to iterate through all relation parts to check
25
            foreach ($parts as $i => $part) {
26
                $relation = $model->$part();
27
                $model = $relation->getRelated();
28
            }
29
30
            return $relation;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $relation seems to be defined by a foreach iteration on line 25. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
31
        }
32
    }
33
34
    /**
35
     * Grabs an relation instance and returns the class name of the related model.
36
     *
37
     * @param  array  $field
38
     * @return string
39
     */
40
    public function inferFieldModelFromRelationship($field)
41
    {
42
        $relation = $this->getRelationInstance($field);
43
44
        return get_class($relation->getRelated());
45
    }
46
47
    /**
48
     * Return the relation type from a given field: BelongsTo, HasOne ... etc.
49
     *
50
     * @param  array  $field
51
     * @return string
52
     */
53
    public function inferRelationTypeFromRelationship($field)
54
    {
55
        $relation = $this->getRelationInstance($field);
56
57
        return Arr::last(explode('\\', get_class($relation)));
58
    }
59
60
    public function getOnlyRelationEntity($relation_field)
61
    {
62
        $relation_model = $this->getRelationModel($relation_field['entity'], -1);
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

62
        /** @scrutinizer ignore-call */ 
63
        $relation_model = $this->getRelationModel($relation_field['entity'], -1);

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...
63
        $related_method = Str::afterLast($relation_field['entity'], '.');
64
65
        if (! method_exists($relation_model, $related_method)) {
66
            return Str::beforeLast($relation_field['entity'], '.');
67
        }
68
69
        return $relation_field['entity'];
70
    }
71
72
    /**
73
     * Get the fields for relationships, according to the relation type. It looks only for direct
74
     * relations - it will NOT look through relationships of relationships.
75
     *
76
     * @param  string|array  $relation_types  Eloquent relation class or array of Eloquent relation classes. Eg: BelongsTo
77
     * @return array The fields with corresponding relation types.
78
     */
79
    public function getFieldsWithRelationType($relation_types): array
80
    {
81
        $relation_types = (array) $relation_types;
82
83
        return collect($this->fields())
0 ignored issues
show
Bug introduced by
The method fields() does not exist on Backpack\CRUD\app\Librar...el\Traits\Relationships. Did you maybe mean fieldsWithOverwrittenNamesForHtml()? ( Ignorable by Annotation )

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

83
        return collect($this->/** @scrutinizer ignore-call */ fields())

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...
84
            ->where('model')
85
            ->whereIn('relation_type', $relation_types)
86
            ->filter(function ($item) {
87
                $related_model = get_class($this->model->{Str::before($item['entity'], '.')}()->getRelated());
88
89
                return Str::contains($item['entity'], '.') && $item['model'] !== $related_model ? false : true;
90
            })
91
            ->toArray();
92
    }
93
94
    protected function changeBelongsToNamesFromRelationshipToForeignKey($data)
95
    {
96
        $belongs_to_fields = $this->getFieldsWithRelationType('BelongsTo');
97
98
        foreach ($belongs_to_fields as $relation_field) {
99
            $relation = $this->getRelationInstance($relation_field);
100
            if (Arr::has($data, $relation->getRelationName())) {
101
                $data[$relation->getForeignKeyName()] = Arr::get($data, $relation->getRelationName());
102
                unset($data[$relation->getRelationName()]);
103
            }
104
        }
105
106
        return $data;
107
    }
108
109
    /**
110
     * Get the CRUD fields for the current operation, but with
111
     * their names ready to be used inside inputs. For example
112
     * 'relationship.attribute' => 'relationship[attribute]'.
113
     *
114
     * @return array
115
     */
116
    public function fieldsWithOverwrittenNamesForHtml($fields = null)
117
    {
118
        $fields = $fields ?? $this->fields();
119
120
        foreach ($fields as $key => $field) {
121
            $fields[$key] = $this->overwriteFieldNameFromDotNotationToArray($field);
0 ignored issues
show
Bug introduced by
It seems like overwriteFieldNameFromDotNotationToArray() 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

121
            /** @scrutinizer ignore-call */ 
122
            $fields[$key] = $this->overwriteFieldNameFromDotNotationToArray($field);
Loading history...
122
        }
123
124
        return $fields;
125
    }
126
127
    /**
128
     * Based on relation type returns the default field type.
129
     *
130
     * @param  string  $relation_type
131
     * @return bool
132
     */
133
    public function inferFieldTypeFromFieldRelation($field)
134
    {
135
        switch ($field['relation_type']) {
136
            case 'BelongsToMany':
137
            case 'HasMany':
138
            case 'HasManyThrough':
139
            case 'MorphMany':
140
            case 'MorphToMany':
141
            case 'BelongsTo':
142
                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...
143
144
            default:
145
                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...
146
        }
147
    }
148
149
    /**
150
     * Based on relation type returns if relation allows multiple entities.
151
     *
152
     * @param  string  $relation_type
153
     * @return bool
154
     */
155
    public function guessIfFieldHasMultipleFromRelationType($relation_type)
156
    {
157
        switch ($relation_type) {
158
            case 'BelongsToMany':
159
            case 'HasMany':
160
            case 'HasManyThrough':
161
            case 'HasOneOrMany':
162
            case 'MorphMany':
163
            case 'MorphOneOrMany':
164
            case 'MorphToMany':
165
                return true;
166
167
            default:
168
                return false;
169
        }
170
    }
171
172
    /**
173
     * Based on relation type returns if relation has a pivot table.
174
     *
175
     * @param  string  $relation_type
176
     * @return bool
177
     */
178
    public function guessIfFieldHasPivotFromRelationType($relation_type)
179
    {
180
        switch ($relation_type) {
181
            case 'BelongsToMany':
182
            case 'HasManyThrough':
183
            case 'MorphMany':
184
            case 'MorphOneOrMany':
185
            case 'MorphToMany':
186
                return true;
187
            default:
188
                return false;
189
        }
190
    }
191
}
192