Passed
Push — master ( a343df...d20b40 )
by Tim
10:40
created

Transform::setInclusiveNamespaces()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 11
nc 2
nop 1
dl 0
loc 20
rs 9.9
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\XMLSecurity\XML\ds;
6
7
use DOMElement;
8
use SimpleSAML\Assert\Assert;
9
use SimpleSAML\XML\Exception\InvalidDOMElementException;
10
use SimpleSAML\XML\Exception\SchemaViolationException;
11
use SimpleSAML\XML\Exception\TooManyElementsException;
12
use SimpleSAML\XMLSecurity\Constants as C;
13
use SimpleSAML\XMLSecurity\XML\ec\InclusiveNamespaces;
14
15
use function array_pop;
16
17
/**
18
 * Class representing transforms.
19
 *
20
 * @package simplesamlphp/xml-security
21
 */
22
class Transform extends AbstractDsElement
23
{
24
    /**
25
     * Initialize the Transform element.
26
     *
27
     * @param string $algorithm
28
     * @param \SimpleSAML\XMLSecurity\XML\ds\XPath|null $xpath
29
     * @param \SimpleSAML\XMLSecurity\XML\ec\InclusiveNamespaces|null $prefixes
30
     */
31
    final public function __construct(
32
        protected string $algorithm,
33
        protected ?XPath $xpath = null,
34
        protected ?InclusiveNamespaces $inclusiveNamespaces = null,
35
    ) {
36
        Assert::validURI($algorithm, SchemaViolationException::class);
37
38
        if ($xpath !== null) {
39
            Assert::nullOrEq(
40
                $this->algorithm,
41
                C::XPATH_URI,
42
                sprintf('Transform algorithm "%s" required if XPath provided.', C::XPATH_URI),
43
            );
44
        }
45
46
        if ($inclusiveNamespaces !== null) {
47
            Assert::oneOf(
48
                $this->algorithm,
49
                [
50
                    C::C14N_INCLUSIVE_WITH_COMMENTS,
51
                    C::C14N_EXCLUSIVE_WITHOUT_COMMENTS,
52
                ],
53
                sprintf(
54
                    'Transform algorithm "%s" or "%s" required if InclusiveNamespaces provided.',
55
                    C::C14N_EXCLUSIVE_WITH_COMMENTS,
56
                    C::C14N_EXCLUSIVE_WITHOUT_COMMENTS
57
                ),
58
            );
59
        }
60
    }
61
62
63
    /**
64
     * Get the algorithm associated with this transform.
65
     *
66
     * @return string
67
     */
68
    public function getAlgorithm(): string
69
    {
70
        return $this->algorithm;
71
    }
72
73
74
    /**
75
     * Get the XPath associated with this transform.
76
     *
77
     * @return \SimpleSAML\XMLSecurity\XML\ds\XPath|null
78
     */
79
    public function getXPath(): ?XPath
80
    {
81
        return $this->xpath;
82
    }
83
84
85
    /**
86
     * Get the InclusiveNamespaces associated with this transform.
87
     *
88
     * @return \SimpleSAML\XMLSecurity\XML\ec\InclusiveNamespaces|null
89
     */
90
    public function getInclusiveNamespaces(): ?InclusiveNamespaces
91
    {
92
        return $this->inclusiveNamespaces;
93
    }
94
95
96
    /**
97
     * Convert XML into a Transform element.
98
     *
99
     * @param \DOMElement $xml The XML element we should load.
100
     * @return static
101
     */
102
    public static function fromXML(DOMElement $xml): static
103
    {
104
        Assert::same($xml->localName, 'Transform', InvalidDOMElementException::class);
105
        Assert::same($xml->namespaceURI, Transform::NS, InvalidDOMElementException::class);
106
107
        /** @psalm-var string $alg */
108
        $alg = self::getAttribute($xml, 'Algorithm');
109
110
        $xpath = XPath::getChildrenOfClass($xml);
111
        Assert::maxCount($xpath, 1, 'Only one XPath element supported per Transform.', TooManyElementsException::class);
112
113
        $prefixes = InclusiveNamespaces::getChildrenOfClass($xml);
114
        Assert::maxCount(
115
            $prefixes,
116
            1,
117
            'Only one InclusiveNamespaces element supported per Transform.',
118
            TooManyElementsException::class,
119
        );
120
121
        return new static($alg, array_pop($xpath), array_pop($prefixes));
122
    }
123
124
125
    /**
126
     * Convert this Transform element to XML.
127
     *
128
     * @param \DOMElement|null $parent The element we should append this Transform element to.
129
     * @return \DOMElement
130
     */
131
    public function toXML(DOMElement $parent = null): DOMElement
132
    {
133
        $e = $this->instantiateParentElement($parent);
134
135
        $algorithm = $this->getAlgorithm();
136
        $e->setAttribute('Algorithm', $algorithm);
137
138
        switch ($algorithm) {
139
            case C::XPATH_URI:
140
                $this->getXpath()?->toXML($e);
141
                break;
142
            case C::C14N_EXCLUSIVE_WITH_COMMENTS:
143
            case C::C14N_EXCLUSIVE_WITHOUT_COMMENTS:
144
                $this->getInclusiveNamespaces()?->toXML($e);
145
                break;
146
        }
147
148
        return $e;
149
    }
150
}
151