Passed
Push — master ( 66592a...152b2f )
by Tim
02:08
created

Organization::fromArray()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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

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