Passed
Push — master ( c686fd...179aa0 )
by Tim
01:52
created

Body::setFault()   A

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
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\SOAP11\XML\env;
6
7
use DOMElement;
8
use SimpleSAML\Assert\Assert;
9
use SimpleSAML\SOAP\Constants as C;
10
use SimpleSAML\SOAP\Exception\ProtocolViolationException;
11
use SimpleSAML\XML\Chunk;
12
use SimpleSAML\XML\Exception\InvalidDOMElementException;
13
use SimpleSAML\XML\ExtendableElementTrait;
14
use SimpleSAML\XML\ExtendableAttributesTrait;
15
16
use function array_diff;
17
use function array_filter;
18
use function array_pop;
19
use function array_values;
20
21
/**
22
 * Class representing a env:Body element.
23
 *
24
 * @package simplesaml/xml-soap
25
 */
26
final class Body extends AbstractSoapElement
27
{
28
    use ExtendableAttributesTrait;
29
    use ExtendableElementTrait;
30
31
    /** The namespace-attribute for the xs:any element */
32
    public const NAMESPACE = C::XS_ANY_NS_ANY;
33
34
    /**
35
     * @var \SimpleSAML\SOAP11\XML\env\Fault|null
36
     */
37
    protected ?Fault $fault;
38
39
40
    /**
41
     * Initialize a soap:Body
42
     *
43
     * @param \SimpleSAML\XML\Chunk[] $children
44
     * @param \DOMAttr[] $namespacedAttributes
45
     */
46
    public function __construct(array $children = [], array $namespacedAttributes = [])
47
    {
48
        /**
49
         * 4.4: If present, the SOAP Fault element MUST appear as a body entry and MUST NOT
50
         * appear more than once within a Body element.
51
         */
52
        $fault =  array_values(array_filter($children, function ($elt) {
53
            return $elt instanceof Fault;
54
        }));
55
        Assert::maxCount($fault, 1, ProtocolViolationException::class);
56
57
        $this->setFault(array_pop($fault));
58
        $this->setElements(array_diff($children, $fault));
59
        $this->setAttributesNS($namespacedAttributes);
60
    }
61
62
63
    /**
64
     * @param \SimpleSAML\SOAP11\XML\env\Fault|null $fault
65
     */
66
    public function setFault(?Fault $fault): void
67
    {
68
        $this->fault = $fault;
69
    }
70
71
72
    /**
73
     * @return \SimpleSAML\SOAP11\XML\env\Fault|null
74
     */
75
    public function getFault(): ?Fault
76
    {
77
        return $this->fault;
78
    }
79
80
81
    /**
82
     * Test if an object, at the state it's in, would produce an empty XML-element
83
     *
84
     * @return bool
85
     */
86
    public function isEmptyElement(): bool
87
    {
88
        return empty($this->fault) && empty($this->elements) && empty($this->namespacedAttributes);
89
    }
90
91
92
    /*
93
     * Convert XML into an Body element
94
     *
95
     * @param \DOMElement $xml The XML element we should load
96
     * @return static
97
     *
98
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
99
     *   If the qualified name of the supplied element is wrong
100
     */
101
    public static function fromXML(DOMElement $xml): static
102
    {
103
        Assert::same($xml->localName, 'Body', InvalidDOMElementException::class);
104
        Assert::same($xml->namespaceURI, Body::NS, InvalidDOMElementException::class);
105
106
        $children = [];
107
        foreach ($xml->childNodes as $child) {
108
            if (!($child instanceof DOMElement)) {
109
                continue;
110
            } elseif ($child->namespaceURI === C::NS_SOAP_ENV_11) {
111
                if ($child->localName === 'Fault') {
112
                    Fault::fromXML($child);
113
                    continue;
114
                }
115
            }
116
            $children[] = new Chunk($child);
117
        }
118
119
        return new static(
120
            $children,
121
            self::getAttributesNSFromXML($xml)
122
        );
123
    }
124
125
126
    /**
127
     * Convert this Body to XML.
128
     *
129
     * @param \DOMElement|null $parent The element we should add this Body to.
130
     * @return \DOMElement This Body-element.
131
     */
132
    public function toXML(DOMElement $parent = null): DOMElement
133
    {
134
        $e = $this->instantiateParentElement($parent);
135
136
        foreach ($this->getAttributesNS() as $attr) {
137
            $e->setAttributeNS($attr['namespaceURI'], $attr['qualifiedName'], $attr['value']);
138
        }
139
140
        $this->getFault()?->toXML($e);
141
142
        /** @psalm-var \SimpleSAML\XML\SerializableElementInterface $child */
143
        foreach ($this->getElements() as $child) {
144
            if (!$child->isEmptyElement()) {
145
                $child->toXML($e);
146
            }
147
        }
148
149
        return $e;
150
    }
151
}
152