Passed
Pull Request — master (#6)
by Tim
02:33
created

SubjectConfirmationData::toXML()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 38
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 29
c 1
b 0
f 0
dl 0
loc 38
rs 8.8337
cc 6
nc 6
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\SAML11\XML\saml;
6
7
use DOMElement;
8
use SimpleSAML\Assert\Assert;
9
use SimpleSAML\SAML11\Constants as C;
10
use SimpleSAML\SAML11\Type\StringValue;
11
use SimpleSAML\XML\AbstractElement;
12
use SimpleSAML\XML\Attribute as XMLAttribute;
13
use SimpleSAML\XML\Chunk;
14
use SimpleSAML\XML\Exception\InvalidDOMElementException;
15
use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait};
16
use SimpleSAML\XML\Type\{IntegerValue, ValueTypeInterface};
17
18
use function class_exists;
19
use function explode;
20
use function gettype;
21
use function str_contains;
22
use function strval;
23
24
/**
25
 * Serializable class representing an SubjectConfirmationData.
26
 *
27
 * @package simplesamlphp/saml11
28
 */
29
class SubjectConfirmationData extends AbstractSamlElement implements SchemaValidatableElementInterface
30
{
31
    use SchemaValidatableElementTrait;
32
33
    /**
34
     * Create an SubjectConfirmationData.
35
     *
36
     * @param mixed $value The value of this element. Can be one of:
37
     *  - \SimpleSAML\XML\Type\IntegerValue
38
     *  - \SimpleSAML\SAML11\Type\StringValue
39
     *  - null
40
     *  - \SimpleSAML\XML\AbstractElement
41
     *
42
     * @throws \SimpleSAML\Assert\AssertionFailedException if the supplied value is neither a string or a DOMElement
43
     */
44
    final public function __construct(
45
        protected StringValue|IntegerValue|null|AbstractElement $value,
46
    ) {
47
    }
48
49
50
    /**
51
     * Get the XSI type of this attribute value.
52
     *
53
     * @return string
54
     */
55
    public function getXsiType(): string
56
    {
57
        $value = $this->getValue();
58
59
        if ($value === null) {
60
            return 'xs:nil';
61
        } elseif ($value instanceof ValueTypeInterface) {
62
            return $value::SCHEMA_TYPE;
63
        } else {
64
            return sprintf(
65
                '%s:%s',
66
                $value::getNamespacePrefix(),
67
                $value::getLocalName(),
68
            );
69
        }
70
    }
71
72
73
    /**
74
     * Get this attribute value.
75
     *
76
     * @return string|int|\SimpleSAML\XML\AbstractElement[]|null
77
     */
78
    public function getValue(): StringValue|IntegerValue|AbstractElement|null
79
    {
80
        return $this->value;
81
    }
82
83
84
    /**
85
     * Convert XML into a SubjectConfirmationData
86
     *
87
     * @param \DOMElement $xml The XML element we should load
88
     * @return static
89
     *
90
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
91
     *   if the qualified name of the supplied element is wrong
92
     */
93
    public static function fromXML(DOMElement $xml): static
94
    {
95
        Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class);
96
        Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class);
97
98
        if ($xml->childElementCount > 0) {
99
            $node = $xml->firstElementChild;
100
101
            if (str_contains($node->tagName, ':')) {
102
                list($prefix, $eltName) = explode(':', $node->tagName);
103
                $className = sprintf('\SimpleSAML\SAML11\XML\%s\%s', $prefix, $eltName);
104
105
                if (class_exists($className)) {
106
                    $value = $className::fromXML($node);
107
                } else {
108
                    $value = Chunk::fromXML($node);
109
                }
110
            } else {
111
                $value = Chunk::fromXML($node);
112
            }
113
        } elseif (
114
            $xml->hasAttributeNS(C::NS_XSI, "type") &&
115
            $xml->getAttributeNS(C::NS_XSI, "type") === "xs:integer"
116
        ) {
117
            // we have an integer as value
118
            $value = IntegerValue::fromString($xml->textContent);
119
        } elseif (
120
            // null value
121
            $xml->hasAttributeNS(C::NS_XSI, "nil") &&
122
            ($xml->getAttributeNS(C::NS_XSI, "nil") === "1" ||
123
                $xml->getAttributeNS(C::NS_XSI, "nil") === "true")
124
        ) {
125
            $value = null;
126
        } else {
127
            $value = StringValue::fromString($xml->textContent);
128
        }
129
130
        return new static($value);
131
    }
132
133
134
    /**
135
     * Append this attribute value to an element.
136
     *
137
     * @param \DOMElement|null $parent The element we should append this attribute value to.
138
     *
139
     * @return \DOMElement The generated SubjectConfirmationData element.
140
     */
141
    public function toXML(?DOMElement $parent = null): DOMElement
142
    {
143
        $e = parent::instantiateParentElement($parent);
144
145
        $value = $this->getValue();
146
        $type = gettype($value);
147
148
        switch ($type) {
149
            case "integer":
150
                // make sure that the xs namespace is available in the SubjectConfirmationData
151
                $e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xsi', C::NS_XSI);
152
                $e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xs', C::NS_XS);
153
                $e->setAttributeNS(C::NS_XSI, 'xsi:type', 'xs:integer');
154
                $e->textContent = strval($value);
155
                break;
156
            case "NULL":
157
                $e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xsi', C::NS_XSI);
158
                $e->setAttributeNS(C::NS_XSI, 'xsi:nil', '1');
159
                $e->textContent = '';
160
                break;
161
            case "object":
162
                if ($value instanceof ValueTypeInterface) {
163
                    if ($this->value instanceof IntegerValue) {
164
                        $e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xsi', C::NS_XSI);
165
                        $e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xs', C::NS_XS);
166
                        $e->setAttributeNS(C::NS_XSI, 'xsi:type', 'xs:integer');
167
                    }
168
                    $e->textContent = strval($value);
169
                } else {
170
                    $value->toXML($e);
171
                }
172
                break;
173
            default: // string
174
                $e->textContent = strval($value);
175
                break;
176
        }
177
178
        return $e;
179
    }
180
}
181