Completed
Push — master ( f7b88b...3755ed )
by Josh
14:40
created

ConvertCurlyExpressionsInText::normalizeNode()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 37
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 37
ccs 20
cts 20
cp 1
rs 8.8571
c 0
b 0
f 0
cc 3
eloc 20
nc 3
nop 1
crap 3
1
<?php
2
3
/**
4
* @package   s9e\TextFormatter
5
* @copyright Copyright (c) 2010-2017 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 DOMNode;
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 $queries = ['//*[namespace-uri() != $XSL]/text()[contains(., "{@") or contains(., "{$")]'];
26
27
	/**
28
	* Insert a text node before given node
29
	*
30
	* @param  string  $text
31
	* @param  DOMNode $node
32
	* @return void
33
	*/
34 2
	protected function insertTextBefore($text, $node)
35
	{
36 2
		$node->parentNode->insertBefore($this->createTextNode($text), $node);
37 2
	}
38
39
	/**
40
	* {@inheritdoc}
41
	*/
42 2
	protected function normalizeNode(DOMNode $node)
43
	{
44 2
		$parentNode = $node->parentNode;
45
46 2
		preg_match_all(
47 2
			'#\\{([$@][-\\w]+)\\}#',
48 2
			$node->textContent,
49 2
			$matches,
50 2
			PREG_SET_ORDER | PREG_OFFSET_CAPTURE
51
		);
52
53 2
		$lastPos = 0;
54 2
		foreach ($matches as $m)
55
		{
56 2
			$pos = $m[0][1];
57
58
			// Catch up to current position
59 2
			if ($pos > $lastPos)
60
			{
61 1
				$text = substr($node->textContent, $lastPos, $pos - $lastPos);
62 1
				$this->insertTextBefore($text, $node);
63
			}
64 2
			$lastPos = $pos + strlen($m[0][0]);
65
66
			// Add the xsl:value-of element
67
			$parentNode
68 2
				->insertBefore($this->createElement('xsl:value-of'), $node)
69 2
				->setAttribute('select', $m[1][0]);
70
		}
71
72
		// Append the rest of the text
73 2
		$text = substr($node->textContent, $lastPos);
74 2
		$this->insertTextBefore($text, $node);
75
76
		// Now remove the old text node
77 2
		$parentNode->removeChild($node);
78
	}
79
}