Completed
Push — master ( 227e0a...8a63ba )
by Maksim
01:19
created

MultiUnitSupport::hasSetMutator()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
namespace MaksimM\MultiUnitModels\Traits;
4
5
use Illuminate\Database\Eloquent\Model;
6
use Illuminate\Support\Arr;
7
use MaksimM\MultiUnitModels\Exceptions\NotSupportedMultiUnitField;
8
use UnitConverter\Unit\AbstractUnit;
9
10
trait MultiUnitSupport
11
{
12
    protected $unitAttributePostfix = '_units';
13
    protected $unitConversionDataPostfix = '_ucd';
14
    protected $multiUnitColumns = [];
15
16
    private function getUnitConversionDataColumns()
17
    {
18
        return array_map(function ($column) {
19
            return $column.$this->getUnitConversionDataPostfix();
20
        }, array_keys($this->getMultiUnitColumns()));
21
    }
22
23
    private function getUnitConversionUnitColumns()
24
    {
25
        return array_map(function ($column) {
26
            return $column.$this->getUnitAttributePostfix();
27
        }, array_keys($this->getMultiUnitColumns()));
28
    }
29
30
    /**
31
     * Allows to set input units and process them before multi-unit field.
32
     *
33
     * @param array $attributes
34
     *
35
     * @return array
36
     */
37
    protected function fillableFromArray(array $attributes)
38
    {
39
        return array_merge(array_intersect_key($attributes, array_flip($this->getUnitConversionUnitColumns())), parent::fillableFromArray($attributes));
40
    }
41
42
    /**
43
     * @return array
44
     */
45
    public function getFillable()
46
    {
47
        return array_merge($this->getUnitConversionDataColumns(), $this->getUnitConversionUnitColumns(), parent::getFillable());
48
    }
49
50
    /**
51
     * @return mixed
52
     */
53
    public function getHidden()
54
    {
55
        return array_merge(parent::getHidden(), $this->getUnitConversionDataColumns());
56
    }
57
58
    protected static function bootMultiUnitSupport()
59
    {
60
        //save conversion table if base value is changed
61
        static::creating(function ($model) {
62
            /**
63
             * @var Model|MultiUnitSupport $model
64
             */
65
            foreach ($model->getMultiUnitColumns() as $unitBasedColumn => $options) {
0 ignored issues
show
Bug introduced by
The method getMultiUnitColumns does only exist in MaksimM\MultiUnitModels\Traits\MultiUnitSupport, but not in Illuminate\Database\Eloquent\Model.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
66
                if (isset($model->attributes[$unitBasedColumn])) {
67
                    $model->{$unitBasedColumn.$model->getUnitConversionDataPostfix()} = json_encode(
0 ignored issues
show
Bug introduced by
The method getUnitConversionDataPostfix does only exist in MaksimM\MultiUnitModels\Traits\MultiUnitSupport, but not in Illuminate\Database\Eloquent\Model.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
68
                        $model->calculateMultiUnitConversionData(
0 ignored issues
show
Bug introduced by
The method calculateMultiUnitConversionData does only exist in MaksimM\MultiUnitModels\Traits\MultiUnitSupport, but not in Illuminate\Database\Eloquent\Model.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
69
                            $model->attributes[$unitBasedColumn],
70
                            $model->getMultiUnitFieldUnit($unitBasedColumn),
0 ignored issues
show
Bug introduced by
The method getMultiUnitFieldUnit does only exist in MaksimM\MultiUnitModels\Traits\MultiUnitSupport, but not in Illuminate\Database\Eloquent\Model.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
71
                            $options['supported_units']
72
                        )
73
                    );
74
                    $model->{$unitBasedColumn} = $model->processMultiUnitFieldChanges(
0 ignored issues
show
Bug introduced by
The method processMultiUnitFieldChanges does only exist in MaksimM\MultiUnitModels\Traits\MultiUnitSupport, but not in Illuminate\Database\Eloquent\Model.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
75
                        $unitBasedColumn,
76
                        $model->{$unitBasedColumn}
77
                    );
78
                }
79
            }
80
            //prevent saving of unit columns
81
            foreach ($model->getUnitConversionUnitColumns() as $unitColumn) {
0 ignored issues
show
Bug introduced by
The method getUnitConversionUnitColumns does only exist in MaksimM\MultiUnitModels\Traits\MultiUnitSupport, but not in Illuminate\Database\Eloquent\Model.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
82
                if (isset($model->attributes[$unitColumn])) {
83
                    unset($model->attributes[$unitColumn]);
84
                }
85
            }
86
        });
87
        static::updating(function ($model) {
88
            /**
89
             * @var Model|MultiUnitSupport $model
90
             */
91
            foreach (Arr::only($model->getMultiUnitColumns(), array_keys($model->getDirty())) as $unitBasedColumn => $options) {
0 ignored issues
show
Bug introduced by
The method getMultiUnitColumns does only exist in MaksimM\MultiUnitModels\Traits\MultiUnitSupport, but not in Illuminate\Database\Eloquent\Model.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
92
                $model->{$unitBasedColumn.$model->getUnitConversionDataPostfix()} = json_encode($model->calculateMultiUnitConversionData($model->getDirty()[$unitBasedColumn], new $options['default_unit'](), $options['supported_units']));
0 ignored issues
show
Bug introduced by
The method getUnitConversionDataPostfix does only exist in MaksimM\MultiUnitModels\Traits\MultiUnitSupport, but not in Illuminate\Database\Eloquent\Model.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
Bug introduced by
The method getDirty does only exist in Illuminate\Database\Eloquent\Model, but not in MaksimM\MultiUnitModels\Traits\MultiUnitSupport.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
Bug introduced by
The method calculateMultiUnitConversionData does only exist in MaksimM\MultiUnitModels\Traits\MultiUnitSupport, but not in Illuminate\Database\Eloquent\Model.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
93
            }
94
        });
95
    }
96
97
    /**
98
     * @param              $value
99
     * @param AbstractUnit $unit
100
     * @param string[]     $requiredUnits
101
     *
102
     * @return array
103
     */
104
    private function calculateMultiUnitConversionData($value, AbstractUnit $unit, $requiredUnits)
105
    {
106
        $conversionData = [];
107
        foreach ($requiredUnits as $requiredUnitClass) {
108
            /**
109
             * @var AbstractUnit $requiredUnit
110
             */
111
            $requiredUnit = new $requiredUnitClass();
112
            $conversionData[$requiredUnit->getSymbol()] = (new $unit($value))->as($requiredUnit);
113
        }
114
115
        return $conversionData;
116
    }
117
118
    public function getMultiUnitExistingConversionData($field)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
119
    {
120
        return json_decode($this->{$field.$this->getUnitConversionDataPostfix()} ?? null);
121
    }
122
123
    /**
124
     * @return string
125
     */
126
    public function getUnitAttributePostfix()
127
    {
128
        return $this->unitAttributePostfix;
129
    }
130
131
    /**
132
     * @return string
133
     */
134
    protected function getUnitConversionDataPostfix()
135
    {
136
        return $this->unitConversionDataPostfix;
137
    }
138
139
    /**
140
     * @return array
141
     */
142
    public function getMultiUnitColumns()
143
    {
144
        return $this->multiUnitColumns;
145
    }
146
147
    /**
148
     * @param $field
149
     *
150
     * @throws NotSupportedMultiUnitField
151
     *
152
     * @return AbstractUnit[]
153
     */
154
    public function getMultiUnitFieldSupportedUnits($field)
155
    {
156
        if ($this->isMultiUnitField($field)) {
157
            return $this->getMultiUnitColumns()[$field]['supported_units'];
158
        }
159
160
        throw new NotSupportedMultiUnitField($field);
161
    }
162
163
    /**
164
     * @param $field
165
     *
166
     * @throws NotSupportedMultiUnitField
167
     *
168
     * @return AbstractUnit
169
     */
170
    public function getMultiUnitFieldDefaultUnit($field)
171
    {
172
        if ($this->isMultiUnitField($field)) {
173
            $unitClass = $this->getMultiUnitColumns()[$field]['default_unit'];
174
175
            return new $unitClass();
176
        }
177
178
        throw new NotSupportedMultiUnitField($field);
179
    }
180
181
    /**
182
     * @param        $field
183
     * @param string $unit
0 ignored issues
show
Documentation introduced by
Should the type for parameter $unit not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
184
     *
185
     * @throws NotSupportedMultiUnitField
186
     *
187
     * @return mixed
188
     */
189
    public function getMultiUnitFieldValueByUnitName($field, $unit = null)
190
    {
191
        if ($this->isMultiUnitField($field)) {
192
            if (isset($this->{$field})) {
193
                if (is_null($unit)) {
194
                    $unit = $this->getMultiUnitFieldUnit($field);
195
                } else {
196
                    foreach ($this->getMultiUnitFieldSupportedUnits($field) as $unitClass) {
197
                        /**
198
                         * @var AbstractUnit $unit
199
                         */
200
                        $supportedUnit = new $unitClass();
201
                        if (strtolower($supportedUnit->getSymbol()) == strtolower($unit)) {
202
                            $unit = $supportedUnit;
203
                            break;
204
                        }
205
                    }
206
                }
207
                if (is_string($unit)) {
208
                    throw new NotSupportedMultiUnitField($field);
209
                }
210
                $existingConversionData = $this->getMultiUnitExistingConversionData($field);
211 View Code Duplication
                if (!is_null($existingConversionData) && !is_null($existingConversionData->{$unit->getSymbol()})) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
212
                    return $existingConversionData->{$unit->getSymbol()};
213
                }
214
215
                return ($this->getMultiUnitFieldDefaultUnit($field)->setValue($this->{$field} ?? $this->attributes[$field]))->as(new $unit());
0 ignored issues
show
Bug introduced by
The property attributes does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
216
            } else {
217
                return;
218
            }
219
        }
220
221
        throw new NotSupportedMultiUnitField($field);
222
    }
