Completed
Push — master ( 09a120...247d83 )
by Tom
02:21
created

DataFunction::traverse()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 17
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 1 Features 0
Metric Value
c 6
b 1
f 0
dl 0
loc 17
rs 9.2
cc 4
eloc 12
nc 4
nop 3
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\Hook;
8
/* Handles data() and iteration() function calls from the stylesheet */
9
class DataFunction {
10
	private $dataStorage;
11
	private $data;
12
	private $baseDir;
13
14
	public function __construct(\SplObjectStorage $objectStorage, $data, $baseDir) {
15
		$this->dataStorage = $objectStorage;
16
		$this->data = $data;
17
		$this->baseDir = $baseDir;
18
	}
19
20
	public function setBaseDir($dir) {
21
		$this->baseDir = $dir;
22
	}
23
24
	/** Binds data to an element */
25
	public function bind(\DomNode $element, $data, $type = 'data') {
26
		//This is a bit of a hack to workaround #24, might need a better way of doing this if it causes a problem
27
		if (is_array($data) && $this->isObjectArray($data)) $data = $data[0];
28
		$content = isset($this->dataStorage[$element]) ? $this->dataStorage[$element] : [];
29
		$content[$type] = $data;
30
		$this->dataStorage[$element] = $content;
31
	}
32
33
	private function isObjectArray(array $data) {
34
		return count($data) === 1 && isset($data[0]) && is_object($data[0]);
35
	}
36
37
	public function iteration($val, $element) {
38
		$data = $this->getData($element, 'iteration');
39
		$value = $this->traverse($val, $data, $element);
40
		return $value;
41
	}
42
43
	public function key($val, $element) {
0 ignored issues
show
Unused Code introduced by
The parameter $val 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...
44
		$data = $this->getData($element, 'key');
45
		return $data;
46
	}
47
48
	/** Returns the data that has been bound to $element, or, if no data is bound to $element climb the DOM tree to find the data bound to a parent node*/
49
	public function getData(\DomElement $element = null, $type = 'data') {
50
		while ($element) {
51
			if (isset($this->dataStorage[$element]) && isset($this->dataStorage[$element][$type])) return $this->dataStorage[$element][$type];
52
			$element = $element->parentNode;
53
		}
54
		return $this->data;
55
	}
56
57
	public function data($val, \DomElement $element = null) {
58
		$data = $this->getData($element);
59
		$value = $this->traverse($val, $data, $element);
60
		return $value;
61
	}
62
63
	private function traverse($name, $data, $element) {
64
		$name[0] = str_replace(['[', ']'], ['.', ''], $name[0]);
65
		$parts = explode('.', $name[0]);
66
		$obj = $data;
67
		$valueParser = new \Transphporm\Parser\Value($this);
68
69
		foreach ($parts as $part) {
70
			if ($part === '') continue;
71
			$part = $valueParser->parse($part, $element)[0];
72
			$funcResult = $this->traverseObj($part, $obj, $valueParser, $element);
73
74
			if ($funcResult !== false) $obj = $funcResult;
75
			
76
			else $obj = $this->ifNull($obj, $part);
77
		}
78
		return $obj;
79
	}
80
81
	private function traverseObj($part, $obj, $valueParser, $element) {
82
		if (strpos($part, '(') !== false) {
83
			$subObjParser = new \Transphporm\Parser\Value($obj, $valueParser, false);
84
			return $subObjParser->parse($part, $element)[0];
85
		}
86
		else if (method_exists($obj, $part)) return call_user_func([$obj, $part]); 
87
		else return false;
88
	}
89
90
	private function ifNull($obj, $key) {
91
		if (is_array($obj)) return isset($obj[$key]) ? $obj[$key] : null;
92
		else return isset($obj->$key) ? $obj->$key : null;
93
	}
94
95
	public function attr($val, $element) {
96
		return $element->getAttribute(trim($val[0]));
97
	}
98
99
	public function template($val, $element) {
100
		$templateFunction = new TemplateFunction($this->baseDir . $val[0], isset($val[1]) ? $val[1] : null, isset($val[2]) ? $this->baseDir . $val[2] : null);		
101
		return $templateFunction->getTemplateNodes($this->getData($element));
102
	}
103
}
104