Skip to content

Commit 507fd1b

Browse files
committed
Reach phpstan level 8
1 parent 8e9f7d8 commit 507fd1b

File tree

3 files changed

+57
-16
lines changed

3 files changed

+57
-16
lines changed

src/Util/Xml.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,15 @@
1212

1313
class Xml
1414
{
15+
/**
16+
* @param array<mixed> $array
17+
*/
1518
public static function arrayToXml(DOMDocument $xml, DOMNode $domNode, array $array = []): DOMDocument
1619
{
1720
foreach ($array as $el => $val) {
21+
/**
22+
* @var string|array< $val
23+
*/
1824
if (is_array($val)) {
1925
self::arrayToXml($xml, $domNode->$el, $val);
2026
} else {
@@ -24,7 +30,10 @@ public static function arrayToXml(DOMDocument $xml, DOMNode $domNode, array $arr
2430
return $xml;
2531
}
2632

27-
public static function toXml(DOMDocument|DOMElement|XmlBuilder|string|null $xml): DOMDocument
33+
/**
34+
* @param array<DOMNode|XmlBuilder|array<mixed>|string|null> $xml
35+
*/
36+
public static function toXml(DOMNode|XmlBuilder|array|string|null $xml): DOMDocument
2837
{
2938
if ($xml instanceof XmlBuilder) {
3039
return $xml->getDom();

src/Util/XmlBuilder.php

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use DOMDocument;
88
use DOMElement;
9+
use DOMNode;
910
use Exception;
1011

1112
/**
@@ -74,7 +75,7 @@ class XmlBuilder
7475
{
7576
protected DOMDocument $dom;
7677

77-
protected DOMElement|DOMDocument $currentNode;
78+
protected DOMNode $currentNode;
7879

7980
public function __construct()
8081
{
@@ -93,7 +94,7 @@ public function __get(string $tag): XmlBuilder
9394
return $this;
9495
}
9596

96-
public function val($val): self
97+
public function val(string $val): self
9798
{
9899
$this->currentNode->nodeValue = $val;
99100
return $this;
@@ -104,6 +105,9 @@ public function val($val): self
104105
*/
105106
public function attr(string $attr, string $val): self
106107
{
108+
if (!$this->currentNode instanceof DOMElement) {
109+
throw new Exception('Current node is not DOMElement');
110+
}
107111
$this->currentNode->setAttribute($attr, $val);
108112
return $this;
109113
}
@@ -113,38 +117,46 @@ public function attr(string $attr, string $val): self
113117
*/
114118
public function parent(): self
115119
{
120+
if ($this->currentNode->parentNode === null) {
121+
throw new Exception('Element has no parent');
122+
}
116123
$this->currentNode = $this->currentNode->parentNode;
117124
return $this;
118125
}
119126

120127
/**
121-
* Traverses to parent with $name
128+
* Traverses to parent with $tagName
122129
*
123130
* @throws Exception
124131
*/
125-
public function parents(string $tag): self
132+
public function parents(string $tagName): self
126133
{
127134
$traverseNode = $this->currentNode;
128135
$elFound = false;
129136
while ($traverseNode->parentNode) {
130137
$traverseNode = $traverseNode->parentNode;
131-
if ($traverseNode->tagName === $tag) {
138+
if ($traverseNode instanceof DOMElement && $traverseNode->tagName === $tagName) {
132139
$this->currentNode = $traverseNode;
133140
$elFound = true;
134141
break;
135142
}
136143
}
137144

138145
if (!$elFound) {
139-
throw new Exception("Parent {$tag} not found in XML");
146+
throw new Exception("Parent {$tagName} not found in XML");
140147
}
141148

142149
return $this;
143150
}
144151

145152
public function __toString(): string
146153
{
147-
return $this->dom->saveXML();
154+
$string = $this->dom->saveXML();
155+
if ($string === false) {
156+
throw new Exception('Failed to convert DOM to string');
157+
}
158+
159+
return $string;
148160
}
149161

150162
public function getDom(): DOMDocument

src/Util/XmlStructure.php

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@
1414

1515
class XmlStructure
1616
{
17-
protected DOMDocument|DOMNode $xml;
17+
protected DOMDocument $xml;
1818

19+
/**
20+
* @param array<DOMNode|XmlBuilder|array<mixed>|string|null> $xml
21+
*/
1922
public function __construct($xml)
2023
{
2124
$this->xml = SoapXmlUtil::toXml($xml);
@@ -36,37 +39,54 @@ public function matchElement(string $cssOrXPath): ?DOMNode
3639
$domXpath = new DOMXpath($this->xml);
3740
$selector = (new CssSelectorConverter())->toXPath($cssOrXPath);
3841
$els = $domXpath->query($selector);
39-
if ($els) {
42+
if ($els !== false && count($els) > 0) {
4043
return $els->item(0);
4144
}
4245
$els = $domXpath->query($cssOrXPath);
43-
if ($els->length !== 0) {
46+
if ($els !== false && count($els) > 0) {
4447
return $els->item(0);
4548
}
4649
throw new ElementNotFound($cssOrXPath);
4750
}
4851

52+
/**
53+
* @param array<DOMNode|XmlBuilder|array<mixed>|string|null> $xml
54+
*/
4955
public function matchXmlStructure($xml): bool
5056
{
5157
$xml = SoapXmlUtil::toXml($xml);
5258
$root = $xml->firstChild;
59+
if ($root === null) {
60+
throw new \Exception('XML is empty');
61+
}
5362
$els = $this->xml->getElementsByTagName($root->nodeName);
54-
if (empty($els)) {
63+
if (count($els) === 0) {
5564
throw new ElementNotFound($root->nodeName, 'Element');
5665
}
5766

58-
$matches = false;
5967
foreach ($els as $node) {
60-
$matches |= $this->matchForNode($root, $node);
68+
/**
69+
* @var DOMNode $node
70+
*/
71+
if ($this->matchForNode($root, $node)) {
72+
return true;
73+
}
6174
}
62-
return $matches;
75+
76+
return false;
6377
}
6478

65-
protected function matchForNode($schema, $xml): bool
79+
protected function matchForNode(DOMNode $schema, DOMNode $xml): bool
6680
{
6781
foreach ($schema->childNodes as $node1) {
82+
/**
83+
* @var DOMNode $node1
84+
*/
6885
$matched = false;
6986
foreach ($xml->childNodes as $node2) {
87+
/**
88+
* @var DOMNode $node2
89+
*/
7090
if ($node1->nodeName == $node2->nodeName) {
7191
$matched = $this->matchForNode($node1, $node2);
7292
if ($matched) {

0 commit comments

Comments
 (0)