Passed
Push — master ( 612985...f12b4f )
by Tim
01:50
created

ExtendableElementTrait::getNamespace()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 5
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 8
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\XML;
6
7
use DOMElement;
8
use RuntimeException;
9
use SimpleSAML\Assert\Assert;
10
use SimpleSAML\XML\Constants;
11
12
/**
13
 * Trait grouping common functionality for elements implementing the xs:any element.
14
 *
15
 * @package simplesamlphp/xml-common
16
 */
17
trait ExtendableElementTrait
18
{
19
    /** @var \SimpleSAML\XML\XMLElementInterface[] */
20
    protected array $elements = [];
21
22
23
    /**
24
     * Set an array with all elements present.
25
     *
26
     * @param array \SimpleSAML\XML\XMLElementInterface[]
27
     */
28
    protected function setElements(array $elements): void
29
    {
30
        Assert::allIsInstanceOf($elements, XMLElementInterface::class);
31
        $namespace = $this->getNamespace();
32
33
        // Validate namespace value
34
        Assert::true(is_array($namespace) || is_string($namespace));
35
        if (!is_array($namespace)) {
36
            // Must be one of the predefined values
37
            Assert::oneOf($namespace, Constants::XS_ANY_NS);
38
        } else {
39
            // Array must be non-empty and cannot contain ##any or ##other
40
            Assert::notEmpty($namespace);
41
            Assert::allNotSame($namespace, Constants::XS_ANY_NS_ANY);
42
            Assert::allNotSame($namespace, Constants::XS_ANY_NS_OTHER);
43
        }
44
45
        // Get namespaces for all elements
46
        $actual_namespaces = array_map(
47
            function ($elt) {
48
                return $elt->getNamespaceURI();
49
            },
50
            $elements
51
        );
52
53
        if ($namespace === Constants::XS_ANY_NS_LOCAL) {
54
            // If ##local then all namespaces must be null
55
            Assert::allNull($actual_namespaces);
56
        } elseif (is_array($namespace)) {
57
            // Make a local copy of the property that we can edit
58
            $allowed_namespaces = $namespace;
59
60
            // Replace the ##targetedNamespace with the actual namespace
61
            if (($key = array_search(Constants::XS_ANY_NS_TARGET, $allowed_namespaces)) !== false) {
62
                $allowed_namespaces[$key] = static::NS;
1 ignored issue
show
Bug introduced by
The constant SimpleSAML\XML\ExtendableElementTrait::NS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
63
            }
64
65
            // Replace the ##local with null
66
            if (($key = array_search(Constants::XS_ANY_NS_LOCAL, $allowed_namespaces)) !== false) {
67
                $allowed_namespaces[$key] = null;
68
            }
69
70
            $diff = array_diff($actual_namespaces, $allowed_namespaces);
71
            Assert::isEmpty(
72
                $diff,
73
                sprintf(
74
                    'Elements from namespaces [ %s ] are not allowed inside a %s element.',
75
                    rtrim(implode(', ', $diff)),
76
                    static::NS
77
                )
78
            );
79
        } else {
80
            // All elements must be namespaced, ergo non-null
81
            Assert::allNotNull($actual_namespaces);
82
83
            if ($namespace === Constants::XS_ANY_NS_OTHER) {
84
                // Must be any namespace other than the parent element
85
                Assert::allNotSame($actual_namespaces, static::NS);
86
            } elseif ($namespace === Constants::XS_ANY_NS_TARGET) {
87
                // Must be the same namespace as the one of the parent element
88
                Assert::allSame($actual_namespaces, static::NS);
89
            }
90
        }
91
92
        $this->elements = $elements;
93
    }
94
95
96
    /**
97
     * Get an array with all elements present.
98
     *
99
     * @return \SimpleSAML\XML\XMLElementInterface[]
100
     */
101
    public function getElements(): array
102
    {
103
        return $this->elements;
104
    }
105
106
107
    /**
108
     * @return array|string
109
     */
110
    public function getNamespace()
111
    {
112
        Assert::true(
113
            defined('static::NAMESPACE'),
114
            self::getClassName(static::class) . '::NAMESPACE constant must be defined and set to the namespace for the xs:any element.',
115
            RuntimeException::class
116
        );
117
        return static::NAMESPACE;
1 ignored issue
show
Bug introduced by
The constant SimpleSAML\XML\ExtendableElementTrait::NAMESPACE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
118
    }
119
}
120