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

Organization::processArrayContents()   B

Complexity

Conditions 7
Paths 32

Size

Total Lines 58
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 34
nc 32
nop 1
dl 0
loc 58
rs 8.4426
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\md;
6
7
use DOMElement;
8
use SimpleSAML\SAML2\Assert\Assert;
9
use SimpleSAML\SAML2\Exception\ArrayValidationException;
10
use SimpleSAML\SAML2\Exception\ProtocolViolationException;
11
use SimpleSAML\SAML2\XML\ExtendableElementTrait;
12
use SimpleSAML\XML\ArrayizableElementInterface;
13
use SimpleSAML\XML\Attribute as XMLAttribute;
14
use SimpleSAML\XML\Constants as C;
15
use SimpleSAML\XML\ExtendableAttributesTrait;
16
use SimpleSAML\XML\SchemaValidatableElementInterface;
17
use SimpleSAML\XML\SchemaValidatableElementTrait;
18
use SimpleSAML\XMLSchema\Exception\InvalidDOMElementException;
19
use SimpleSAML\XMLSchema\Exception\MissingElementException;
20
use SimpleSAML\XMLSchema\Exception\TooManyElementsException;
21
use SimpleSAML\XMLSchema\XML\Constants\NS;
22
23
use function array_change_key_case;
24
use function array_filter;
25
use function array_key_exists;
26
use function array_keys;
27
use function array_merge;
28
29
/**
30
 * Class representing SAML 2 Organization element.
31
 *
32
 * @package simplesamlphp/saml2
33
 */
34
final class Organization extends AbstractMdElement implements
35
    ArrayizableElementInterface,
36
    SchemaValidatableElementInterface
