_chain = $chain; } public function __call($name, $args) { $this->_isMethod = true; $this->_name = $name; $this->_arguments = $args; $this->_chain[] = $this; return new ChainCollectorNode($this->_chain); } public function __get($name) { $this->_isMethod = false; $this->_name = $name; $this->_chain[] = $this; return new ChainCollectorNode($this->_chain); } public function finish() { return ChainRunner::getInstance()->runChain($this->_chain); } /** * Returns the chain as an array of ChainCollectorNodes * * @return Array */ public function getChain() { return $this->_chain; } public function getName() { return $this->_name; } public function getArguments() { return $this->_arguments; } public function isMethodCall() { return $this->_isMethod; } public function isPropertyGet() { return !$this->_isMethod; } } class ChainCollectorStartNode extends ChainCollectorNode { private $_className; public function __construct($className) { parent::__construct(); $this->_className = $className; } public function getClassName() { return $this->_className; } } class ChainRunner { private $_specialCalls = array(); private static $_instance; private function __construct() { // $this->_specialCalls['if'] = new IfChainParser(); } /** * Return a ChainRunner instance * * @return ChainRunner */ public static function getInstance() { if(!self::$_instance) self::$_instance = new ChainRunner(); return self::$_instance; } /** * Runs a chain * @param Array $chain Array of chaincollectornodes * @return Mixed result */ public function runChain($chain) { $firstClass = $chain[0]->getClassName(); $node = array_shift($chain); $obj = new $firstClass(); $index = 0; while($node != null) { if($node->isMethodCall()) { $methodName = $node->getName(); $arguments = $node->getArguments(); if($this->_isSpecial($methodName)) { $this->_specialCalls[$methodName]->setChain($chain) ->parseIndex($index, $arguments); } else { //echo "Mtd ".get_class($obj)." $methodName
"; $obj = call_user_func_array(array($obj,$methodName),$arguments); } } else { $propertyName = $node->getName(); //echo "Prop ".get_class($obj)." $propertyName
"; $obj = $obj->$propertyName; } $node = array_shift($chain); $index++; } //echo "Returning ".get_class($obj)."
"; return $obj; } private function _isSpecial($name) { return array_key_exists($name, $this->_specialCalls); } }