| 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 |  |  | 	/** Binds data to an element */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  | 	public function bind(\DomElement $element, $data, $type = 'data') { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  | 		//This is a bit of a hack to workaround #24, might need a better way of doing this if it causes a problem | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  | 		if (is_array($data) && $this->isObjectArray($data)) $data = $data[0]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  | 		$content = isset($this->dataStorage[$element]) ? $this->dataStorage[$element] : []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  | 		$content[$type] = $data; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  | 		$this->dataStorage[$element] = $content; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  | 	private function isObjectArray(array $data) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  | 		return count($data) === 1 && isset($data[0]) && is_object($data[0]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  | 	public function iteration($val, $element) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  | 		$data = $this->getData($element, 'iteration'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  | 		$value = $this->traverse($val, $data, $element); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  | 		return $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  | 	public function key($val, $element) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  | 		$data = $this->getData($element, 'key'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  | 		return $data; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  | 	/** 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*/ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  | 	private function getData(\DomElement $element = null, $type = 'data') { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  | 		while ($element) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  | 			if (isset($this->dataStorage[$element]) && isset($this->dataStorage[$element][$type])) return $this->dataStorage[$element][$type]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  | 			$element = $element->parentNode; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  | 		return $this->data; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  | 	public function data($val, \DomElement $element = null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  | 		$data = $this->getData($element); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  | 		$value = $this->traverse($val, $data, $element); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  | 		return $value;			 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  | 	private function traverse($name, $data, $element) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  | 		$name[0] = str_replace(['[', ']'], ['.', ''], $name[0]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  | 		$parts = explode('.', $name[0]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  | 		$obj = $data; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  | 		$valueParser = new \Transphporm\Parser\Value($this); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  | 		foreach ($parts as $part) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  | 			if ($part === '') continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  | 			$part = $valueParser->parse($part, $element)[0]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  | 			$funcResult = $this->processNestedFunc($part, $obj, $valueParser, $element); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  | 			 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  | 			if ($funcResult !== false) $obj = $funcResult; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  | 			else if (method_exists($obj, $part)) $obj = call_user_func([$obj, $part]);  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  | 			else $obj = $this->ifNull($obj, $part); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  | 		return $obj; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  | 	private function processNestedFunc($part, $obj, $valueParser, $element) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  | 		if (strpos($part, '(') !== false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  | 			$subObjParser = new \Transphporm\Parser\Value($obj, $valueParser, false); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  | 			return $subObjParser->parse($part, $element); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  | 		else return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  | 	private function ifNull($obj, $key) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  | 		if (is_array($obj)) return isset($obj[$key]) ? $obj[$key] : null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  | 		else return isset($obj->$key) ? $obj->$key : null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  | 	public function attr($val, $element) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  | 		return $element->getAttribute(trim($val[0])); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  | 	private function templateSubsection($css, $doc, $element) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  | 		$xpathStr = (new \Transphporm\Parser\CssToXpath($css, new \Transphporm\Parser\Value($this)))->getXpath(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  | 		$xpath = new \DomXpath($doc); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  | 		$nodes = $xpath->query($xpathStr); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  | 		$result = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  | 		foreach ($nodes as $node) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  | 			$result[] = $element->ownerDocument->importNode($node, true); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  | 		return $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  | 	} | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 106 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 107 |  |  | 	public function template($val, $element) { | 
            
                                                        
            
                                    
            
            
                | 108 |  |  | 		$newTemplate = new \Transphporm\Builder($this->baseDir . $val[0]); | 
            
                                                        
            
                                    
            
            
                | 109 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 110 |  |  | 		$doc = $newTemplate->output([], true)->body; | 
            
                                                        
            
                                    
            
            
                | 111 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 112 |  |  | 		if (isset($val[1])) return $this->templateSubsection($val[1], $doc, $element); | 
            
                                                        
            
                                    
            
            
                | 113 |  |  | 		 | 
            
                                                        
            
                                    
            
            
                | 114 |  |  | 		$newNode = $element->ownerDocument->importNode($doc->documentElement, true); | 
            
                                                        
            
                                    
            
            
                | 115 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 116 |  |  | 		$result = []; | 
            
                                                        
            
                                    
            
            
                | 117 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 118 |  |  | 		if ($newNode->tagName === 'template') { | 
            
                                                        
            
                                    
            
            
                | 119 |  |  | 			foreach ($newNode->childNodes as $node) $result[] = $node->cloneNode(true); | 
            
                                                        
            
                                    
            
            
                | 120 |  |  | 		}		 | 
            
                                                        
            
                                    
            
            
                | 121 |  |  | 		//else $result[] = $newNode; | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                        
            
                                    
            
            
                | 122 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 123 |  |  | 		return $result; | 
            
                                                        
            
                                    
            
            
                | 124 |  |  | 	} | 
            
                                                        
            
                                    
            
            
                | 125 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 126 |  |  |  | 
            
                        
This check looks from parameters that have been defined for a function or method, but which are not used in the method body.