37
{
38
    use ExtendableAttributesTrait;
39
    use ExtendableElementTrait;
40
    use SchemaValidatableElementTrait;
41
42
43
    /** The namespace-attribute for the xs:anyAttribute element */
44
    public const string XS_ANY_ATTR_NAMESPACE = NS::OTHER;
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected T_STRING, expecting '=' on line 44 at column 24
Loading history...
45
46
47
    /**
48
     * Organization constructor.
49
     *
50
     * @param \SimpleSAML\SAML2\XML\md\OrganizationName[] $organizationName
51
     * @param \SimpleSAML\SAML2\XML\md\OrganizationDisplayName[] $organizationDisplayName
52
     * @param \SimpleSAML\SAML2\XML\md\OrganizationURL[] $organizationURL
53
     * @param \SimpleSAML\SAML2\XML\md\Extensions|null $extensions
54
     * @param list<\SimpleSAML\XML\Attribute> $namespacedAttributes
55
     */
56
    public function __construct(
57
        protected array $organizationName,
58
        protected array $organizationDisplayName,
59
        protected array $organizationURL,
60
        ?Extensions $extensions = null,
61
        array $namespacedAttributes = [],
62
    ) {
63
        Assert::maxCount($organizationName, C::UNBOUNDED_LIMIT);
64
        Assert::maxCount($organizationDisplayName, C::UNBOUNDED_LIMIT);
65
        Assert::maxCount($organizationURL, C::UNBOUNDED_LIMIT);
66
67
        // [One or More]
68
        Assert::minCount($organizationName, 1, ProtocolViolationException::class);
69
        Assert::minCount($organizationDisplayName, 1, ProtocolViolationException::class);
70
        Assert::minCount($organizationURL, 1, ProtocolViolationException::class);
71
72
        Assert::allIsInstanceOf($organizationName, OrganizationName::class);
73
        Assert::allIsInstanceOf($organizationDisplayName, OrganizationDisplayName::class);
74
        Assert::allIsInstanceOf($organizationURL, OrganizationURL::class);
75
76
        $this->setExtensions($extensions);
77
        $this->setAttributesNS($namespacedAttributes);
78
    }
79
80
81
    /**
82
     * Collect the value of the OrganizationName property.
83
     *
84
     * @return \SimpleSAML\SAML2\XML\md\OrganizationName[]
85
     */
86
    public function getOrganizationName(): array
87
    {
88
        return $this->organizationName;
89
    }
90
91
92
    /**
93
     * Collect the value of the OrganizationDisplayName property.
94
     *
95
     * @return \SimpleSAML\SAML2\XML\md\OrganizationDisplayName[]
96
     */
97
    public function getOrganizationDisplayName(): array
98
    {
99
        return $this->organizationDisplayName;
100
    }
101
102
103
    /**
104
     * Collect the value of the OrganizationURL property.
105
     *
106
     * @return \SimpleSAML\SAML2\XML\md\OrganizationURL[]
107
     */
108
    public function getOrganizationURL(): array
109
    {
110
        return $this->organizationURL;
111
    }
112
113
114
    /**
115
     * Initialize an Organization element.
116
     *
117
     * @throws \SimpleSAML\XMLSchema\Exception\InvalidDOMElementException
118
     *   if the qualified name of the supplied element is wrong
119
     * @throws \SimpleSAML\XMLSchema\Exception\MissingElementException
120
     *   if one of the mandatory child-elements is missing
121
     */
122
    public static function fromXML(DOMElement $xml): static
123
    {
124
        Assert::same($xml->localName, 'Organization', InvalidDOMElementException::class);
125
        Assert::same($xml->namespaceURI, Organization::NS, InvalidDOMElementException::class);
126
127
        $names = OrganizationName::getChildrenOfClass($xml);
128
        Assert::minCount($names, 1, 'Missing at least one OrganizationName.', MissingElementException::class);
129
130
        $displayNames = OrganizationDisplayName::getChildrenOfClass($xml);
131
        Assert::minCount(
132
            $displayNames,
133
            1,
134
            'Missing at least one OrganizationDisplayName',
135
            MissingElementException::class,
136
        );
137
138
        $urls = OrganizationURL::getChildrenOfClass($xml);
139
        Assert::minCount($urls, 1, 'Missing at least one OrganizationURL', MissingElementException::class);
140
141
        $extensions = Extensions::getChildrenOfClass($xml);
142
        Assert::maxCount(
143
            $extensions,
144
            1,
145
            'Cannot process more than one md:Extensions element.',
146
            TooManyElementsException::class,
147
        );
148
149
        return new static(
150
            $names,
151
            $displayNames,
152
            $urls,
153
            !empty($extensions) ? $extensions[0] : null,
154
            self::getAttributesNSFromXML($xml),
155
        );
156
    }
157
158
159
    /**
160
     * Convert this Organization to XML.
161
     */
162
    public function toXML(?DOMElement $parent = null): DOMElement
163
    {
164
        $e = $this->instantiateParentElement($parent);
165
166
        foreach ($this->getAttributesNS() as $attr) {
167
            $attr->toXML($e);
168
        }
169
170
        $this->getExtensions()?->toXML($e);
171
172
        foreach ($this->getOrganizationName() as $name) {
173
            $name->toXML($e);
174
        }
175
176
        foreach ($this->getOrganizationDisplayName() as $displayName) {
177
            $displayName->toXML($e);
178
        }
179
180
        foreach ($this->getOrganizationURL() as $url) {
181
            $url->toXML($e);
182
        }
183
184
        return $e;
185
    }
186
187
188
    /**
189
     * Create a class from an array
190
     *
191
     * @param array{
192
     *   'OrganizationName': string,
193
     *   'OrganizationDisplayName': string,
194
     *   'OrganizationURL': string,
195
     *   'Extensions'?: array,
196
     *   'attributes'?: array,
197
     * } $data
198
     */
199
    public static function fromArray(array $data): static
200
    {
201
        $data = self::processArrayContents($data);
202
203
        return new static(
204
            $data['OrganizationName'],
205
            $data['OrganizationDisplayName'],
206
            $data['OrganizationURL'],
207
            $data['Extensions'] ?? null,
208
            $data['attributes'] ?? [],
209
        );
210
    }
211
212
213
    /**
214
     * Validates an array representation of this object and returns the same array with
215
     * rationalized keys (casing) and parsed sub-elements.
216
     *
217
     * @param array{
218
     *   'OrganizationName': string,
219
     *   'OrganizationDisplayName': string,
220
     *   'OrganizationURL': string,
221
     *   'Extensions'?: array,
222
     *   'attributes'?: array,
223
     * } $data
224
     * @return array{
225
     *   'OrganizationName': string,
226
     *   'OrganizationDisplayName': string,
227
     *   'OrganizationURL': string,
228
     *   'Extensions'?: array,
229
     *   'attributes'?: array,
230
     * }
231
     */
232
    private static function processArrayContents(array $data): array
233
    {
234
        $data = array_change_key_case($data, CASE_LOWER);
235
236
        // Make sure the array keys are known for this kind of object
237
        Assert::allOneOf(
238
            array_keys($data),
239
            [
240
                'organizationname',
241
                'organizationdisplayname',
242
                'organizationurl',
243
                'extensions',
244
                'attributes',
245
            ],
246
            ArrayValidationException::class,
247
        );
248
249
        Assert::keyExists($data, 'organizationname', ArrayValidationException::class);
250
        Assert::keyExists($data, 'organizationdisplayname', ArrayValidationException::class);
251
        Assert::keyExists($data, 'organizationurl', ArrayValidationException::class);
252
253
        // The minimum count is validated by the constructor
254
        Assert::isArray($data['organizationname'], ArrayValidationException::class);
255
        Assert::isArray($data['organizationdisplayname'], ArrayValidationException::class);
256
        Assert::isArray($data['organizationurl'], ArrayValidationException::class);
257
258
        foreach ($data['organizationname'] as $lang => $orgName) {
259
            $data['organizationname'][$lang] = OrganizationName::fromArray([$lang => $orgName]);
260
        }
261
262
        foreach ($data['organizationdisplayname'] as $lang => $orgDisplayName) {
263
            $data['organizationdisplayname'][$lang] = OrganizationDisplayName::fromArray([$lang => $orgDisplayName]);
264
        }
265
266
        foreach ($data['organizationurl'] as $lang => $orgUrl) {
267
            $data['organizationurl'][$lang] = OrganizationURL::fromArray([$lang => $orgUrl]);
268
        }
269
270
        $retval = [
271
            'OrganizationName' => $data['organizationname'],
272
            'OrganizationDisplayName' => $data['organizationdisplayname'],
273
            'OrganizationURL' => $data['organizationurl'],
274
        ];
275
276
        if (array_key_exists('extensions', $data)) {
277
            Assert::isArray($data['extensions'], ArrayValidationException::class);
278
            $retval['Extensions'] = new Extensions($data['extensions']);
279
        }
280
281
        if (array_key_exists('attributes', $data)) {
282
            Assert::isArray($data['attributes'], ArrayValidationException::class);
283
            Assert::allIsArray($data['attributes'], ArrayValidationException::class);
284
            foreach ($data['attributes'] as $i => $attr) {
285
                $retval['attributes'][] = XMLAttribute::fromArray($attr);
286
            }
287
        }
288
289
        return $retval;
290
    }
291
292
293
    /**
294
     * Create an array from this class
295
     *
296
     * @return array{
297
     *   'OrganizationName': string,
298
     *   'OrganizationDisplayName': string,
299
     *   'OrganizationURL': string,
300
     *   'Extensions'?: array,
301
     *   'attributes'?: array,
302
     * }
303
     */
304
    public function toArray(): array
305
    {
306
        $data = [
307
            'OrganizationName' => [],
308
            'OrganizationDisplayName' => [],
309
            'OrganizationURL' => [],
310
            'Extensions' => $this->getExtensions()?->getList(),
311
            'attributes' => [],
312
        ];
313
314
        foreach ($this->getOrganizationName() as $orgName) {
315
            $data['OrganizationName'] = array_merge($data['OrganizationName'], $orgName->toArray());
316
        }
317
318
        foreach ($this->getOrganizationDisplayName() as $orgDisplayName) {
319
            $data['OrganizationDisplayName'] = array_merge(
320
                $data['OrganizationDisplayName'],
321
                $orgDisplayName->toArray(),
322
            );
323
        }
324
325
        foreach ($this->getOrganizationURL() as $orgURL) {
326
            $data['OrganizationURL'] = array_merge($data['OrganizationURL'], $orgURL->toArray());
327
        }
328
329
        foreach ($this->getAttributesNS() as $attr) {
330
            $data['attributes'][] = $attr->toArray();
331
        }
332
333
        return array_filter($data);
334
    }
335
}
336