====== Intercepting Filters Chain ======
===== Description =====
Intercepting filters are used to pre-process requests and post-process responses. They wrap and modify or transform inputs and outputs to/from core application logic. Intercepting Filter pattern can be applied at any level of an application. Limb uses intercepting filters as a part of FrontController. You can read more about this pattern at
[[http://www.phpwact.org/pattern/intercepting_filter| WACT DocuWiki - lmbInterceptingFilter]]
===== UML charts =====
UML Static Structure:
{{{ limb:architecture:limb3.0_filters.png }}}
UML Sequence:
{{{ limb:architecture:limb3.0_filters_sequence.png }}}
===== Comments =====
It's easy to control core application logic with intercepting filters. Common Limb-based application is just a filter chain and all the application needs to do is to process this chain. Your index.php file can look like this:
require_once(dirname(__FILE__) . '/setup.php');
require_once(dirname(__FILE__) . '/src/MyApplication.class.php');
$application = new MyApplication();
$application->process();
And MyApplication class:
require_once(LPKG_CORE_DIR . '/src/filter/lmbFilterChain.class.php');
class MyApplication extends lmbFilterChain
{
function __construct()
{
$this->registerFilter(new lmbHandle(LPKG_CORE_DIR . '/src/filter/lmbTimingFilter'));
$this->registerFilter(new lmbHandle(LPKG_CORE_DIR . '/src/filter/ResponseProcessingFilter'));
$this->registerFilter(new lmbHandle(LPKG_CORE_DIR . '/src/filter/lmbUncaughtExceptionHandlingFilter'));
$this->registerFilter(new lmbHandle(LPKG_CORE_DIR . '/src/filter/lmbViewRenderingFilter'));
$this->registerFilter(new lmbHandle(LPKG_CORE_DIR . '/src/filter/lmbRequestDispatchingFilter'));
$this->registerFilter(new lmbHandle(LPKG_CORE_DIR . '/src/filter/lmbCommandProcessingFilter'));
}
}
You can think about Limb filter chain as of a set of nested filters, like this:
+-authentication filter
|
| +-full page cache filter
| |
| | +-other filter
| | |
| | |_
| |
| |_
|
|_
It's up to the filter to decide whether to pass control to the next filter or not, e.g:
class SimpleInterceptingFilter implements lmbInterceptingFilter
{
function run($filter_chain)
{
//pre-processing is done here
if ($this->someConditionPassed())
$filter_chain->next();
//post-processing is done here
}
}
===== Base Limb filters=====
^Name^Purpose^
|[[lmbCommandProcessingFilter]]|Executes a command that belongs to requested lmbService and Action|
|UOWFilter|Starts and finishes an ORM transaction|
|lmbSessionStartupFilter|Starts a session|
|[[lmbRequestDispatchingFilter]]|Determines requested lmbService and Action using [[lmbRequestDispatcher]]|
|[[lmbViewRenderingFilter]]|Renders View that could be set somethere in [[lmbCommand]]|
|lmbUncaughtExceptionHandlingFilter|Allows to process system errors in more "user-friendly" way|