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

Passed
Pull Request — master (#3654)
by
unknown
13:52
created

changeBelongsToNamesFromRelationshipToForeignKey()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 3
eloc 7
c 2
b 1
f 0
nc 3
nop 1
dl 0
loc 13
rs 10
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
     *
78
     * @return array The fields with corresponding relation types.
79
     */
80
    public function getFieldsWithRelationType($relation_types): array
81
    {
82
        $relation_types = (array) $relation_types;
83
84
        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

84
        return collect($this->/** @scrutinizer ignore-call */ fields())
Loading history...
85
            ->where('model')
86
            ->whereIn('relation_type', $relation_types)
87
            ->filter(function ($item) {
88
                $related_model = get_class($this->model->{Str::before($item['entity'], '.')}()->getRelated());
89
90
                return Str::contains($item['entity'], '.') && $item['model'] !== $related_model ? false : true;
91
            })
92
            ->toArray();
93
    }
94
95
    /**
96
     * Parse the field name back to the related entity after the form is submited.
97
     * Its called in getAllFieldNames().
98
     *
99
     * @param array $fields
100
     * @return array
101
     */
102
    public function parseRelationFieldNamesFromHtml($fields)
103
    {
104
        foreach ($fields as &$field) {
105
            //we only want to parse fields that has a relation type and their name contains [ ] used in html.
106
            if (isset($field['relation_type']) && preg_match('/[\[\]]/', $field['name']) !== 0) {
107
                $chunks = explode('[', $field['name']);
108
109
                foreach ($chunks as &$chunk) {
110
                    if (strpos($chunk, ']')) {
111
                        $chunk = str_replace(']', '', $chunk);
112
                    }
113
                }
114
                $field['name'] = implode('.', $chunks);
115
            }
116
        }
117
118
        return $fields;
119
    }
120
121
    protected function changeBelongsToNamesFromRelationshipToForeignKey($data)
122
    {
123
        $belongs_to_fields = $this->getFieldsWithRelationType('BelongsTo');
124
125
        foreach ($belongs_to_fields as $relation_field) {
126
            $relation = $this->getRelationInstance($relation_field);
127
            if (Arr::has($data, $relation->getRelationName())) {
128
                $data[$relation->getForeignKeyName()] = Arr::get($data, $relation->getRelationName());
129
                unset($data[$relation->getRelationName()]);
130
            }
131
        }
132
133
        return $data;
134
    }
135
136
    /**
137
     * Based on relation type returns the default field type.
138
     *
139
     * @param string $relation_type
140
     * @return bool
141
     */
142
    public function inferFieldTypeFromFieldRelation($field)
143
    {
144
        switch ($field['relation_type']) {
145
            case 'BelongsToMany':
146
            case 'HasMany':
147
            case 'HasManyThrough':
148
            case 'MorphMany':
149
            case 'MorphToMany':
150
            case 'BelongsTo':
151
                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...
152
153
            default:
154
                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...
155
        }
156
    }
157
158
    /**
159
     * Based on relation type returns if relation allows multiple entities.
160
     *
161
     * @param string $relation_type
162
     * @return bool
163
     */
164
    public function guessIfFieldHasMultipleFromRelationType($relation_type)
165
    {
166
        switch ($relation_type) {
167
            case 'BelongsToMany':
168
            case 'HasMany':
169
            case 'HasManyThrough':
170
            case 'HasOneOrMany':
171
            case 'MorphMany':
172
            case 'MorphOneOrMany':
173
            case 'MorphToMany':
174
                return true;
175
176
            default:
177
                return false;
178
        }
179
    }
180
181
    /**
182
     * Based on relation type returns if relation has a pivot table.
183
     *
184
     * @param string $relation_type
185
     * @return bool
186
     */
187
    public function guessIfFieldHasPivotFromRelationType($relation_type)
188
    {
189
        switch ($relation_type) {
190
            case 'BelongsToMany':
191
            case 'HasManyThrough':
192
            case 'MorphMany':
193
            case 'MorphOneOrMany':
194
            case 'MorphToMany':
195
                return true;
196
            default:
197
                return false;
198
        }
199
    }
200
}
201