Passed
Push — master ( 66592a...152b2f )
by Tim
02:08
created

DiscoHints::processArrayContents()   B

Complexity

Conditions 8
Paths 16

Size

Total Lines 53
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 32
nc 16
nop 1
dl 0
loc 53
rs 8.1635
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\SAML2\XML\mdui;
6
7
use DOMElement;
8
use SimpleSAML\Assert\Assert;
9
use SimpleSAML\SAML2\Exception\ArrayValidationException;
10
use SimpleSAML\SAML2\Utils\XPath;
11
use SimpleSAML\XML\ArrayizableElementInterface;
12
use SimpleSAML\XML\Chunk;
13
use SimpleSAML\XML\Constants as C;
14
use SimpleSAML\XML\Exception\InvalidDOMElementException;
15
use SimpleSAML\XML\ExtendableElementTrait;
16
17
use function array_filter;
18
use function array_key_exists;
19
use function array_keys;
20
21
/**
22
 * Class for handling the metadata extensions for login and discovery user interface
23
 *
24
 * @link: http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-metadata-ui/v1.0/sstc-saml-metadata-ui-v1.0.pdf
25
 * @package simplesamlphp/saml2
26
 */
27
final class DiscoHints extends AbstractMduiElement implements ArrayizableElementInterface
28
{
29
    use ExtendableElementTrait;
30
31
    /** The namespace-attribute for the xs:any element */
32
    public const XS_ANY_ELT_NAMESPACE = C::XS_ANY_NS_OTHER;
33
34
35
    /**
36
     * Create a DiscoHints element.
37
     *
38
     * @param \SimpleSAML\XML\Chunk[] $children
39
     * @param \SimpleSAML\SAML2\XML\mdui\IPHint[] $ipHint
40
     * @param \SimpleSAML\SAML2\XML\mdui\DomainHint[] $domainHint
41
     * @param \SimpleSAML\SAML2\XML\mdui\GeolocationHint[] $geolocationHint
42
     */
43
    public function __construct(
44
        array $children = [],
45
        protected array $ipHint = [],
46
        protected array $domainHint = [],
47
        protected array $geolocationHint = [],
48
    ) {
49
        Assert::allIsInstanceOf($ipHint, IPHint::class);
50
        Assert::allIsInstanceOf($domainHint, DomainHint::class);
51
        Assert::allIsInstanceOf($geolocationHint, GeolocationHint::class);
52
53
        $this->setElements($children);
54
    }
55
56
57
    /**
58
     * Collect the value of the IPHint-property
59
     *
60
     * @return \SimpleSAML\SAML2\XML\mdui\IPHint[]
61
     */
62
    public function getIPHint(): array
63
    {
64
        return $this->ipHint;
65
    }
66
67
68
    /**
69
     * Collect the value of the DomainHint-property
70
     *
71
     * @return \SimpleSAML\SAML2\XML\mdui\DomainHint[]
72
     */
73
    public function getDomainHint(): array
74
    {
75
        return $this->domainHint;
76
    }
77
78
79
    /**
80
     * Collect the value of the GeolocationHint-property
81
     *
82
     * @return \SimpleSAML\SAML2\XML\mdui\GeolocationHint[]
83
     */
84
    public function getGeolocationHint(): array
85
    {
86
        return $this->geolocationHint;
87
    }
88
89
90
    /**
91
     * Add the value to the elements-property
92
     *
93
     * @param \SimpleSAML\XML\Chunk $child
94
     */
95
    public function addChild(Chunk $child): void
96
    {
97
        $this->elements[] = $child;
98
    }
99
100
101
    /**
102
     * Test if an object, at the state it's in, would produce an empty XML-element
103
     *
104
     * @return bool
105
     */
106
    public function isEmptyElement(): bool
107
    {
108
        return empty($this->elements)
109
            && empty($this->ipHint)
110
            && empty($this->domainHint)
111
            && empty($this->geolocationHint);
112
    }
113
114
115
    /**
116
     * Convert XML into a DiscoHints
117
     *
118
     * @param \DOMElement $xml The XML element we should load
119
     * @return static
120
     *
121
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
122
     *   if the qualified name of the supplied element is wrong
123
     */
124
    public static function fromXML(DOMElement $xml): static
125
    {
126
        Assert::same($xml->localName, 'DiscoHints', InvalidDOMElementException::class);
127
        Assert::same($xml->namespaceURI, DiscoHints::NS, InvalidDOMElementException::class);
128
129
        $IPHint = IPHint::getChildrenOfClass($xml);
130
        $DomainHint = DomainHint::getChildrenOfClass($xml);
131
        $GeolocationHint = GeolocationHint::getChildrenOfClass($xml);
132
        $children = [];
133
134
        /** @var \DOMElement[] $nodes */
135
        $nodes = XPath::xpQuery($xml, "./*[namespace-uri()!='" . DiscoHints::NS . "']", XPath::getXPath($xml));
136
        foreach ($nodes as $node) {
137
            $children[] = new Chunk($node);
138
        }
139
140
        return new static($children, $IPHint, $DomainHint, $GeolocationHint);
141
    }
142
143
144
    /**
145
     * Convert this DiscoHints to XML.
146
     *
147
     * @param \DOMElement|null $parent The element we should append to.
148
     * @return \DOMElement
149
     */
150
    public function toXML(DOMElement $parent = null): DOMElement
151
    {
152
        $e = $this->instantiateParentElement($parent);
153
154
        foreach ($this->getIPHint() as $hint) {
155
            $hint->toXML($e);
156
        }
157
158
        foreach ($this->getDomainHint() as $hint) {
159
            $hint->toXML($e);
160
        }
161
162
        foreach ($this->getGeolocationHint() as $hint) {
163
            $hint->toXML($e);
164
        }
165
166
        /** @var \SimpleSAML\XML\SerializableElementInterface $child */
167
        foreach ($this->getElements() as $child) {
168
            $child->toXML($e);
169
        }
170
171
        return $e;
172
    }
173
174
175
    /**
176
     * Create a class from an array
177
     *
178
     * @param array $data
179
     * @return static
180
     */
181
    public static function fromArray(array $data): static
182
    {
183
        $data = self::processArrayContents($data);
184
185
        return new static(
186
            $data['children'] ?? [],
187
            $data['IPHint'] ?? [],
188
            $data['DomainHint'] ?? [],
189
            $data['GeolocationHint'] ?? [],
190
        );
191
    }
192
193
194
    /**
195
     * Validates an array representation of this object and returns the same array with
196
     * rationalized keys (casing) and parsed sub-elements.
197
     *
198
     * @param array $data
199
     * @return array $data
200
     */
201
    private static function processArrayContents(array $data): array
202
    {
203
        $data = array_change_key_case($data, CASE_LOWER);
204
205
        // Make sure the array keys are known for this kind of object
206
        Assert::allOneOf(
207
            array_keys($data),
208
            [
209
                'iphint',
210
                'domainhint',
211
                'geolocationhint',
212
                'children',
213
            ],
214
            ArrayValidationException::class,
215
        );
216
217
        $retval = [];
218
219
        if (array_key_exists('iphint', $data)) {
220
            Assert::isArray($data['iphint'], ArrayValidationException::class);
221
            Assert::allString($data['iphint'], ArrayValidationException::class);
222
            foreach ($data['iphint'] as $hint) {
223
                $retval['IPHint'][] = new IPHint($hint);
224
            }
225
        }
226
227
        if (array_key_exists('domainhint', $data)) {
228
            Assert::isArray($data['domainhint'], ArrayValidationException::class);
229
            Assert::allString($data['domainhint'], ArrayValidationException::class);
230
            foreach ($data['domainhint'] as $hint) {
231
                $retval['DomainHint'][] = new DomainHint($hint);
232
            }
233
        }
234
235
        if (array_key_exists('geolocationhint', $data)) {
236
            Assert::isArray($data['geolocationhint'], ArrayValidationException::class);
237
            Assert::allString($data['geolocationhint'], ArrayValidationException::class);
238
            foreach ($data['geolocationhint'] as $hint) {
239
                $retval['GeolocationHint'][] = new GeolocationHint($hint);
240
            }
241
        }
242
243
        if (array_key_exists('children', $data)) {
244
            Assert::isArray($data['children'], ArrayValidationException::class);
245
            Assert::allIsInstanceOf(
246
                $data['children'],
247
                SerializableElementInterface::class,
0 ignored issues
show
Bug introduced by
The type SimpleSAML\SAML2\XML\mdu...lizableElementInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
248
                ArrayValidationException::class,
249
            );
250
            $retval['children'] = $data['children'];
251
        }
252
253
        return $retval;
254
    }
255
256
257
    /**
258
     * Create an array from this class
259
     *
260
     * @return array
261
     */
262
    public function toArray(): array
263
    {
264
        $data = [
265
            'IPHint' => [],
266
            'DomainHint' => [],
267
            'GeolocationHint' => [],
268
            'children' => $this->getElements(),
269
        ];
270
271
        foreach ($this->getIPHint() as $hint) {
272
            $data['IPHint'][] = $hint->getContent();
273
        }
274
275
        foreach ($this->getDomainHint() as $hint) {
276
            $data['DomainHint'][] = $hint->getContent();
277
        }
278
279
        foreach ($this->getGeolocationHint() as $hint) {
280
            $data['GeolocationHint'][] = $hint->getContent();
281
        }
282
283
        return array_filter($data);
284
    }
285
}
286