Normalizer   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 70
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 21
dl 0
loc 70
ccs 22
cts 22
cp 1
rs 10
c 0
b 0
f 0
wmc 12

1 Method

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