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

Relationships::parseRelationFieldNamesFromHtml()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 17
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 8
nc 5
nop 1
dl 0
loc 17
rs 9.2222
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
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

83
        return collect($this->/** @scrutinizer ignore-call */ fields())
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
     * Based on relation type returns the default field type.
111
     *
112
     * @param  string  $relation_type
113
     * @return bool
114
     */
115
    public function inferFieldTypeFromFieldRelation($field)
116
    {
117
        switch ($field['relation_type']) {
118
            case 'BelongsToMany':
119
            case 'HasMany':
120
            case 'HasManyThrough':
121
            case 'MorphMany':
122
            case 'MorphToMany':
123
            case 'BelongsTo':
124
                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...
125
126
            default:
127
                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...
128
        }
129
    }
130
131
    /**
132
     * Based on relation type returns if relation allows multiple entities.
133
     *
134
     * @param  string  $relation_type
135
     * @return bool
136
     */
137
    public function guessIfFieldHasMultipleFromRelationType($relation_type)
138
    {
139
        switch ($relation_type) {
140
            case 'BelongsToMany':
141
            case 'HasMany':
142
            case 'HasManyThrough':
143
            case 'HasOneOrMany':
144
            case 'MorphMany':
145
            case 'MorphOneOrMany':
146
            case 'MorphToMany':
147
                return true;
148
149
            default:
150
                return false;
151
        }
152
    }
153
154
    /**
155
     * Based on relation type returns if relation has a pivot table.
156
     *
157
     * @param  string  $relation_type
158
     * @return bool
159
     */
160
    public function guessIfFieldHasPivotFromRelationType($relation_type)
161
    {
162
        switch ($relation_type) {
163
            case 'BelongsToMany':
164
            case 'HasManyThrough':
165
            case 'MorphMany':
166
            case 'MorphOneOrMany':
167
            case 'MorphToMany':
168
                return true;
169
            default:
170
                return false;
171
        }
172
    }
173
}
174