Passed
Pull Request — master (#374)
by Tim
02:36
created

processArrayContents()   B

Complexity

Conditions 6
Paths 16

Size

Total Lines 56
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 34
nc 16
nop 1
dl 0
loc 56
rs 8.7537
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\SAML2\XML\md;
6
7
use DOMElement;
8
use SimpleSAML\SAML2\Assert\Assert;
9
use SimpleSAML\SAML2\Exception\ArrayValidationException;
10
use SimpleSAML\SAML2\Type\SAMLAnyURIValue;
11
use SimpleSAML\XML\ArrayizableElementInterface;
12
use SimpleSAML\XML\Attribute as XMLAttribute;
13
use SimpleSAML\XML\SerializableElementInterface;
14
use SimpleSAML\XMLSchema\Exception\InvalidDOMElementException;
15
use SimpleSAML\XMLSchema\Type\BooleanValue;
16
use SimpleSAML\XMLSchema\Type\UnsignedShortValue;
17
18
use function array_filter;
19
use function array_key_exists;
20
use function array_keys;
21
22
/**
23
 * Class representing a SAML2 IndexedEndpointType.
24
 *
25
 * @package simplesamlphp/saml2
26
 */
27
abstract class AbstractIndexedEndpointType extends AbstractEndpointType implements ArrayizableElementInterface
28
{
29
    use IndexedElementTrait;
30
31
32
    /**
33
     * IndexedEndpointType constructor.
34
     *
35
     * Note: if you extend this class, the constructor must retain its signature. You cannot extend this class and
36
     * modify the signature of the constructor, unless you implement fromXML() yourself. This class provides
37
     * static methods to get its properties from a given \DOMElement for your convenience. Look at the implementation
38
     * of fromXML() to know how to use them.
39
     *
40
     * @param \SimpleSAML\XMLSchema\Type\UnsignedShortValue $index
41
     * @param \SimpleSAML\SAML2\Type\SAMLAnyURIValue $binding
42
     * @param \SimpleSAML\SAML2\Type\SAMLAnyURIValue $location
43
     * @param \SimpleSAML\XMLSchema\Type\BooleanValue|null $isDefault
44
     * @param \SimpleSAML\SAML2\Type\SAMLAnyURIValue|null $responseLocation
45
     * @param array $children
46
     * @param list<\SimpleSAML\XML\Attribute> $attributes
0 ignored issues
show
Bug introduced by
The type SimpleSAML\SAML2\XML\md\list 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...
47
     */
48
    public function __construct(
49
        UnsignedShortValue $index,
50
        SAMLAnyURIValue $binding,
51
        SAMLAnyURIValue $location,
52
        ?BooleanValue $isDefault = null,
53
        ?SAMLAnyURIValue $responseLocation = null,
54
        array $children = [],
55
        array $attributes = [],
56
    ) {
57
        parent::__construct($binding, $location, $responseLocation, $children, $attributes);
58
59
        $this->setIndex($index);
60
        $this->setIsDefault($isDefault);
61
    }
62
63
64
    /**
65
     * Initialize an IndexedEndpointType.
66
     *
67
     * @param \DOMElement $xml The XML element we should load.
68
     * @return static
69
     *
70
     * @throws \SimpleSAML\XMLSchema\Exception\InvalidDOMElementException
71
     *   if the qualified name of the supplied element is wrong
72
     * @throws \SimpleSAML\XMLSchema\Exception\MissingAttributeException
73
     *   if the supplied element is missing any of the mandatory attributes
74
     */
75
    public static function fromXML(DOMElement $xml): static
76
    {
77
        $qualifiedName = static::getClassName(static::class);
78
        Assert::eq(
79
            $xml->localName,
80
            $qualifiedName,
81
            'Unexpected name for endpoint: ' . $xml->localName . '. Expected: ' . $qualifiedName . '.',
82
            InvalidDOMElementException::class,
83
        );
84
85
        return new static(
86
            self::getAttribute($xml, 'index', UnsignedShortValue::class),
87
            self::getAttribute($xml, 'Binding', SAMLAnyURIValue::class),
88
            self::getAttribute($xml, 'Location', SAMLAnyURIValue::class),
89
            self::getOptionalAttribute($xml, 'isDefault', BooleanValue::class, null),
90
            self::getOptionalAttribute($xml, 'ResponseLocation', SAMLAnyURIValue::class, null),
91
            self::getChildElementsFromXML($xml),
92
            self::getAttributesNSFromXML($xml),
93
        );
94
    }
95
96
97
    /**
98
     * Add this endpoint to an XML element.
99
     *
100
     * @param \DOMElement $parent The element we should append this endpoint to.
101
     * @return \DOMElement
102
     */
103
    public function toXML(?DOMElement $parent = null): DOMElement
104
    {
105
        $e = parent::instantiateParentElement($parent);
106
        $e->setAttribute('Binding', $this->getBinding()->getValue());
107
        $e->setAttribute('Location', $this->getLocation()->getValue());
108
109
        if ($this->getResponseLocation() !== null) {
110
            $e->setAttribute('ResponseLocation', $this->getResponseLocation()->getValue());
111
        }
112
113
        $e->setAttribute('index', $this->getIndex()->getValue());
114
115
        if ($this->getIsDefault() !== null) {
116
            $e->setAttribute('isDefault', $this->getIsDefault()->getValue());
117
        }
118
119
        foreach ($this->getAttributesNS() as $attr) {
120
            $attr->toXML($e);
121
        }
122
123
        /** @var \SimpleSAML\XML\SerializableElementInterface $child */
124
        foreach ($this->getElements() as $child) {
125
            if (!$child->isEmptyElement()) {
126
                $child->toXML($e);
127
            }
128
        }
129
130
        return $e;
131
    }
132
133
134
    /**
135
     * Create a class from an array
136
     *
137
     * @param array $data
138
     * @return static
139
     */
140
    public static function fromArray(array $data): static
141
    {
142
        $data = self::processArrayContents($data);
143
144
        return new static(
145
            UnsignedShortValue::fromInteger($data['index']),
146
            SAMLAnyURIValue::fromString($data['Binding']),
147
            SAMLAnyURIValue::fromString($data['Location']),
148
            $data['isDefault'] !== null ? BooleanValue::fromBoolean($data['isDefault']) : null,
149
            ($data['ResponseLocation'] ?? null) ? SAMLAnyURIValue::fromString($data['ResponseLocation']) : null,
150
            $data['children'] ?? [],
151
            $data['attributes'] ?? [],
152
        );
153
    }
154
155
156
    /**
157
     * Validates an array representation of this object and returns the same array with
158
     * rationalized keys (casing) and parsed sub-elements.
159
     *
160
     * @param array $data
161
     * @return array $data
162
     */
163
    private static function processArrayContents(array $data): array
164
    {
165
        $data = array_change_key_case($data, CASE_LOWER);
166
167
        // Make sure the array keys are known for this kind of object
168
        Assert::allOneOf(
169
            array_keys($data),
170
            ['index', 'binding', 'location', 'isdefault', 'responselocation', 'children', 'attributes'],
171
            ArrayValidationException::class,
172
        );
173
174
        // Make sure all the mandatory items exist
175
        Assert::keyExists($data, 'binding', ArrayValidationException::class);
176
        Assert::keyExists($data, 'location', ArrayValidationException::class);
177
        Assert::keyExists($data, 'index', ArrayValidationException::class);
178
179
        // Make sure the items have the correct data type
180
        Assert::integer($data['index'], ArrayValidationException::class);
181
        Assert::string($data['binding'], ArrayValidationException::class);
182
        Assert::string($data['location'], ArrayValidationException::class);
183
184
        $retval = [
185
            'Binding' => $data['binding'],
186
            'Location' => $data['location'],
187
            'index' => $data['index'],
188
        ];
189
190
        if (array_key_exists('isdefault', $data)) {
191
            Assert::boolean($data['isdefault'], ArrayValidationException::class);
192
            $retval['isDefault'] = $data['isdefault'];
193
        }
194
195
        if (array_key_exists('responselocation', $data)) {
196
            Assert::string($data['responselocation'], ArrayValidationException::class);
197
            $retval['ResponseLocation'] = $data['responselocation'];
198
        }
199
200
        if (array_key_exists('children', $data)) {
201
            Assert::isArray($data['children'], ArrayValidationException::class);
202
            Assert::allIsInstanceOf(
203
                $data['children'],
204
                SerializableElementInterface::class,
205
                ArrayValidationException::class,
206
            );
207
            $retval['children'] = $data['children'];
208
        }
209
210
        if (array_key_exists('attributes', $data)) {
211
            Assert::isArray($data['attributes'], ArrayValidationException::class);
212
            Assert::allIsArray($data['attributes'], ArrayValidationException::class);
213
            foreach ($data['attributes'] as $i => $attr) {
214
                $retval['attributes'][] = XMLAttribute::fromArray($attr);
215
            }
216
        }
217
218
        return $retval;
219
    }
220
221
222
    /**
223
     * Create an array from this class
224
     *
225
     * @return array
226
     */
227
    public function toArray(): array
228
    {
229
        $data = parent::toArray();
230
        $data['index'] = $this->getIndex()->toInteger();
231
        $data['isDefault'] = $this->getIsDefault()->toBoolean();
232
233
        return array_filter($data);
234
    }
235
}
236