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
unknown
19:56 queued 05:10
created

Update::update()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 1 Features 0
Metric Value
cc 1
eloc 9
nc 1
nop 2
dl 0
loc 18
rs 9.9666
c 4
b 1
f 0
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
                    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...
116
                    case HasMany::class:
117
                    case MorphMany::class:
118
                        if (isset($field['pivotFields']) && is_array($field['pivotFields'])) {
119
                            $pivot_fields = Arr::where($field['pivotFields'], function ($item) use ($field) {
120
                                return $field['name'] != $item['name'];
121
                            });
122
                            $related_models = $relatedModel->{$relationMethod};
123
                            $return = [];
124
125
                            // for any given model, we grab the attributes that belong to our pivot table.
126
                            foreach ($related_models as $related_model) {
127
                                $item = [];
128
                                //for any given related model, we attach the pivot fields.
129
                                foreach ($pivot_fields as $pivot_field) {
130
                                    $item[$pivot_field['name']] = $related_model->{$pivot_field['name']};
131
                                }
132
                                $item[$related_model->getKeyName()] = $related_model->getKey();
133
                                $return[] = $item;
134
                            }
135
                            // we return the json encoded result as expected by repeatable field.
136
                            return json_encode($return);
137
                        }
138
                    break;
139
                    case BelongsToMany::class:
140
                    case MorphToMany::class:
141
                        // if pivot is true and there are `pivotFields` we need to get those pivot values to show on the edit page
142
                        if (isset($field['pivot']) && $field['pivot'] && isset($field['pivotFields']) && is_array($field['pivotFields'])) {
143
144
                            // we remove our current relation from the pivotFields.
145
                            $pivot_fields = Arr::where($field['pivotFields'], function ($item) use ($field) {
146
                                return $field['name'] != $item['name'];
147
                            });
148
149
                            $related_models = $relatedModel->{$relationMethod};
150
                            $return = [];
151
152
                            // for any given model, we grab the attributes that belong to our pivot table.
153
                            foreach ($related_models as $related_model) {
154
                                $item = [];
155
                                $item[$field['name']] = $related_model->getKey();
156
                                //for any given related model, we attach the pivot fields.
157
                                foreach ($pivot_fields as $pivot_field) {
158
                                    $item[$pivot_field['name']] = $related_model->pivot->{$pivot_field['name']};
159
                                }
160
                                $return[] = $item;
161
                            }
162
163
                            // we return the json encoded result as expected by repeatable field.
164
                            return json_encode($return);
165
                        }
166
                    break;
167
                }
168
            }
169
170
            return $relatedModel->{$relationMethod};
171
        }
172
173
        if (is_string($field['name'])) {
174
            return $model->{$field['name']};
175
        }
176
177
        if (is_array($field['name'])) {
178
            $result = [];
179
            foreach ($field['name'] as $key => $value) {
180
                $result = $model->{$value};
181
            }
182
183
            return $result;
184
        }
185
    }
186
}
187