ElementRegistry::getElementHandler()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
c 0
b 0
f 0
dl 0
loc 6
rs 10
cc 1
nc 1
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\XML\Registry;
6
7
use DirectoryIterator;
8
use SimpleSAML\XML\AbstractElement;
9
use SimpleSAML\XML\Assert\Assert;
10
use SimpleSAML\XML\Exception\IOException;
11
use SimpleSAML\XMLSchema\Exception\InvalidDOMElementException;
12
13
use function array_merge_recursive;
14
use function dirname;
15
use function file_exists;
16
use function preg_match;
17
18
final class ElementRegistry
19
{
20
    /** @var \SimpleSAML\XML\Registry\ElementRegistry|null $instance */
21
    private static ?ElementRegistry $instance = null;
22
23
    /** @var array<string, array<string, string>> */
24
    private array $registry = [];
25
26
27
    private function __construct()
28
    {
29
        // Initialize the registry with all the elements we know
30
        $classesDir = dirname(__FILE__, 7) . '/vendor/simplesamlphp/composer-xmlprovider-installer/classes';
31
32
        if (file_exists($classesDir) === true) {
33
            $directory = new DirectoryIterator($classesDir);
34
            foreach ($directory as $fileInfo) {
35
                if ($fileInfo->isFile()) {
36
                    if (preg_match('/^element\.registry\.(.*)\.php$/', $fileInfo->getFilename())) {
37
                        $this->importFromFile($fileInfo->getPathname());
38
                    }
39
                }
40
            }
41
        }
42
    }
43
44
45
    public function importFromFile(string $file): void
46
    {
47
        if (file_exists($file) === true) {
48
            $elements = include($file);
49
            $this->registry = array_merge_recursive($this->registry, $elements);
50
        } else {
51
            throw new IOException('File not found.');
52
        }
53
    }
54
55
56
    public static function getInstance(): ElementRegistry
57
    {
58
        if (self::$instance === null) {
59
            self::$instance = new static();
60
        }
61
62
        return self::$instance;
63
    }
64
65
66
    /**
67
     * Register a class that can process a certain XML-element.
68
     *
69
     * @param string $class The class name of a class extending AbstractElement.
70
     */
71
    public function registerElementHandler(string $class): void
72
    {
73
        Assert::subclassOf($class, AbstractElement::class);
74
        $className = AbstractElement::getClassName($class);
75
        $namespace = $class::NS;
76
77
        $this->registry[$namespace ?? ''][$className] = $class;
78
    }
79
80
81
    /**
82
     * Search for a class that implements an $element in the given $namespace.
83
     *
84
     * Such classes must have been registered previously by calling registerElementHandler(), and they must
85
     * extend \SimpleSAML\XML\AbstractElement.
86
     *
87
     * @param string|null $namespace The namespace URI for the given element.
88
     * @param string $element The local name of the element.
89
     *
90
     * @return string|null The fully-qualified name of a class extending \SimpleSAML\XML\AbstractElement and
91
     * implementing support for the given element, or null if no such class has been registered before.
92
     */
93
    public function getElementHandler(?string $namespace, string $element): ?string
94
    {
95
        Assert::nullOrValidURI($namespace, InvalidDOMElementException::class);
96
        Assert::validNCName($element, InvalidDOMElementException::class);
97
98
        return $this->registry[$namespace ?? ''][$element] ?? null;
99
    }
100
}
101