Completed
Push — master ( 1099f2...b313d2 )
by Tom
10:52 queued 20s
created

Content::shouldRun()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 10
rs 8.8571
cc 5
eloc 6
nc 4
nop 1
1
<?php
2
/* @description     Transformation Style Sheets - Revolutionising PHP templating    *
3
 * @author          Tom Butler [email protected]                                             *
4
 * @copyright       2015 Tom Butler <[email protected]> | https://r.je/                      *
5
 * @license         http://www.opensource.org/licenses/bsd-license.php  BSD License *
6
 * @version         1.0                                                             */
7
namespace Transphporm\Property;
8
class Content implements \Transphporm\Property {
9
	private $data;
10
	private $headers;
11
	private $formatter;
12
13
14
	public function __construct($data, &$headers, \Transphporm\Hook\Formatter $formatter) {
15
		$this->data = $data;
16
		$this->headers = &$headers;
17
		$this->formatter = $formatter;
18
	}
19
20
	public function run($value, \DomElement $element, array $rules, \Transphporm\Hook\PseudoMatcher $pseudoMatcher, array $properties = []) {
21
		if ($this->shouldRun($element) == false) return;
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
22
			
23
		$value = $this->formatter->format($value, $rules);
24
		if (!$this->processPseudo($value, $element, $pseudoMatcher)) {
25
			//Remove the current contents
26
			$this->removeAllChildren($element);
27
			//Now make a text node
28
			if ($this->getContentMode($rules) === 'replace') $this->replaceContent($element, $value);
29
			else $this->appendContent($element, $value);
30
		}
31
	}
32
33
	private function shouldRun($element) {
34
		if ($element->getAttribute('transphporm') === 'remove') return false;
35
36
		while (!($element instanceof \DomDocument) && $element->parentNode) {
37
			if ($element->getAttribute('transphporm') == 'includedtemplate') return false;
38
			$element = $element->parentNode;
39
		}
40
41
		return true;
42
	}
43
	private function getContentMode($rules) {
44
		return (isset($rules['content-mode'])) ? $rules['content-mode'] : 'append';
45
	}
46
47
	private function processPseudo($value, $element, $pseudoMatcher) {
48
		$pseudoContent = ['attr', 'header', 'before', 'after'];
49
		foreach ($pseudoContent as $pseudo) {
50
			if ($pseudoMatcher->hasFunction($pseudo)) {
51
				$this->$pseudo($value, $pseudoMatcher->getFuncArgs($pseudo), $element);
52
				return true;
53
			}
54
		}
55
		return false;
56
	}
57
	
58
	private function getNode($node, $document) {
59
		foreach ($node as $n) {
60
			if ($n instanceof \DomElement) {
61
				$new = $document->importNode($n, true);
62
				$new->setAttribute('transphporm', 'added');
63
			}
64
			else {
65
				if ($n instanceof \DomText) $n = $n->nodeValue;
66
				$new = $document->createElement('text');
67
				$new->appendChild($document->createTextNode($n));
68
				$new->setAttribute('transphporm', 'text');
69
			}
70
			yield $new;
71
		}
72
	}
73
74
	/** Functions for writing to pseudo elements, attr, before, after, header */
75
	private function attr($value, $pseudoArgs, $element) {
76
		$element->setAttribute($pseudoArgs, implode('', $value));
77
	}
78
79
	private function header($value, $pseudoArgs, $element) {
0 ignored issues
show
Unused Code introduced by
The parameter $element is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
80
		$this->headers[] = [$pseudoArgs, implode('', $value)];
81
	}
82
83
	private function before($value, $pseudoArgs, $element) {
0 ignored issues
show
Unused Code introduced by
The parameter $pseudoArgs is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
84
		foreach ($this->getNode($value, $element->ownerDocument) as $node) {
85
			$element->insertBefore($node, $element->firstChild);	
86
		}
87
		return true;
88
	}
89
90
	private function after($value, $pseudoArgs, $element) {
0 ignored issues
show
Unused Code introduced by
The parameter $pseudoArgs is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
91
		 foreach ($this->getNode($value, $element->ownerDocument) as $node) {
92
		 		$element->appendChild($node);
93
		}			 
94
	}
95
96
	private function removeAdded($e) {
97
		$remove = [];
98
		while ($e = $e->previousSibling && !in_array($e->getAttribute('transphporm'), [null, 'remove'])) {
0 ignored issues
show
Comprehensibility introduced by
Consider adding parentheses for clarity. Current Interpretation: $e = ($e->previousSiblin...array(null, 'remove'))), Probably Intended Meaning: ($e = $e->previousSiblin... array(null, 'remove'))
Loading history...
99
			$remove[] = $e;
100
		}
101
		foreach ($remove as $r) $r->parentNode->removeChild($r);
102
	}
103
104
	private function replaceContent($element, $content) {
105
		//If this rule was cached, the elements that were added last time need to be removed prior to running the rule again.
106
		$this->removeAdded($element);
107
		foreach ($this->getNode($content, $element->ownerDocument) as $node) {
108
			$element->parentNode->insertBefore($node, $element);
109
		}		
110
		$element->setAttribute('transphporm', 'remove');
111
	}
112
113
	private function appendContent($element, $content) {
114
		foreach ($this->getNode($content, $element->ownerDocument) as $node) {
115
			$element->appendChild($node);
116
		}
117
	}
118
	
119
	private function removeAllChildren($element) {
120
		while ($element->hasChildNodes()) $element->removeChild($element->firstChild);
121
	}
122
}