/** * Uses service location (i.e. `Libraries::locate()`) to look up a named class of a particular * type, and creates an instance of it, and passes an array of parameters to the constructor. * * If the given class can't be found, an exception is thrown. * * @param string $type The type of class as defined by `Libraries::$_paths`. * @param string $name The un-namespaced name of the class to instantiate. * @param array $options An array of constructor parameters to pass to the class. * @return object If the class is found, returns an instance of it, otherwise throws an * exception. * @throws lithium\core\ClassNotFoundException Throws an exception if the class can't be found. * @filter */ public static function instance($type, $name, array $options = array()) { $params = compact('type', 'name', 'options'); $_paths =& static::$_paths; $implementation = function ($self, $params) use(&$_paths) { $name = $params['name']; $type = $params['type']; if (!$name && !$type) { $message = "Invalid class lookup: `\$name` and `\$type` are empty."; throw new ClassNotFoundException($message); } if (!is_string($type) && $type !== null && !isset($_paths[$type])) { throw new ClassNotFoundException("Invalid class type `{$type}`."); } if (!($class = $self::locate($type, $name))) { throw new ClassNotFoundException("Class `{$name}` of type `{$type}` not found."); } if (is_object($class)) { return $class; } if (!(is_string($class) && class_exists($class))) { throw new ClassNotFoundException("Class `{$name}` of type `{$type}` not defined."); } return new $class($params['options']); }; if (!isset(static::$_methodFilters[__FUNCTION__])) { return $implementation(get_called_class(), $params); } $class = get_called_class(); $method = __FUNCTION__; $data = array_merge(static::$_methodFilters[__FUNCTION__], array($implementation)); return Filters::run($class, $params, compact('data', 'class', 'method')); }
/** * Executes a set of filters against a method by taking a method's main implementation as a * callback, and iteratively wrapping the filters around it. This, along with the `Filters` * class, is the core of Lithium's filters system. This system allows you to "reach into" an * object's methods which are marked as _filterable_, and intercept calls to those methods, * optionally modifying parameters or return values. * * @see lithium\core\Object::applyFilter() * @see lithium\util\collection\Filters * * @param string $method The name of the method being executed, usually the value of * `__METHOD__`. * @param array $params An associative array containing all the parameters passed into * the method. * @param Closure $callback The method's implementation, wrapped in a closure. * @param array $filters Additional filters to apply to the method for this call only. * * @return mixed Returns the return value of `$callback`, modified by any filters passed in * `$filters` or applied with `applyFilter()`. */ protected function _filter($method, $params, $callback, $filters = array()) { list($class, $method) = explode('::', $method); if (empty($this->_methodFilters[$method]) && empty($filters)) { return $callback($this, $params, null); } $f = isset($this->_methodFilters[$method]) ? $this->_methodFilters[$method] : array(); $data = array_merge($f, $filters, array($callback)); return Filters::run($this, $params, compact('data', 'class', 'method')); }