Passed
Push — master ( 7a371e...4a8d98 )
by Tim
02:17
created

PublicationInfo::setUsagePolicy()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 11
nc 1
nop 1
dl 0
loc 22
rs 9.9
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\SAML2\XML\mdrpi;
6
7
use DOMElement;
8
use SimpleSAML\Assert\Assert;
9
use SimpleSAML\SAML2\Exception\ProtocolViolationException;
10
use SimpleSAML\XML\Exception\InvalidDOMElementException;
11
use SimpleSAML\XML\Utils as XMLUtils;
12
13
/**
14
 * Class for handling the mdrpi:PublicationInfo element.
15
 *
16
 * @link: http://docs.oasis-open.org/security/saml/Post2.0/saml-metadata-rpi/v1.0/saml-metadata-rpi-v1.0.pdf
17
 * @package simplesamlphp/saml2
18
 */
19
final class PublicationInfo extends AbstractMdrpiElement
20
{
21
    /**
22
     * Create/parse a mdrpi:PublicationInfo element.
23
     *
24
     * @param string $publisher
25
     * @param int|null $creationInstant
26
     * @param string|null $publicationId
27
     * @param \SimpleSAML\SAML2\XML\mdrpi\UsagePolicy[] $usagePolicy
28
     */
29
    public function __construct(
30
        protected string $publisher,
31
        protected ?int $creationInstant = null,
32
        protected ?string $publicationId = null,
33
        protected array $usagePolicy = [],
34
    ) {
35
        Assert::allIsInstanceOf($usagePolicy, UsagePolicy::class);
36
37
        /**
38
         * 2.2.1:  There MUST NOT be more than one <mdrpi:UsagePolicy>,
39
         *         within a given <mdrpi:UsageInfo>, for a given language
40
         */
41
        $languages = array_map(
42
            function ($up) {
43
                return $up->getLanguage();
44
            },
45
            $usagePolicy,
46
        );
47
        Assert::uniqueValues(
48
            $languages,
49
            'There MUST NOT be more than one <mdrpi:UsagePolicy>,'
50
            . ' within a given <mdrpi:PublicationInfo>, for a given language',
51
            ProtocolViolationException::class,
52
        );
53
    }
54
55
56
    /**
57
     * Collect the value of the publisher-property
58
     *
59
     * @return string
60
     */
61
    public function getPublisher(): string
62
    {
63
        return $this->publisher;
64
    }
65
66
67
    /**
68
     * Collect the value of the creationInstant-property
69
     *
70
     * @return int|null
71
     */
72
    public function getCreationInstant(): ?int
73
    {
74
        return $this->creationInstant;
75
    }
76
77
78
    /**
79
     * Collect the value of the publicationId-property
80
     *
81
     * @return string|null
82
     */
83
    public function getPublicationId(): ?string
84
    {
85
        return $this->publicationId;
86
    }
87
88
89
    /**
90
     * Collect the value of the UsagePolicy-property
91
     *
92
     * @return \SimpleSAML\SAML2\XML\mdrpi\UsagePolicy[]
93
     */
94
    public function getUsagePolicy(): array
95
    {
96
        return $this->usagePolicy;
97
    }
98
99
100
    /**
101
     * Convert XML into a PublicationInfo
102
     *
103
     * @param \DOMElement $xml The XML element we should load
104
     * @return self
105
     *
106
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
107
     *   if the qualified name of the supplied element is wrong
108
     * @throws \SimpleSAML\XML\Exception\MissingAttributeException
109
     *   if the supplied element is missing one of the mandatory attributes
110
     */
111
    public static function fromXML(DOMElement $xml): static
112
    {
113
        Assert::same($xml->localName, 'PublicationInfo', InvalidDOMElementException::class);
114
        Assert::same($xml->namespaceURI, PublicationInfo::NS, InvalidDOMElementException::class);
115
116
        $publisher = self::getAttribute($xml, 'publisher');
117
        $creationInstant = self::getAttribute($xml, 'creationInstant', null);
118
119
        // 2.2.1:  Time values MUST be expressed in the UTC timezone using the 'Z' timezone identifier
120
        if ($creationInstant !== null) {
121
            // Strip sub-seconds - See paragraph 1.3.3 of SAML core specifications
122
            $creationInstant = preg_replace('/([.][0-9]+Z)$/', 'Z', $creationInstant, 1);
123
124
            Assert::validDateTimeZulu($creationInstant, ProtocolViolationException::class);
125
            $creationInstant = XMLUtils::xsDateTimeToTimestamp($creationInstant);
126
        }
127
128
        $publicationId = self::getAttribute($xml, 'publicationId', null);
129
        $UsagePolicy = UsagePolicy::getChildrenOfClass($xml);
130
131
        return new static($publisher, $creationInstant, $publicationId, $UsagePolicy);
132
    }
133
134
135
    /**
136
     * Convert this element to XML.
137
     *
138
     * @param \DOMElement|null $parent The element we should append to.
139
     * @return \DOMElement
140
     */
141
    public function toXML(DOMElement $parent = null): DOMElement
142
    {
143
        $e = $this->instantiateParentElement($parent);
144
        $e->setAttribute('publisher', $this->getPublisher());
145
146
        if ($this->getCreationInstant() !== null) {
147
            $e->setAttribute('creationInstant', gmdate('Y-m-d\TH:i:s\Z', $this->getCreationInstant()));
148
        }
149
150
        if ($this->getPublicationId() !== null) {
151
            $e->setAttribute('publicationId', $this->getPublicationId());
152
        }
153
154
        foreach ($this->getUsagePolicy() as $up) {
155
            $up->toXML($e);
156
        }
157
158
        return $e;
159
    }
160
161
162
    /**
163
     * Create a class from an array
164
     *
165
     * @param array $data
166
     * @return self
167
     */
168
    public static function fromArray(array $data): static
169
    {
170
        Assert::keyExists($data, 'publisher');
171
172
        $publisher = $data['publisher'];
173
        Assert::string($publisher);
174
175
        $creationInstant = $data['creationInstant'] ?? null;
176
        Assert::nullOrInteger($creationInstant);
177
178
        $publicationId = $data['publicationId'] ?? null;
179
        Assert::nullOrString($publicationId);
180
181
        $up = $data['usagePolicy'] ?? [];
182
        Assert::isArray($up);
183
184
        $usagePolicy = [];
185
        foreach ($up as $k => $v) {
186
            $usagePolicy[] = UsagePolicy::fromArray([$k => $v]);
187
        }
188
189
        return new static($publisher, $creationInstant, $publicationId, $usagePolicy);
190
    }
191
192
193
    /**
194
     * Create an array from this class
195
     *
196
     * @return array
197
     */
198
    public function toArray(): array
199
    {
200
        $data = [];
201
        $data['publisher'] = $this->getPublisher();
202
203
        if ($this->getCreationInstant() !== null) {
204
            $data['creationInstant'] = $this->getCreationInstant();
205
        }
206
207
        if ($this->getPublicationId() !== null) {
208
            $data['publicationId'] = $this->getPublicationId();
209
        }
210
211
        if (!empty($this->getUsagePolicy())) {
212
            $data['usagePolicy'] = [];
213
            foreach ($this->getUsagePolicy() as $up) {
214
                $data['usagePolicy'] = array_merge($data['usagePolicy'], $up->toArray());
215
            }
216
        }
217
        return $data;
218
    }
219
}
220