223
224
    /**
225
     * @param                   $field
226
     * @param AbstractUnit|null $unit
227
     *
228
     * @throws NotSupportedMultiUnitField
229
     *
230
     * @return mixed
231
     */
232
    public function getMultiUnitFieldValue($field, AbstractUnit $unit = null)
233
    {
234
        if ($this->isMultiUnitField($field)) {
235
            if (isset($this->{$field})) {
236
                if (is_null($unit)) {
237
                    $unit = $this->getMultiUnitFieldUnit($field);
238
                }
239
                $existingConversionData = $this->getMultiUnitExistingConversionData($field);
240 View Code Duplication
                if (!is_null($existingConversionData) && !is_null($existingConversionData->{$unit->getSymbol()})) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
241
                    return $existingConversionData->{$unit->getSymbol()};
242
                }
243
244
                return ($this->getMultiUnitFieldDefaultUnit($field)->setValue($this->{$field} ?? $this->attributes[$field]))->as(new $unit());
245
            } else {
246
                return;
247
            }
248
        }
249
250
        throw new NotSupportedMultiUnitField($field);
251
    }
252
253
    protected function isMultiUnitField($field)
254
    {
255
        return isset($this->getMultiUnitColumns()[$field]);
256
    }
257
258
    /**
259
     * @param $field
260
     *
261
     * @throws NotSupportedMultiUnitField
262
     *
263
     * @return AbstractUnit
264
     */
