Skip to content

Commit 6dba7d2

Browse files
authored
Merge pull request #89 from simplesamlphp/feature/dom-migration-php84
Migrate DOM-classes to PHP 8.4's new DOM-API
2 parents 8287593 + a30b970 commit 6dba7d2

158 files changed

Lines changed: 1655 additions & 1783 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

composer.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@
7272
"scripts": {
7373
"pre-commit": [
7474
"vendor/bin/phpcs -p",
75-
"vendor/bin/composer-require-checker check --config-file=tools/composer-require-checker.json composer.json",
7675
"vendor/bin/phpstan analyze -c phpstan.neon",
7776
"vendor/bin/phpstan analyze -c phpstan-dev.neon",
7877
"vendor/bin/composer-unused --excludePackage=simplesamlphp/composer-xmlprovider-installer",

src/XML/AbstractElement.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace SimpleSAML\XML;
66

7-
use DOMElement;
7+
use Dom;
88
use RuntimeException;
99
use SimpleSAML\XML\Assert\Assert;
1010
use SimpleSAML\XML\SerializableElementTrait;
@@ -35,9 +35,9 @@ abstract class AbstractElement implements
3535
/**
3636
* Create a document structure for this element
3737
*
38-
* @param \DOMElement|null $parent The element we should append to.
38+
* @param \Dom\Element|null $parent The element we should append to.
3939
*/
40-
public function instantiateParentElement(?DOMElement $parent = null): DOMElement
40+
public function instantiateParentElement(?Dom\Element $parent = null): Dom\Element
4141
{
4242
$qualifiedName = $this->getQualifiedName();
4343
$namespace = static::getNamespaceURI();
@@ -59,15 +59,15 @@ public function instantiateParentElement(?DOMElement $parent = null): DOMElement
5959

6060
/**
6161
* @template T of \SimpleSAML\XMLSchema\Type\Interface\ValueTypeInterface
62-
* @param \DOMElement $xml The element where we should search for the attribute.
62+
* @param \Dom\Element $xml The element where we should search for the attribute.
6363
* @param string $name The name of the attribute.
6464
* @param class-string<T> $type The type of the attribute value.
6565
* @return T
6666
*
6767
* @throws \SimpleSAML\XMLSchema\Exception\MissingAttributeException if the attribute is missing from the element
6868
*/
6969
public static function getAttribute(
70-
DOMElement $xml,
70+
Dom\Element $xml,
7171
string $name,
7272
string $type = StringValue::class,
7373
): ValueTypeInterface {
@@ -91,15 +91,15 @@ public static function getAttribute(
9191
* Get the value of an attribute from a given element.
9292
*
9393
* @template T of \SimpleSAML\XMLSchema\Type\Interface\ValueTypeInterface
94-
* @param \DOMElement $xml The element where we should search for the attribute.
94+
* @param \Dom\Element $xml The element where we should search for the attribute.
9595
* @param string $name The name of the attribute.
9696
* @param class-string<T> $type The type of the attribute value.
9797
* @param \SimpleSAML\XMLSchema\Type\Interface\ValueTypeInterface|null $default
9898
* The default to return in case the attribute does not exist and it is optional.
9999
* @return ($default is \SimpleSAML\XMLSchema\Type\Interface\ValueTypeInterface ? T : T|null)
100100
*/
101101
public static function getOptionalAttribute(
102-
DOMElement $xml,
102+
Dom\Element $xml,
103103
string $name,
104104
string $type = StringValue::class,
105105
?ValueTypeInterface $default = null,
@@ -142,15 +142,15 @@ public function getQualifiedName(): string
142142
/**
143143
* Extract localized names from the children of a given element.
144144
*
145-
* @param \DOMElement $parent The element we want to search.
145+
* @param \Dom\Element $parent The element we want to search.
146146
* @return list<static> An array of objects of this class.
147147
*/
148-
public static function getChildrenOfClass(DOMElement $parent): array
148+
public static function getChildrenOfClass(Dom\Element $parent): array
149149
{
150150
$ret = [];
151151
foreach ($parent->childNodes as $node) {
152152
if (
153-
$node instanceof DOMElement
153+
$node instanceof Dom\Element
154154
&& $node->namespaceURI === static::getNamespaceURI()
155155
&& $node->localName === static::getLocalName()
156156
) {

src/XML/Attribute.php

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
namespace SimpleSAML\XML;
66

7-
use DOMAttr;
8-
use DOMElement;
7+
use Dom;
98
use SimpleSAML\XML\Assert\Assert;
9+
use SimpleSAML\XML\Constants as C;
1010
use SimpleSAML\XMLSchema\Type\Interface\ValueTypeInterface;
1111
use SimpleSAML\XMLSchema\Type\StringValue;
1212

@@ -83,9 +83,9 @@ public function getAttrValue(): ValueTypeInterface
8383
/**
8484
* Create a class from XML
8585
*
86-
* @param \DOMAttr $attr
86+
* @param \Dom\Attr $attr
8787
*/
88-
public static function fromXML(DOMAttr $attr): static
88+
public static function fromXML(Dom\Attr $attr): static
8989
{
9090
return new static($attr->namespaceURI, $attr->prefix, $attr->localName, StringValue::fromString($attr->value));
9191
}
@@ -94,23 +94,20 @@ public static function fromXML(DOMAttr $attr): static
9494
/**
9595
* Create XML from this class
9696
*
97-
* @param \DOMElement $parent
97+
* @param \Dom\Element $parent
9898
*/
99-
public function toXML(DOMElement $parent): DOMElement
99+
public function toXML(Dom\Element $parent): Dom\Element
100100
{
101-
if ($this->getNamespaceURI() !== null && !$parent->lookupPrefix($this->getNamespacePrefix())) {
102-
$parent->setAttributeNS(
103-
'http://www.w3.org/2000/xmlns/',
104-
'xmlns:' . $this->getNamespacePrefix(),
105-
$this->getNamespaceURI(),
106-
);
101+
$prefix = $this->getNamespacePrefix();
102+
$namespaceURI = $this->getNamespaceURI();
103+
104+
if ($namespaceURI !== null && !in_array($prefix, ['xml', 'xmlns']) && !$parent->lookupPrefix($prefix)) {
105+
$parent->setAttributeNS(C::NS_XMLNS, 'xmlns:' . $prefix, $namespaceURI);
107106
}
108107

109108
$parent->setAttributeNS(
110-
$this->getNamespaceURI(),
111-
!in_array($this->getNamespacePrefix(), ['', null])
112-
? ($this->getNamespacePrefix() . ':' . $this->getAttrName())
113-
: $this->getAttrName(),
109+
$namespaceURI,
110+
!in_array($prefix, ['', null]) ? ($prefix . ':' . $this->getAttrName()) : $this->getAttrName(),
114111
strval($this->getAttrValue()),
115112
);
116113

src/XML/Chunk.php

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace SimpleSAML\XML;
66

7-
use DOMElement;
7+
use Dom;
88
use SimpleSAML\XML\Assert\Assert;
99
use SimpleSAML\XML\DOMDocumentFactory;
1010
use SimpleSAML\XML\SerializableElementTrait;
@@ -57,10 +57,10 @@ final class Chunk implements
5757
/**
5858
* Create an XML Chunk from a copy of the given \DOMElement.
5959
*
60-
* @param \DOMElement $xml The element we should copy.
60+
* @param \Dom\Element $xml The element we should copy.
6161
*/
6262
public function __construct(
63-
protected DOMElement $xml,
63+
protected Dom\Element $xml,
6464
) {
6565
$this->setLocalName($xml->localName);
6666
$this->setNamespaceURI($xml->namespaceURI);
@@ -132,9 +132,9 @@ protected function setNamespaceURI(?string $namespaceURI = null): void
132132

133133

134134
/**
135-
* Get this \DOMElement.
135+
* Get this \Dom\Element.
136136
*/
137-
public function getXML(): DOMElement
137+
public function getXML(): Dom\Element
138138
{
139139
return $this->xml;
140140
}
@@ -180,15 +180,15 @@ public function getQualifiedName(): string
180180
* Get the value of an attribute from a given element.
181181
*
182182
* @template T of \SimpleSAML\XMLSchema\Type\Interface\ValueTypeInterface
183-
* @param \DOMElement $xml The element where we should search for the attribute.
183+
* @param \Dom\Element $xml The element where we should search for the attribute.
184184
* @param string $name The name of the attribute.
185185
* @param class-string<T> $type The type of the attribute value.
186186
* @return T
187187
*
188188
* @throws \SimpleSAML\XMLSchema\Exception\MissingAttributeException if the attribute is missing from the element
189189
*/
190190
public static function getAttribute(
191-
DOMElement $xml,
191+
Dom\Element $xml,
192192
string $name,
193193
string $type = StringValue::class,
194194
): ValueTypeInterface {
@@ -209,15 +209,15 @@ public static function getAttribute(
209209
* Get the value of an attribute from a given element.
210210
*
211211
* @template T of \SimpleSAML\XMLSchema\Type\Interface\ValueTypeInterface
212-
* @param \DOMElement $xml The element where we should search for the attribute.
212+
* @param \Dom\Element $xml The element where we should search for the attribute.
213213
* @param string $name The name of the attribute.
214214
* @param class-string<T> $type The type of the attribute value.
215215
* @param \SimpleSAML\XMLSchema\Type\Interface\ValueTypeInterface|null $default
216216
* The default to return in case the attribute does not exist and it is optional.
217217
* @return ($default is \SimpleSAML\XMLSchema\Type\Interface\ValueTypeInterface ? T : T|null)
218218
*/
219219
public static function getOptionalAttribute(
220-
DOMElement $xml,
220+
Dom\Element $xml,
221221
string $name,
222222
string $type = StringValue::class,
223223
?ValueTypeInterface $default = null,
@@ -235,16 +235,16 @@ public static function getOptionalAttribute(
235235
*/
236236
public function isEmptyElement(): bool
237237
{
238-
/** @var \DOMElement $xml */
238+
/** @var \Dom\Element $xml */
239239
$xml = $this->getXML();
240240
return ($xml->childNodes->length === 0) && ($xml->attributes->count() === 0);
241241
}
242242

243243

244244
/**
245-
* @param \DOMElement $xml
245+
* @param \Dom\Element $xml
246246
*/
247-
public static function fromXML(DOMElement $xml): static
247+
public static function fromXML(Dom\Element $xml): static
248248
{
249249
return new static($xml);
250250
}
@@ -253,10 +253,10 @@ public static function fromXML(DOMElement $xml): static
253253
/**
254254
* Append this XML element to a different XML element.
255255
*
256-
* @param \DOMElement|null $parent The element we should append this element to.
257-
* @return \DOMElement The new element.
256+
* @param \Dom\Element|null $parent The element we should append this element to.
257+
* @return \Dom\Element The new element.
258258
*/
259-
public function toXML(?DOMElement $parent = null): DOMElement
259+
public function toXML(?Dom\Element $parent = null): Dom\Element
260260
{
261261
if ($parent === null) {
262262
$doc = DOMDocumentFactory::create();

src/XML/Container/AbstractTestContainer.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace SimpleSAML\XML\Container;
66

7+
use Dom;
78
use SimpleSAML\XML\Attribute as XMLAttribute;
89
use SimpleSAML\XML\Chunk;
910
use SimpleSAML\XML\Type\LangValue;
@@ -28,4 +29,11 @@ abstract public function getLanguageValue(string $language = 'en'): LanguageValu
2829

2930

3031
abstract public function getXMLAttribute(int $x = 1): XMLAttribute;
32+
33+
34+
/**
35+
* @param non-empty-string $text
36+
* @return \Dom\NodeList<\Dom\Node>
37+
*/
38+
abstract public function getDOMText(string $text): Dom\NodeList;
3139
}

src/XML/Container/XMLSchemaElementsTrait.php

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace SimpleSAML\XML\Container;
66

7-
use DOMText;
7+
use Dom;
88
use SimpleSAML\XML\DOMDocumentFactory;
99
use SimpleSAML\XMLSchema\Type\AnyURIValue;
1010
use SimpleSAML\XMLSchema\XML\Appinfo;
@@ -26,22 +26,41 @@ trait XMLSchemaElementsTrait
2626
/** @var array<positive-int, \SimpleSAML\XMLSchema\XML\Appinfo> */
2727
protected array $appinfo = [];
2828

29+
/** @var array<non-empty-string, \Dom\NodeList> */
30+
protected array $domText = [];
31+
2932

3033
/** @param positive-int $x */
3134
public function getAppinfo(int $x = 1): Appinfo
3235
{
3336
if (!array_key_exists($x, $this->appinfo)) {
34-
$appinfoDocument = DOMDocumentFactory::create();
35-
$text = new DOMText(sprintf('Application Information (%d)', $x));
36-
$appinfoDocument->appendChild($text);
37+
$domTextNode = $this->getDOMText(sprintf('Application Information (%d)', $x));
3738

3839
$this->appinfo[$x] = new Appinfo(
39-
$appinfoDocument->childNodes,
40+
$domTextNode,
4041
AnyURIValue::fromString(static::SOURCE),
4142
[$this->getXMLAttribute($x)],
4243
);
4344
}
4445

4546
return $this->appinfo[$x];
4647
}
48+
49+
50+
/** @param non-empty-string $text */
51+
public function getDOMText(string $text): Dom\NodeList
52+
{
53+
if (!array_key_exists($text, $this->domText)) {
54+
$doc = DOMDocumentFactory::create();
55+
56+
$elt = $doc->createElement('root');
57+
$domText = $doc->createTextNode($text);
58+
59+
$elt->appendChild($domText);
60+
61+
$this->domText[$text] = $elt->childNodes;
62+
}
63+
64+
return $this->domText[$text];
65+
}
4766
}

0 commit comments

Comments
 (0)