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

AbstractSubjectQuery::toXML()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

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