AbstractSubjectQuery::fromXML()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 30
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 18
c 1
b 0
f 0
dl 0
loc 30
rs 9.6666
cc 2
nc 2
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\SAML11\XML\samlp;
6
7
use DOMElement;
8
use SimpleSAML\SAML11\Assert\Assert;
9
use SimpleSAML\SAML11\Constants as C;
10
use SimpleSAML\SAML11\Utils;
11
use SimpleSAML\SAML11\XML\{ExtensionPointInterface, ExtensionPointTrait};
12
use SimpleSAML\SAML11\XML\saml\Subject;
13
use SimpleSAML\XML\Chunk;
14
use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait};
15
use SimpleSAML\XMLSchema\Constants as C_XSI;
16
use SimpleSAML\XMLSchema\Exception\{
17
    InvalidDOMElementException,
18
    MissingElementException,
19
    SchemaViolationException,
20
    TooManyElementsException,
21
};
22
use SimpleSAML\XMLSchema\Type\QNameValue;
23
24
use function array_pop;
25
26
/**
27
 * SAMLP Query data type.
28
 *
29
 * @package simplesamlphp/saml11
30
 */
31
abstract class AbstractSubjectQuery extends AbstractSubjectQueryAbstractType implements
32
    ExtensionPointInterface,
33
    SchemaValidatableElementInterface
34
{
35
    use ExtensionPointTrait;
36
    use SchemaValidatableElementTrait;
37
38
    /** @var string */
39
    public const LOCALNAME = 'SubjectQuery';
40
41
42
    /**
43
     * Initialize a custom samlp:SubjectQuery element.
44
     *
45
     * @param \SimpleSAML\XMLSchema\Type\QNameValue $type
46
     */
47
    protected function __construct(
48
        protected QNameValue $type,
49
        Subject $subject,
50
    ) {
51
        parent::__construct($subject);
52
    }
53
54
55
    /**
56
     * Convert an XML element into a SubjectQuery.
57
     *
58
     * @param \DOMElement $xml The root XML element
59
     * @return static
60
     *
61
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
62
     *   if the qualified name of the supplied element is wrong
63
     */
64
    public static function fromXML(DOMElement $xml): static
65
    {
66
        Assert::same($xml->localName, 'SubjectQuery', InvalidDOMElementException::class);
67
        Assert::same($xml->namespaceURI, C::NS_SAMLP, InvalidDOMElementException::class);
68
        Assert::true(
69
            $xml->hasAttributeNS(C_XSI::NS_XSI, 'type'),
70
            'Missing required xsi:type in <samlp:SubjectQuery> element.',
71
            SchemaViolationException::class,
72
        );
73
74
        $type = QNameValue::fromDocument($xml->getAttributeNS(C_XSI::NS_XSI, 'type'), $xml);
75
76
        // now check if we have a handler registered for it
77
        $handler = Utils::getContainer()->getExtensionHandler($type);
78
        if ($handler === null) {
79
            $subject = Subject::getChildrenOfClass($xml);
80
            Assert::minCount($subject, 1, MissingElementException::class);
81
            Assert::maxCount($subject, 1, TooManyElementsException::class);
82
83
            // we don't have a handler, proceed with unknown query
84
            return new UnknownSubjectQuery(new Chunk($xml), $type, array_pop($subject));
85
        }
86
87
        Assert::subclassOf(
88
            $handler,
89
            AbstractSubjectQuery::class,
90
            'Elements implementing SubjectQuery must extend \SimpleSAML\SAML11\XML\samlp\AbstractSubjectQuery.',
91
        );
92
93
        return $handler::fromXML($xml);
94
    }
95
}
96