AsEnumArrayObject.php$0 ➔ castUsing()   B
last analyzed

Complexity

Conditions 4

Size

Total Lines 101

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 4.5311

Importance

Changes 0
Metric Value
cc 4
c 0
b 0
f 0
dl 0
loc 101
ccs 19
cts 28
cp 0.6786
crap 4.5311
rs 8

5 Methods

Rating   Name   Duplication   Size   Complexity  
A AsEnumArrayObject.php$0 ➔ getStorableEnumValue() 0 7 4
A AsEnumArrayObject.php$0 ➔ set() 0 13 3
A AsEnumArrayObject.php$0 ➔ get() 0 22 5
A AsEnumArrayObject.php$0 ➔ __construct() 0 3 1
A AsEnumArrayObject.php$0 ➔ serialize() 0 5 1

How to fix   Long Method   

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 LaravelFreelancerNL\Aranguent\Eloquent\Casts;
4
5
use BackedEnum;
0 ignored issues
show
Bug introduced by
The type BackedEnum was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
7
use Illuminate\Database\Eloquent\Casts\ArrayObject;
8
use Illuminate\Database\Eloquent\Casts\AsEnumArrayObject as IlluminateAsEnumArrayObjectAlias;
9
use Illuminate\Support\Collection;
10
use LaravelFreelancerNL\Aranguent\Eloquent\Model;
11
12
/**
13
 * @SuppressWarnings("PHPMD.UndefinedVariable")
14
 * @SuppressWarnings("PHPMD.UnusedFormalParameter")
15
 */
16
class AsEnumArrayObject extends IlluminateAsEnumArrayObjectAlias
17
{
18
    /**
19
     * Get the caster class to use when casting from / to this cast target.
20
     *
21
     * @template TEnum
22
     *
23
     * @param  array{class-string<TEnum>}  $arguments
0 ignored issues
show
Documentation Bug introduced by
The doc comment array{class-string<TEnum>} at position 2 could not be parsed: Expected ':' at position 2, but found 'class-string'.
Loading history...
24
     * @return \Illuminate\Contracts\Database\Eloquent\CastsAttributes<\Illuminate\Database\Eloquent\Casts\ArrayObject<array-key, TEnum>, iterable<TEnum>>
25
     *
26
     * @SuppressWarnings("PHPMD.ExcessiveMethodLength")
27
     */
28 1
    public static function castUsing(array $arguments)
29
    {
30 1
        return new class ($arguments) implements CastsAttributes {
31
            /**
32
             * @var array<class-string<TEnum>>
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<class-string<TEnum>> at position 2 could not be parsed: Unknown type name 'class-string' at position 2 in array<class-string<TEnum>>.
Loading history...
33
             */
34
            protected $arguments;
35
36
            /**
37
             * @param array<class-string<TEnum>> $arguments
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<class-string<TEnum>> at position 2 could not be parsed: Unknown type name 'class-string' at position 2 in array<class-string<TEnum>>.
Loading history...
38
             *
39
             * @SuppressWarnings("PHPMD.UndefinedVariable")
40
             */
41
            public function __construct(array $arguments)
42
            {
43 1
                $this->arguments = $arguments;
44
            }
45
46
            /**
47
             * @param $model
48
             * @param $key
49
             * @param $value
50
             * @param $attributes
51
             * @return ArrayObject|void
52
             *
53
             * @SuppressWarnings("PHPMD.UndefinedVariable")
54
             */
55
            public function get($model, $key, $value, $attributes)
56
            {
57 1
                if (! isset($attributes[$key])) {
58
                    return;
59
                }
60
61 1
                $data = $attributes[$key];
62 1
                if (is_object($data)) {
63
                    $data = (array) $data;
64
                }
65
66 1
                if (! is_array($data)) {
67
                    return;
68
                }
69
70 1
                $enumClass = $this->arguments[0];
71
72 1
                return new ArrayObject((new Collection($data))->map(function ($value) use ($enumClass) {
0 ignored issues
show
Bug introduced by
$data of type array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $items of Illuminate\Support\Collection::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

72
                return new ArrayObject((new Collection(/** @scrutinizer ignore-type */ $data))->map(function ($value) use ($enumClass) {
Loading history...
Bug Best Practice introduced by
The expression return new Illuminate\Da...* ... */ })->toArray()) returns the type Illuminate\Database\Eloquent\Casts\ArrayObject which is incompatible with the return type mandated by Illuminate\Contracts\Dat...\CastsAttributes::get() of Illuminate\Contracts\Database\Eloquent\TGet|null.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
73 1
                    return is_subclass_of($enumClass, BackedEnum::class)
74
                        ? $enumClass::from($value)
75 1
                        : constant($enumClass . '::' . $value);
76 1
                })->toArray());
77
            }
78
79
            /**
80
             * @param Model $model
81
             * @param string $key
82
             * @param mixed $value
83
             * @param mixed[] $attributes
84
             * @return mixed[]
85
             *
86
             * @SuppressWarnings("PHPMD.UnusedFormalParameter")
87
             * @SuppressWarnings("PHPMD.UndefinedVariable")
88
             */
89
            public function set($model, $key, $value, $attributes)
90
            {
91 1
                if ($value === null) {
92
                    return [$key => null];
93
                }
94
95 1
                $storable = [];
96
97 1
                foreach ($value as $enum) {
98 1
                    $storable[] = $this->getStorableEnumValue($enum);
99
                }
100
101 1
                return [$key => $storable];
102
            }
103
104
            /**
105
             * @param Model $model
106
             * @param string $key
107
             * @param mixed $value
108
             * @param mixed[] $attributes
109
             * @return mixed[]
110
             */
111
            public function serialize($model, string $key, $value, array $attributes)
0 ignored issues
show
Unused Code introduced by
The parameter $model is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

111
            public function serialize(/** @scrutinizer ignore-unused */ $model, string $key, $value, array $attributes)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $key is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

111
            public function serialize($model, /** @scrutinizer ignore-unused */ string $key, $value, array $attributes)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $attributes is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

111
            public function serialize($model, string $key, $value, /** @scrutinizer ignore-unused */ array $attributes)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
112
            {
113
                return (new Collection($value->getArrayCopy()))->map(function ($enum) {
114
                    return $this->getStorableEnumValue($enum);
115
                })->toArray();
116
            }
117
118
            /**
119
             * @param mixed $enum
120
             * @return int|string
121
             */
122
            protected function getStorableEnumValue($enum)
123
            {
124 1
                if (is_string($enum) || is_int($enum)) {
125
                    return $enum;
126
                }
127
128 1
                return $enum instanceof BackedEnum ? $enum->value : $enum->name;
129
            }
130 1
        };
131
    }
132
133
    /**
134
     * Specify the Enum for the cast.
135
     *
136
     * @param  class-string  $class
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
137
     * @return string
138
     *
139
     * @SuppressWarnings("PHPMD.ShortMethodName")
140
     */
141 18
    public static function of($class)
142
    {
143 18
        return static::class . ':' . $class;
144
    }
145
}
146