DiscoHints::processArrayContents()   B
last analyzed

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\Chunk;
15
use SimpleSAML\XML\Constants as C;
16
use SimpleSAML\XML\ExtendableElementTrait;
17
use SimpleSAML\XML\SchemaValidatableElementInterface;
18
use SimpleSAML\XML\SchemaValidatableElementTrait;
19
use SimpleSAML\XML\SerializableElementInterface;
20
use SimpleSAML\XMLSchema\Exception\InvalidDOMElementException;
21
use SimpleSAML\XMLSchema\XML\Constants\NS;
22
23
use function array_filter;
24
use function array_key_exists;
25
use function array_keys;
26
27
/**
28
 * Class for handling the metadata extensions for login and discovery user interface
29
 *
30
 * @link: http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-metadata-ui/v1.0/sstc-saml-metadata-ui-v1.0.pdf
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 XS_ANY_ELT_NAMESPACE = NS::OTHER;
43
44
45
    /**
46
     * Create a DiscoHints element.
47
     *
48
     * @param \SimpleSAML\XML\Chunk[] $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\Chunk $child
107
     */
108
    public function addChild(Chunk $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
     * @return bool
118
     */
119
    public function isEmptyElement(): bool
120
    {
121
        return empty($this->getElements())
122
            && empty($this->getIPHint())
123
            && empty($this->getDomainHint())
124
            && empty($this->getGeolocationHint());
125
    }
126
127
128
    /**
129
     * Convert XML into a DiscoHints
130
     *
131
     * @param \DOMElement $xml The XML element we should load
132
     * @return static
133
     *
134
     * @throws \SimpleSAML\XMLSchema\Exception\InvalidDOMElementException
135
     *   if the qualified name of the supplied element is wrong
136
     */
137
    public static function fromXML(DOMElement $xml): static
138
    {
139
        Assert::same($xml->localName, 'DiscoHints', InvalidDOMElementException::class);
140
        Assert::same($xml->namespaceURI, DiscoHints::NS, InvalidDOMElementException::class);
141
142
        $IPHint = IPHint::getChildrenOfClass($xml);
143
        $DomainHint = DomainHint::getChildrenOfClass($xml);
144
        $GeolocationHint = GeolocationHint::getChildrenOfClass($xml);
145
        $children = self::getChildElementsFromXML($xml);
146
147
        return new static($children, $IPHint, $DomainHint, $GeolocationHint);
148
    }
149
150
151
    /**
152
     * Convert this DiscoHints to XML.
153
     *
154
     * @param \DOMElement|null $parent The element we should append to.
155
     * @return \DOMElement
156
     */
157
    public function toXML(?DOMElement $parent = null): DOMElement
158
    {
159
        $e = $this->instantiateParentElement($parent);
160
161
        foreach ($this->getIPHint() as $hint) {
162
            $hint->toXML($e);
163
        }
164
165
        foreach ($this->getDomainHint() as $hint) {
166
            $hint->toXML($e);
167
        }
168
169
        foreach ($this->getGeolocationHint() as $hint) {
170
            $hint->toXML($e);
171
        }
172
173
        /** @var \SimpleSAML\XML\SerializableElementInterface $child */
174
        foreach ($this->getElements() as $child) {
175
            $child->toXML($e);
176
        }
177
178
        return $e;
179
    }
180
181
182
    /**
183
     * Create a class from an array
184
     *
185
     * @param array $data
186
     * @return static
187
     */
188
    public static function fromArray(array $data): static
189
    {
190
        $data = self::processArrayContents($data);
191
192
        return new static(
193
            $data['children'] ?? [],
194
            $data['IPHint'] ?? [],
195
            $data['DomainHint'] ?? [],
196
            $data['GeolocationHint'] ?? [],
197
        );
198
    }
199
200
201
    /**
202
     * Validates an array representation of this object and returns the same array with
203
     * rationalized keys (casing) and parsed sub-elements.
204
     *
205
     * @param array $data
206
     * @return array $data
207
     */
208
    private static function processArrayContents(array $data): array
209
    {
210
        $data = array_change_key_case($data, CASE_LOWER);
211
212
        // Make sure the array keys are known for this kind of object
213
        Assert::allOneOf(
214
            array_keys($data),
215
            [
216
                'iphint',
217
                'domainhint',
218
                'geolocationhint',
219
                'children',
220
            ],
221
            ArrayValidationException::class,
222
        );
223
224
        $retval = [];
225
226
        if (array_key_exists('iphint', $data)) {
227
            Assert::isArray($data['iphint'], ArrayValidationException::class);
228
            Assert::allString($data['iphint'], ArrayValidationException::class);
229
            foreach ($data['iphint'] as $hint) {
230
                $retval['IPHint'][] = new IPHint(
231
                    CIDRValue::fromString($hint),
232
                );
233
            }
234
        }
235
236
        if (array_key_exists('domainhint', $data)) {
237
            Assert::isArray($data['domainhint'], ArrayValidationException::class);
238
            Assert::allString($data['domainhint'], ArrayValidationException::class);
239
            foreach ($data['domainhint'] as $hint) {
240
                $retval['DomainHint'][] = new DomainHint(
241
                    DomainValue::fromString($hint),
242
                );
243
            }
244
        }
245
246
        if (array_key_exists('geolocationhint', $data)) {
247
            Assert::isArray($data['geolocationhint'], ArrayValidationException::class);
248
            Assert::allString($data['geolocationhint'], ArrayValidationException::class);
249
            foreach ($data['geolocationhint'] as $hint) {
250
                $retval['GeolocationHint'][] = new GeolocationHint(
251
                    GeolocationValue::fromString($hint),
252
                );
253
            }
254
        }
255
256
        if (array_key_exists('children', $data)) {
257
            Assert::isArray($data['children'], ArrayValidationException::class);
258
            Assert::allIsInstanceOf(
259
                $data['children'],
260
                SerializableElementInterface::class,
261
                ArrayValidationException::class,
262
            );
263
            $retval['children'] = $data['children'];
264
        }
265
266
        return $retval;
267
    }
268
269
270
    /**
271
     * Create an array from this class
272
     *
273
     * @return array
274
     */
275
    public function toArray(): array
276
    {
277
        $data = [
278
            'IPHint' => [],
279
            'DomainHint' => [],
280
            'GeolocationHint' => [],
281
            'children' => $this->getElements(),
282
        ];
283
284
        foreach ($this->getIPHint() as $hint) {
285
            $data['IPHint'][] = $hint->getContent();
286
        }
287
288
        foreach ($this->getDomainHint() as $hint) {
289
            $data['DomainHint'][] = $hint->getContent();
290
        }
291
292
        foreach ($this->getGeolocationHint() as $hint) {
293
            $data['GeolocationHint'][] = $hint->getContent();
294
        }
295
296
        return array_filter($data);
297
    }
298
}
299