Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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 <matthieu@mnapoli.fr>
14
 */
15
class SourceChain implements DefinitionSource, MutableDefinitionSource
16
{
17
    private ?MutableDefinitionSource $mutableSource;
18
 
19
    /**
20
     * @param list<DefinitionSource> $sources
21
     */
22
    public function __construct(
23
        private array $sources,
24
    ) {
25
    }
26
 
27
    /**
28
     * @param int $startIndex Use this parameter to start looking from a specific
29
     *                        point in the source chain.
30
     */
31
    public function getDefinition(string $name, int $startIndex = 0) : Definition|null
32
    {
33
        $count = count($this->sources);
34
        for ($i = $startIndex; $i < $count; ++$i) {
35
            $source = $this->sources[$i];
36
 
37
            $definition = $source->getDefinition($name);
38
 
39
            if ($definition) {
40
                if ($definition instanceof ExtendsPreviousDefinition) {
41
                    $this->resolveExtendedDefinition($definition, $i);
42
                }
43
 
44
                return $definition;
45
            }
46
        }
47
 
48
        return null;
49
    }
50
 
51
    public function getDefinitions() : array
52
    {
53
        $allDefinitions = array_merge(...array_map(fn ($source) => $source->getDefinitions(), $this->sources));
54
 
55
        /** @var string[] $allNames */
56
        $allNames = array_keys($allDefinitions);
57
 
58
        $allValues = array_filter(array_map(fn ($name) => $this->getDefinition($name), $allNames));
59
 
60
        return array_combine($allNames, $allValues);
61
    }
62
 
63
    public function addDefinition(Definition $definition) : void
64
    {
65
        if (! $this->mutableSource) {
66
            throw new \LogicException("The container's definition source has not been initialized correctly");
67
        }
68
 
69
        $this->mutableSource->addDefinition($definition);
70
    }
71
 
72
    private function resolveExtendedDefinition(ExtendsPreviousDefinition $definition, int $currentIndex)
73
    {
74
        // Look in the next sources only (else infinite recursion, and we can only extend
75
        // entries defined in the previous definition files - a previous == next here because
76
        // the array was reversed ;) )
77
        $subDefinition = $this->getDefinition($definition->getName(), $currentIndex + 1);
78
 
79
        if ($subDefinition) {
80
            $definition->setExtendedDefinition($subDefinition);
81
        }
82
    }
83
 
84
    public function setMutableDefinitionSource(MutableDefinitionSource $mutableSource) : void
85
    {
86
        $this->mutableSource = $mutableSource;
87
 
88
        array_unshift($this->sources, $mutableSource);
89
    }
90
}