PublicationInfo::processArrayContents()   A
last analyzed

Complexity

Conditions 5
Paths 8

Size

Total Lines 33
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 20
nc 8
nop 1
dl 0
loc 33
rs 9.2888
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\SAML2\Assert\Assert;
9
use SimpleSAML\SAML2\Constants as C;
0 ignored issues
show
Bug introduced by
The type SimpleSAML\SAML2\Constants 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...
10
use SimpleSAML\SAML2\Exception\ArrayValidationException;
11
use SimpleSAML\SAML2\Exception\ProtocolViolationException;
12
use SimpleSAML\SAML2\Type\SAMLDateTimeValue;
0 ignored issues
show
Bug introduced by
The type SimpleSAML\SAML2\Type\SAMLDateTimeValue 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...
13
use SimpleSAML\SAML2\Type\SAMLStringValue;
14
use SimpleSAML\XML\ArrayizableElementInterface;
15
use SimpleSAML\XML\SchemaValidatableElementInterface;
16
use SimpleSAML\XML\SchemaValidatableElementTrait;
17
use SimpleSAML\XMLSchema\Exception\InvalidDOMElementException;
18
19
use function array_change_key_case;
20
use function array_keys;
21
22
/**
23
 * Class for handling the mdrpi:PublicationInfo element.
24
 *
25
 * @link: http://docs.oasis-open.org/security/saml/Post2.0/saml-metadata-rpi/v1.0/saml-metadata-rpi-v1.0.pdf
26
 * @package simplesamlphp/saml2
27
 */
28
final class PublicationInfo extends AbstractMdrpiElement implements
0 ignored issues
show
Bug introduced by
The type SimpleSAML\SAML2\XML\mdrpi\AbstractMdrpiElement 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...
29
    ArrayizableElementInterface,
30
    SchemaValidatableElementInterface
