Passed
Pull Request — master (#87)
by Dmitriy
12:15
created

Normalizer   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 74
Duplicated Lines 0 %

Test Coverage

Coverage 95.83%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 23
c 1
b 0
f 0
dl 0
loc 74
ccs 23
cts 24
cp 0.9583
rs 10
wmc 13

1 Method

Rating   Name   Duplication   Size   Complexity  
C normalize() 0 51 13
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 ($definition instanceof DefinitionInterface) {
57
            return $definition;
58
        }
59
60 11
        if (is_string($definition)) {
61
            // Current class
62
            if (
63 3
                $class === $definition ||
64 3
                ($class === null && class_exists($definition))
65
            ) {
66
                /** @psalm-var class-string $definition */
67 1
                return ArrayDefinition::fromPreparedData($definition);
68
            }
69
70
            // Reference to another class or alias
71 2
            return Reference::to($definition);
72
        }
73
74
        // Callable definition
75 9
        if (is_callable($definition, true)) {
76 4
            return new CallableDefinition($definition);
77
        }
78
79
        // Array definition
80 5
        if (is_array($definition)) {
81 3
            $config = $definition;
82 3
            if (!array_key_exists(ArrayDefinition::CLASS_NAME, $config)) {
83 2
                if ($class === null) {
84 1
                    throw new InvalidConfigException(
85 1
                        'Array definition should contain the key "class": ' . var_export($definition, true)
86 1
                    );
87
                }
88 1
                $config[ArrayDefinition::CLASS_NAME] = $class;
89
            }
90
            /** @psalm-var ArrayDefinitionConfig $config */
91 2
            return ArrayDefinition::fromConfig($config);
92
        }
93
94
        // Ready object
95 2
        if (is_object($definition) && !($definition instanceof DefinitionInterface)) {
96 1
            return new ValueDefinition($definition);
97
        }
98
99 1
        throw new InvalidConfigException('Invalid definition: ' . var_export($definition, true));
100
    }
101
}
102