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

Normalizer::normalize()   C

Complexity

Conditions 13
Paths 10

Size

Total Lines 51
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 13.0122

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 13
eloc 23
c 1
b 0
f 0
nc 10
nop 2
dl 0
loc 51
ccs 23
cts 24
cp 0.9583
crap 13.0122
rs 6.6166

How to fix   Long Method    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\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