Passed
Push — master ( d20c81...8bfdc8 )
by Thijs
03:09 queued 31s
created

ContactPerson::getStringElement()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 3
nop 2
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SAML2\XML\md;
6
7
use DOMElement;
8
use SAML2\Constants;
9
use SAML2\Utils;
10
use SAML2\XML\Chunk;
11
use Webmozart\Assert\Assert;
12
13
/**
14
 * Class representing SAML 2 ContactPerson.
15
 *
16
 * @package SimpleSAMLphp
17
 */
18
class ContactPerson
19
{
20
    /**
21
     * The contact type.
22
     *
23
     * @var string
24
     */
25
    private $contactType;
26
27
    /**
28
     * Extensions on this element.
29
     *
30
     * Array of extension elements.
31
     *
32
     * @var array
33
     */
34
    private $Extensions = [];
35
36
    /**
37
     * The Company of this contact.
38
     *
39
     * @var string|null
40
     */
41
    private $Company = null;
42
43
    /**
44
     * The GivenName of this contact.
45
     *
46
     * @var string|null
47
     */
48
    private $GivenName = null;
49
50
    /**
51
     * The SurName of this contact.
52
     *
53
     * @var string|null
54
     */
55
    private $SurName = null;
56
57
    /**
58
     * The EmailAddresses of this contact.
59
     *
60
     * @var array
61
     */
62
    private $EmailAddress = [];
63
64
    /**
65
     * The TelephoneNumbers of this contact.
66
     *
67
     * @var array
68
     */
69
    private $TelephoneNumber = [];
70
71
    /**
72
     * Extra attributes on the contact element.
73
     *
74
     * @var array
75
     */
76
    private $ContactPersonAttributes = [];
77
78
79
    /**
80
     * Initialize a ContactPerson element.
81
     *
82
     * @param \DOMElement|null $xml The XML element we should load.
83
     * @throws \Exception
84
     */
85
    public function __construct(DOMElement $xml = null)
86
    {
87
        if ($xml === null) {
88
            return;
89
        }
90
91
        if (!$xml->hasAttribute('contactType')) {
92
            throw new \Exception('Missing contactType on ContactPerson.');
93
        }
94
        $this->setContactType($xml->getAttribute('contactType'));
95
96
        $this->setExtensions(Extensions::getList($xml));
97
98
        $this->setCompany(self::getStringElement($xml, 'Company'));
99
        $this->setGivenName(self::getStringElement($xml, 'GivenName'));
100
        $this->setSurName(self::getStringElement($xml, 'SurName'));
101
        $this->setEmailAddress(self::getStringElements($xml, 'EmailAddress'));
102
        $this->setTelephoneNumber(self::getStringElements($xml, 'TelephoneNumber'));
103
104
        foreach ($xml->attributes as $attr) {
105
            if ($attr->nodeName == "contactType") {
106
                continue;
107
            }
108
109
            $this->addContactPersonAttributes($attr->nodeName, $attr->nodeValue);
110
        }
111
    }
112
113
114
    /**
115
     * Retrieve the value of a child \DOMElements as an array of strings.
116
     *
117
     * @param  \DOMElement $parent The parent element.
118
     * @param  string      $name   The name of the child elements.
119
     * @return array       The value of the child elements.
120
     */
121
    private static function getStringElements(\DOMElement $parent, string $name): array
122
    {
123
        $e = Utils::xpQuery($parent, './saml_metadata:' . $name);
124
125
        $ret = [];
126
        foreach ($e as $i) {
127
            $ret[] = $i->textContent;
128
        }
129
130
        return $ret;
131
    }
132
133
134
    /**
135
     * Retrieve the value of a child \DOMElement as a string.
136
     *
137
     * @param  \DOMElement  $parent The parent element.
138
     * @param  string       $name   The name of the child element.
139
     * @throws \Exception
140
     * @return string|null The value of the child element.
141
     */
142
    private static function getStringElement(\DOMElement $parent, string $name): ?string
143
    {
144
        $e = self::getStringElements($parent, $name);
145
        if (empty($e)) {
146
            return null;
147
        }
148
        if (count($e) > 1) {
149
            throw new \Exception('More than one ' . $name . ' in ' . $parent->tagName);
150
        }
151
152
        return $e[0];
153
    }
154
155
156
    /**
157
     * Collect the value of the contactType-property
158
     *
159
     * @return string
160
     *
161
     * @throws \InvalidArgumentException if assertions are false
162
     */
163
    public function getContactType(): string
164
    {
165
        Assert::notEmpty($this->contactType);
166
167
        return $this->contactType;
168
    }
169
170
171
    /**
172
     * Set the value of the contactType-property
173
     *
174
     * @param string $contactType
175
     * @return void
176
     */
177
    public function setContactType(string $contactType): void
178
    {
179
        $this->contactType = $contactType;
180
    }
181
182
183
    /**
184
     * Collect the value of the Company-property
185
     *
186
     * @return string|null
187
     */
188
    public function getCompany(): ?string
189
    {
190
        return $this->Company;
191
    }
192
193
194
    /**
195
     * Set the value of the Company-property
196
     *
197
     * @param string|null $company
198
     * @return void
199
     */
200
    public function setCompany(string $company = null): void
201
    {
202
        $this->Company = $company;
203
    }
204
205
206
    /**
207
     * Collect the value of the GivenName-property
208
     *
209
     * @return string|null
210
     */
211
    public function getGivenName(): ?string
212
    {
213
        return $this->GivenName;
214
    }
215
216
217
    /**
218
     * Set the value of the GivenName-property
219
     *
220
     * @param string|null $givenName
221
     * @return void
222
     */
223
    public function setGivenName(string $givenName = null): void
224
    {
225
        $this->GivenName = $givenName;
226
    }
227
228
229
    /**
230
     * Collect the value of the SurName-property
231
     *
232
     * @return string|null
233
     */
234
    public function getSurName(): ?string
235
    {
236
        return $this->SurName;
237
    }
238
239
240
    /**
241
     * Set the value of the SurName-property
242
     *
243
     * @param string|null $surName
244
     * @return void
245
     */
246
    public function setSurName(string $surName = null): void
247
    {
248
        $this->SurName = $surName;
249
    }
250
251
    /**
252
     * Collect the value of the EmailAddress-property.
253
     *
254
     * @return string[]
255
     */
256
    public function getEmailAddress(): array
257
    {
258
        return $this->EmailAddress;
259
    }
260
261
    /**
262
     * Remove a "mailto:" prefix on an email address, if present.
263
     * Check the address for syntactical validity. If not, throw an exception.
264
     *
265
     * @param string $emailAddress
266
     * @return string
267
     * @throws \InvalidArgumentException if supplied email address is not valid
268
     */
269
    private function validateEmailAddress(string $emailAddress): string
270
    {
271
        $address = preg_replace('/^mailto:/i', '', $emailAddress);
272
        if (filter_var($address, FILTER_VALIDATE_EMAIL) === FALSE) {
273
            throw new \InvalidArgumentException("Invalid email address for ContactPerson: " . var_export($address, true));
274
        }
275
        return $address;
276
    }
277
278
    /**
279
     * Set the value of the EmailAddress-property
280
     *
281
     * @param string[] $emailAddress
282
     * @return void
283
     */
284
    public function setEmailAddress(array $emailAddress): void
285
    {
286
        $this->EmailAddress = array_map([$this, 'validateEmailAddress'], $emailAddress);
287
    }
288
289
    /**
290
     * Add the value to the EmailAddress-property
291
     *
292
     * @param string $emailAddress
293
     * @return void
294
     */
295
    public function addEmailAddress(string $emailAddress): void
296
    {
297
        $this->EmailAddress[] = $this->validateEmailAddress($emailAddress);
298
    }
299
300
    /**
301
     * Collect the value of the TelephoneNumber-property
302
     *
303
     * @return string[]
304
     */
305
    public function getTelephoneNumber(): array
306
    {
307
        return $this->TelephoneNumber;
308
    }
309
310
311
    /**
312
     * Set the value of the TelephoneNumber-property
313
     *
314
     * @param string[] $telephoneNumber
315
     * @return void
316
     */
317
    public function setTelephoneNumber(array $telephoneNumber): void
318
    {
319
        $this->TelephoneNumber = $telephoneNumber;
320
    }
321
322
323
    /**
324
     * Add the value to the TelephoneNumber-property
325
     *
326
     * @param string $telephoneNumber
327
     * @return void
328
     */
329
    public function addTelephoneNumber($telephoneNumber): void
330
    {
331
        $this->TelephoneNumber[] = $telephoneNumber;
332
    }
333
334
335
    /**
336
     * Collect the value of the Extensions-property
337
     *
338
     * @return \SAML2\XML\Chunk[]
339
     */
340
    public function getExtensions(): array
341
    {
342
        return $this->Extensions;
343
    }
344
345
346
    /**
347
     * Set the value of the Extensions-property
348
     *
349
     * @param array $extensions
350
     * @return void
351
     */
352
    public function setExtensions(array $extensions): void
353
    {
354
        $this->Extensions = $extensions;
355
    }
356
357
358
    /**
359
     * Add an Extension.
360
     *
361
     * @param \SAML2\XML\Chunk $extensions The Extensions
362
     * @return void
363
     */
364
    public function addExtension(Chunk $extension): void
365
    {
366
        $this->Extensions[] = $extension;
367
    }
368
369
370
    /**
371
     * Collect the value of the ContactPersonAttributes-property
372
     *
373
     * @return string[]
374
     */
375
    public function getContactPersonAttributes(): array
376
    {
377
        return $this->ContactPersonAttributes;
378
    }
379
380
381
    /**
382
     * Set the value of the ContactPersonAttributes-property
383
     *
384
     * @param string[] $contactPersonAttributes
385
     * @return void
386
     */
387
    public function setContactPersonAttributes(array $contactPersonAttributes): void
388
    {
389
        $this->ContactPersonAttributes = $contactPersonAttributes;
390
    }
391
392
393
    /**
394
     * Add the key/value of the ContactPersonAttributes-property
395
     *
396
     * @param string $attr
397
     * @param string $value
398
     * @return void
399
     */
400
    public function addContactPersonAttributes(string $attr, string $value): void
401
    {
402
        $this->ContactPersonAttributes[$attr] = $value;
403
    }
404
405
406
    /**
407
     * Convert this ContactPerson to XML.
408
     *
409
     * @param  \DOMElement $parent The element we should add this contact to.
410
     * @return \DOMElement The new ContactPerson-element.
411
     *
412
     * @throws \InvalidArgumentException if assertions are false
413
     */
414
    public function toXML(DOMElement $parent): DOMElement
415
    {
416
        Assert::notEmpty($this->contactType);
417
        Assert::allEmail($this->EmailAddress);
418
419
        $doc = $parent->ownerDocument;
420
421
        $e = $doc->createElementNS(Constants::NS_MD, 'md:ContactPerson');
422
        $parent->appendChild($e);
423
424
        $e->setAttribute('contactType', $this->contactType);
425
426
        foreach ($this->ContactPersonAttributes as $attr => $val) {
427
            $e->setAttribute($attr, $val);
428
        }
429
430
        Extensions::addList($e, $this->Extensions);
431
432
        if ($this->Company !== null) {
433
            Utils::addString($e, Constants::NS_MD, 'md:Company', $this->Company);
434
        }
435
        if ($this->GivenName !== null) {
436
            Utils::addString($e, Constants::NS_MD, 'md:GivenName', $this->GivenName);
437
        }
438
        if ($this->SurName !== null) {
439
            Utils::addString($e, Constants::NS_MD, 'md:SurName', $this->SurName);
440
        }
441
        if (!empty($this->EmailAddress)) {
442
            /** @var array $addresses */
443
            $addresses = preg_filter('/^/', 'mailto:', $this->EmailAddress);
444
            Utils::addStrings($e, Constants::NS_MD, 'md:EmailAddress', false, $addresses);
445
        }
446
        if (!empty($this->TelephoneNumber)) {
447
            Utils::addStrings($e, Constants::NS_MD, 'md:TelephoneNumber', false, $this->TelephoneNumber);
448
        }
449
450
        return $e;
451
    }
452
}
453