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

Body   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 132
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 39
c 1
b 0
f 0
dl 0
loc 132
rs 10
wmc 15

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 24 2
A getFault() 0 3 1
A toXML() 0 16 3
A setFault() 0 3 1
A isEmptyElement() 0 3 3
A fromXML() 0 21 5
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\SOAP12\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\SOAP12\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
         * 5.4: To be recognized as carrying SOAP error information, a SOAP message MUST contain a single SOAP Fault
50
         * element information item as the only child element information item of the SOAP Body .
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
        /**
58
         * 5.4: When generating a fault, SOAP senders MUST NOT include additional element information items in the SOAP Body .
59
         */
60
        $children = array_diff($children, $fault);
61
        Assert::false(
62
            !empty($fault) && !empty($children),
63
            "When generating a fault, SOAP senders MUST NOT include additional element information items in the SOAP Body.",
64
            ProtocolViolationException::class,
65
        );
66
67
        $this->setFault(array_pop($fault));
68
        $this->setElements($children);
69
        $this->setAttributesNS($namespacedAttributes);
70
    }
71
72
73
    /**
74
     * @param \SimpleSAML\SOAP12\XML\env\Fault|null $fault
75
     */
76
    public function setFault(?Fault $fault): void
77
    {
78
        $this->fault = $fault;
79
    }
80
81
82
    /**
83
     * @return \SimpleSAML\SOAP12\XML\env\Fault|null
84
     */
85
    public function getFault(): ?Fault
86
    {
87
        return $this->fault;
88
    }
89
90
91
    /**
92
     * Test if an object, at the state it's in, would produce an empty XML-element
93
     *
94
     * @return bool
95
     */
96
    public function isEmptyElement(): bool
97
    {
98
        return empty($this->fault) && empty($this->elements) && empty($this->namespacedAttributes);
99
    }
100
101
102
    /*
103
     * Convert XML into an Body element
104
     *
105
     * @param \DOMElement $xml The XML element we should load
106
     * @return static
107
     *
108
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
109
     *   If the qualified name of the supplied element is wrong
110
     */
111
    public static function fromXML(DOMElement $xml): static
112
    {
113
        Assert::same($xml->localName, 'Body', InvalidDOMElementException::class);
114
        Assert::same($xml->namespaceURI, Body::NS, InvalidDOMElementException::class);
115
116
        $children = [];
117
        foreach ($xml->childNodes as $child) {
118
            if (!($child instanceof DOMElement)) {
119
                continue;
120
            } elseif ($child->namespaceURI === C::NS_SOAP_ENV_12) {
121
                if ($child->localName === 'Fault') {
122
                    Fault::fromXML($child);
123
                    continue;
124
                }
125
            }
126
            $children[] = new Chunk($child);
127
        }
128
129
        return new static(
130
            $children,
131
            self::getAttributesNSFromXML($xml)
132
        );
133
    }
134
135
136
    /**
137
     * Convert this Body to XML.
138
     *
139
     * @param \DOMElement|null $parent The element we should add this Body to.
140
     * @return \DOMElement This Body-element.
141
     */
142
    public function toXML(DOMElement $parent = null): DOMElement
143
    {
144
        $e = $this->instantiateParentElement($parent);
145
146
        foreach ($this->getAttributesNS() as $attr) {
147
            $e->setAttributeNS($attr['namespaceURI'], $attr['qualifiedName'], $attr['value']);
148
        }
149
150
        $this->getFault()?->toXML($e);
151
152
        /** @psalm-var \SimpleSAML\XML\SerializableElementInterface $child */
153
        foreach ($this->getElements() as $child) {
154
            $child->toXML($e);
155
        }
156
157
        return $e;
158
    }
159
}
160