/** * Call to undefined method. * @param string method name * @param array arguments * @return mixed * @throws MemberAccessException */ public function __call($name, $args) { $class = new Nette\Reflection\ClassType($this); if ($name === '') { throw new Nette\MemberAccessException("Call to class '{$class->name}' method without name."); } // event functionality if ($class->hasProperty($name)) { if (!$this->_eventSetupCalled) { $this->_eventSetupCalled = true; $this->eventSetup(); $this->onEventSetup($this); } if (is_array($list = $this->{$name}) || $list instanceof \Traversable) { foreach ($list as $handler) { callback($handler)->invokeArgs($args); } } return NULL; } // extension methods if ($cb = Nette\ObjectMixin::getExtensionMethod(get_class($this), $name)) { array_unshift($args, $this); return $cb->invokeArgs($args); } throw new Nette\MemberAccessException("Call to undefined method {$class->name}::{$name}()."); }
/** * Adding method to class. * @param string method name * @param callable * @return mixed */ public static function extensionMethod($name, $callback = NULL) { if (strpos($name, '::') === FALSE) { $class = get_called_class(); } else { list($class, $name) = explode('::', $name); $rc = new \ReflectionClass($class); $class = $rc->getName(); } if ($callback === NULL) { return ObjectMixin::getExtensionMethod($class, $name); } else { ObjectMixin::setExtensionMethod($class, $name, $callback); } }