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 (#3410)
by Cristian
12:28
created

Update::getUpdateFields()   B

Complexity

Conditions 7
Paths 20

Size

Total Lines 29
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 16
nc 20
nop 1
dl 0
loc 29
rs 8.8333
c 0
b 0
f 0
1
<?php
2
3
namespace Backpack\CRUD\app\Library\CrudPanel\Traits;
4
5
use Illuminate\Support\Arr;
6
7
trait Update
8
{
9
    /*
10
    |--------------------------------------------------------------------------
11
    |                                   UPDATE
12
    |--------------------------------------------------------------------------
13
    */
14
15
    /**
16
     * Update a row in the database.
17
     *
18
     * @param int   $id   The entity's id
19
     * @param array $data All inputs to be updated.
20
     *
21
     * @return object
22
     */
23
    public function update($id, $data)
24
    {
25
        $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

25
        /** @scrutinizer ignore-call */ 
26
        $data = $this->decodeJsonCastedAttributes($data);
Loading history...
26
        $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

26
        /** @scrutinizer ignore-call */ 
27
        $data = $this->compactFakeFields($data);
Loading history...
27
        $item = $this->model->findOrFail($id);
28
29
        // omit the n-n relationships when updating the eloquent item
30
        $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

30
        $nn_relationships = Arr::pluck($this->/** @scrutinizer ignore-call */ getRelationFieldsWithPivot(), 'name');
Loading history...
31
32
        // handle BelongsTo 1:1 relations
33
        $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

33
        /** @scrutinizer ignore-call */ 
34
        $item = $this->associateOrDissociateBelongsToRelations($item, $data);
Loading history...
34
35
        $item->fill(Arr::except($data, $nn_relationships));
36
        $item->save();
37
38
        $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

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

52
        /** @scrutinizer ignore-call */ 
53
        $fields = $this->fields();
Loading history...
53
        $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

53
        $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

53
        $entry = ($id != false) ? $this->getEntry($id) : $this->/** @scrutinizer ignore-call */ getCurrentEntry();
Loading history...
54
55
        foreach ($fields as &$field) {
56
            // set the value
57
            if (! isset($field['value'])) {
58
                if (isset($field['subfields'])) {
59
                    $field['value'] = [];
60
                    foreach ($field['subfields'] as $subfield) {
61
                        $field['value'][] = $entry->{$subfield['name']};
62
                    }
63
                } else {
64
                    $field['value'] = $this->getModelAttributeValue($entry, $field);
65
                }
66
            }
67
        }
68
69
        // always have a hidden input for the entry id
70
        if (! array_key_exists('id', $fields)) {
71
            $fields['id'] = [
72
                'name'  => $entry->getKeyName(),
73
                'value' => $entry->getKey(),
74
                'type'  => 'hidden',
75
            ];
76
        }
77
78
        return $fields;
79
    }
80
81
    /**
82
     * Get the value of the 'name' attribute from the declared relation model in the given field.
83
     *
84
     * @param \Illuminate\Database\Eloquent\Model $model The current CRUD model.
85
     * @param array                               $field The CRUD field array.
86
     *
87
     * @return mixed The value of the 'name' attribute from the relation model.
88
     */
89
    private function getModelAttributeValue($model, $field)
90
    {
91
        if (isset($field['entity']) && $field['entity'] !== false) {
92
            $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

92
            $relational_entity = $this->/** @scrutinizer ignore-call */ parseRelationFieldNamesFromHtml([$field])[0]['name'];
Loading history...
93
94
            $relation_array = explode('.', $relational_entity);
95
96
            $relatedModel = array_reduce(array_splice($relation_array, 0, -1), function ($obj, $method) {
97
                return $obj->{$method} ? $obj->{$method} : $obj;
98
            }, $model);
99
100
            $relationMethod = Arr::last($relation_array);
101
            if (method_exists($relatedModel, $relationMethod)) {
102
                $relation = $relatedModel->{$relationMethod}();
103
                $relation_type = (new \ReflectionClass($relation))->getShortName();
104
105
                switch ($relation_type) {
106
                    case 'HasOne':
107
                    case 'MorphOne':
108
                        return $relatedModel->{$relationMethod}->{Arr::last(explode('.', $relational_entity))};
109
                    break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
110
                    case 'HasMany':
111
                    case 'MorphMany':
112
                        if (isset($field['pivotFields']) && is_array($field['pivotFields'])) {
113
                            $pivot_fields = Arr::where($field['pivotFields'], function ($item) use ($field) {
114
                                return $field['name'] != $item['name'];
115
                            });
116
                            $related_models = $relatedModel->{$relationMethod};
117
                            $return = [];
118
119
                            // for any given model, we grab the attributes that belong to our pivot table.
120
                            foreach ($related_models as $related_model) {
121
                                $item = [];
122
                                //for any given related model, we attach the pivot fields.
123
                                foreach ($pivot_fields as $pivot_field) {
124
                                    $item[$pivot_field['name']] = $related_model->{$pivot_field['name']};
125
                                }
126
                                $item[$related_model->getKeyName()] = $related_model->getKey();
127
                                $return[] = $item;
128
                            }
129
                            // we return the json encoded result as expected by repeatable field.
130
                            return json_encode($return);
131
                        }
132
                    break;
133
                    case 'BelongsToMany':
134
                    case 'MorphToMany':
135
                        // if pivot is true and there are `pivotFields` we need to get those pivot values to show on the edit page
136
                        if (isset($field['pivot']) && $field['pivot'] && isset($field['pivotFields']) && is_array($field['pivotFields'])) {
137
138
                            // we remove our current relation from the pivotFields.
139
                            $pivot_fields = Arr::where($field['pivotFields'], function ($item) use ($field) {
140
                                return $field['name'] != $item['name'];
141
                            });
142
143
                            $related_models = $relatedModel->{$relationMethod};
144
                            $return = [];
145
146
                            // for any given model, we grab the attributes that belong to our pivot table.
147
                            foreach ($related_models as $related_model) {
148
                                $item = [];
149
                                $item[$field['name']] = $related_model->getKey();
150
                                //for any given related model, we attach the pivot fields.
151
                                foreach ($pivot_fields as $pivot_field) {
152
                                    $item[$pivot_field['name']] = $related_model->pivot->{$pivot_field['name']};
153
                                }
154
                                $return[] = $item;
155
                            }
156
157
                            // we return the json encoded result as expected by repeatable field.
158
                            return json_encode($return);
159
                        }
160
                    break;
161
                }
162
            }
163
164
            return $relatedModel->{$relationMethod};
165
        }
166
167
        if (is_string($field['name'])) {
168
            return $model->{$field['name']};
169
        }
170
171
        if (is_array($field['name'])) {
172
            $result = [];
173
            foreach ($field['name'] as $key => $value) {
174
                $result = $model->{$value};
175
            }
176
177
            return $result;
178
        }
179
    }
180
}
181