Completed
Push — master ( da4b66...3ae217 )
by Tim
19s queued 15s
created

AbstractQuery::fromXML()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 37
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

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