Passed
Push — master ( 19c658...3efbb7 )
by Tim
02:20
created

IDPList::toArray()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 0
dl 0
loc 12
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\SAML2\XML\samlp;
6
7
use DOMElement;
8
use SimpleSAML\Assert\Assert;
9
use SimpleSAML\SAML2\Exception\ArrayValidationException;
10
use SimpleSAML\XML\Constants as C;
11
use SimpleSAML\XML\Exception\InvalidDOMElementException;
12
use SimpleSAML\XML\Exception\MissingElementException;
13
use SimpleSAML\XML\Exception\TooManyElementsException;
14
use SimpleSAML\XML\Utils as XMLUtils;
15
16
use function array_change_key_case;
17
use function array_filter;
18
use function array_key_exists;
19
use function array_keys;
20
use function array_pop;
21
use function is_null;
22
23
/**
24
 * Class for handling SAML2 IDPList.
25
 *
26
 * @package simplesamlphp/saml2
27
 */
28
final class IDPList extends AbstractSamlpElement
29
{
30
    /**
31
     * Initialize an IDPList element.
32
     *
33
     * @param \SimpleSAML\SAML2\XML\samlp\IDPEntry[] $IDPEntry
34
     * @param \SimpleSAML\SAML2\XML\samlp\GetComplete|null $getComplete
35
     */
36
    public function __construct(
37
        protected array $IDPEntry,
38
        protected ?GetComplete $getComplete = null,
39
    ) {
40
        Assert::maxCount($IDPEntry, C::UNBOUNDED_LIMIT);
41
        Assert::minCount($IDPEntry, 1, 'At least one samlp:IDPEntry must be specified.');
42
        Assert::allIsInstanceOf($IDPEntry, IDPEntry::class);
43
    }
44
45
46
    /**
47
     * @return \SimpleSAML\SAML2\XML\samlp\IDPEntry[]
48
     */
49
    public function getIdpEntry(): array
50
    {
51
        return $this->IDPEntry;
52
    }
53
54
55
    /**
56
     * @return \SimpleSAML\SAML2\XML\samlp\GetComplete|null
57
     */
58
    public function getGetComplete(): ?GetComplete
59
    {
60
        return $this->getComplete;
61
    }
62
63
64
    /**
65
     * Convert XML into a IDPList-element
66
     *
67
     * @param \DOMElement $xml The XML element we should load
68
     * @return static
69
     *
70
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
71
     *   if the qualified name of the supplied element is wrong
72
     * @throws \SimpleSAML\XML\Exception\MissingElementException
73
     *   if one of the mandatory child-elements is missing
74
     * @throws \SimpleSAML\XML\Exception\TooManyElementsException
75
     *   if too many child-elements of a type are specified
76
     */
77
    public static function fromXML(DOMElement $xml): static
78
    {
79
        Assert::same($xml->localName, 'IDPList', InvalidDOMElementException::class);
80
        Assert::same($xml->namespaceURI, IDPList::NS, InvalidDOMElementException::class);
81
82
        $idpEntry = IDPEntry::getChildrenOfClass($xml);
83
        Assert::minCount(
84
            $idpEntry,
85
            1,
86
            'At least one <samlp:IDPEntry> must be specified.',
87
            MissingElementException::class,
88
        );
89
90
        $getComplete = GetComplete::getChildrenOfClass($xml);
91
        Assert::maxCount(
92
            $getComplete,
93
            1,
94
            'Only one <samlp:GetComplete> element is allowed.',
95
            TooManyElementsException::class,
96
        );
97
98
        return new static(
99
            $idpEntry,
100
            empty($getComplete) ? null : array_pop($getComplete),
101
        );
102
    }
103
104
105
    /**
106
     * Convert this IDPList to XML.
107
     *
108
     * @param \DOMElement|null $parent The element we should append this IDPList to.
109
     * @return \DOMElement
110
     */
111
    public function toXML(DOMElement $parent = null): DOMElement
112
    {
113
        $e = $this->instantiateParentElement($parent);
114
115
        foreach ($this->getIDPEntry() as $idpEntry) {
116
            $idpEntry->toXML($e);
117
        }
118
119
        $this->getGetComplete()?->toXML($e);
120
121
        return $e;
122
    }
123
124
125
    /**
126
     * Create a class from an array
127
     *
128
     * @param array $data
129
     * @return static
130
     */
131
    public static function fromArray(array $data): static
132
    {
133
        $data = self::processArrayContents($data);
134
135
        return new static(
136
            $data['IDPEntry'],
137
            $data['GetComplete'] ?? null,
138
        );
139
    }
140
141
142
    /**
143
     * Validates an array representation of this object and returns the same array with
144
     * rationalized keys (casing) and parsed sub-elements.
145
     *
146
     * @param array $data
147
     * @return array $data
148
     */
149
    private static function processArrayContents(array $data): array
150
    {
151
        $data = array_change_key_case($data, CASE_LOWER);
152
153
        // Make sure the array keys are known for this kind of object
154
        Assert::allOneOf(
155
            array_keys($data),
156
            [
157
                'idpentry',
158
                'getcomplete',
159
            ],
160
            ArrayValidationException::class,
161
        );
162
163
        Assert::keyExists($data, 'idpentry', ArrayValidationException::class);
164
        Assert::isArray($data['idpentry'], ArrayValidationException::class);
165
166
        $retval = ['IDPEntry' => [], 'GetComplete' => null];
167
168
        foreach ($data['idpentry'] as $entry) {
169
            $retval['IDPEntry'][] = IDPEntry::fromArray($entry);
170
        }
171
172
        if (array_key_exists('getcomplete', $data)) {
173
            $retval['GetComplete'] = GetComplete::fromArray($data['getcomplete']);
174
        }
175
176
        return $retval;
177
    }
178
179
180
    /**
181
     * Create an array from this class
182
     *
183
     * @return array
184
     */
185
    public function toArray(): array
186
    {
187
        $data = [
188
            'IDPEntry' => [],
189
            'GetComplete' => $this->getGetComplete()?->toArray(),
190
        ];
191
192
        foreach ($this->getIDPEntry() as $entry) {
193
            $data['IDPEntry'][] = $entry->toArray();
194
        }
195
196
        return array_filter($data);
197
    }
198
}
199