Passed
Branch major/TemplateNormalizationsSw... (c391a8)
by Josh
02:38
created

ConvertCurlyExpressionsInText::normalizeText()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 34
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 17
dl 0
loc 34
rs 9.7
c 0
b 0
f 0
cc 3
nc 3
nop 1
1
<?php
2
3
/**
4
* @package   s9e\TextFormatter
5
* @copyright Copyright (c) 2010-2023 The s9e authors
6
* @license   http://www.opensource.org/licenses/mit-license.php The MIT License
7
*/
8
namespace s9e\TextFormatter\Configurator\TemplateNormalizations;
9
10
use DOMText;
11
12
/**
13
* Convert simple expressions in curly brackets in text into xsl:value-of elements
14
*
15
* Will replace
16
*     <span>{$FOO}{@bar}</span>
17
* with
18
*     <span><xsl:value-of value="$FOO"/><xsl:value-of value="@bar"/></span>
19
*/
20
class ConvertCurlyExpressionsInText extends AbstractNormalization
21
{
22
	/**
23
	* {@inheritdoc}
24
	*/
25
	protected array $queries = ['//*[namespace-uri() != "' . self::XMLNS_XSL . '"]/text()[contains(., "{@") or contains(., "{$")]'];
26
27
	/**
28
	* Insert a text node before given node
29
	*
30
	* @param  string  $text
31
	* @param  DOMNode $node
0 ignored issues
show
Bug introduced by
The type s9e\TextFormatter\Config...eNormalizations\DOMNode was not found. Did you mean DOMNode? If so, make sure to prefix the type with \.
Loading history...
32
	* @return void
33
	*/
34
	protected function insertTextBefore($text, $node)
35
	{
36
		if ($text > '')
37
		{
38
			$node->parentNode->insertBefore($this->createText($text), $node);
39
		}
40
	}
41
42
	/**
43
	* {@inheritdoc}
44
	*/
45
	protected function normalizeText(DOMText $node)
46
	{
47
		$parentNode = $node->parentNode;
48
49
		preg_match_all(
50
			'#\\{([$@][-\\w]+)\\}#',
51
			$node->textContent,
52
			$matches,
53
			PREG_SET_ORDER | PREG_OFFSET_CAPTURE
54
		);
55
56
		$lastPos = 0;
57
		foreach ($matches as $m)
58
		{
59
			$pos = $m[0][1];
60
61
			// Catch up to current position
62
			if ($pos > $lastPos)
63
			{
64
				$text = substr($node->textContent, $lastPos, $pos - $lastPos);
65
				$this->insertTextBefore($text, $node);
66
			}
67
			$lastPos = $pos + strlen($m[0][0]);
68
69
			// Add the xsl:value-of element
70
			$parentNode->insertBefore($this->ownerDocument->createXslValueOf($m[1][0]), $node);
71
		}
72
73
		// Append the rest of the text
74
		$text = substr($node->textContent, $lastPos);
75
		$this->insertTextBefore($text, $node);
76
77
		// Now remove the old text node
78
		$node->remove();
79
	}
80
}