31
{
32
    use SchemaValidatableElementTrait;
33
34
35
    /**
36
     * Create/parse a mdrpi:PublicationInfo element.
37
     *
38
     * @param \SimpleSAML\SAML2\Type\SAMLStringValue $publisher
39
     * @param \SimpleSAML\SAML2\Type\SAMLDateTimeValue|null $creationInstant
40
     * @param \SimpleSAML\SAML2\Type\SAMLStringValue|null $publicationId
41
     * @param \SimpleSAML\SAML2\XML\mdrpi\UsagePolicy[] $usagePolicy
42
     */
43
    public function __construct(
44
        protected SAMLStringValue $publisher,
45
        protected ?SAMLDateTimeValue $creationInstant = null,
46
        protected ?SAMLStringValue $publicationId = null,
47
        protected array $usagePolicy = [],
48
    ) {
49
        Assert::maxCount($usagePolicy, C::UNBOUNDED_LIMIT);
50
        Assert::allIsInstanceOf($usagePolicy, UsagePolicy::class);
0 ignored issues
show
Bug introduced by
The type SimpleSAML\SAML2\XML\mdrpi\UsagePolicy 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...
51
52
        /**
53
         * 2.2.1:  There MUST NOT be more than one <mdrpi:UsagePolicy>,
54
         *         within a given <mdrpi:UsageInfo>, for a given language
55
         */
56
        $languages = array_map(
57
            function ($up) {
58
                return $up->getLanguage();
59
            },
60
            $usagePolicy,
61
        );
62
        Assert::uniqueValues(
63
            $languages,
64
            'There MUST NOT be more than one <mdrpi:UsagePolicy>,'
65
            . ' within a given <mdrpi:PublicationInfo>, for a given language',
66
            ProtocolViolationException::class,
67
        );
68
    }
69
70
71
    /**
72
     * Collect the value of the publisher-property
73
     *
74
     * @return \SimpleSAML\SAML2\Type\SAMLStringValue
75
     */
76
    public function getPublisher(): SAMLStringValue
77
    {
78
        return $this->publisher;
79
    }
80
81
82
    /**
83
     * Collect the value of the creationInstant-property
84
     *
85
     * @return \SimpleSAML\SAML2\Type\SAMLDateTimeValue|null
86
     */
87
    public function getCreationInstant(): ?SAMLDateTimeValue
88
    {
89
        return $this->creationInstant;
90
    }
91
92
93
    /**
94
     * Collect the value of the publicationId-property
95
     *
96
     * @return \SimpleSAML\SAML2\Type\SAMLStringValue|null
97
     */
98
    public function getPublicationId(): ?SAMLStringValue
99
    {
100
        return $this->publicationId;
101
    }
102
103
104
    /**
105
     * Collect the value of the UsagePolicy-property
106
     *
107
     * @return \SimpleSAML\SAML2\XML\mdrpi\UsagePolicy[]
108
     */
109
    public function getUsagePolicy(): array
110
    {
111
        return $this->usagePolicy;
112
    }
113
114
115
    /**
116
     * Convert XML into a PublicationInfo
117
     *
118
     * @throws \SimpleSAML\XMLSchema\Exception\InvalidDOMElementException
119
     *   if the qualified name of the supplied element is wrong
120
     * @throws \SimpleSAML\XMLSchema\Exception\MissingAttributeException
121
     *   if the supplied element is missing one of the mandatory attributes
122
     */
123
    public static function fromXML(DOMElement $xml): static
124
    {
125
        Assert::same($xml->localName, 'PublicationInfo', InvalidDOMElementException::class);
126
        Assert::same($xml->namespaceURI, PublicationInfo::NS, InvalidDOMElementException::class);
127
128
        $publisher = self::getAttribute($xml, 'publisher', SAMLStringValue::class);
129
        $creationInstant = self::getOptionalAttribute($xml, 'creationInstant', SAMLDateTimeValue::class, null);
130
        $publicationId = self::getOptionalAttribute($xml, 'publicationId', SAMLStringValue::class, null);
131
        $UsagePolicy = UsagePolicy::getChildrenOfClass($xml);
132
133
        return new static($publisher, $creationInstant, $publicationId, $UsagePolicy);
134
    }
135
136
137
    /**
138
     * Convert this element to XML.
139
     */
140
    public function toXML(?DOMElement $parent = null): DOMElement
141
    {
142
        $e = $this->instantiateParentElement($parent);
143
        $e->setAttribute('publisher', $this->getPublisher()->getValue());
144
145
        if ($this->getCreationInstant() !== null) {
146
            $e->setAttribute('creationInstant', $this->getCreationInstant()->getValue());
147
        }
148
149
        if ($this->getPublicationId() !== null) {
150
            $e->setAttribute('publicationId', $this->getPublicationId()->getValue());
151
        }
152
153
        foreach ($this->getUsagePolicy() as $up) {
154
            $up->toXML($e);
155
        }
156
157
        return $e;
158
    }
159
160
161
    /**
162
     * Create a class from an array
163
     *
164
     * @param array{
165
     *   'publisher': string,
166
     *   'creationInstant'?: string,
167
     *   'publicationId'?: string,
168
     *   'UsagePolicy'?: array,
169
     * } $data
170
     */
171
    public static function fromArray(array $data): static
172
    {
173
        $data = self::processArrayContents($data);
174
175
        return new static(
176
            SAMLStringValue::fromString($data['publisher']),
177
            $data['creationInstant'] !== null ? SAMLDateTimeValue::fromString($data['creationInstant']) : null,
178
            $data['publicationId'] !== null ? SAMLStringValue::fromString($data['publicationId']) : null,
179
            $data['UsagePolicy'] ?? [],
180
        );
181
    }
182
183
184
    /**
185
     * Validates an array representation of this object and returns the same array with
186
     * rationalized keys (casing) and parsed sub-elements.
187
     *
188
     * @param array{
189
     *   'publisher': string,
190
     *   'creationInstant'?: string,
191
     *   'publicationId'?: string,
192
     *   'UsagePolicy'?: array,
193
     * } $data
194
     * @return array{
0 ignored issues
show
Documentation Bug introduced by
The doc comment array{ at position 2 could not be parsed: the token is null at position 2.
Loading history...
195
     *   'publisher': string,
196
     *   'creationInstant'?: string,
197
     *   'publicationId'?: string,
198
     *   'UsagePolicy'?: array,
199
     * }
200
     */
201
    private static function processArrayContents(array $data): array
202
    {
203
        $data = array_change_key_case($data, CASE_LOWER);
204
205
        Assert::allOneOf(
206
            array_keys($data),
207
            ['publisher', 'creationinstant', 'publicationid', 'usagepolicy'],
208
            ArrayValidationException::class,
209
        );
210
        Assert::keyExists($data, 'publisher', ArrayValidationException::class);
211
212
        Assert::string($data['publisher'], ArrayValidationException::class);
213
        $retval = ['publisher' => $data['publisher']];
214
215
        if (array_key_exists('creationinstant', $data)) {
216
            Assert::string($data['creationinstant'], ArrayValidationException::class);
217
            Assert::validSAMLDateTime($data['creationinstant'], ArrayValidationException::class);
218
            $retval['creationInstant'] = $data['creationinstant'];
219
        }
220
221
        if (array_key_exists('publicationid', $data)) {
222
            Assert::string($data['publicationid'], ArrayValidationException::class);
223
            $retval['publicationId'] = $data['publicationid'];
224
        }
225
226
        if (array_key_exists('usagepolicy', $data)) {
227
            Assert::isArray($data['usagepolicy'], ArrayValidationException::class);
228
            foreach ($data['usagepolicy'] as $lang => $up) {
229
                $retval['UsagePolicy'][] = UsagePolicy::fromArray([$lang => $up]);
230
            }
231
        }
232
233
        return $retval;
234
    }
235
236
237
    /**
238
     * Create an array from this class
239
     *
240
     * @return array{
0 ignored issues
show
Documentation Bug introduced by
The doc comment array{ at position 2 could not be parsed: the token is null at position 2.
Loading history...
241
     *   'publisher': string,
242
     *   'creationInstant'?: string,
243
     *   'publicationId'?: string,
244
     *   'UsagePolicy'?: array,
245
     * }
246
     */
247
    public function toArray(): array
248
    {
249
        $data = [];
250
        $data['publisher'] = $this->getPublisher()->getValue();
251
252
        if ($this->getCreationInstant() !== null) {
253
            $data['creationInstant'] = $this->getCreationInstant()->getValue();
254
        }
255
256
        if ($this->getPublicationId() !== null) {
257
            $data['publicationId'] = $this->getPublicationId()->getValue();
258
        }
259
260
        if (!empty($this->getUsagePolicy())) {
261
            $data['UsagePolicy'] = [];
262
            foreach ($this->getUsagePolicy() as $up) {
263
                $data['UsagePolicy'] = array_merge($data['UsagePolicy'], $up->toArray());
264
            }
265
        }
266
        return $data;
267
    }
268
}
269