IDPList   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 172
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 50
dl 0
loc 172
rs 10
c 0
b 0
f 0
wmc 13

8 Methods

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