Passed
Push — latest ( c5296c...5fe1f6 )
by Mark
02:28
created

Normalize::propertyValue()   D

Complexity

Conditions 19
Paths 117

Size

Total Lines 58
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 32
CRAP Score 19

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 31
c 1
b 0
f 1
dl 0
loc 58
ccs 32
cts 32
cp 1
rs 4.375
cc 19
nc 117
nop 3
crap 19

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
declare(strict_types=1);
4
5
namespace UnicornFail\Emoji;
6
7
/**
8
 * {@internal}
9
 */
10
final class Normalize
11
{
12
    public const TYPES = ['array', 'bool', 'boolean', 'double', 'float', 'int', 'integer', 'null', 'object', 'string'];
13
14
    /**
15
     * @param mixed[]  $properties
16
     * @param string[] $types
17
     *
18
     * @return mixed[]
19
     */
20 48
    public static function properties(array $properties, array $types): array
21
    {
22 48
        $properties += \array_fill_keys(\array_keys($types), null);
23 48
        foreach ($properties as $key => $value) {
24 48
            $properties[$key] = static::propertyValue($types, $key, $value);
25
        }
26
27 48
        return $properties;
28
    }
29
30
    /**
31
     * @param string[]   $types
32
     * @param int|string $key
33
     * @param mixed      $value
34
     *
35
     * @return mixed
36
     */
37 48
    protected static function propertyValue(array $types, $key, $value)
38
    {
39 48
        $type = $types[$key] ?? '?string';
40
41 48
        $emptyNullable = false;
42 48
        $nullable      = false;
43 48
        $iterable      = false;
44
45
        // Determine if type is empty or nullable, prefixed with ?!.
46 48
        if (\substr($type, 0, 2) === '!?') {
47 36
            $emptyNullable = true;
48 36
            $nullable      = true;
49 36
            $type          = \substr($type, 2);
50
        // Determine if type is nullable, prefixed with ?.
51 45
        } elseif ($type[0] === '?') {
52 36
            $nullable = true;
53 36
            $type     = \substr($type, 1);
54
        }
55
56
        // Immediately return if already empty or null.
57 48
        if (($emptyNullable && ! $value) || ($nullable && $value === null)) {
58 36
            return null;
59
        }
60
61
        // Determine if type is iterable, suffixed with [].
62 45
        if (\substr($type, -2, 2) === '[]') {
63 42
            $iterable = true;
64 42
            $type     = \substr($type, 0, -2);
65
        }
66
67
        // Determine if PHP type.
68 45
        $phpType = \in_array($type, self::TYPES, true);
69
70 45
        if (! $phpType && \class_exists($type)) {
71 36
            $value = new $type($value);
72 36
            if ($iterable && \is_iterable($value)) {
73 3
                return $value;
74
            }
75
        }
76
77 42
        if (! $phpType && \is_callable($type)) {
78 36
            $value = $type($value);
79 36
            if ($iterable && \is_iterable($value)) {
80 36
                return $value;
81
            }
82
        }
83
84 39
        if ($iterable) {
85 36
            $value = (array) $value;
86 36
            $type  = $nullable ? \sprintf('?%s', $type) : $type;
87
88
            /** @var string[] $types */
89 36
            $types = \array_fill_keys(\array_keys($value), $type);
90
91 36
            return static::properties($value, $types);
92
        }
93
94 39
        return $phpType ? static::setType($value, $type, $emptyNullable) : $value;
95
    }
96
97
    /**
98
     * @param mixed $value
99
     *
100
     * @return mixed[]|bool|float|int|object|string|null
101
     */
102 99
    public static function setType($value, string $type, bool $emptyNullable = false)
103
    {
104 99
        if ($emptyNullable && ! $value) {
105 18
            return null;
106
        }
107
108
        switch ($type) {
109 81
            case 'array':
110 3
                $value = (array) ($value ?? []);
111 3
                break;
112
113 78
            case 'bool':
114 72
            case 'boolean':
115 12
                $value = (bool) ($value ?? false);
116 12
                break;
117
118 66
            case 'double':
119 60
            case 'float':
120 45
                $value = (float) ($value ?? 0.0);
121 45
                break;
122
123 54
            case 'int':
124 51
            case 'integer':
125 42
                $value = (int) ($value ?? 0);
126 42
                break;
127
128 45
            case 'null':
129 6
                $value = null;
130 6
                break;
131
132 39
            case 'object':
133 3
                $value = (object) ($value ?? new \stdClass());
134 3
                break;
135
136 36
            case 'string':
137 36
                $value = (string) ($value ?? '');
138 36
                break;
139
        }
140
141 81
        return $emptyNullable && ! $value ? null : $value;
142
    }
143
144
    /**
145
     * @param string|string[] $shortcode
146
     *
147
     * @return string[]
148
     */
149 123
    public static function shortcodes($shortcode): array
150
    {
151 123
        $normalized = [];
152 123
        foreach (\func_get_args() as $shortcodes) {
153 123
            $normalized = \array_values(\array_unique(\array_merge(
154 123
                $normalized,
155 123
                \array_map(
156
                    static function ($shortcode) {
157 123
                        return \preg_replace('/[^a-z0-9-]/', '-', \strtolower(\trim($shortcode, ':(){}[]')));
158
                    },
159 123
                    (array) $shortcodes
160
                )
161
            )));
162
        }
163
164 123
        return \array_unique(\array_filter($normalized));
165
    }
166
}
167