Ejemplo n.º 1
0
 /**
  * This method calls the next Callable in the list.  All of the method arguments
  * coming into this method are substituted into the original method argument of
  * call in the chain.
  *
  * If the original method call has these parameters
  * <code>
  * $originalobject->dyExampleMethod('param1', 'param2', 'param3')
  * </code>
  * <code>
  * $callchain->dyExampleMethod('alt1', 'alt2')
  * </code>
  * then the next call in the call chain will recieve the parameters as if this were called
  * <code>
  * $behavior->dyExampleMethod('alt1', 'alt2', 'param3', $callchainobject)
  * </code>
  *
  * When dealing with {@link IClassBehaviors}, the first parameter of the stored argument
  * list in 'dy' event calls is always the object containing the behavior.  This modifies
  * the parameter replacement mechanism slightly to leave the object containing the behavior
  * alone and only replacing the other parameters in the argument list.  As per {@link __call},
  * any calls to a 'dy' event do not need the object containing the behavior as the addition of
  * the object to the argument list as the first element is automatic for IClassBehaviors.
  *
  * The last parameter of the method parameter list for any callable in the call chain
  * will be the TCallChain object itself.  This is so that any behavior implementing
  * these calls will have access to the call chain.  Each callable should either call
  * the TCallChain call method internally for direct chaining or call the method being
  * chained (in which case the dynamic handler will pass through to this call method).
  *
  * If the dynamic intra object/behavior event is not called in the behavior implemented
  * dynamic method, it will return to this method and call the following behavior
  * implementation so as no behavior with an implementation of the dynamic event is left
  * uncalled.  This does break the call chain though and will not act as a "parameter filter".
  *
  * When there are no handlers or no handlers left, it returns the first parameter of the
  * argument list.
  *
  */
 public function call()
 {
     $args = func_get_args();
     if ($this->getCount() === 0) {
         return isset($args[0]) ? $args[0] : null;
     }
     if (!$this->_iterator) {
         $chain_array = array_reverse($this->toArray());
         $this->_iterator = new TListIterator($chain_array);
     }
     if ($this->_iterator->valid()) {
         do {
             $handler = $this->_iterator->current();
             $this->_iterator->next();
             if (is_array($handler[0]) && $handler[0][0] instanceof IClassBehavior) {
                 array_splice($handler[1], 1, count($args), $args);
             } else {
                 array_splice($handler[1], 0, count($args), $args);
             }
             $handler[1][] = $this;
             $result = call_user_func_array($handler[0], $handler[1]);
         } while ($this->_iterator->valid());
     } else {
         $result = $args[0];
     }
     return $result;
 }