Passed
Pull Request — master (#58)
by Dmitriy
08:59 queued 06:34
created

Normalizer   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 74
Duplicated Lines 0 %

Test Coverage

Coverage 95.45%

Importance

Changes 0
Metric Value
eloc 23
dl 0
loc 74
ccs 21
cts 22
cp 0.9545
rs 10
c 0
b 0
f 0
wmc 12

1 Method

Rating   Name   Duplication   Size   Complexity  
C normalize() 0 51 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 13
    public static function normalize(mixed $definition, ?string $class = null): DefinitionInterface
50
    {
51
        // Reference
52 13
        if ($definition instanceof ReferenceInterface) {
53 1
            return $definition;
54
        }
55
56 12
        if (is_string($definition)) {
57
            // Current class
58
            if (
59
                $class === $definition ||
60 4
                ($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 3
            return Reference::to($definition);
68
        }
69
70
        // Callable definition
71 8
        if (is_callable($definition, true)) {
72 3
            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
                    );
83
                }
84 1
                $config[ArrayDefinition::CLASS_NAME] = $class;
85
            }
86
            /** @psalm-var ArrayDefinitionConfig $config */
87 2
            return ArrayDefinition::fromConfig($config);
88
        }
89
90 2
        if ($definition instanceof DefinitionInterface) {
91
            return $definition;
92
        }
93
94
        // Ready object
95 2
        if (is_object($definition)) {
96 1
            return new ValueDefinition($definition);
97
        }
98
99 1
        throw new InvalidConfigException('Invalid definition: ' . var_export($definition, true));
100
    }
101
}
102