Passed
Pull Request — master (#58)
by Dmitriy
12:28 queued 09:49
created

Normalizer   A

Complexity

Total Complexity 11

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 11

1 Method

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