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

ContactPerson::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 8
dl 0
loc 16
rs 10
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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