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 (#3981)
by
unknown
21:29 queued 06:17
created

changeBelongsToNamesFromRelationshipToForeignKey()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 2 Features 0
Metric Value
cc 3
eloc 7
c 4
b 2
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
     * @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