Passed
Branch feature/php83 (cb5cde)
by Tim
14:20
created

DiscoHints::processArrayContents()   B

Complexity

Conditions 8
Paths 16

Size

Total Lines 59
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 35
nc 16
nop 1
dl 0
loc 59
rs 8.1155
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\SAML2\Assert\Assert;
9
use SimpleSAML\SAML2\Exception\ArrayValidationException;
10
use SimpleSAML\SAML2\Type\CIDRValue;
11
use SimpleSAML\SAML2\Type\DomainValue;
12
use SimpleSAML\SAML2\Type\GeolocationValue;
13
use SimpleSAML\XML\ArrayizableElementInterface;
14
use SimpleSAML\XML\Constants as C;
15
use SimpleSAML\XML\ExtendableElementTrait;
16
use SimpleSAML\XML\SchemaValidatableElementInterface;
17
use SimpleSAML\XML\SchemaValidatableElementTrait;
18
use SimpleSAML\XML\SerializableElementInterface;
19
use SimpleSAML\XMLSchema\Exception\InvalidDOMElementException;
20
use SimpleSAML\XMLSchema\XML\Constants\NS;
21
22
use function array_filter;
23
use function array_key_exists;
24
use function array_keys;
25
26
/**
27
 * Class for handling the metadata extensions for login and discovery user interface
28
 *
29
 * @link: http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-metadata-ui/v1.0/sstc-saml-metadata-ui-v1.0.pdf
30
 *
31
 * @package simplesamlphp/saml2
32
 */
33
final class DiscoHints extends AbstractMduiElement implements
34
    ArrayizableElementInterface,
35
    SchemaValidatableElementInterface
