NormalizerFactory::loadNormalizersFromDto()   B
last analyzed

Complexity

Conditions 10
Paths 10

Size

Total Lines 30
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 10

Importance

Changes 0
Metric Value
eloc 23
c 0
b 0
f 0
dl 0
loc 30
ccs 21
cts 21
cp 1
rs 7.6666
cc 10
nc 10
nop 3
crap 10

How to fix   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
namespace kalanis\Pohoda\Common\OptionsResolver\Normalizers;
4
5
use Closure;
6
use kalanis\Pohoda\Common;
7
use kalanis\PohodaException;
8
9
class NormalizerFactory
10
{
11 167
    public static function loadNormalizersFromDto(
12
        Common\OptionsResolver $resolver,
13
        Common\Dtos\AbstractDto $dto,
14
        bool $useOneDirectionalVariables,
15
    ): void {
16 167
        $propertyOptions = Common\Dtos\Processing::getOptions($dto, $useOneDirectionalVariables);
17 167
        foreach ($propertyOptions as $propertyName => $allOptions) {
18 165
            foreach ($allOptions as $option) {
19 165
                if (is_a($option, Common\Attributes\Options\AbstractOption::class)) {
20 165
                    switch ($option->getAction()) {
21 165
                        case Common\OptionsResolver\ActionsEnum::DEFAULT_VALUES:
22 94
                            static::fillDefaultValues($resolver, $option, $propertyName);
23 94
                            break;
24 165
                        case Common\OptionsResolver\ActionsEnum::IS_REQUIRED:
25 88
                            static::fillAsRequired($resolver, $propertyName);
26 88
                            break;
27 162
                        case Common\OptionsResolver\ActionsEnum::NORMALIZER:
28 158
                            static::fillNormalizers($resolver, $option, $propertyName, $dto);
29 158
                            break;
30 137
                        case Common\OptionsResolver\ActionsEnum::ALLOWED_VALUES:
31 58
                            static::fillAllowedValues($resolver, $option, $propertyName);
32 58
                            break;
33 116
                        case Common\OptionsResolver\ActionsEnum::ALLOWED_ENUMS:
34 116
                            static::fillAllowedEnums($resolver, $option, $propertyName);
35 116
                            break;
36
                            // @codeCoverageIgnoreStart
37
                            // okay, I do not know what might happen when I will want to use check by types
38
                        case Common\OptionsResolver\ActionsEnum::ALLOWED_TYPES:
39
                            static::fillAllowedTypes($resolver, $option, $propertyName);
40
                            break;
41
                            // @codeCoverageIgnoreEnd
42
                    };
43
                }
44
            }
45
        }
46
    }
47
48 94
    protected static function fillDefaultValues(
49
        Common\OptionsResolver $resolver,
50
        Common\Attributes\Options\AbstractOption $option,
51
        string $propertyName,
52
    ): void {
53 94
        if (\is_callable($option->value)) {
54 35
            $resolver->setDefault($propertyName, Closure::fromCallable($option->value));
55 61
        } elseif (is_object($option->value) && is_a($option->value, Common\Enums\EnhancedEnumInterface::class)) {
56 46
            $resolver->setDefault($propertyName, $option->value->currentValue());
57
        } else {
58 28
            $resolver->setDefault($propertyName, $option->value);
59
        }
60
    }
61
62 88
    protected static function fillAsRequired(
63
        Common\OptionsResolver $resolver,
64
        string $propertyName,
65
    ): void {
66 88
        $resolver->setRequired($propertyName);
67
    }
68
69 158
    protected static function fillNormalizers(
70
        Common\OptionsResolver $resolver,
71
        Common\Attributes\Options\AbstractOption $option,
72
        string $propertyName,
73
        Common\Dtos\AbstractDto $dto,
74
    ): void {
75 158
        $reflect = new \ReflectionClass($option->getNormalizer());
76 158
        $instance = $reflect->newInstance();
77 158
        if (is_a($instance, AbstractNormalizer::class)) {
78 158
            $instance->setParams(
79 158
                \is_null($option->value) ? null : (\is_numeric($option->value) || \is_string($option->value) ? \intval($option->value) : null),
80 158
                $option->isNullable,
81 158
                $option->value,
82 158
                $dto,
83 158
            );
84 158
            $resolver->setNormalizer($propertyName, $instance->normalize(...));
85
        }
86
    }
87
88 58
    protected static function fillAllowedValues(
89
        Common\OptionsResolver $resolver,
90
        Common\Attributes\Options\AbstractOption $option,
91
        string $propertyName,
92
    ): void {
93 58
        $values = is_array($option->value) ? static::updateNulls($option->value) : $option->value;
94 58
        $resolver->setAllowedValues($propertyName, $values);
95
    }
96
97 116
    protected static function fillAllowedEnums(
98
        Common\OptionsResolver $resolver,
99
        Common\Attributes\Options\AbstractOption $option,
100
        string $propertyName,
101
    ): void {
102 116
        $enum = $option->value;
103
        /** @var Common\Enums\EnhancedEnumInterface $enum */
104 116
        $resolver->setAllowedValues($propertyName, static::updateNulls($enum::values()));
105
    }
106
107
    /**
108
     * @param array<string|int|float|bool> $values
109
     * @return array<string|int|float|bool|null>
110
     */
111 137
    protected static function updateNulls(array $values): array
112
    {
113 137
        return array_map(fn($v) => Common\EmptyInterface::EMPTY_VALUE === $v ? null : $v, $values);
114
    }
115
116
    // @codeCoverageIgnoreStart
117
    // okay, I do not know what might happen when I will want to use check by types
118
    protected static function fillAllowedTypes(
119
        Common\OptionsResolver $resolver,
120
        Common\Attributes\Options\AbstractOption $option,
121
        string $propertyName,
122
    ): void {
123
        $values = array_map(fn($v) => \strval($v), (array) $option->value);
124
        $resolver->setAllowedTypes($propertyName, $values);
125
    }
126
    // @codeCoverageIgnoreEnd
127
128
    /**
129
     * Create normalizer.
130
     *
131
     * @param string   $type
132
     * @throws PohodaException
133
     * @return AbstractNormalizer
134
     * @see vendor/symfony/options-resolver/OptionsResolver.php:1128
135
     */
136 30
    public static function createNormalizer(string $type): AbstractNormalizer
137
    {
138 30
        return match ($type) {
139 4
            'str', 'string' => new Strings(),
140 15
            'float', 'number' => new Numbers(),
141 2
            'int', 'integer' => new Integers(),
142 16
            'bool', 'boolean' => new Booleans(),
143 4
            'date' => new Dates(),
144 1
            'datetime' => new DateTimes(),
145 1
            'time' => new Times(),
146 1
            'list_request_type' => new ListRequestType(),
147 30
            default => throw new PohodaException('Not a valid normalizer type: ' . $type),
148 30
        };
149
    }
150
}
151