Completed
Push — master ( 4d66a1...40cfc1 )
by Matthieu
01:32
created

SourceChain::resolveExtendedDefinition()   A

Complexity

Conditions 2
Paths 2

Duplication

Lines 0
Ratio 0 %

Size

Total Lines 11
Code Lines 4

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 2
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace DI\Definition\Source;
6
7
use DI\Definition\Definition;
8
use DI\Definition\ExtendsPreviousDefinition;
9
10
/**
11
 * Manages a chain of other definition sources.
12
 *
13
 * @author Matthieu Napoli <[email protected]>
14
 */
15
class SourceChain implements DefinitionSource, MutableDefinitionSource
16
{
17
    /**
18
     * @var DefinitionSource[]
19
     */
20
    private $sources;
21
22
    /**
23
     * @var DefinitionSource
24
     */
25
    private $rootSource;
26
27
    /**
28
     * @var MutableDefinitionSource|null
29
     */
30
    private $mutableSource;
31
32
    /**
33
     * @param DefinitionSource[] $sources
34
     */
35
    public function __construct(array $sources)
36
    {
37
        // We want a numerically indexed array to ease the traversal later
38
        $this->sources = array_values($sources);
39
        $this->rootSource = $this;
40
    }
41
42
    /**
43
     * {@inheritdoc}
44
     * @param int $startIndex Use this parameter to start looking from a specific
45
     *                        point in the source chain.
46
     */
47
    public function getDefinition(string $name, int $startIndex = 0)
48
    {
49
        $count = count($this->sources);
50
        for ($i = $startIndex; $i < $count; ++$i) {
51
            $source = $this->sources[$i];
52
53
            $definition = $source->getDefinition($name);
0 ignored issues
show
Bug introduced by Matthieu Napoli
Are you sure the assignment to $definition is correct as $source->getDefinition($name) (which targets DI\Definition\Source\Def...Source::getDefinition()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
54
55
            if ($definition) {
56
                if ($definition instanceof ExtendsPreviousDefinition) {
57
                    $this->resolveExtendedDefinition($definition, $i);
58
                }
59
60
                return $definition;
61
            }
62
        }
63
64
        return null;
65
    }
66
67
    public function getDefinitions() : array
68
    {
69
        $names = [];
70
        foreach ($this->sources as $source) {
71
            $names = array_merge($names, $source->getDefinitions());
72
        }
73
        $names = array_keys($names);
74
75
        $definitions = array_combine($names, array_map(function (string $name) {
76
            return $this->getDefinition($name);
77
        }, $names));
78
79
        return $definitions;
80
    }
81
82
    public function addDefinition(Definition $definition)
83
    {
84
        if (! $this->mutableSource) {
85
            throw new \LogicException("The container's definition source has not been initialized correctly");
86
        }
87
88
        $this->mutableSource->addDefinition($definition);
89
    }
90
91
    private function resolveExtendedDefinition(ExtendsPreviousDefinition $definition, int $currentIndex)
92
    {
93
        // Look in the next sources only (else infinite recursion, and we can only extend
94
        // entries defined in the previous definition files - a previous == next here because
95
        // the array was reversed ;) )
96
        $subDefinition = $this->getDefinition($definition->getName(), $currentIndex + 1);
97
98
        if ($subDefinition) {
99
            $definition->setExtendedDefinition($subDefinition);
100
        }
101
    }
102
103
    public function setMutableDefinitionSource(MutableDefinitionSource $mutableSource)
104
    {
105
        $this->mutableSource = $mutableSource;
106
107
        array_unshift($this->sources, $mutableSource);
108
    }
109
}
110