Passed
Push — master ( 482d42...6f3615 )
by Josh
02:01
created

NodeCreator::createXslChoose()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php declare(strict_types=1);
2
3
/**
4
* @package   s9e\SweetDOM
5
* @copyright Copyright (c) The s9e authors
6
* @license   http://www.opensource.org/licenses/mit-license.php The MIT License
7
*/
8
namespace s9e\SweetDOM;
9
10
use DOMException;
11
use const DOM_NAMESPACE_ERR, DOM_SYNTAX_ERR, ENT_XML1;
12
use function htmlspecialchars, str_contains, strpos, substr;
13
14
class NodeCreator
15
{
16
	public function __construct(protected Document $ownerDocument)
17
	{
18
	}
19
20
	public function createComment(string $data): Comment
21
	{
22
		if (str_contains($data, '--'))
23
		{
24
			throw new DOMException('Double hyphen within comment: ' . $data, DOM_SYNTAX_ERR);
25
		}
26
27
		return $this->ownerDocument->createComment($data);
1 ignored issue
show
Bug Best Practice introduced by
The expression return $this->ownerDocument->createComment($data) returns the type DOMComment which includes types incompatible with the type-hinted return s9e\SweetDOM\Comment.
Loading history...
28
	}
29
30
	/**
31
	* Create and return an element
32
	*/
33
	public function createElement(string $nodeName, string $textContent = ''): Element
34
	{
35
		$value = htmlspecialchars($textContent, ENT_XML1);
36
37
		$pos = strpos($nodeName, ':');
38
		if ($pos === false)
39
		{
40
			return $this->ownerDocument->createElement($nodeName, $value);
41
		}
42
43
		$prefix = substr($nodeName, 0, $pos);
44
		$nsURI  = $this->ownerDocument->lookupNamespaceURI($prefix);
45
		if ($nsURI === null)
46
		{
47
			throw new DOMException('Undefined namespace prefix', DOM_NAMESPACE_ERR);
48
		}
49
50
		return $this->ownerDocument->createElementNS($nsURI, $nodeName, $value);
51
	}
52
53
	public function createElementNS(?string $namespace, string $nodeName, string $textContent = ''): Element
54
	{
55
		$value = htmlspecialchars($textContent, ENT_XML1);
56
57
		return $this->ownerDocument->createElementNS($namespace, $nodeName, $value);
58
	}
59
60
	/**
61
	* Create and return an xsl:apply-templates element
62
	*/
63
	public function createXslApplyTemplates(string $select = null, string $mode = null): Element
64
	{
65
		return $this->createXslElementByName('apply-templates', '', ['mode' => $mode, 'select' => $select]);
66
	}
67
68
	/**
69
	* Create and return an xsl:attribute element
70
	*/
71
	public function createXslAttribute(string $name, string $textContent = '', string $namespace = null): Element
72
	{
73
		return $this->createXslElementByName('attribute', $textContent, ['name' => $name, 'namespace' => $namespace]);
74
	}
75
76
	/**
77
	* Create and return an xsl:choose element
78
	*/
79
	public function createXslChoose(): Element
80
	{
81
		return $this->createXslElementByName('choose');
82
	}
83
84
	/**
85
	* Create and return an xsl:comment element
86
	*/
87
	public function createXslComment(string $textContent = ''): Element
88
	{
89
		return $this->createXslElementByName('comment', $textContent);
90
	}
91
92
	/**
93
	* Create and return an xsl:copy-of element
94
	*/
95
	public function createXslCopyOf(string $select): Element
96
	{
97
		return $this->createXslElementByName('copy-of', '', ['select' => $select]);
98
	}
99
100
	/**
101
	* Create and return an xsl:element element
102
	*/
103
	public function createXslElement(string $name, string $namespace = null, string $useAttributeSets = null): Element
104
	{
105
		return $this->createXslElementByName('element', '', ['name' => $name, 'namespace' => $namespace, 'use-attribute-sets' => $useAttributeSets]);
106
	}
107
108
	/**
109
	* Create and return an XSL element
110
	*/
111
	protected function createXslElementByName(string $localName, string $textContent = '', array $attributes = []): Element
112
	{
113
		$element = $this->ownerDocument->createElementNS(
114
			'http://www.w3.org/1999/XSL/Transform',
115
			'xsl:' . $localName,
116
			htmlspecialchars($textContent, ENT_XML1)
117
		);
118
		foreach ($attributes as $attrName => $attrValue)
119
		{
120
			// Skip attributes with a NULL value
121
			if (isset($attrValue))
122
			{
123
				$element->setAttribute($attrName, $attrValue);
124
			}
125
		}
126
127
		return $element;
128
	}
129
130
	/**
131
	* Create and return an xsl:if element
132
	*/
133
	public function createXslIf(string $test, string $textContent = ''): Element
134
	{
135
		return $this->createXslElementByName('if', $textContent, ['test' => $test]);
136
	}
137
138
	/**
139
	* Create and return an xsl:otherwise element
140
	*/
141
	public function createXslOtherwise(string $textContent = ''): Element
142
	{
143
		return $this->createXslElementByName('otherwise', $textContent);
144
	}
145
146
	/**
147
	* Create and return an xsl:text element
148
	*/
149
	public function createXslText(string $textContent = '', string $disableOutputEscaping = null): Element
150
	{
151
		return $this->createXslElementByName('text', $textContent, ['disable-output-escaping' => $disableOutputEscaping]);
152
	}
153
154
	/**
155
	* Create and return an xsl:value-of element
156
	*/
157
	public function createXslValueOf(string $select, string $disableOutputEscaping = null): Element
158
	{
159
		return $this->createXslElementByName('value-of', '', ['disable-output-escaping' => $disableOutputEscaping, 'select' => $select]);
160
	}
161
162
	/**
163
	* Create and return an xsl:variable element
164
	*/
165
	public function createXslVariable(string $name, string $select = null): Element
166
	{
167
		return $this->createXslElementByName('variable', '', ['name' => $name, 'select' => $select]);
168
	}
169
170
	/**
171
	* Create and return an xsl:when element
172
	*/
173
	public function createXslWhen(string $test, string $textContent = ''): Element
174
	{
175
		return $this->createXslElementByName('when', $textContent, ['test' => $test]);
176
	}
177
}