This method is useful if you want to apply a filter inside a global bootstrap file to a
static class which may or may not be loaded during every request, or which may be loaded
lazily elsewhere in your application. If the class is already loaded, the filter will be
applied immediately.
However, if the class has not been loaded, the filter will be stored and applied to the class
the first time the method specified in $method is called. This works for any class which
extends StaticObject.
public static apply ( string $class, string $method, Closure $filter ) : void | ||
$class | string | The fully namespaced name of a **static** class to which the filter will be applied. The class name specified in `$class` **must** extend `StaticObject`, or else statically implement the `applyFilter()` method. |
$method | string | The method to which the filter will be applied. |
$filter | Closure | The filter to apply to the class method. |
Résultat | void |
public function testLazyApply() { $class = 'lithium\\tests\\mocks\\util\\MockFilters'; Filters::apply($class, 'filteredMethod', function ($self, $params, $chain) { return md5($chain->next($self, $params, $chain)); }); $expected = md5('Working?'); $result = $class::filteredMethod(); $this->assertEqual($expected, $result); Filters::apply($class, 'filteredMethod', function ($self, $params, $chain) { return sha1($chain->next($self, $params, $chain)); }); $expected = md5(sha1('Working?')); $result = $class::filteredMethod(); $this->assertEqual($expected, $result); }
public function testWriteFilter() { $base = Libraries::get(true, 'resources') . '/tmp/logs'; $this->skipIf(!is_writable($base), "Path `{$base}` is not writable."); Filters::apply('lithium\\analysis\\Logger', 'write', function ($self, $params, $chain) { $params['message'] = 'Filtered Message'; return $chain->next($self, $params, $chain); }); $config = array('default' => array('adapter' => 'File', 'timestamp' => false, 'format' => "{:message}\n")); Logger::config($config); $result = Logger::write('info', 'Original Message'); $this->assertTrue(file_exists($base . '/info.log')); $expected = "Filtered Message\n"; $result = file_get_contents($base . '/info.log'); $this->assertEqual($expected, $result); unlink($base . '/info.log'); }
<?php // Define used classes. use lithium\util\collection\Filters; use lithium\security\Auth; // Get to the `Auth` instance by filtering the `Dispatcher` Filters::apply('\\lithium\\action\\Dispatcher', '_callable', function ($self, $params, $chain) { $controller = $chain->next($self, $params, $chain); Auth::applyFilter('check', function ($self, $params, $chain) { $profiler = \Profiler::start('security\\Auth::check'); $result = $chain->next($self, $params, $chain); $profiler->end(); return $result; }); Auth::applyFilter('set', function ($self, $params, $chain) { $profiler = \Profiler::start('security\\Auth::set'); $result = $chain->next($self, $params, $chain); $profiler->end(); return $result; }); Auth::applyFilter('clear', function ($self, $params, $chain) { $profiler = \Profiler::start('security\\Auth::clear'); $result = $chain->next($self, $params, $chain); $profiler->end(); return $result; }); // Return the controller object. return $controller; });
<?php use lithium\util\collection\Filters; use li3_memoize\extensions\Memoize; /** * Filters the creation of helpers/models */ Filters::apply('lithium\\core\\Libraries', 'instance', function ($self, $params, $chain) { // Prescan Model if (isset($params['options']['model'])) { Memoize::catchModel($self, $params, $chain); } $object = $chain->next($self, $params, $chain); // Postscan Helper if ($params['type'] == 'helper') { Memoize::catchHelper($object); } return $object; });
public static function apply($object, array $conditions, $handler) { $conditions = $conditions ?: array('type' => 'Exception'); list($class, $method) = is_string($object) ? explode('::', $object) : $object; $wrap = static::$_exceptionHandler; $_self = get_called_class(); $filter = function ($self, $params, $chain) use($_self, $conditions, $handler, $wrap) { try { return $chain->next($self, $params, $chain); } catch (Exception $e) { if (!$_self::matches($e, $conditions)) { throw $e; } return $handler($wrap($e, true), $params); } }; if (is_string($class)) { Filters::apply($class, $method, $filter); } else { $class->applyFilter($method, $filter); } }
<?php // Define used classes. use lithium\util\collection\Filters; // Get to the `Controller` instance by filtering the `Dispatcher` Filters::apply('\\lithium\\action\\Dispatcher', '_callable', function ($self, $params, $chain) { $controller = $chain->next($self, $params, $chain); if (is_a($controller, '\\lithium\\action\\Controller')) { /** * Apply the filter to our `Controller` instance. We can't apply the * filter statically. */ $controller->applyFilter('__invoke', function ($self, $params, $chain) { $profiler = \Profiler::start('action\\Controller::__invoke'); $response = $chain->next($self, $params, $chain); $profiler->end(); // Return the response object. return $response; }); } // Return the controller object. return $controller; });
<?php // Define used classes. use lithium\util\collection\Filters; use lithium\storage\Session; // Get to the `Session` instance by filtering the `Dispatcher` Filters::apply('\\lithium\\action\\Dispatcher', '_callable', function ($self, $params, $chain) { $controller = $chain->next($self, $params, $chain); Session::applyFilter('read', function ($self, $params, $chain) { $profiler = \Profiler::start('storage\\Session::read'); $result = $chain->next($self, $params, $chain); $profiler->end(); return $result; }); Session::applyFilter('write', function ($self, $params, $chain) { $profiler = \Profiler::start('storage\\Session::write'); $result = $chain->next($self, $params, $chain); $profiler->end(); return $result; }); // Return the controller object. return $controller; });
// Define used classes. use lithium\util\collection\Filters; use lithium\data\Connections; // Attach to the `Connections` adapters after dispatch. Filters::apply('\\lithium\\action\\Dispatcher', '_callable', function ($self, $params, $chain) { /** * Loop over all defined `Connections` adapters and tack in our * filter on the `_execute` method. */ foreach (Connections::get() as $connection) { $connection = Connections::get($connection); $connection->applyFilter('_execute', function ($self, $params, $chain) { $profiler = \Profiler::sqlStart($params['sql']); $response = $chain->next($self, $params, $chain); $profiler->end(); return $response; }); $connection->applyFilter('read', function ($self, $params, $chain) { $response = $chain->next($self, $params, $chain); \Profiler::start($response->model()); $info = $response->result()->resource(); $profiler = \Profiler::sqlStart(json_encode($info->info())); $profiler->end(); \Profiler::end($response->model()); return $response; }); } // Return the controller. return $chain->next($self, $params, $chain); });
Filters::apply('lithium\\action\\Dispatcher', '_callable', function ($self, $params, $chain) { if (!Environment::is(Libraries::get('li3_profiler', 'environment'))) { // Enable the profiler. \Profiler::disable(); } else { $controller = $chain->next($self, $params, $chain); if (Libraries::get('li3_profiler', 'inject')) { /** * If we have a `Controller` object we will filter it so that we can * inject our rendering HTML. */ if (is_a($controller, '\\lithium\\action\\Controller')) { $controller->applyFilter('__invoke', function ($self, $params, $chain) { $response = $chain->next($self, $params, $chain); if ($response->type === 'text/html') { /** * Here we tack in our rendering if the `Response` object happens * to be "text/html" and we are enabled. */ ob_start(); \Profiler::render(); $response->body = str_replace('</body>', ob_get_clean() . '</body>', $response->body); } return $response; }); } } return $controller; } return $chain->next($self, $params, $chain); });
<?php // Define used classes. use lithium\util\collection\Filters; // Tack in our `Dispatcher` profiling. Filters::apply('\\lithium\\action\\Dispatcher', '_callable', function ($self, $params, $chain) { $profiler = \Profiler::start('action\\Dispatcher::_callable'); $controller = $chain->next($self, $params, $chain); $profiler->end(); return $controller; });
public static function initDispatcher() { // Request -> Response Filters::apply('lithium\\action\\Dispatcher', 'run', function ($self, $params, $chain) { $data = array(); $data['start'] = microtime(true); $data['memory'] = memory_get_usage(true); $data['name'] = 'Dispatcher::run'; $response = $chain->next($self, $params, $chain); $data['end'] = microtime(true); $data['memory'] = memory_get_usage(true) - $data['memory']; $data['time'] = $data['end'] - $data['start']; Debugger::push('events', $data); Debugger::inc('events.time', $data['time']); return $response; }); // Router -> Controller Filters::apply('lithium\\action\\Dispatcher', '_callable', function ($self, $params, $chain) { $data = array(); $data['start'] = microtime(true); $data['memory'] = memory_get_usage(true); $data['name'] = 'Dispatcher::_callable'; $controller = $chain->next($self, $params, $chain); $data['end'] = microtime(true); $data['memory'] = memory_get_usage(true) - $data['memory']; $data['time'] = $data['end'] - $data['start']; Debugger::push('events', $data); Debugger::inc('events.time', $data['time']); if ($controller instanceof \lithium\action\Controller) { Debugger::setRequest($params['request']); Debugger::bindTo($controller); } return $controller; }); }
<?php // Define used classes. use lithium\util\collection\Filters; // Tack in our `Dispatcher` profiling. Filters::apply('\\lithium\\net\\http\\Media', 'render', function ($self, $params, $chain) { $profiler = \Profiler::start('net\\http\\Media::render'); $result = $chain->next($self, $params, $chain); $profiler->end(); return $result; });