Passed
Pull Request — master (#76)
by Sergei
06:29 queued 03:59
created

Normalizer::normalize()   B

Complexity

Conditions 11
Paths 9

Size

Total Lines 46
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 11

Importance

Changes 0
Metric Value
cc 11
eloc 21
nc 9
nop 2
dl 0
loc 46
ccs 22
cts 22
cp 1
crap 11
rs 7.3166
c 0
b 0
f 0

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
declare(strict_types=1);
4
5
namespace Yiisoft\Definitions\Helpers;
6
7
use Yiisoft\Definitions\ArrayDefinition;
8
use Yiisoft\Definitions\CallableDefinition;
9
use Yiisoft\Definitions\Contract\DefinitionInterface;
10
use Yiisoft\Definitions\Exception\InvalidConfigException;
11
use Yiisoft\Definitions\Reference;
12
use Yiisoft\Definitions\ValueDefinition;
13
14
use function array_key_exists;
15
use function is_array;
16
use function is_callable;
17
use function is_object;
18
use function is_string;
19
20
/**
21
 * Normalizer definition from configuration to an instance of {@see DefinitionInterface}.
22
 *
23
 * @psalm-import-type ArrayDefinitionConfig from ArrayDefinition
24
 */
25
final class Normalizer
26
{
27
    /**
28
     * Normalize definition to an instance of {@see DefinitionInterface}.
29
     * Definition may be defined multiple ways:
30
     *  - class name,
31
     *  - string as reference to another class or alias,
32
     *  - instance of {@see DefinitionInterface},
33
     *  - callable,
34
     *  - array,
35
     *  - ready object.
36
     *
37
     * @param mixed $definition The definition for normalization.
38
     * @param string|null $class The class name of the object to be defined (optional). It is used in two cases.
39
     *  - The definition is a string, and class name equals to definition. Returned `ArrayDefinition` with defined
40
     *    class.
41
     *  - The definition is an array without class name. Class name will be added to array and `ArrayDefinition`
42
     *    will be returned.
43
     *
44
     * @throws InvalidConfigException If configuration is not valid.
45
     *
46
     * @return DefinitionInterface Normalized definition as an object.
47
     */
48 13
    public static function normalize(mixed $definition, ?string $class = null): DefinitionInterface
49
    {
50 13
        if ($definition instanceof DefinitionInterface) {
51 2
            return $definition;
52
        }
53
54 11
        if (is_string($definition)) {
55
            // Current class
56
            if (
57 3
                $class === $definition ||
58 3
                ($class === null && class_exists($definition))
59
            ) {
60
                /** @psalm-var class-string $definition */
61 1
                return ArrayDefinition::fromPreparedData($definition);
62
            }
63
64
            // Reference to another class or alias
65 2
            return Reference::to($definition);
66
        }
67
68
        // Callable definition
69 9
        if (is_callable($definition, true)) {
70 4
            return new CallableDefinition($definition);
71
        }
72
73
        // Array definition
74 5
        if (is_array($definition)) {
75 3
            $config = $definition;
76 3
            if (!array_key_exists(ArrayDefinition::CLASS_NAME, $config)) {
77 2
                if ($class === null) {
78 1
                    throw new InvalidConfigException(
79 1
                        'Array definition should contain the key "class": ' . var_export($definition, true)
80 1
                    );
81
                }
82 1
                $config[ArrayDefinition::CLASS_NAME] = $class;
83
            }
84
            /** @psalm-var ArrayDefinitionConfig $config */
85 2
            return ArrayDefinition::fromConfig($config);
86
        }
87
88
        // Ready object
89 2
        if (is_object($definition)) {
90 1
            return new ValueDefinition($definition);
91
        }
92
93 1
        throw new InvalidConfigException('Invalid definition: ' . var_export($definition, true));
94
    }
95
}
96