AbstractOperatorContentType::toXML()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 14
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 6
c 1
b 0
f 0
dl 0
loc 14
rs 10
cc 3
nc 4
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\WSSecurity\XML\wsp;
6
7
use DOMElement;
8
use InvalidArgumentException;
9
use SimpleSAML\WSSecurity\Assert\Assert;
10
use SimpleSAML\XML\Chunk;
11
use SimpleSAML\XML\Constants as C;
12
use SimpleSAML\XML\Exception\InvalidDOMElementException;
13
use SimpleSAML\XML\ExtendableElementTrait;
14
use SimpleSAML\XML\SerializableElementInterface;
15
use SimpleSAML\XML\XsNamespace as NS;
16
17
/**
18
 * Class representing a wsp:OperatorContentType element.
19
 *
20
 * @package simplesamlphp/ws-security
21
 *
22
 * @phpstan-consistent-constructor
23
 */
24
abstract class AbstractOperatorContentType extends AbstractWspElement
25
{
26
    use ExtendableElementTrait;
0 ignored issues
show
introduced by
The trait SimpleSAML\XML\ExtendableElementTrait requires some properties which are not provided by SimpleSAML\WSSecurity\XM...ractOperatorContentType: $namespaceURI, $localName, $childNodes
Loading history...
27
28
    /** The namespace-attribute for the xs:any element */
29
    public const XS_ANY_ELT_NAMESPACE = NS::OTHER;
30
31
32
    /**
33
     * Initialize a wsp:OperatorContentType
34
     *
35
     * @param (\SimpleSAML\WSSecurity\XML\wsp\All|
36
     *         \SimpleSAML\WSSecurity\XML\wsp\ExactlyOne|
37
     *         \SimpleSAML\WSSecurity\XML\wsp\Policy|
38
     *         \SimpleSAML\WSSecurity\XML\wsp\PolicyReference)[] $operatorContent
39
     * @param \SimpleSAML\XML\SerializableElementInterface[] $children
40
     */
41
    public function __construct(
42
        protected array $operatorContent = [],
43
        array $children = [],
44
    ) {
45
        Assert::maxCount($operatorContent, C::UNBOUNDED_LIMIT);
46
        Assert::maxCount($children, C::UNBOUNDED_LIMIT);
47
        Assert::allIsInstanceOfAny(
48
            $operatorContent,
49
            [All::class, ExactlyOne::class, Policy::class, PolicyReference::class],
50
            InvalidDOMElementException::class,
51
        );
52
        Assert::allIsInstanceOfAny(
53
            $children,
54
            [SerializableElementInterface::class],
55
            InvalidArgumentException::class,
56
        );
57
58
        $this->setElements($children);
59
    }
60
61
62
    /**
63
     * @return (\SimpleSAML\XML\Chunk|
0 ignored issues
show
Documentation Bug introduced by
The doc comment (\SimpleSAML\XML\Chunk| at position 3 could not be parsed: the token is null at position 3.
Loading history...
64
     *         \SimpleSAML\WSSecurity\XML\wsp\All|
65
     *         \SimpleSAML\WSSecurity\XML\wsp\ExactlyOne|
66
     *         \SimpleSAML\WSSecurity\XML\wsp\Policy|
67
     *         \SimpleSAML\WSSecurity\XML\wsp\PolicyReference)[] $operatorContent
68
     */
69
    public function getOperatorContent(): array
70
    {
71
        return $this->operatorContent;
72
    }
73
74
75
    /**
76
     * Test if an object, at the state it's in, would produce an empty XML-element
77
     *
78
     * @return bool
79
     */
80
    public function isEmptyElement(): bool
81
    {
82
        return empty($this->getOperatorContent())
83
            && empty($this->getElements());
84
    }
85
86
87
    /*
88
     * Convert XML into an wsp:OperatorContentType element
89
     *
90
     * @param \DOMElement $xml The XML element we should load
91
     * @return static
92
     *
93
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
94
     *   If the qualified name of the supplied element is wrong
95
     */
96
    public static function fromXML(DOMElement $xml): static
97
    {
98
        Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class);
99
        Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class);
100
101
        $operatorContent = $children = [];
102
        for ($n = $xml->firstChild; $n !== null; $n = $n->nextSibling) {
103
            if (!($n instanceof DOMElement)) {
104
                continue;
105
            } elseif ($n->namespaceURI === self::NS) {
106
                $operatorContent[] = match ($n->localName) {
107
                    'All' => All::fromXML($n),
108
                    'ExactlyOne' => ExactlyOne::fromXML($n),
109
                    'Policy' => Policy::fromXML($n),
110
                    'PolicyReference' => PolicyReference::fromXML($n),
111
                    default => null,
112
                };
113
                continue;
114
            }
115
116
            $children[] = new Chunk($n);
117
        }
118
119
        return new static($operatorContent, $children);
120
    }
121
122
123
    /**
124
     * Convert this wsp:OperatorContentType to XML.
125
     *
126
     * @param \DOMElement|null $parent The element we should add this wsp:OperatorContentType to.
127
     * @return \DOMElement This wsp:AbstractOperatorContentType element.
128
     */
129
    public function toXML(?DOMElement $parent = null): DOMElement
130
    {
131
        $e = $this->instantiateParentElement($parent);
132
133
        foreach ($this->getOperatorContent() as $n) {
134
            $n->toXML($e);
135
        }
136
137
        foreach ($this->getElements() as $c) {
138
            /** @psalm-var \SimpleSAML\XML\SerializableElementInterface $c */
139
            $c->toXML($e);
140
        }
141
142
        return $e;
143
    }
144
}
145