AbstractCondition::getXsiType()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\SAML2\XML\saml;
6
7
use DOMElement;
8
use SimpleSAML\SAML2\Assert\Assert;
9
use SimpleSAML\SAML2\Constants as C;
10
use SimpleSAML\SAML2\Utils;
11
use SimpleSAML\SAML2\XML\ExtensionPointInterface;
12
use SimpleSAML\SAML2\XML\ExtensionPointTrait;
13
use SimpleSAML\XML\Attribute as XMLAttribute;
14
use SimpleSAML\XML\Chunk;
15
use SimpleSAML\XML\Exception\InvalidDOMElementException;
16
use SimpleSAML\XML\Exception\SchemaViolationException;
17
use SimpleSAML\XML\SchemaValidatableElementInterface;
18
use SimpleSAML\XML\SchemaValidatableElementTrait;
19
20
use function count;
21
use function explode;
22
23
/**
24
 * SAML Condition data type.
25
 *
26
 * @package simplesamlphp/saml2
27
 */
28
abstract class AbstractCondition extends AbstractConditionType implements
29
    ExtensionPointInterface,
30
    SchemaValidatableElementInterface
31
{
32
    use ExtensionPointTrait;
33
    use SchemaValidatableElementTrait;
34
35
36
    /** @var string */
37
    public const LOCALNAME = 'Condition';
38
39
40
    /**
41
     * Initialize a custom saml:Condition element.
42
     *
43
     * @param string $type
44
     */
45
    protected function __construct(
46
        protected string $type,
47
    ) {
48
    }
49
50
51
    /**
52
     * @inheritDoc
53
     */
54
    public function getXsiType(): string
55
    {
56
        return $this->type;
57
    }
58
59
60
    /**
61
     * Convert an XML element into a Condition.
62
     *
63
     * @param \DOMElement $xml The root XML element
64
     * @return static
65
     *
66
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
67
     *   if the qualified name of the supplied element is wrong
68
     */
69
    public static function fromXML(DOMElement $xml): static
70
    {
71
        Assert::same($xml->localName, 'Condition', InvalidDOMElementException::class);
72
        Assert::same($xml->namespaceURI, C::NS_SAML, InvalidDOMElementException::class);
73
        Assert::true(
74
            $xml->hasAttributeNS(C::NS_XSI, 'type'),
75
            'Missing required xsi:type in <saml:Condition> element.',
76
            SchemaViolationException::class,
77
        );
78
79
        $type = $xml->getAttributeNS(C::NS_XSI, 'type');
80
        Assert::validQName($type, SchemaViolationException::class);
81
82
        // first, try to resolve the type to a full namespaced version
83
        $qname = explode(':', $type, 2);
84
        if (count($qname) === 2) {
85
            list($prefix, $element) = $qname;
86
        } else {
87
            $prefix = null;
88
            list($element) = $qname;
89
        }
90
        $ns = $xml->lookupNamespaceUri($prefix);
91
        $type = ($ns === null) ? $element : implode(':', [$ns, $element]);
92
93
        // now check if we have a handler registered for it
94
        $handler = Utils::getContainer()->getExtensionHandler($type);
95
        if ($handler === null) {
96
            // we don't have a handler, proceed with unknown condition
97
            return new UnknownCondition(new Chunk($xml), $type);
98
        }
99
100
        Assert::subclassOf(
101
            $handler,
102
            AbstractCondition::class,
103
            'Elements implementing Condition must extend \SimpleSAML\SAML2\XML\saml\AbstractCondition.',
104
        );
105
        return $handler::fromXML($xml);
106
    }
107
108
109
    /**
110
     * Convert this Condition to XML.
111
     *
112
     * @param \DOMElement $parent The element we are converting to XML.
113
     * @return \DOMElement The XML element after adding the data corresponding to this Condition.
114
     */
115
    public function toXML(?DOMElement $parent = null): DOMElement
116
    {
117
        $e = $this->instantiateParentElement($parent);
118
        $e->setAttributeNS(
119
            'http://www.w3.org/2000/xmlns/',
120
            'xmlns:' . static::getXsiTypePrefix(),
121
            static::getXsiTypeNamespaceURI(),
122
        );
123
124
        $type = new XMLAttribute(C::NS_XSI, 'xsi', 'type', $this->getXsiType());
125
        $type->toXML($e);
126
127
        return $e;
128
    }
129
}
130