Passed
Pull Request — master (#337)
by Tim
02:20
created

Organization::validateArray()   B

Complexity

Conditions 7
Paths 32

Size

Total Lines 46
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 27
nc 32
nop 1
dl 0
loc 46
rs 8.5546
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\SAML2\XML\md;
6
7
use DOMDocument;
8
use DOMElement;
9
use Exception;
10
use SimpleSAML\Assert\Assert;
11
use SimpleSAML\SAML2\Exception\ProtocolViolationException;
12
use SimpleSAML\SAML2\XML\ExtendableElementTrait;
13
use SimpleSAML\XML\Constants as C;
14
use SimpleSAML\XML\ArrayizableElementInterface;
15
use SimpleSAML\XML\Attribute as XMLAttribute;
16
use SimpleSAML\XML\Exception\InvalidDOMElementException;
17
use SimpleSAML\XML\Exception\MissingElementException;
18
use SimpleSAML\XML\Exception\TooManyElementsException;
19
use SimpleSAML\XML\ExtendableAttributesTrait;
20
use SimpleSAML\XML\SerializableElementInterface;
21
use SimpleSAML\XML\Utils as XMLUtils;
22
23
use function array_filter;
24
use function array_key_exists;
25
use function array_merge;
26
27
/**
28
 * Class representing SAML 2 Organization element.
29
 *
30
 * @package simplesamlphp/saml2
31
 */
32
final class Organization extends AbstractMdElement implements ArrayizableElementInterface
33
{
34
    use ExtendableAttributesTrait;
1 ignored issue
show
introduced by
The trait SimpleSAML\XML\ExtendableAttributesTrait requires some properties which are not provided by SimpleSAML\SAML2\XML\md\Organization: $localName, $nodeValue, $namespaceURI, $prefix, $attributes
Loading history...
35
    use ExtendableElementTrait;
36
37
    /** The namespace-attribute for the xs:anyAttribute element */
38
    public const XS_ANY_ATTR_NAMESPACE = C::XS_ANY_NS_OTHER;
39
40
41
    /**
42
     * Organization constructor.
43
     *
44
     * @param \SimpleSAML\SAML2\XML\md\OrganizationName[] $organizationName
45
     * @param \SimpleSAML\SAML2\XML\md\OrganizationDisplayName[] $organizationDisplayName
46
     * @param \SimpleSAML\SAML2\XML\md\OrganizationURL[] $organizationURL
47
     * @param \SimpleSAML\SAML2\XML\md\Extensions|null $extensions
48
     * @param list<\SimpleSAML\XML\Attribute> $namespacedAttributes
0 ignored issues
show
Bug introduced by
The type SimpleSAML\SAML2\XML\md\list 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...
49
     */
50
    public function __construct(
51
        protected array $organizationName,
52
        protected array $organizationDisplayName,
53
        protected array $organizationURL,
54
        ?Extensions $extensions = null,
55
        array $namespacedAttributes = [],
56
    ) {
57
        Assert::allIsInstanceOf($organizationName, OrganizationName::class);
58
        Assert::allIsInstanceOf($organizationDisplayName, OrganizationDisplayName::class);
59
        Assert::allIsInstanceOf($organizationURL, OrganizationURL::class);
60
61
        // [One or More]
62
        Assert::minCount($organizationName, 1, ProtocolViolationException::class);
63
        Assert::minCount($organizationDisplayName, 1, ProtocolViolationException::class);
64
        Assert::minCount($organizationURL, 1, ProtocolViolationException::class);
65
66
        $this->setExtensions($extensions);
67
        $this->setAttributesNS($namespacedAttributes);
68
    }
69
70
71
    /**
72
     * Collect the value of the OrganizationName property.
73
     *
74
     * @return \SimpleSAML\SAML2\XML\md\OrganizationName[]
75
     */
76
    public function getOrganizationName(): array
77
    {
78
        return $this->organizationName;
79
    }
80
81
82
    /**
83
     * Collect the value of the OrganizationDisplayName property.
84
     *
85
     * @return \SimpleSAML\SAML2\XML\md\OrganizationDisplayName[]
86
     */
87
    public function getOrganizationDisplayName(): array
88
    {
89
        return $this->organizationDisplayName;
90
    }
91
92
93
    /**
94
     * Collect the value of the OrganizationURL property.
95
     *
96
     * @return \SimpleSAML\SAML2\XML\md\OrganizationURL[]
97
     */
98
    public function getOrganizationURL(): array
99
    {
100
        return $this->organizationURL;
101
    }
102
103
104
    /**
105
     * Initialize an Organization element.
106
     *
107
     * @param \DOMElement $xml The XML element we should load.
108
     * @return static
109
     *
110
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
111
     *   if the qualified name of the supplied element is wrong
112
     * @throws \SimpleSAML\XML\Exception\MissingElementException
113
     *   if one of the mandatory child-elements is missing
114
     */
115
    public static function fromXML(DOMElement $xml): static
116
    {
117
        Assert::same($xml->localName, 'Organization', InvalidDOMElementException::class);
118
        Assert::same($xml->namespaceURI, Organization::NS, InvalidDOMElementException::class);
119
120
        $names = OrganizationName::getChildrenOfClass($xml);
121
        Assert::minCount($names, 1, 'Missing at least one OrganizationName.', MissingElementException::class);
122
123
        $displayNames = OrganizationDisplayName::getChildrenOfClass($xml);
124
        Assert::minCount(
125
            $displayNames,
126
            1,
127
            'Missing at least one OrganizationDisplayName',
128
            MissingElementException::class,
129
        );
130
131
        $urls = OrganizationURL::getChildrenOfClass($xml);
132
        Assert::minCount($urls, 1, 'Missing at least one OrganizationURL', MissingElementException::class);
133
134
        $extensions = Extensions::getChildrenOfClass($xml);
135
        Assert::maxCount(
136
            $extensions,
137
            1,
138
            'Cannot process more than one md:Extensions element.',
139
            TooManyElementsException::class,
140
        );
141
142
        return new static(
143
            $names,
144
            $displayNames,
145
            $urls,
146
            !empty($extensions) ? $extensions[0] : null,
147
            self::getAttributesNSFromXML($xml),
148
        );
149
    }
150
151
152
    /**
153
     * Convert this Organization to XML.
154
     *
155
     * @param \DOMElement|null $parent The element we should add this organization to.
156
     * @return \DOMElement This Organization-element.
157
     */
158
    public function toXML(DOMElement $parent = null): DOMElement
159
    {
160
        $e = $this->instantiateParentElement($parent);
161
162
        foreach ($this->getAttributesNS() as $attr) {
163
            $attr->toXML($e);
164
        }
165
166
        $this->getExtensions()?->toXML($e);
167
168
        foreach ($this->getOrganizationName() as $name) {
169
            $name->toXML($e);
170
        }
171
172
        foreach ($this->getOrganizationDisplayName() as $displayName) {
173
            $displayName->toXML($e);
174
        }
175
176
        foreach ($this->getOrganizationURL() as $url) {
177
            $url->toXML($e);
178
        }
179
180
        return $e;
181
    }
182
183
184
    /**
185
     * Create a class from an array
186
     *
187
     * @param array $data
188
     * @return static
189
     */
190
    public static function fromArray(array $data): static
191
    {
192
        self::validateArray($data);
193
194
        $orgNames = [];
195
        if (array_key_exists('OrganizationName', $data)) {
196
            foreach ($data['OrganizationName'] as $lang => $orgName) {
197
                $orgNames[] = new OrganizationName($lang, $orgName);
198
            }
199
        }
200
201
        $orgDisplayNames = [];
202
        if (array_key_exists('OrganizationDisplayName', $data)) {
203
            foreach ($data['OrganizationDisplayName'] as $lang => $orgDisplayName) {
204
                $orgDisplayNames[] = new OrganizationDisplayName($lang, $orgDisplayName);
205
            }
206
        }
207
208
        $orgURLs = [];
209
        if (array_key_exists('OrganizationURL', $data)) {
210
            foreach ($data['OrganizationURL'] as $lang => $orgURL) {
211
                $orgURLs[] = new OrganizationURL($lang, $orgURL);
212
            }
213
        }
214
215
        $Extensions = array_key_exists('Extensions', $data) ? new Extensions($data['Extensions']) : null;
216
217
        $attributes = [];
218
        if (array_key_exists('attributes', $data)) {
219
            foreach ($data['attributes'] as $attr) {
220
                $attributes[] = new XMLAttribute(
221
                    $attr['namespaceURI'],
222
                    $attr['namespacePrefix'],
223
                    $attr['attrName'],
224
                    $attr['attrValue'],
225
                );
226
            }
227
        }
228
229
        return new static(
230
            $orgNames,
231
            $orgDisplayNames,
232
            $orgURLs,
233
            $Extensions,
234
            $attributes,
235
        );
236
    }
237
238
239
    /**
240
     * Validate an array
241
     *
242
     * @param array $data
243
     * @return void
244
     */
245
    public static function validateArray(array $data): void
246
    {
247
        // Make sure the array keys are known for this kind of object
248
        Assert::allOneOf(
249
            array_keys($data),
250
            [
251
                'OrganizationName',
252
                'OrganizationDisplayName',
253
                'OrganizationURL',
254
                'attributes',
255
                'Extensions',
256
            ],
257
        );
258
259
        Assert::keyExists($data, 'OrganizationName');
260
        Assert::keyExists($data, 'OrganizationDisplayName');
261
        Assert::keyExists($data, 'OrganizationURL');
262
263
        // The minimum count is validated by the constructor
264
        Assert::isArray($data['OrganizationName']);
265
        Assert::isArray($data['OrganizationDisplayName']);
266
        Assert::isArray($data['OrganizationURL']);
267
268
        foreach ($data['OrganizationName'] as $lang => $orgName) {
269
            AbstractLocalizedName::validateArray([$lang => $orgName]);
270
        }
271
272
        foreach ($data['OrganizationDisplayName'] as $lang => $orgDisplayName) {
273
            AbstractLocalizedName::validateArray([$lang => $orgName]);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $orgName seems to be defined by a foreach iteration on line 268. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
274
        }
275
276
        foreach ($data['OrganizationURL'] as $lang => $orgUrl) {
277
            AbstractLocalizedName::validateArray([$lang => $orgUrl]);
278
        }
279
280
        if (array_key_exists('attributes', $data)) {
281
            Assert::isArray($data['attributes']);
282
            Assert::allIsArray($data['attributes']);
283
            foreach ($data['attributes'] as $attr) {
284
                XMLAttribute::validateArray($attr);
285
            }
286
        }
287
288
        if (array_key_exists('Extensions', $data)) {
289
            Assert::isArray($data['Extensions']);
290
            Assert::allIsInstanceOf($data['Extensions'], SerializableElementInterface::class);
291
        }
292
    }
293
294
295
    /**
296
     * Create an array from this class
297
     *
298
     * @return array
299
     */
300
    public function toArray(): array
301
    {
302
        $data = [
303
            'OrganizationName' => [],
304
            'OrganizationDisplayName' => [],
305
            'OrganizationURL' => [],
306
            'Extensions' => $this->getExtensions()?->getList(),
0 ignored issues
show
Bug introduced by
The method getList() does not exist on SimpleSAML\XML\AbstractElement. It seems like you code against a sub-type of SimpleSAML\XML\AbstractElement such as SimpleSAML\SAML2\XML\md\Extensions or SimpleSAML\SAML2\XML\samlp\Extensions. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

306
            'Extensions' => $this->getExtensions()?->/** @scrutinizer ignore-call */ getList(),
Loading history...
307
            'attributes' => [],
308
        ];
309
310
        foreach ($this->getOrganizationName() as $orgName) {
311
            $data['OrganizationName'] = array_merge($data['OrganizationName'], $orgName->toArray());
312
        }
313
314
        foreach ($this->getOrganizationDisplayName() as $orgDisplayName) {
315
            $data['OrganizationDisplayName'] = array_merge(
316
                $data['OrganizationDisplayName'],
317
                $orgDisplayName->toArray(),
318
            );
319
        }
320
321
        foreach ($this->getOrganizationURL() as $orgURL) {
322
            $data['OrganizationURL'] = array_merge($data['OrganizationURL'], $orgURL->toArray());
323
        }
324
325
        foreach ($this->getAttributesNS() as $attr) {
326
            $data['attributes'][] = $attr->toArray();
327
        }
328
329
        return array_filter($data);
330
    }
331
}
332