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
25:11 queued 09:27
created

Relationships::isNestedRelation()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 7
rs 10
c 1
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);
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

18
        /** @scrutinizer ignore-call */ 
19
        $entity = $this->getOnlyRelationEntity($field);
Loading history...
19
        $entity_array = explode('.', $entity);
20
        $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

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

59
        return collect($this->/** @scrutinizer ignore-call */ fields())
Loading history...
60
            ->where('model')
61
            ->whereIn('relation_type', $relation_types)
62
            ->filter(function ($item) {
63
                return Str::contains($item['entity'], '.') ? false : true;
64
            })
65
            ->toArray();
66
    }
67
68
    /**
69
     * Grabs an relation instance and returns the class name of the related model.
70
     *
71
     * @param array $field
72
     * @return string
73
     */
74
    public function inferFieldModelFromRelationship($field)
75
    {
76
        $relation = $this->getRelationInstance($field);
77
78
        return get_class($relation->getRelated());
79
    }
80
81
    /**
82
     * Return the relation type from a given field: BelongsTo, HasOne ... etc.
83
     *
84
     * @param array $field
85
     * @return string
86
     */
87
    public function inferRelationTypeFromRelationship($field)
88
    {
89
        $relation = $this->getRelationInstance($field);
90
91
        return Arr::last(explode('\\', get_class($relation)));
92
    }
93
94
    /**
95
     * Parse the field name back to the related entity after the form is submited.
96
     * Its called in getAllFieldNames().
97
     *
98
     * @param array $fields
99
     * @return array
100
     */
101
    public function parseRelationFieldNamesFromHtml($fields)
102
    {
103
        foreach ($fields as &$field) {
104
            //we only want to parse fields that has a relation type and their name contains [ ] used in html.
105
            if (isset($field['relation_type']) && preg_match('/[\[\]]/', $field['name']) !== 0) {
106
                $chunks = explode('[', $field['name']);
107
108
                foreach ($chunks as &$chunk) {
109
                    if (strpos($chunk, ']')) {
110
                        $chunk = str_replace(']', '', $chunk);
111
                    }
112
                }
113
                $field['name'] = implode('.', $chunks);
114
            }
115
        }
116
117
        return $fields;
118
    }
119
120
    /**
121
     * Based on relation type returns the default field type.
122
     *
123
     * @param string $relation_type
124
     * @return bool
125
     */
126
    public function inferFieldTypeFromFieldRelation($field)
127
    {
128
        switch ($field['relation_type']) {
129
            case 'BelongsToMany':
130
            case 'HasMany':
131
            case 'HasManyThrough':
132
            case 'MorphMany':
133
            case 'MorphToMany':
134
            case 'BelongsTo':
135
                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...
136
137
            default:
138
                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...
139
        }
140
    }
141
142
    /**
143
     * Based on relation type returns if relation allows multiple entities.
144
     *
145
     * @param string $relation_type
146
     * @return bool
147
     */
148
    public function guessIfFieldHasMultipleFromRelationType($relation_type)
149
    {
150
        switch ($relation_type) {
151
            case 'BelongsToMany':
152
            case 'HasMany':
153
            case 'HasManyThrough':
154
            case 'HasOneOrMany':
155
            case 'MorphMany':
156
            case 'MorphOneOrMany':
157
            case 'MorphToMany':
158
                return true;
159
160
            default:
161
                return false;
162
        }
163
    }
164
165
    /**
166
     * Based on relation type returns if relation has a pivot table.
167
     *
168
     * @param string $relation_type
169
     * @return bool
170
     */
171
    public function guessIfFieldHasPivotFromRelationType($relation_type)
172
    {
173
        switch ($relation_type) {
174
            case 'BelongsToMany':
175
            case 'HasManyThrough':
176
            case 'MorphMany':
177
            case 'MorphOneOrMany':
178
            case 'MorphToMany':
179
                return true;
180
            default:
181
                return false;
182
        }
183
    }
184
185
    /**
186
     * Check if field name contains a dot, if so, meaning it's a nested relation.
187
     *
188
     * @param array $field
189
     * @return bool
190
     */
191
    protected function isNestedRelation($field): bool
192
    {
193
        if (strpos($field['entity'], '.') !== false) {
194
            return true;
195
        }
196
197
        return false;
198
    }
199
200
    /**
201
     * Associate and dissociate BelongsTo relations in the model.
202
     *
203
     * @param  Model
204
     * @param  array The form data.
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...
205
     * @return Model Model with relationships set up.
0 ignored issues
show
Bug introduced by
The type Backpack\CRUD\app\Library\CrudPanel\Traits\Model 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...
206
     */
207
    public function associateBelongsToRelations($item, array $data)
208
    {
209
        $belongsToFields = $this->getFieldsWithRelationType('BelongsTo');
210
211
        foreach ($belongsToFields as $relationField) {
212
            if (method_exists($item, $this->getOnlyRelationEntity($relationField))) {
213
                $relatedId = Arr::get($data, $relationField['name']);
214
                $related = $relationField['model']::find($relatedId);
215
216
                $item->{$this->getOnlyRelationEntity($relationField)}()->associate($related);
217
            }
218
        }
219
220
        return $item;
221
    }
222
}
223