265
    protected function getMultiUnitFieldUnit($field)
266
    {
267
        if (isset($this->{$field.$this->getUnitAttributePostfix()})) {
268
            foreach ($this->getMultiUnitFieldSupportedUnits($field) as $unitClass) {
269
                /**
270
                 * @var AbstractUnit $unit
271
                 */
272
                $unit = new $unitClass();
273
                if (strtolower($unit->getSymbol()) == strtolower($this->{$field.$this->getUnitAttributePostfix()})) {
274
                    return $unit;
275
                }
276
            }
277
        }
278
279
        return $this->getMultiUnitFieldDefaultUnit($field);
280
    }
281
282
    protected function forgetMultiUnitFieldUnitInput($field)
283
    {
284
        //prevent column_units to by saved to DB
285
        if (isset($this->attributes[$field.$this->getUnitAttributePostfix()])) {
286
            $this->syncOriginalAttribute($field.$this->getUnitAttributePostfix());
0 ignored issues
show
Bug introduced by
It seems like syncOriginalAttribute() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
287
        }
288
    }
289
290
    protected function setMultiUnitFieldUnit($field, AbstractUnit $unit)
291
    {
292
        $this->{$field.$this->getUnitAttributePostfix()} = $unit->getSymbol();
293
        $this->forgetMultiUnitFieldUnitInput($field);
294
    }
295
296
    /**
297
     * @param $field
298
     *
299
     * @throws NotSupportedMultiUnitField
300
     */
301
    protected function resetMultiUnitFieldUnit($field)
