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

Organization::fromArray()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 8
nc 2
nop 1
dl 0
loc 12
rs 10
c 1
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_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 ArrayizableElementInterface
35
{
36
    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...
37
    use ExtendableElementTrait;
38
39
    /** The namespace-attribute for the xs:anyAttribute element */
40
    public const XS_ANY_ATTR_NAMESPACE = C::XS_ANY_NS_OTHER;
41
42
43
    /**
44
     * Organization constructor.
45
     *
46
     * @param \SimpleSAML\SAML2\XML\md\OrganizationName[] $organizationName
47
     * @param \SimpleSAML\SAML2\XML\md\OrganizationDisplayName[] $organizationDisplayName
48
     * @param \SimpleSAML\SAML2\XML\md\OrganizationURL[] $organizationURL
49
     * @param \SimpleSAML\SAML2\XML\md\Extensions|null $extensions
50
     * @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...
51
     */
52
    public function __construct(
53
        protected array $organizationName,
54
        protected array $organizationDisplayName,
55
        protected array $organizationURL,
56
        ?Extensions $extensions = null,
57
        array $namespacedAttributes = [],
58
    ) {
59
        Assert::allIsInstanceOf($organizationName, OrganizationName::class);
60
        Assert::allIsInstanceOf($organizationDisplayName, OrganizationDisplayName::class);
61
        Assert::allIsInstanceOf($organizationURL, OrganizationURL::class);
62
63
        // [One or More]
64
        Assert::minCount($organizationName, 1, ProtocolViolationException::class);
65
        Assert::minCount($organizationDisplayName, 1, ProtocolViolationException::class);
66
        Assert::minCount($organizationURL, 1, ProtocolViolationException::class);
67
68
        $this->setExtensions($extensions);
69
        $this->setAttributesNS($namespacedAttributes);
70
    }
71
72
73
    /**
74
     * Collect the value of the OrganizationName property.
75
     *
76
     * @return \SimpleSAML\SAML2\XML\md\OrganizationName[]
77
     */
78
    public function getOrganizationName(): array
79
    {
80
        return $this->organizationName;
81
    }
82
83
84
    /**
85
     * Collect the value of the OrganizationDisplayName property.
86
     *
87
     * @return \SimpleSAML\SAML2\XML\md\OrganizationDisplayName[]
88
     */
89
    public function getOrganizationDisplayName(): array
90
    {
91
        return $this->organizationDisplayName;
92
    }
93
94
95
    /**
96
     * Collect the value of the OrganizationURL property.
97
     *
98
     * @return \SimpleSAML\SAML2\XML\md\OrganizationURL[]
99
     */
100
    public function getOrganizationURL(): array
101
    {
102
        return $this->organizationURL;
103
    }
104
105
106
    /**
107
     * Initialize an Organization element.
108
     *
109
     * @param \DOMElement $xml The XML element we should load.
110
     * @return static
111
     *
112
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
113
     *   if the qualified name of the supplied element is wrong
114
     * @throws \SimpleSAML\XML\Exception\MissingElementException
115
     *   if one of the mandatory child-elements is missing
116
     */
117
    public static function fromXML(DOMElement $xml): static
118
    {
119
        Assert::same($xml->localName, 'Organization', InvalidDOMElementException::class);
120
        Assert::same($xml->namespaceURI, Organization::NS, InvalidDOMElementException::class);
121
122
        $names = OrganizationName::getChildrenOfClass($xml);
123
        Assert::minCount($names, 1, 'Missing at least one OrganizationName.', MissingElementException::class);
124
125
        $displayNames = OrganizationDisplayName::getChildrenOfClass($xml);
126
        Assert::minCount(
127
            $displayNames,
128
            1,
129
            'Missing at least one OrganizationDisplayName',
130
            MissingElementException::class,
131
        );
132
133
        $urls = OrganizationURL::getChildrenOfClass($xml);
134
        Assert::minCount($urls, 1, 'Missing at least one OrganizationURL', MissingElementException::class);
135
136
        $extensions = Extensions::getChildrenOfClass($xml);
137
        Assert::maxCount(
138
            $extensions,
139
            1,
140
            'Cannot process more than one md:Extensions element.',
141
            TooManyElementsException::class,
142
        );
143
144
        return new static(
145
            $names,
146
            $displayNames,
147
            $urls,
148
            !empty($extensions) ? $extensions[0] : null,
149
            self::getAttributesNSFromXML($xml),
150
        );
151
    }
152
153
154
    /**
155
     * Convert this Organization to XML.
156
     *
157
     * @param \DOMElement|null $parent The element we should add this organization to.
158
     * @return \DOMElement This Organization-element.
159
     */
160
    public function toXML(DOMElement $parent = null): DOMElement
161
    {
162
        $e = $this->instantiateParentElement($parent);
163
164
        foreach ($this->getAttributesNS() as $attr) {
165
            $attr->toXML($e);
166
        }
167
168
        $this->getExtensions()?->toXML($e);
169
170
        foreach ($this->getOrganizationName() as $name) {
171
            $name->toXML($e);
172
        }
173
174
        foreach ($this->getOrganizationDisplayName() as $displayName) {
175
            $displayName->toXML($e);
176
        }
177
178
        foreach ($this->getOrganizationURL() as $url) {
179
            $url->toXML($e);
180
        }
181
182
        return $e;
183
    }
184
185
186
    /**
187
     * Create a class from an array
188
     *
189
     * @param array $data
190
     * @return static
191
     */
192
    public static function fromArray(array $data): static
193
    {
194
        $data = self::validateArray($data);
195
196
        $Extensions = array_key_exists('Extensions', $data) ? new Extensions($data['Extensions']) : null;
197
198
        return new static(
199
            $data['OrganizationName'],
200
            $data['OrganizationDisplayName'],
201
            $data['OrganizationURL'],
202
            $Extensions,
203
            $data['attributes'],
204
        );
205
    }
206
207
208
    /**
209
     * Validates an array representation of this object and returns the same array with
210
     * rationalized keys (casing) and parsed sub-elements.
211
     *
212
     * @param array $data
213
     * @return array $data
214
     */
215
    private static function validateArray(array $data): array
216
    {
217
        $data = array_change_key_case($data, CASE_LOWER);
218
219
        // Make sure the array keys are known for this kind of object
220
        Assert::allOneOf(
221
            array_keys($data),
222
            [
223
                'organizationname',
224
                'organizationdisplayname',
225
                'organizationurl',
226
                'extensions',
227
                'attributes',
228
            ],
229
        );
230
231
        Assert::keyExists($data, 'organizationname');
232
        Assert::keyExists($data, 'organizationdisplayname');
233
        Assert::keyExists($data, 'organizationurl');
234
235
        // The minimum count is validated by the constructor
236
        Assert::isArray($data['organizationname']);
237
        Assert::isArray($data['organizationdisplayname']);
238
        Assert::isArray($data['organizationurl']);
239
240
        foreach ($data['organizationname'] as $lang => $orgName) {
241
            $data['organizationname'][$lang] = OrganizationName::fromArray([$lang => $orgName]);
242
        }
243
244
        foreach ($data['organizationdisplayname'] as $lang => $orgDisplayName) {
245
            $data['organizationdisplayname'][$lang] = OrganizationDisplayName::fromArray([$lang => $orgDisplayName]);
246
        }
247
248
        foreach ($data['organizationurl'] as $lang => $orgUrl) {
249
            $data['organizationurl'][$lang] = OrganizationURL::fromArray([$lang => $orgUrl]);
250
        }
251
252
        $retval = [
253
            'OrganizationName' => $data['organizationname'],
254
            'OrganizationDisplayName' => $data['organizationdisplayname'],
255
            'OrganizationURL' => $data['organizationurl'],
256
        ];
257
258
        if (array_key_exists('extensions', $data)) {
259
            Assert::isArray($data['extensions']);
260
            Assert::allIsInstanceOf($data['extensions'], SerializableElementInterface::class);
261
            $retval['Extensions'] = $data['extensions'];
262
        }
263
264
        if (array_key_exists('attributes', $data)) {
265
            Assert::isArray($data['attributes']);
266
            Assert::allIsArray($data['attributes']);
267
            foreach ($data['attributes'] as $i => $attr) {
268
                $retval['attributes'][] = XMLAttribute::fromArray($attr);
269
            }
270
        }
271
272
        return $retval;
273
    }
274
275
276
    /**
277
     * Create an array from this class
278
     *
279
     * @return array
280
     */
281
    public function toArray(): array
282
    {
283
        $data = [
284
            'OrganizationName' => [],
285
            'OrganizationDisplayName' => [],
286
            'OrganizationURL' => [],
287
            '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

287
            'Extensions' => $this->getExtensions()?->/** @scrutinizer ignore-call */ getList(),
Loading history...
288
            'attributes' => [],
289
        ];
290
291
        foreach ($this->getOrganizationName() as $orgName) {
292
            $data['OrganizationName'] = array_merge($data['OrganizationName'], $orgName->toArray());
293
        }
294
295
        foreach ($this->getOrganizationDisplayName() as $orgDisplayName) {
296
            $data['OrganizationDisplayName'] = array_merge(
297
                $data['OrganizationDisplayName'],
298
                $orgDisplayName->toArray(),
299
            );
300
        }
301
302
        foreach ($this->getOrganizationURL() as $orgURL) {
303
            $data['OrganizationURL'] = array_merge($data['OrganizationURL'], $orgURL->toArray());
304
        }
305
306
        foreach ($this->getAttributesNS() as $attr) {
307
            $data['attributes'][] = $attr->toArray();
308
        }
309
310
        return array_filter($data);
311
    }
312
}
313