debuggable

 
Contact Us
 

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:

if ($this->action == __FUNCTION__)

So for example you could use it like this:

class PostsController extends AppController
{
    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

 
&nsbp;

You can skip to the end and add a comment.

Drayen  said on Jul 18, 2006:

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!

Drayen  said on Jul 18, 2006:

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();

}

}

Felix Geisendörfer said on Jul 18, 2006:

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 ; ).

Drayen  said on Jul 18, 2006:

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?

Drayen  said on Jul 18, 2006:

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();

}

}

Alan Blount said on Aug 21, 2008:

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!

David Klogo  said on Oct 01, 2008:

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.