Passed
Pull Request — master (#21)
by Jaime Pérez
02:00
created

Transform::setXPath()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 11
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\XMLSecurity\XML\ds;
6
7
use DOMElement;
8
use SimpleSAML\XMLSecurity\Constants as C;
9
use SimpleSAML\XMLSecurity\XML\ec\InclusiveNamespaces;
10
use Webmozart\Assert\Assert;
11
12
/**
13
 * Class representing transforms.
14
 *
15
 * @package simplesamlphp/xml-security
16
 */
17
class Transform extends AbstractDsElement
18
{
19
    /**
20
     * The algorithm used for this transform.
21
     *
22
     * @var string
23
     */
24
    protected string $algorithm;
25
26
    /**
27
     * An XPath object.
28
     *
29
     * @var XPath|null
30
     */
31
    protected XPath $xpath;
32
33
    /**
34
     * An InclusiveNamespaces object.
35
     *
36
     * @var InclusiveNamespaces|null
37
     */
38
    protected InclusiveNamespaces $inclusiveNamespaces;
39
40
41
    /**
42
     * Initialize the Transform element.
43
     *
44
     * @param string $algorithm
45
     * @param XPath|null $xpath
46
     * @param InclusiveNamespaces|null $prefixes
47
     */
48
    public function __construct(
49
        string $algorithm,
50
        ?XPath $xpath,
51
        ?InclusiveNamespaces $inclusiveNamespaces
52
    ) {
53
        $this->setAlgorithm($algorithm);
54
        $this->setXPath($xpath);
55
        $this->setInclusiveNamespaces($inclusiveNamespaces);
56
    }
57
58
59
    /**
60
     * Get the algorithm associated with this transform.
61
     *
62
     * @return string
63
     */
64
    public function getAlgorithm(): string
65
    {
66
        return $this->algorithm;
67
    }
68
69
70
    /**
71
     * Set the value of the algorithm property.
72
     *
73
     * @param string $algorithm
74
     */
75
    private function setAlgorithm(string $algorithm): void
76
    {
77
        Assert::oneOf(
78
            $algorithm,
79
            [
80
                C::C14N_EXCLUSIVE_WITH_COMMENTS,
81
                C::C14N_EXCLUSIVE_WITHOUT_COMMENTS,
82
                C::C14N_INCLUSIVE_WITH_COMMENTS,
83
                C::C14N_INCLUSIVE_WITHOUT_COMMENTS
84
            ],
85
            'Unsupported Transform algorithm.'
86
        );
87
    }
88
89
90
    /**
91
     * Get the XPath associated with this transform.
92
     *
93
     * @return XPath|null
94
     */
95
    public function getXPath(): XPath
96
    {
97
        return $this->xpath;
98
    }
99
100
101
    /**
102
     * Set and validate the XPath object.
103
     *
104
     * @param XPath|null $XPath
105
     */
106
    private function setXPath(?XPath $xpath): void
107
    {
108
        if ($xpath === null) {
109
            return;
110
        }
111
        Assert::eq(
112
            $this->algorithm,
113
            C::XPATH_URI,
114
            'Transform algorithm "' . C::XPATH_URI . '" required if XPath provided.'
115
        );
116
        $this->xpath = $xpath;
117
    }
118
119
120
    /**
121
     * Get the InclusiveNamespaces associated with this transform.
122
     *
123
     * @return InclusiveNamespaces|null
124
     */
125
    public function getInclusiveNamespaces(): array
126
    {
127
        return $this->inclusiveNamespaces;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->inclusiveNamespaces returns the type SimpleSAML\XMLSecurity\XML\ec\InclusiveNamespaces which is incompatible with the type-hinted return array.
Loading history...
128
    }
129
130
131
    /**
132
     * Set and validate the InclusiveNamespaces object.
133
     *
134
     * @param InclusiveNamespaces|null $inclusiveNamespaces
135
     */
136
    private function setInclusiveNamespaces(?InclusiveNamespaces $inclusiveNamespaces)
137
    {
138
        if ($inclusiveNamespaces === null) {
139
            return;
140
        }
141
        Assert::oneOf(
142
            $this->algorithm,
143
            [
144
                C::C14N_INCLUSIVE_WITH_COMMENTS,
145
                C::C14N_EXCLUSIVE_WITHOUT_COMMENTS
146
            ],
147
            'Transform algorithm "' . C::C14N_EXCLUSIVE_WITH_COMMENTS . '" or "' .
148
            C::C14N_EXCLUSIVE_WITHOUT_COMMENTS . '" required if InclusiveNamespaces provided.'
149
        );
150
        $this->inclusiveNamespaces = $inclusiveNamespaces;
151
    }
152
153
154
    /**
155
     * Convert XML into a Transform element.
156
     *
157
     * @param \DOMElement $xml The XML element we should load.
158
     * @return self
159
     */
160
    public static function fromXML(DOMElement $xml): object
161
    {
162
        $alg = self::getAttribute($xml, 'Algorithm');
163
        $xpath = XPath::getChildrenOfClass($xml);
164
        Assert::maxCount($xpath, 1, 'Only one XPath element supported per Transform.');
165
        $prefixes = InclusiveNamespaces::getChildrenOfClass($xml);
166
        Assert::maxCount(
167
            $prefixes,
168
            1,
169
            'Only one InclusiveNamespaces element supported per Transform.'
170
        );
171
172
        return new self($alg, array_pop($xpath), array_pop($prefixes));
173
    }
174
175
176
    /**
177
     * Convert this Transform element to XML.
178
     *
179
     * @param \DOMElement|null $parent The element we should append this Transform element to.
180
     * @return \DOMElement
181
     */
182
    public function toXML(DOMElement $parent = null): DOMElement
183
    {
184
        $e = $this->instantiateParentElement($parent);
185
186
        $e->setAttribute('Algorithm', $this->algorithm);
187
188
        switch ($this->algorithm) {
189
            case C::XPATH_URI:
190
                if ($this->xpath !== null) {
191
                    $this->xpath->toXML($e);
192
                }
193
                break;
194
            case C::C14N_EXCLUSIVE_WITH_COMMENTS:
195
            case C::C14N_EXCLUSIVE_WITHOUT_COMMENTS:
196
                if ($this->inclusiveNamespaces !== null) {
197
                    $this->inclusiveNamespaces->toXML($e);
198
                }
199
        }
200
201
        return $e;
202
    }
203
}
204