Completed
Push — master ( e6458b...c9bd8d )
by Tom
03:29
created

Repeat   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 53
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 14
Bugs 1 Features 0
Metric Value
wmc 13
c 14
b 1
f 0
lcom 1
cbo 3
dl 0
loc 53
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B run() 0 18 5
A cloneElement() 0 9 1
A tagElement() 0 4 2
A getMax() 0 3 2
A createHook() 0 5 2
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 Repeat implements \Transphporm\Property {
9
	private $functionSet;
10
	private $elementData;
11
12
	public function __construct(\Transphporm\FunctionSet $functionSet, \Transphporm\Hook\ElementData $elementData) {
13
		$this->functionSet = $functionSet;
14
		$this->elementData = $elementData;
15
	}
16
17
	public function run(array $values, \DomElement $element, array $rules, \Transphporm\Hook\PseudoMatcher $pseudoMatcher, array $properties = []) {
18
		if ($element->getAttribute('transphporm') === 'added') return $element->parentNode->removeChild($element);
19
		$max = $this->getMax($values);
20
		$count = 0;
21
22
		if (empty($values[0])) $values[0] = [];
23
		foreach ($values[0] as $key => $iteration) {
24
			if ($count+1 > $max) break;
25
			$clone = $this->cloneElement($element, $iteration, $key, $count++);
26
			//Re-run the hook on the new element, but use the iterated data
27
			//Don't run repeat on the clones element or it will loop forever
28
			unset($rules['repeat']);
29
			$this->createHook($rules, $pseudoMatcher, $properties)->run($clone);
30
		}
31
		//Remove the original element
32
		$element->parentNode->removeChild($element);
33
		return false;
34
	}
35
36
	private function cloneElement($element, $iteration, $key, $count) {
37
		$clone = $element->cloneNode(true);
38
		$this->tagElement($clone, $count);
39
40
		$this->elementData->bind($clone, $iteration, 'iteration');
41
		$this->elementData->bind($clone, $key, 'key');
42
		$element->parentNode->insertBefore($clone, $element);
43
		return $clone;
44
	}
45
46
	private function tagElement($element, $count) {
47
		//Mark all but one of the nodes as having been added by transphporm, when the hook is run again, these are removed
48
		if ($count > 0) $element->setAttribute('transphporm', 'added');
49
	}
50
51
	private function getMax($values) {
52
		return isset($values[1]) ? $values[1] : PHP_INT_MAX;
53
	}
54
55
	private function createHook($newRules, $pseudoMatcher, $properties) {
56
		$hook = new \Transphporm\Hook\PropertyHook($newRules, $pseudoMatcher, new \Transphporm\Parser\Value($this->functionSet));
57
		foreach ($properties as $name => $property) $hook->registerProperty($name, $property);
58
		return $hook;
59
	}
60
}
61