Issues (100)

src/Impl/Instance/DomDocumentImpl.php (2 issues)

Labels
Severity
1
<?php
2
3
namespace Xml\Impl\Instance;
4
5
use Xml\Instance\{
6
    DomElementInterface,
7
    DomDocumentInterface
8
};
9
use Xml\Impl\Util\XmlQName;
10
use Xml\Impl\Util\DomUtil;
11
use Xml\Exception\ModelException;
12
13
class DomDocumentImpl implements DomDocumentInterface
14
{
15
    public const GENERIC_NS_PREFIX = "ns";
16
    public const XMLNS_ATTRIBUTE_NS_URI = "http://www.w3.org/2000/xmlns/";
17
18
    private $document;
19
20
    public function __construct(DomDocumentExt $document)
21
    {
22
        $this->document = $document;
23
    }
24
25
    public function getDomSource(): DomDocumentExt
26
    {
27
        return $this->document;
28
    }
29
30
    public function getRootElement(): ?DomElementInterface
31
    {
32
        $documentElement = $this->document->documentElement;
33
        if ($documentElement !== null) {
34
            return new DomElementImpl($documentElement);
35
        } else {
36
            return null;
37
        }
38
    }
39
40
    public function setRootElement(DomElementInterface $rootElement): void
41
    {
42
        $documentElement = $this->document->documentElement;
43
        $newDocumentElement = $rootElement->getElement();
44
        if ($documentElement !== null) {
45
            $this->document->replaceChild($newDocumentElement, $documentElement);
0 ignored issues
show
It seems like $newDocumentElement can also be of type null; however, parameter $node of DOMNode::replaceChild() does only seem to accept DOMNode, maybe add an additional type check? ( Ignorable by Annotation )

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

45
            $this->document->replaceChild(/** @scrutinizer ignore-type */ $newDocumentElement, $documentElement);
Loading history...
46
        } else {
47
            $this->document->appendChild($newDocumentElement);
0 ignored issues
show
It seems like $newDocumentElement can also be of type null; however, parameter $node of DOMNode::appendChild() does only seem to accept DOMNode, maybe add an additional type check? ( Ignorable by Annotation )

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

47
            $this->document->appendChild(/** @scrutinizer ignore-type */ $newDocumentElement);
Loading history...
48
        }
49
    }
50
51
    public function createElement(string $namespaceUri, string $localName): DomElementInterface
52
    {
53
        $xmlQName = new XmlQName($this, null, $namespaceUri, $localName);
54
        $element = $this->document->createElementNS($xmlQName->getNamespaceUri(), $xmlQName->getPrefixedName());
55
        return new DomElementImpl($element);
56
    }
57
58
    public function getElementById(string $id): ?DomElementInterface
59
    {
60
        $element = $this->document->getElementById($id);
61
        if ($element !== null) {
62
            return new DomElementImpl($element);
63
        } else {
64
            return null;
65
        }
66
    }
67
68
    public function getElementsByNameNs(string $namespaceUri, string $localName): array
69
    {
70
        $elementsByTagNameNS = $this->document->getElementsByTagNameNS($namespaceUri, $localName);
71
        return DomUtil::filterNodeListByName($elementsByTagNameNS, $namespaceUri, $localName);
72
    }
73
74
    public function registerNamespace(?string $prefix, string $namespaceUri): void
75
    {
76
        $rootElement = $this->getRootElement();
77
        if ($rootElement !== null) {
78
            $rootElement->registerNamespace($prefix, $namespaceUri);
79
        } else {
80
            throw new ModelException("Unable to define a new namespace without a root document element");
81
        }
82
    }
83
84
    public function getUnusedGenericNsPrefix(): string
85
    {
86
        $documentElement = $this->document->documentElement;
87
        if ($documentElement === null) {
88
            return self::GENERIC_NS_PREFIX . "0";
89
        } else {
90
            for ($i = 0; $i < PHP_INT_MAX; $i += 1) {
91
                if (!$documentElement->hasAttributeNS(self::XMLNS_ATTRIBUTE_NS_URI, self::GENERIC_NS_PREFIX . $i)) {
92
                    return self::GENERIC_NS_PREFIX . $i;
93
                }
94
            }
95
            return self::GENERIC_NS_PREFIX . "0";
96
        }
97
    }
98
99
    public function clone(): DomDocumentInterface
100
    {
101
        $xml = $this->document->saveXML();
102
        $clone = new DomDocumentExt();
103
        $clone->loadXML($xml);
104
        return new DomDocumentImpl($clone);
105
    }
106
}
107