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

ContactPerson::validateArray()   B

Complexity

Conditions 9
Paths 128

Size

Total Lines 53
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 32
nc 128
nop 1
dl 0
loc 53
rs 7.8222
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 DOMDocument;
8
use DOMElement;
9
use Exception;
10
use SimpleSAML\Assert\Assert;
11
use SimpleSAML\SAML2\Exception\ProtocolViolationException;
12
use SimpleSAML\SAML2\Utils\XPath;
13
use SimpleSAML\SAML2\XML\ExtendableElementTrait;
14
use SimpleSAML\XML\ArrayizableElementInterface;
15
use SimpleSAML\XML\Attribute as XMLAttribute;
16
use SimpleSAML\XML\Constants as C;
17
use SimpleSAML\XML\Exception\InvalidDOMElementException;
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_keys;
26
use function array_map;
27
use function array_pop;
28
use function count;
29
use function filter_var;
30
use function preg_replace;
31
use function var_export;
32
33
/**
34
 * Class representing SAML 2 ContactPerson.
35
 *
36
 * @package simplesamlphp/saml2
37
 */
38
final class ContactPerson extends AbstractMdElement implements ArrayizableElementInterface
39
{
40
    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\ContactPerson: $localName, $nodeValue, $namespaceURI, $prefix, $attributes
Loading history...
41
    use ExtendableElementTrait;
42
43
    /** The namespace-attribute for the xs:anyAttribute element */
44
    public const XS_ANY_ATTR_NAMESPACE = C::XS_ANY_NS_OTHER;
45
46
47
    /**
48
     * The several different contact types as defined per specification
49
     */
50
    public const CONTACT_TYPES = [
51
        'technical',
52
        'support',
53
        'administrative',
54
        'billing',
55
        'other',
56
    ];
57
58
59
    /**
60
     * ContactPerson constructor.
61
     *
62
     * @param string $contactType
63
     * @param \SimpleSAML\SAML2\XML\md\Company|null $company
64
     * @param \SimpleSAML\SAML2\XML\md\GivenName|null $givenName
65
     * @param \SimpleSAML\SAML2\XML\md\SurName|null $surName
66
     * @param \SimpleSAML\SAML2\XML\md\Extensions|null $extensions
67
     * @param \SimpleSAML\SAML2\XML\md\EmailAddress[] $emailAddress
68
     * @param \SimpleSAML\SAML2\XML\md\TelephoneNumber[] $telephoneNumber
69
     * @param list<\SimpleSAML\XML\Attribute> $namespacedAttribute
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...
70
     */
71
    public function __construct(
72
        protected string $contactType,
73
        protected ?Company $company = null,
74
        protected ?GivenName $givenName = null,
75
        protected ?SurName $surName = null,
76
        ?Extensions $extensions = null,
77
        protected array $emailAddress = [],
78
        protected array $telephoneNumber = [],
79
        array $namespacedAttribute = [],
80
    ) {
81
        Assert::oneOf($contactType, self::CONTACT_TYPES);
82
        Assert::allIsInstanceOf($emailAddress, EmailAddress::class);
83
        Assert::allIsInstanceOf($telephoneNumber, TelephoneNumber::class);
84
85
        $this->setExtensions($extensions);
86
        $this->setAttributesNS($namespacedAttribute);
87
    }
88
89
90
    /**
91
     * Collect the value of the contactType-property
92
     *
93
     * @return string
94
     */
95
    public function getContactType(): string
96
    {
97
        return $this->contactType;
98
    }
99
100
101
    /**
102
     * Collect the value of the Company-property
103
     *
104
     * @return \SimpleSAML\SAML2\XML\md\Company|null
105
     */
106
    public function getCompany(): ?Company
107
    {
108
        return $this->company;
109
    }
110
111
112
    /**
113
     * Collect the value of the GivenName-property
114
     *
115
     * @return \SimpleSAML\SAML2\XML\md\GivenName|null
116
     */
117
    public function getGivenName(): ?GivenName
118
    {
119
        return $this->givenName;
120
    }
121
122
123
    /**
124
     * Collect the value of the SurName-property
125
     *
126
     * @return \SimpleSAML\SAML2\XML\md\SurName|null
127
     */
128
    public function getSurName(): ?SurName
129
    {
130
        return $this->surName;
131
    }
132
133
134
    /**
135
     * Collect the value of the EmailAddress-property.
136
     *
137
     * @return \SimpleSAML\SAML2\XML\md\EmailAddress[]
138
     */
139
    public function getEmailAddress(): array
140
    {
141
        return $this->emailAddress;
142
    }
143
144
145
    /**
146
     * Collect the value of the TelephoneNumber property
147
     *
148
     * @return \SimpleSAML\SAML2\XML\md\TelephoneNumber[]
149
     */
150
    public function getTelephoneNumber(): array
151
    {
152
        return $this->telephoneNumber;
153
    }
154
155
156
    /**
157
     * Initialize a ContactPerson element.
158
     *
159
     * @param \DOMElement $xml The XML element we should load.
160
     * @return static
161
     *
162
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
163
     *   if the qualified name of the supplied element is wrong
164
     * @throws \SimpleSAML\XML\Exception\MissingAttributeException
165
     *   if the supplied element is missing one of the mandatory attributes
166
     * @throws \SimpleSAML\XML\Exception\TooManyElementsException
167
     *   if too many child-elements of a type are specified
168
     */
169
    public static function fromXML(DOMElement $xml): static
170
    {
171
        Assert::same($xml->localName, 'ContactPerson', InvalidDOMElementException::class);
172
        Assert::same($xml->namespaceURI, ContactPerson::NS, InvalidDOMElementException::class);
173
174
        $contactType = self::getAttribute($xml, 'contactType');
175
176
        $company = Company::getChildrenOfClass($xml);
177
        Assert::maxCount($company, 1, 'More than one Company in md:ContactPerson');
178
179
        $givenName = GivenName::getChildrenOfClass($xml);
180
        Assert::maxCount($givenName, 1, 'More than one GivenName in md:ContactPerson');
181
182
        $surName = SurName::getChildrenOfClass($xml);
183
        Assert::maxCount($surName, 1, 'More than one SurName in md:ContactPerson');
184
185
        $email = EmailAddress::getChildrenOfClass($xml);
186
        $telephone = TelephoneNumber::getChildrenOfClass($xml);
187
188
        $extensions = Extensions::getChildrenOfClass($xml);
189
        Assert::maxCount($extensions, 1, 'Only one md:Extensions element is allowed.', TooManyElementsException::class);
190
191
        return new static(
192
            $contactType,
193
            array_pop($company),
194
            array_pop($givenName),
195
            array_pop($surName),
196
            (count($extensions) === 1) ? $extensions[0] : null,
197
            $email,
198
            $telephone,
199
            self::getAttributesNSFromXML($xml),
200
        );
201
    }
202
203
204
    /**
205
     * Convert this ContactPerson to XML.
206
     *
207
     * @param \DOMElement|null $parent The element we should add this contact to.
208
     *
209
     * @return \DOMElement The new ContactPerson-element.
210
     */
211
    public function toXML(DOMElement $parent = null): DOMElement
212
    {
213
        $e = $this->instantiateParentElement($parent);
214
215
        $e->setAttribute('contactType', $this->getContactType());
216
217
        foreach ($this->getAttributesNS() as $attr) {
218
            $attr->toXML($e);
219
        }
220
221
        $this->getExtensions()?->toXML($e);
222
        $this->getCompany()?->toXML($e);
223
        $this->getGivenName()?->toXML($e);
224
        $this->getSurName()?->toXML($e);
225
226
        foreach ($this->getEmailAddress() as $mail) {
227
            $mail->toXML($e);
228
        }
229
230
        foreach ($this->getTelephoneNumber() as $telephone) {
231
            $telephone->toXML($e);
232
        }
233
234
        return $e;
235
    }
236
237
238
    /**
239
     * Create a class from an array
240
     *
241
     * @param array $data
242
     * @return static
243
     */
244
    public static function fromArray(array $data): static
245
    {
246
        self::validateArray($data);
247
248
        $ContactType = $data['ContactType'];
249
        $Company = isset($data['Company']) ? new Company($data['Company']) : null;
250
        $GivenName = isset($data['GivenName']) ? new GivenName($data['GivenName']) : null;
251
        $SurName = isset($data['SurName']) ? new SurName($data['SurName']) : null;
252
        $Extensions = array_key_exists('Extensions', $data) ? new Extensions($data['Extensions']) : null;
253
254
        $EmailAddress = [];
255
        if (array_key_exists('EmailAddress', $data)) {
256
            foreach ($data['EmailAddress'] as $mail) {
257
                $EmailAddress[] = new EmailAddress($mail);
258
            }
259
        }
260
261
        $TelephoneNumber = [];
262
        if (array_key_exists('TelephoneNumber', $data)) {
263
            foreach ($data['TelephoneNumber'] as $telephone) {
264
                $TelephoneNumber[] = new TelephoneNumber($telephone);
265
            }
266
        }
267
268
        $attributes = [];
269
        if (array_key_exists('attributes', $data)) {
270
            foreach ($data['attributes'] as $attr) {
271
                $attributes[] = new XMLAttribute(
272
                    $attr['namespaceURI'],
273
                    $attr['namespacePrefix'],
274
                    $attr['attrName'],
275
                    $attr['attrValue'],
276
                );
277
            }
278
        }
279
280
        return new static(
281
            $ContactType,
282
            $Company,
283
            $GivenName,
284
            $SurName,
285
            $Extensions,
286
            $EmailAddress,
287
            $TelephoneNumber,
288
            $attributes,
289
        );
290
    }
291
292
293
    /**
294
     * Validate an array
295
     *
296
     * @param array $data
297
     * @return void
298
     */
299
    public static function validateArray(array $data): void
300
    {
301
        // Make sure the array keys are known for this kind of object
302
        Assert::allOneOf(
303
            array_keys($data),
304
            [
305
                'ContactType',
306
                'Company',
307
                'GivenName',
308
                'SurName',
309
                'EmailAddress',
310
                'TelephoneNumber',
311
                'attributes',
312
                'Extensions',
313
            ],
314
        );
315
316
        Assert::keyExists($data, 'ContactType');
317
        Assert::string($data['ContactType']);
318
319
        if (array_key_exists('Company', $data)) {
320
            Assert::string($data['Company']);
321
        }
322
323
        if (array_key_exists('GivenName', $data)) {
324
            Assert::string($data['GivenName']);
325
        }
326
327
        if (array_key_exists('SurName', $data)) {
328
            Assert::string($data['SurName']);
329
        }
330
331
        if (array_key_exists('EmailAddress', $data)) {
332
            Assert::isArray($data['EmailAddress']);
333
            Assert::allString($data['EmailAddress']);
334
        }
335
336
        if (array_key_exists('TelephoneNumber', $data)) {
337
            Assert::isArray($data['TelephoneNumber']);
338
            Assert::allString($data['TelephoneNumber']);
339
        }
340
341
        if (array_key_exists('attributes', $data)) {
342
            Assert::isArray($data['attributes']);
343
            Assert::allIsArray($data['attributes']);
344
            foreach ($data['attributes'] as $attr) {
345
                XMLAttribute::validateArray($attr);
346
            }
347
        }
348
349
        if (array_key_exists('Extensions', $data)) {
350
            Assert::isArray($data['Extensions']);
351
            Assert::allIsInstanceOf($data['Extensions'], SerializableElementInterface::class);
352
        }
353
    }
354
355
356
    /**
357
     * Create an array from this class
358
     *
359
     * @return array
360
     */
361
    public function toArray(): array
362
    {
363
        $data = [
364
            'ContactType' => $this->getContactType(),
365
            'Company' => $this->getCompany()?->getContent(),
366
            'GivenName' => $this->getGivenName()?->getContent(),
367
            'SurName' => $this->getSurName()?->getContent(),
368
            'EmailAddress' => [],
369
            'TelephoneNumber' => [],
370
            'Extensions' => $this->Extensions->getList(),
0 ignored issues
show
Bug introduced by
The method getList() does not exist on null. ( Ignorable by Annotation )

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

370
            'Extensions' => $this->Extensions->/** @scrutinizer ignore-call */ getList(),

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
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

370
            'Extensions' => $this->Extensions->/** @scrutinizer ignore-call */ getList(),
Loading history...
371
            'attributes' => [],
372
        ];
373
374
        foreach ($this->getEmailAddress() as $mail) {
375
            $data['EmailAddress'] = array_merge($data['EmailAddress'], $mail->toArray());
376
        }
377
378
        foreach ($this->getTelephoneNumber() as $telephone) {
379
            $data['TelephoneNumber'] = array_merge($data['TelephoneNumber'], $telephone->toArray());
380
        }
381
382
        foreach ($this->getAttributesNS() as $attr) {
383
            $data['attributes'][] = $attr->toArray();
384
        }
385
386
        return array_filter($data);
387
    }
388
}
389