36
{
37
    use ExtendableElementTrait;
38
    use SchemaValidatableElementTrait;
39
40
41
    /** The namespace-attribute for the xs:any element */
42
    public const string XS_ANY_ELT_NAMESPACE = NS::OTHER;
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected T_STRING, expecting '=' on line 42 at column 24
Loading history...
43
44
45
    /**
46
     * Create a DiscoHints element.
47
     *
48
     * @param \SimpleSAML\XML\SerializableElementInterface[] $children
49
     * @param \SimpleSAML\SAML2\XML\mdui\IPHint[] $ipHint
50
     * @param \SimpleSAML\SAML2\XML\mdui\DomainHint[] $domainHint
51
     * @param \SimpleSAML\SAML2\XML\mdui\GeolocationHint[] $geolocationHint
52
     */
53
    public function __construct(
54
        array $children = [],
55
        protected array $ipHint = [],
56
        protected array $domainHint = [],
57
        protected array $geolocationHint = [],
58
    ) {
59
        Assert::maxCount($ipHint, C::UNBOUNDED_LIMIT);
60
        Assert::maxCount($domainHint, C::UNBOUNDED_LIMIT);
61
        Assert::maxCount($geolocationHint, C::UNBOUNDED_LIMIT);
62
        Assert::allIsInstanceOf($ipHint, IPHint::class);
63
        Assert::allIsInstanceOf($domainHint, DomainHint::class);
64
        Assert::allIsInstanceOf($geolocationHint, GeolocationHint::class);
65
66
        $this->setElements($children);
67
    }
68
69
70
    /**
71
     * Collect the value of the IPHint-property
72
     *
73
     * @return \SimpleSAML\SAML2\XML\mdui\IPHint[]
74
     */
75
    public function getIPHint(): array
76
    {
77
        return $this->ipHint;
78
    }
79
80
81
    /**
82
     * Collect the value of the DomainHint-property
83
     *
84
     * @return \SimpleSAML\SAML2\XML\mdui\DomainHint[]
85
     */
86
    public function getDomainHint(): array
87
    {
88
        return $this->domainHint;
89
    }
90
91
92
    /**
93
     * Collect the value of the GeolocationHint-property
94
     *
95
     * @return \SimpleSAML\SAML2\XML\mdui\GeolocationHint[]
96
     */
97
    public function getGeolocationHint(): array
98
    {
99
        return $this->geolocationHint;
100
    }
101
102
103
    /**
104
     * Add the value to the elements-property
105
     *
106
     * @param \SimpleSAML\XML\SerializableElementInterface $child
107
     */
108
    public function addChild(SerializableElementInterface $child): void
109
    {
110
        $this->elements[] = $child;
111
    }
112
113
114
    /**
115
     * Test if an object, at the state it's in, would produce an empty XML-element
116
     */
117
    public function isEmptyElement(): bool
118
    {
119
        return empty($this->getElements())
120
            && empty($this->getIPHint())
121
            && empty($this->getDomainHint())
122
            && empty($this->getGeolocationHint());
123
    }
124
125
126
    /**
127
     * Convert XML into a DiscoHints
128
     *
129
     * @throws \SimpleSAML\XMLSchema\Exception\InvalidDOMElementException
130
     *   if the qualified name of the supplied element is wrong
131
     */
132
    public static function fromXML(DOMElement $xml): static
133
    {
134
        Assert::same($xml->localName, 'DiscoHints', InvalidDOMElementException::class);
135
        Assert::same($xml->namespaceURI, DiscoHints::NS, InvalidDOMElementException::class);
136
137
        $IPHint = IPHint::getChildrenOfClass($xml);
138
        $DomainHint = DomainHint::getChildrenOfClass($xml);
139
        $GeolocationHint = GeolocationHint::getChildrenOfClass($xml);
140
        $children = self::getChildElementsFromXML($xml);
141
142
        return new static($children, $IPHint, $DomainHint, $GeolocationHint);
143
    }
144
145
146
    /**
147
     * Convert this DiscoHints to XML.
148
     */
149
    public function toXML(?DOMElement $parent = null): DOMElement
150
    {
151
        $e = $this->instantiateParentElement($parent);
152
153
        foreach ($this->getIPHint() as $hint) {
154
            $hint->toXML($e);
155
        }
156
157
        foreach ($this->getDomainHint() as $hint) {
158
            $hint->toXML($e);
159
        }
160
161
        foreach ($this->getGeolocationHint() as $hint) {
162
            $hint->toXML($e);
163
        }
164
165
        /** @var \SimpleSAML\XML\SerializableElementInterface $child */
166
        foreach ($this->getElements() as $child) {
167
            $child->toXML($e);
168
        }
169
170
        return $e;
171
    }
172
173
174
    /**
175
     * Create a class from an array
176
     *
177
     * @param array{
178
     *   'children'?: array,
179
     *   'IPHint'?: array,
180
     *   'DomainHint'?: array,
181
     *   'GeolocationHint'?: array,
182
     * } $data
183
     */
184
    public static function fromArray(array $data): static
185
    {
186
        $data = self::processArrayContents($data);
187
188
        return new static(
189
            $data['children'] ?? [],
190
            $data['IPHint'] ?? [],
191
            $data['DomainHint'] ?? [],
192
            $data['GeolocationHint'] ?? [],
193
        );
194
    }
195
196
197
    /**
198
     * Validates an array representation of this object and returns the same array with
199
     * rationalized keys (casing) and parsed sub-elements.
200
     *
201
     * @param array{
202
     *   'children'?: array,
203
     *   'IPHint'?: array,
204
     *   'DomainHint'?: array,
205
     *   'GeolocationHint'?: array,
206
     * } $data
207
     * @return array{
208
     *   'children'?: array,
209
     *   'IPHint'?: array,
210
     *   'DomainHint'?: array,
211
     *   'GeolocationHint'?: array,
212
     * }
213
     */
214
    private static function processArrayContents(array $data): array
215
    {
216
        $data = array_change_key_case($data, CASE_LOWER);
217
218
        // Make sure the array keys are known for this kind of object
219
        Assert::allOneOf(
220
            array_keys($data),
221
            [
222
                'iphint',
223
                'domainhint',
224
                'geolocationhint',
225
                'children',
226
            ],
227
            ArrayValidationException::class,
228
        );
229
230
        $retval = [];
231
232
        if (array_key_exists('iphint', $data)) {
233
            Assert::isArray($data['iphint'], ArrayValidationException::class);
234
            Assert::allString($data['iphint'], ArrayValidationException::class);
235
            foreach ($data['iphint'] as $hint) {
236
                $retval['IPHint'][] = new IPHint(
237
                    CIDRValue::fromString($hint),
238
                );
239
            }
240
        }
241
242
        if (array_key_exists('domainhint', $data)) {
243
            Assert::isArray($data['domainhint'], ArrayValidationException::class);
244
            Assert::allString($data['domainhint'], ArrayValidationException::class);
245
            foreach ($data['domainhint'] as $hint) {
246
                $retval['DomainHint'][] = new DomainHint(
247
                    DomainValue::fromString($hint),
248
                );
249
            }
250
        }
251
252
        if (array_key_exists('geolocationhint', $data)) {
253
            Assert::isArray($data['geolocationhint'], ArrayValidationException::class);
254
            Assert::allString($data['geolocationhint'], ArrayValidationException::class);
255
            foreach ($data['geolocationhint'] as $hint) {
256
                $retval['GeolocationHint'][] = new GeolocationHint(
257
                    GeolocationValue::fromString($hint),
258
                );
259
            }
260
        }
261
262
        if (array_key_exists('children', $data)) {
263
            Assert::isArray($data['children'], ArrayValidationException::class);
264
            Assert::allIsInstanceOf(
265
                $data['children'],
266
                SerializableElementInterface::class,
267
                ArrayValidationException::class,
268
            );
269
            $retval['children'] = $data['children'];
270
        }
271
272
        return $retval;
273
    }
274
275
276
    /**
277
     * Create an array from this class
278
     *
279
     * @return array{
280
     *   'children'?: array,
281
     *   'IPHint'?: array,
282
     *   'DomainHint'?: array,
283
     *   'GeolocationHint'?: array,
284
     * }
285
     */
286
    public function toArray(): array
287
    {
288
        $data = [
289
            'IPHint' => [],
290
            'DomainHint' => [],
291
            'GeolocationHint' => [],
292
            'children' => $this->getElements(),
293
        ];
294
295
        foreach ($this->getIPHint() as $hint) {
296
            $data['IPHint'][] = $hint->getContent();
297
        }
298
299
        foreach ($this->getDomainHint() as $hint) {
300
            $data['DomainHint'][] = $hint->getContent();
301
        }
302
303
        foreach ($this->getGeolocationHint() as $hint) {
304
            $data['GeolocationHint'][] = $hint->getContent();
305
        }
306
307
        return array_filter($data);
308
    }
309
}
310