302
    {
303
        $this->setMultiUnitFieldUnit($field, $this->getMultiUnitFieldDefaultUnit($field));
304
    }
305
306
    /**
307
     * Determine if a set mutator exists for an attribute.
308
     *
309
     * @param string $key
310
     *
311
     * @return bool
312
     */
313
    public function hasSetMutator($key)
314
    {
315
        if ($this->isMultiUnitField($key)) {
316
            return true;
317
        }
318
319
        return parent::hasSetMutator($key);
320
    }
321
322
    /**
323
     * Set the value of an attribute using its mutator.
324
     *
325
     * @param string $key
326
     * @param mixed  $value
327
     *
328
     * @throws NotSupportedMultiUnitField
329
     *
330
     * @return mixed
331
     */
332
    protected function setMutatedAttributeValue($key, $value)
333
    {
334
        if ($this->isMultiUnitField($key)) {
335
            $value = $this->processMultiUnitFieldChanges($key, $value);
336
            $this->attributes[$key] = $value;
337
338
            if (parent::hasSetMutator($key)) {
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (hasSetMutator() instead of setMutatedAttributeValue()). Are you sure this is correct? If so, you might want to change this to $this->hasSetMutator().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
339
                return parent::setMutatedAttributeValue($key, $value);
340
            }
341
342
            return $value;
343
        }
344
345
        parent::setMutatedAttributeValue($key, $value);
346
    }
347
348
    /**
349
     * Detect changes and set proper base value.
350
     *
351
     * @param $field
352
     * @param $value
353
     *
354
     * @throws NotSupportedMultiUnitField
355
     *
356
     * @return mixed
357
     */
358
    private function processMultiUnitFieldChanges($field, $value)
359
    {
360
        $existingConversionData = $this->getMultiUnitExistingConversionData($field);
361
        if (!is_null($existingConversionData)) {
362
            $inputUnit = $this->getMultiUnitFieldUnit($field);
363
            //change existing value only in case if new value doesn't match with stored conversion table or not exists
364
            if (!isset($existingConversionData->{$inputUnit->getSymbol()}) || $value != $existingConversionData->{$inputUnit->getSymbol()}) {
365
                $this->resetMultiUnitFieldUnit($field);
366
367
                return (new $inputUnit($value))->as($this->getMultiUnitFieldDefaultUnit($field));
368
            } elseif ($value == $existingConversionData->{$inputUnit->getSymbol()}) {
369
                //forget changes if value actually isn't changed
370
                $this->resetMultiUnitFieldUnit($field);
371
                $originalValue = $existingConversionData->{$this->getMultiUnitFieldDefaultUnit($field)->getSymbol()};
372
                $this->attributes[$field] = $originalValue;
373
                $this->syncOriginalAttribute($field);
0 ignored issues
show
Bug introduced by
It seems like syncOriginalAttribute() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
374
375
                return $originalValue;
376
            }
377
            $this->resetMultiUnitFieldUnit($field);
378
        }
379
380
        return $value;
381
    }
382
383
    /**
384
     * Determine if a get mutator exists for an attribute.
385
     *coo.
386
     *
387
     * @param string $key
388
     *
389
     * @return bool
390
     */
391
    public function hasGetMutator($key)
392
    {
393
        if ($this->isMultiUnitField($key) && isset($this->{$key})) {
394
            return true;
395
        }
396
397
        return parent::hasGetMutator($key);
398
    }
399
400
    /**
401
     * Get the value of an attribute using its mutator.
402
     *
403
     * @param string $key
404
     * @param mixed  $value
405
     *
406
     * @throws NotSupportedMultiUnitField
407
     *
408
     * @return mixed
409
     */
410
    public function mutateAttribute($key, $value)
411
    {
412
        if ($this->isMultiUnitField($key)) {
413
            $requestedUnit = $this->getMultiUnitFieldUnit($key);
414
415
            $value = $this->getMultiUnitFieldValue($key, new $requestedUnit());
416
            if (parent::hasGetMutator($key)) {
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (hasGetMutator() instead of mutateAttribute()). Are you sure this is correct? If so, you might want to change this to $this->hasGetMutator().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
417
                return parent::mutateAttribute($key, $value);
418
            }
419
            return $value;
420
        }
421
422
        return parent::mutateAttribute($key, $value);
423
    }
424
}
425