Issues (343)

src/XML/Chunk.php (3 issues)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\XML;
6
7
use DOMElement;
8
use SimpleSAML\XML\Assert\Assert;
9
use SimpleSAML\XML\DOMDocumentFactory;
0 ignored issues
show
The type SimpleSAML\XML\DOMDocumentFactory 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\XML\SerializableElementTrait;
11
use SimpleSAML\XMLSchema\Exception\MissingAttributeException;
12
use SimpleSAML\XMLSchema\Exception\SchemaViolationException;
13
use SimpleSAML\XMLSchema\Type\Interface\ValueTypeInterface;
14
use SimpleSAML\XMLSchema\Type\StringValue;
0 ignored issues
show
The type SimpleSAML\XMLSchema\Type\StringValue 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...
15
16
/**
17
 * Serializable class used to hold an XML element.
18
 *
19
 * @package simplesamlphp/xml-common
20
 */
21
final class Chunk implements
22
    SerializableElementInterface,
23
    ElementInterface
24
{
25
    use SerializableElementTrait;
26
27
28
    /**
29
     * Whether the element may be normalized
30
     *
31
     * @var bool $normalization
32
     */
33
    protected bool $normalization = true;
34
35
    /**
36
     * The localName of the element.
37
     *
38
     * @var string
39
     */
40
    protected string $localName;
41
42
    /**
43
     * The namespaceURI of this element.
44
     *
45
     * @var string|null
46
     */
47
    protected ?string $namespaceURI;
48
49
    /**
50
     * The prefix of this element.
51
     *
52
     * @var string
53
     */
54
    protected string $prefix;
55
56
57
    /**
58
     * Create an XML Chunk from a copy of the given \DOMElement.
59
     *
60
     * @param \DOMElement $xml The element we should copy.
61
     */
62
    public function __construct(
63
        protected DOMElement $xml,
64
    ) {
65
        $this->setLocalName($xml->localName);
66
        $this->setNamespaceURI($xml->namespaceURI);
67
        $this->setPrefix($xml->prefix);
68
    }
69
70
71
    /**
72
     * Collect the value of the normalization-property
73
     */
74
    public function getNormalization(): bool
75
    {
76
        return $this->normalization;
77
    }
78
79
80
    /**
81
     * Set the value of the normalization-property
82
     *
83
     * @param bool $normalization
84
     */
85
    public function setNormalization(bool $normalization): void
86
    {
87
        $this->normalization = $normalization;
88
    }
89
90
91
    /**
92
     * Collect the value of the localName-property
93
     */
94
    public function getLocalName(): string
95
    {
96
        return $this->localName;
97
    }
98
99
100
    /**
101
     * Set the value of the localName-property
102
     *
103
     * @param string $localName
104
     * @throws \SimpleSAML\Assert\AssertionFailedException if $localName is an empty string
105
     */
106
    public function setLocalName(string $localName): void
107
    {
108
        Assert::validNCName($localName, SchemaViolationException::class); // Covers the empty string
109
        $this->localName = $localName;
110
    }
111
112
113
    /**
114
     * Collect the value of the namespaceURI-property
115
     */
116
    public function getNamespaceURI(): ?string
117
    {
118
        return $this->namespaceURI;
119
    }
120
121
122
    /**
123
     * Set the value of the namespaceURI-property
124
     *
125
     * @param string|null $namespaceURI
126
     */
127
    protected function setNamespaceURI(?string $namespaceURI = null): void
128
    {
129
        Assert::nullOrValidURI($namespaceURI, SchemaViolationException::class);
130
        $this->namespaceURI = $namespaceURI;
131
    }
132
133
134
    /**
135
     * Get this \DOMElement.
136
     */
137
    public function getXML(): DOMElement
138
    {
139
        return $this->xml;
140
    }
141
142
143
    /**
144
     * Collect the value of the prefix-property
145
     */
146
    public function getPrefix(): string
147
    {
148
        return $this->prefix;
149
    }
150
151
152
    /**
153
     * Set the value of the prefix-property
154
     *
155
     * @param string|null $prefix
156
     */
157
    protected function setPrefix(?string $prefix = null): void
158
    {
159
        $this->prefix = strval($prefix);
160
    }
161
162
163
    /**
164
     * Get the XML qualified name (prefix:name, or just name when not prefixed)
165
     *  of the element represented by this class.
166
     */
167
    public function getQualifiedName(): string
168
    {
169
        $prefix = $this->getPrefix();
170
171
        if (empty($prefix)) {
172
            return $this->getLocalName();
173
        } else {
174
            return $prefix . ':' . $this->getLocalName();
175
        }
176
    }
177
178
179
    /**
180
     * Get the value of an attribute from a given element.
181
     *
182
     * @template T of \SimpleSAML\XMLSchema\Type\Interface\ValueTypeInterface
183
     * @param \DOMElement     $xml The element where we should search for the attribute.
184
     * @param string          $name The name of the attribute.
185
     * @param class-string<T> $type The type of the attribute value.
186
     * @return T
187
     *
188
     * @throws \SimpleSAML\XMLSchema\Exception\MissingAttributeException if the attribute is missing from the element
189
     */
190
    public static function getAttribute(
191
        DOMElement $xml,
192
        string $name,
193
        string $type = StringValue::class,
194
    ): ValueTypeInterface {
195
        Assert::isAOf($type, ValueTypeInterface::class);
196
197
        Assert::true(
198
            $xml->hasAttribute($name),
199
            'Missing \'' . $name . '\' attribute on ' . $xml->prefix . ':' . $xml->localName . '.',
200
            MissingAttributeException::class,
201
        );
202
203
        $value = $xml->getAttribute($name);
204
        return $type::fromString($value);
205
    }
206
207
208
    /**
209
     * Get the value of an attribute from a given element.
210
     *
211
     * @template T of \SimpleSAML\XMLSchema\Type\Interface\ValueTypeInterface
212
     * @param \DOMElement  $xml The element where we should search for the attribute.
213
     * @param string       $name The name of the attribute.
214
     * @param class-string<T> $type The type of the attribute value.
215
     * @param \SimpleSAML\XMLSchema\Type\Interface\ValueTypeInterface|null $default
216
     *   The default to return in case the attribute does not exist and it is optional.
217
     * @return ($default is \SimpleSAML\XMLSchema\Type\Interface\ValueTypeInterface ? T : T|null)
218
     */
219
    public static function getOptionalAttribute(
220
        DOMElement $xml,
221
        string $name,
222
        string $type = StringValue::class,
223
        ?ValueTypeInterface $default = null,
224
    ): ?ValueTypeInterface {
225
        if (!$xml->hasAttribute($name)) {
226
            return $default;
227
        }
228
229
        return self::getAttribute($xml, $name, $type);
230
    }
231
232
233
    /**
234
     * Test if an object, at the state it's in, would produce an empty XML-element
235
     */
236
    public function isEmptyElement(): bool
237
    {
238
        /** @var \DOMElement $xml */
239
        $xml = $this->getXML();
240
        return ($xml->childNodes->length === 0) && ($xml->attributes->count() === 0);
0 ignored issues
show
The method count() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

240
        return ($xml->childNodes->length === 0) && ($xml->attributes->/** @scrutinizer ignore-call */ count() === 0);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
241
    }
242
243
244
    /**
245
     * @param \DOMElement $xml
246
     */
247
    public static function fromXML(DOMElement $xml): static
248
    {
249
        return new static($xml);
250
    }
251
252
253
    /**
254
     * Append this XML element to a different XML element.
255
     *
256
     * @param  \DOMElement|null $parent The element we should append this element to.
257
     * @return \DOMElement The new element.
258
     */
259
    public function toXML(?DOMElement $parent = null): DOMElement
260
    {
261
        if ($parent === null) {
262
            $doc = DOMDocumentFactory::create();
263
        } else {
264
            $doc = $parent->ownerDocument;
265
            Assert::notNull($doc);
266
        }
267
268
        if ($parent === null) {
269
            $parent = $doc;
270
        }
271
272
        $parent->appendChild($doc->importNode($this->getXML(), true));
273
        return $doc->documentElement;
274
    }
275
}
276