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 (#3410)
by
unknown
13:32
created

Update::getModelAttributeValue()   C

Complexity

Conditions 16
Paths 16

Size

Total Lines 56
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 2 Features 0
Metric Value
cc 16
eloc 34
c 4
b 2
f 0
nc 16
nop 2
dl 0
loc 56
rs 5.5666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Backpack\CRUD\app\Library\CrudPanel\Traits;
4
5
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
6
use Illuminate\Database\Eloquent\Relations\HasMany;
7
use Illuminate\Database\Eloquent\Relations\HasOne;
8
use Illuminate\Database\Eloquent\Relations\MorphMany;
9
use Illuminate\Database\Eloquent\Relations\MorphOne;
10
use Illuminate\Database\Eloquent\Relations\MorphToMany;
11
use Illuminate\Support\Arr;
12
13
trait Update
14
{
15
    /*
16
    |--------------------------------------------------------------------------
17
    |                                   UPDATE
18
    |--------------------------------------------------------------------------
19
    */
20
21
    /**
22
     * Update a row in the database.
23
     *
24
     * @param int   $id   The entity's id
25
     * @param array $data All inputs to be updated.
26
     *
27
     * @return object
28
     */
29
    public function update($id, $data)
30
    {
31
        $data = $this->decodeJsonCastedAttributes($data);
0 ignored issues
show
Bug introduced by
It seems like decodeJsonCastedAttributes() 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

31
        /** @scrutinizer ignore-call */ 
32
        $data = $this->decodeJsonCastedAttributes($data);
Loading history...
32
        $data = $this->compactFakeFields($data);
0 ignored issues
show
Bug introduced by
It seems like compactFakeFields() 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

32
        /** @scrutinizer ignore-call */ 
33
        $data = $this->compactFakeFields($data);
Loading history...
33
        $item = $this->model->findOrFail($id);
34
35
        // omit the n-n relationships when updating the eloquent item
36
        $nn_relationships = Arr::pluck($this->getRelationFieldsWithPivot(), 'name');
0 ignored issues
show
Bug introduced by
It seems like getRelationFieldsWithPivot() 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

36
        $nn_relationships = Arr::pluck($this->/** @scrutinizer ignore-call */ getRelationFieldsWithPivot(), 'name');
Loading history...
37
38
        // handle BelongsTo 1:1 relations
39
        $item = $this->associateOrDissociateBelongsToRelations($item, $data);
0 ignored issues
show
Bug introduced by
It seems like associateOrDissociateBelongsToRelations() 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

39
        /** @scrutinizer ignore-call */ 
40
        $item = $this->associateOrDissociateBelongsToRelations($item, $data);
Loading history...
40
41
        $item->fill(Arr::except($data, $nn_relationships));
42
        $item->save();
43
44
        $this->createRelations($item, $data);
0 ignored issues
show
Bug introduced by
It seems like createRelations() 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

44
        $this->/** @scrutinizer ignore-call */ 
45
               createRelations($item, $data);
Loading history...
45
46
        return $item;
47
    }
48
49
    /**
50
     * Get all fields needed for the EDIT ENTRY form.
51
     *
52
     * @param int $id The id of the entry that is being edited.
53
     *
54
     * @return array The fields with attributes, fake attributes and values.
55
     */
56
    public function getUpdateFields($id = false)
57
    {
58
        $fields = $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

58
        /** @scrutinizer ignore-call */ 
59
        $fields = $this->fields();
Loading history...
59
        $entry = ($id != false) ? $this->getEntry($id) : $this->getCurrentEntry();
0 ignored issues
show
Bug introduced by
It seems like getEntry() 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
        $entry = ($id != false) ? $this->/** @scrutinizer ignore-call */ getEntry($id) : $this->getCurrentEntry();
Loading history...
Bug Best Practice introduced by
It seems like you are loosely comparing $id of type false|integer against false; this is ambiguous if the integer can be zero. Consider using a strict comparison !== instead.
Loading history...
Bug introduced by
It seems like getCurrentEntry() 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
        $entry = ($id != false) ? $this->getEntry($id) : $this->/** @scrutinizer ignore-call */ getCurrentEntry();
Loading history...
60
61
        foreach ($fields as &$field) {
62
            // set the value
63
            if (! isset($field['value'])) {
64
                if (isset($field['subfields'])) {
65
                    $field['value'] = [];
66
                    foreach ($field['subfields'] as $subfield) {
67
                        $field['value'][] = $entry->{$subfield['name']};
68
                    }
69
                } else {
70
                    $field['value'] = $this->getModelAttributeValue($entry, $field);
71
                }
72
            }
73
        }
74
75
        // always have a hidden input for the entry id
76
        if (! array_key_exists('id', $fields)) {
77
            $fields['id'] = [
78
                'name'  => $entry->getKeyName(),
79
                'value' => $entry->getKey(),
80
                'type'  => 'hidden',
81
            ];
82
        }
83
84
        return $fields;
85
    }
86
87
    /**
88
     * Get the value of the 'name' attribute from the declared relation model in the given field.
89
     *
90
     * @param \Illuminate\Database\Eloquent\Model $model The current CRUD model.
91
     * @param array                               $field The CRUD field array.
92
     *
93
     * @return mixed The value of the 'name' attribute from the relation model.
94
     */
95
    private function getModelAttributeValue($model, $field)
96
    {
97
        if (isset($field['entity']) && $field['entity'] !== false) {
98
            $relational_entity = $this->parseRelationFieldNamesFromHtml([$field])[0]['name'];
0 ignored issues
show
Bug introduced by
It seems like parseRelationFieldNamesFromHtml() 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

98
            $relational_entity = $this->/** @scrutinizer ignore-call */ parseRelationFieldNamesFromHtml([$field])[0]['name'];
Loading history...
99
100
            $relation_array = explode('.', $relational_entity);
101
102
            $relatedModel = array_reduce(array_splice($relation_array, 0, -1), function ($obj, $method) {
103
                return $obj->{$method} ? $obj->{$method} : $obj;
104
            }, $model);
105
106
            $relationMethod = Arr::last($relation_array);
107
            if (method_exists($relatedModel, $relationMethod)) {
108
                $relation = $relatedModel->{$relationMethod}();
109
                $relation_type = get_class($relation);
110
111
                switch ($relation_type) {
112
                    case HasOne::class:
113
                    case MorphOne::class:
114
                        return $relatedModel->{$relationMethod}->{Arr::last(explode('.', $relational_entity))};
115
116
                    case HasMany::class:
117
                    case MorphMany::class:
118
119
                        $attribute_value = $this->getManyRelationAttributeValue($relatedModel, $relationMethod, $field, $relation_type);
120
                        // we only want to return the json_encoded values here
121
                        if (is_string($attribute_value)) {
122
                            return $attribute_value;
123
                        }
124
125
                    break;
126
                    case BelongsToMany::class:
127
                    case MorphToMany::class:
128
                        $attribute_value = $this->getManyRelationAttributeValue($relatedModel, $relationMethod, $field, $relation_type);
129
                        // we only want to return the json_encoded values here
130
                        if (is_string($attribute_value)) {
131
                            return $attribute_value;
132
                        }
133
                    break;
134
                }
135
            }
136
137
            return $relatedModel->{$relationMethod};
138
        }
139
140
        if (is_string($field['name'])) {
141
            return $model->{$field['name']};
142
        }
143
144
        if (is_array($field['name'])) {
145
            $result = [];
146
            foreach ($field['name'] as $key => $value) {
147
                $result = $model->{$value};
148
            }
149
150
            return $result;
151
        }
152
    }
153
154
    /**
155
     * Returns the json encoded pivot fields from supported relations.
156
     *
157
     * @param \Illuminate\Database\Eloquent\Model $model
158
     * @param string $relation_method
159
     * @param array $field
160
     * @param string $relation_type
161
     * @return bool|string
162
     */
163
    private function getManyRelationAttributeValue($model, $relation_method, $field, $relation_type)
164
    {
165
        if (! isset($field['pivotFields']) || ! is_array($field['pivotFields'])) {
166
            return false;
167
        }
168
169
        $pivot_fields = Arr::where($field['pivotFields'], function ($item) use ($field) {
170
            return $field['name'] != $item['name'];
171
        });
172
        $related_models = $model->{$relation_method};
173
        $return = [];
174
        // for any given model, we grab the attributes that belong to our pivot table.
175
        foreach ($related_models as $related_model) {
176
            $item = [];
177
            switch ($relation_type) {
178
                case HasMany::class:
179
                case MorphMany::class:
180
                        // for any given related model, we get the value from pivot fields
181
                        foreach ($pivot_fields as $pivot_field) {
182
                            $item[$pivot_field['name']] = $related_model->{$pivot_field['name']};
183
                        }
184
                        $item[$related_model->getKeyName()] = $related_model->getKey();
185
                        $return[] = $item;
186
            break;
187
            case BelongsToMany::class:
188
            case MorphToMany::class:
189
190
                    $item[$field['name']] = $related_model->getKey();
191
                    //for any given related model, we get the pivot fields.
192
                    foreach ($pivot_fields as $pivot_field) {
193
                        $item[$pivot_field['name']] = $related_model->pivot->{$pivot_field['name']};
194
                    }
195
                    $return[] = $item;
196
            }
197
        }
198
        // we return the json encoded result as expected by repeatable field.
199
        return json_encode($return);
200
    }
201
}
202