Logo   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 197
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 53
dl 0
loc 197
rs 10
c 0
b 0
f 0
wmc 15

10 Methods

Rating   Name   Duplication   Size   Complexity  
A toXML() 0 12 2
A processArrayContents() 0 35 2
A validateContent() 0 7 3
A getLanguage() 0 3 1
A fromArray() 0 5 1
A getWidth() 0 3 1
A toArray() 0 9 2
A __construct() 0 7 1
A fromXML() 0 12 1
A getHeight() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\SAML2\XML\mdui;
6
7
use DOMElement;
8
use InvalidArgumentException;
9
use SimpleSAML\Assert\Assert;
10
//use SimpleSAML\SAML2\Assert\Assert as SAMLAssert;
11
use SimpleSAML\SAML2\Exception\ArrayValidationException;
12
use SimpleSAML\SAML2\Exception\ProtocolViolationException;
13
use SimpleSAML\SAML2\XML\StringElementTrait;
14
use SimpleSAML\XML\ArrayizableElementInterface;
15
use SimpleSAML\XML\Exception\InvalidDOMElementException;
16
use SimpleSAML\XML\SchemaValidatableElementInterface;
17
use SimpleSAML\XML\SchemaValidatableElementTrait;
18
19
use function filter_var;
20
use function strval;
21
use function substr;
22
use function trim;
23
24
/**
25
 * Class for handling the Logo metadata extensions for login and discovery user interface
26
 *
27
 * @link: http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-metadata-ui/v1.0/sstc-saml-metadata-ui-v1.0.pdf
28
 * @package simplesamlphp/saml2
29
 */
30
final class Logo extends AbstractMduiElement implements
31
    ArrayizableElementInterface,
32
    SchemaValidatableElementInterface
33
{
34
    use SchemaValidatableElementTrait;
35
    use StringElementTrait;
0 ignored issues
show
introduced by
The trait SimpleSAML\SAML2\XML\StringElementTrait requires some properties which are not provided by SimpleSAML\SAML2\XML\mdui\Logo: $localName, $namespaceURI
Loading history...
36
37
38
    /**
39
     * Initialize a Logo.
40
     *
41
     * @param string $url
42
     * @param int $height
43
     * @param int $width
44
     * @param string|null $lang
45
     */
46
    public function __construct(
47
        protected string $url,
48
        protected int $height,
49
        protected int $width,
50
        protected ?string $lang = null,
51
    ) {
52
        $this->setContent($url);
53
    }
54
55
56
    /**
57
     * Validate the content of the element.
58
     *
59
     * @param string $content  The value to go in the XML textContent
60
     * @throws \InvalidArgumentException on failure
61
     * @return void
62
     */
63
    protected function validateContent(string $content): void
64
    {
65
        // NOTE:  we override the validateContent from the trait to be able to be less restrictive
66
        // SAMLAssert::validURI($content, SchemaViolationException::class);
67
        Assert::notWhitespaceOnly($content, ProtocolViolationException::class);
68
        if (!filter_var(trim($content), FILTER_VALIDATE_URL) && substr(trim($content), 0, 5) !== 'data:') {
69
            throw new InvalidArgumentException('mdui:Logo is not a valid URL.');
70
        }
71
    }
72
73
74
    /**
75
     * Collect the value of the lang-property
76
     *
77
     * @return string|null
78
     */
79
    public function getLanguage(): ?string
80
    {
81
        return $this->lang;
82
    }
83
84
85
    /**
86
     * Collect the value of the height-property
87
     *
88
     * @return int
89
     */
90
    public function getHeight(): int
91
    {
92
        return $this->height;
93
    }
94
95
96
    /**
97
     * Collect the value of the width-property
98
     *
99
     * @return int
100
     */
101
    public function getWidth(): int
102
    {
103
        return $this->width;
104
    }
105
106
107
    /**
108
     * Convert XML into a Logo
109
     *
110
     * @param \DOMElement $xml The XML element we should load
111
     * @return static
112
     *
113
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
114
     *   if the qualified name of the supplied element is wrong
115
     * @throws \SimpleSAML\XML\Exception\MissingAttributeException
116
     *   if the supplied element is missing one of the mandatory attributes
117
     */
118
    public static function fromXML(DOMElement $xml): static
119
    {
120
        Assert::same($xml->localName, 'Logo', InvalidDOMElementException::class);
121
        Assert::same($xml->namespaceURI, Logo::NS, InvalidDOMElementException::class);
122
        Assert::stringNotEmpty($xml->textContent, 'Missing url value for Logo.');
123
124
        $Url = $xml->textContent;
125
        $Width = self::getIntegerAttribute($xml, 'width');
126
        $Height = self::getIntegerAttribute($xml, 'height');
127
        $lang = self::getOptionalAttribute($xml, 'xml:lang', null);
128
129
        return new static($Url, $Height, $Width, $lang);
130
    }
131
132
133
    /**
134
     * Convert this Logo to XML.
135
     *
136
     * @param \DOMElement|null $parent The element we should append this Logo to.
137
     * @return \DOMElement
138
     */
139
    public function toXML(?DOMElement $parent = null): DOMElement
140
    {
141
        $e = $this->instantiateParentElement($parent);
142
        $e->textContent = $this->getContent();
143
        $e->setAttribute('height', strval($this->getHeight()));
144
        $e->setAttribute('width', strval($this->getWidth()));
145
146
        if ($this->getLanguage() !== null) {
147
            $e->setAttribute('xml:lang', $this->getLanguage());
148
        }
149
150
        return $e;
151
    }
152
153
154
    /**
155
     * Create a class from an array
156
     *
157
     * @param array $data
158
     * @return static
159
     */
160
    public static function fromArray(array $data): static
161
    {
162
        $data = self::processArrayContents($data);
163
164
        return new static($data['url'], $data['height'], $data['width'], $data['lang'] ?? null);
165
    }
166
167
168
    /**
169
     * Validates an array representation of this object and returns the same array with
170
     * rationalized keys (casing) and parsed sub-elements.
171
     *
172
     * @param array $data
173
     * @return array $data
174
     */
175
    private static function processArrayContents(array $data): array
176
    {
177
        $data = array_change_key_case($data, CASE_LOWER);
178
179
        // Make sure the array keys are known for this kind of object
180
        Assert::allOneOf(
181
            array_keys($data),
182
            [
183
                'url',
184
                'height',
185
                'width',
186
                'lang',
187
            ],
188
            ArrayValidationException::class,
189
        );
190
191
        Assert::keyExists($data, 'url', ArrayValidationException::class);
192
        Assert::keyExists($data, 'height', ArrayValidationException::class);
193
        Assert::keyExists($data, 'width', ArrayValidationException::class);
194
195
        Assert::integer($data['height'], ArrayValidationException::class);
196
        Assert::integer($data['width'], ArrayValidationException::class);
197
198
        $retval = [
199
            'url' => $data['url'],
200
            'height' => $data['height'],
201
            'width' => $data['width'],
202
        ];
203
204
        if (array_key_exists('lang', $data)) {
205
            Assert::string($data['lang'], ArrayValidationException::class);
206
            $retval['lang'] = $data['lang'];
207
        }
208
209
        return $retval;
210
    }
211
212
213
    /**
214
     * Create an array from this class
215
     *
216
     * @return array
217
     */
218
    public function toArray(): array
219
    {
220
        $lang = $this->getLanguage();
221
222
        return [
223
            'url' => $this->getContent(),
224
            'width' => $this->getWidth(),
225
            'height' => $this->getHeight(),
226
        ] + (isset($lang) ? ['lang' => $lang] : []);
227
    }
228
}
229