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