[eluser]Unknown[/eluser]
Sorry in advance for the tome of a post, but I am new to Codeigniter and am hoping you gurus out there can tell me a better way to do something.
I've been trying to find a logical and clean way to hook into the framework to allow something called a trust filter. A Filter is a common design pattern in the Java world (which is where I come from) that allows all inbound requests to be examined before the primary method processing occurs. Typically there is a chain of filters that each get called in turn to do some work, and optionally reject the request.
The concept of a filter (also known as a Valve) is the main pattern I am trying to implement; in particular a trust filter that will examine the inbound IP and vet it against valid ranges and IPs.
I've tried the following approaches that worked but were ugly because of the massively repeated code.
Use Hooks
So I created hook that uses post_controller_constructor to call my filter method. In order to ensure the result, a mere boolean called $trusted, is accessible from all downstream methods I had to make it global. The hook worked fine in terms of getting the answer before any methods were dispatched, but unfortunately there is no way to stop further processing without putting something like at the head of every method.:
Code:
if(!$_IS_TRUSTED)
{
reject_request();
}
Use Subclassing
I rejected the hook approach because I didn't want to pepper my code with the same call. So I decided to sublcass CI_Controller instead, putting the work in the base constructor and assigning the result as a class variable. Seemed clean but then I discovered there was no way to tell the framework to stop further processing. Not sure why I assumed the Controller would have this feature, but it did.
So I ended up getting what I wanted by hacking Codeigniter.php - something I really didn't want to do for obvious reasons. I levereged the Controller sublcass described above and for the pages I wanted seHere is my hack starting around line 355:
Code:
if($CI instanceof SST_Controller && ! $CI->trusted)
{
$CI->reject_request();
}
else
{
// Call the requested method.
// Any URI segments present (besides the class/function) will be passed to the method for convenience
call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2));
}
My question is, does anyone know of a better way to do this so I don't have to go into the core classes in the system folder and can modify just stuff in the application folder? This seems to me like a fundamental feature of any framework, and to be honest I was shocked CI didn't have it considering the obvious thought and years of experience that the team has put into it.