Check if an action was called from within a Controller
Posted on 6/7/06 by Felix Geisendörfer
Gopher just asked me weather it was possible in CakePHP to see if an action was invoked by the dispatcher or called by $this->action();. So since I think this is one of these things that could be useful for others as well, here is my solution:
All you need to do is to check whether $this->action and the name of the function that is currently beeing executed match. This can be done like this:
So for example you could use it like this:
{
function index()
{
$post3 = $this->view(3);
}
function view($id)
{
$post = $this->Post->find(array('id' => $id));
if ($this->action != __FUNCTION__)
return $post;
else
$this->render();
}
}
Ok, this is a pretty useless example I have to admit, but I'm sure there are more interesting ways to utilize this ; ).
--Felix Geisendörfer aka the_undefined
You can skip to the end and add a comment.
whoops, should be :
function beforeFilter(){
/**
* array holding the names of functions that can be access by non-authenticated users
*/
$authByPass = array('view');
/* function is not in authByPass array and isnt being called by another function */
if(array_search($this->action,$authByPass) === FALSE AND $this->action != __FUNCTION__){
$this->checkSession();
}
}
Hi Drayen,
thanks for this example, I'm glad this is useful to somebody ; ). Anyway, why do you use array_search instead of in_array in your beforeFilter? I think in_array() is very intuitive and easy to understand when reading foreign code ; ).
No good reason really.
I am now trying to find a way to get this to work with requestAction() or something similar, so i can make calls from other classes. Any ideas?
Worked something out, but not sure how secure it would be - very interested to hear what you think :
/**
* Run before any of the functions to insure data is clean and users are valid
*/
function beforeFilter(){
/**
* array holding the names of functions that can be accessed by non-authenticated users
*/
$authBypass = array('');
$possibleUrls = array($this->here,$this->here.'/'.implode('/',array_slice($this->params['url'],1)));
/**
* UGLY, but should work, it checks :
* that it's not in authorise to bypass the check
* that it's not a local function
* that it's not being called by another controller** It does this by creating an array of possible URLs for direct access (one with params the Cake way /'ed, and one querystring style, as in ?param=1) and checks that against the calling URL
*/
if(in_array($this->action,$authBypass) === FALSE
AND ($this->action != __FUNCTION__)
AND in_array("/".implode('/',$this->params['url']), $possibleUrls) )
{
$this->checkSession();
}
}
This is great information, much better than what I've been doing - which is passing in an additional parameter to actions which told them to "return" or "render" or "redirect"...
thanks!
First of all i was inspire by what the young man is doing for the CakePHP
community and the beginners like us.
Great work my friend and keep it up. Your posts have been helping me all day
just want to get in touch. I will be glad if i can get your contact email so we talk.
Once again great work done
This post is too old. We do not allow comments here anymore in order to fight spam. If you have real feedback or questions for the post, please contact us.
Here is a non trival use :
class AppController extends Controller
{
/**
* Checks that the user is logged in.
*/
function checkSession()
{
// If the session info hasn't been set...
if (!$this->Session->check('User'))
{
// Force the user to login
$this->redirect('/users/login');
}
}
class MyController extends AppController
{
/**
* Run before any of the functions to insure data is clean and users are valid
*/
function beforeFilter(){
/**
* array holding the names of functions that can be access by non-authenticated users
*/
$authByPass = array('view');
if(array_search($this->action,$authByPass) === FALSE OR $this->action == __FUNCTION__){
$this->checkSession();
}
}
}
This means you can bypass auth and still call funcitons from other controlers which would otherwise require auth - bloody handy!