Completed
Push — master ( 76f73f...63574b )
by Josh
14:23
created

UninlineAttributes   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 82
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 8
lcom 1
cbo 2
dl 0
loc 82
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A normalizeElement() 0 9 2
A uninlineAttribute() 0 14 2
A uninlineDynamicAttribute() 0 23 3
A uninlineStaticAttribute() 0 4 1
1
<?php
2
3
/**
4
* @package   s9e\TextFormatter
5
* @copyright Copyright (c) 2010-2019 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 DOMAttr;
11
use DOMElement;
12
use s9e\TextFormatter\Configurator\Helpers\AVTHelper;
13
14
/**
15
* Uninline element attributes
16
*
17
* Will replace
18
*     <a href="{@url}">...</a>
19
* with
20
*     <a><xsl:attribute name="href"><xsl:value-of select="@url"/></xsl:attribute>...</a>
21
*/
22
class UninlineAttributes extends AbstractNormalization
23
{
24
	/**
25
	* {@inheritdoc}
26
	*/
27
	protected $queries = ['//*[namespace-uri() != $XSL]'];
28
29
	/**
30
	* {@inheritdoc}
31
	*/
32
	protected function normalizeElement(DOMElement $element)
33
	{
34
		$firstChild = $element->firstChild;
35
		while ($element->attributes->length > 0)
36
		{
37
			$attribute = $element->attributes->item(0);
38
			$element->insertBefore($this->uninlineAttribute($attribute), $firstChild);
39
		}
40
	}
41
42
	/**
43
	* Remove an attribute from its parent element and return its content as an xsl:attribute
44
	*
45
	* @param  DOMAttr    $attribute Attribute node
46
	* @return DOMElement            xsl:attribute element
47
	*/
48
	protected function uninlineAttribute(DOMAttr $attribute)
49
	{
50
		$xslAttribute = (strpos($attribute->value, '{') === false)
51
		              ? $this->uninlineStaticAttribute($attribute)
52
		              : $this->uninlineDynamicAttribute($attribute);
53
54
		// Set the xsl:attribute element's name
55
		$xslAttribute->setAttribute('name', $attribute->nodeName);
56
57
		// Remove the attribute from its parent element
58
		$attribute->parentNode->removeAttributeNode($attribute);
59
60
		return $xslAttribute;
61
	}
62
63
	/**
64
	* Uninline an AVT-style attribute
65
	*
66
	* @param  DOMAttr    $attribute Attribute node
67
	* @return DOMElement            xsl:attribute element
68
	*/
69
	protected function uninlineDynamicAttribute(DOMAttr $attribute)
70
	{
71
		$xslAttribute = $this->createElement('xsl:attribute');
72
73
		// Build the content of the xsl:attribute element
74
		foreach (AVTHelper::parse($attribute->value) as list($type, $content))
75
		{
76
			if ($type === 'expression')
77
			{
78
				$childNode = $this->createElement('xsl:value-of');
79
				$childNode->setAttribute('select', $content);
80
			}
81
			else
82
			{
83
				$childNode = $this->createElement('xsl:text');
84
				$childNode->appendChild($this->createTextNode($content));
85
			}
86
87
			$xslAttribute->appendChild($childNode);
88
		}
89
90
		return $xslAttribute;
91
	}
92
93
	/**
94
	* Uninline an attribute with a static value
95
	*
96
	* @param  DOMAttr    $attribute Attribute node
97
	* @return DOMElement            xsl:attribute element
98
	*/
99
	protected function uninlineStaticAttribute(DOMAttr $attribute)
100
	{
101
		return $this->createElement('xsl:attribute', str_replace('}}', '}', $attribute->value));
102
	}
103
}