SubjectConfirmationData   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 156
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 20
eloc 66
c 1
b 0
f 0
dl 0
loc 156
rs 10

5 Methods

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