1

Using CakePHP 3.9: I'm trying to redirect a user to a page where they can choose which organisation to log in with, if they haven't chosen any. To make sure this happens on every page, I added the code in the AppController::initialize() method. The redirect statement doesn't (directly) execute though. It still runs the code in the child controller (OrganisationsController extends AppController), where it bumps into the problem that no organisation was selected (duh).

I have tried the solutions in this post, but it seems to be a little outdated and/or not working.

Here is my original AppController code:

public function initialize() {
    parent::initialize();

    if( $this->getRequest()->getSession()->check('organisation.selected') ) {
        $organisation_id = $this->getRequest()->getSession()->read('organisation.selected');
        $this->loadModel('Organisations');
        $organisation = $this->Organisations->get($organisation_id);
        $this->organisation = [
            'id' => $organisation['id'],
            'name' => $organisation['name'],
        ];
    }
    else {
        if( !$this->isSuperuser && !empty($this->Auth->user('id')) && !($this->request->getParam('controller') == "Organisations" && $this->request->getParam('action') == 'switch') ) {
            // THIS DOESN'T REDIRECT:
            return $this->redirect(['controller' => 'Organisations', 'action' => 'switch', '?' => ['redirect' => $path]]);
        }
    }
}

I'd like to only change the AppController code, since there are too many other controllers/actions that depend on the $this->organisation to be set. Writing code in all these places would not be clean.

1. Override startupProcess in your controller(s)

I guess this should be 'Override initialize' in my case, but the following has no effect:

else {
    if( !$this->isSuperuser && !empty($this->Auth->user('id')) && !($this->request->getParam('controller') == "Organisations" && $this->request->getParam('action') == 'switch') ) {
        return $this->redirect(['controller' => 'Organisations', 'action' => 'switch', '?' => ['redirect' => $path]]);
    }
}
return parent::initialize(); // NO EFFECT :(

2. Send the response from AppController

I didn't try this, because it is not a clean solution as the author of the answer already states himself.

3. Use Dispatcher Filters

The CakePHP documentation says this is deprecated, and should be handled with middleware now. I couldn't find how though.

3
  • 1
    The initialize function is not meant to return anything, hence why your attempt to redirect from there is having no effect. When you say you couldn't find how to do this with middleware, is your problem with understanding how to use middleware in general, or how to implement this specific thing in middleware? Commented Dec 17, 2020 at 16:10
  • Ah, that would explain it, thanks. I haven't really used middleware yet, but since it exists of multiple levels, I also wouldn't know in what place to put this redirect. Could you show me a little more into the right direction? Commented Dec 18, 2020 at 12:34
  • 1
    There's no way to give a definitive list of what order things need to be done in. If a middleware A relies on something that B does, or might not happen depending on results from B, then A has to be loaded after B. So, for example, middleware for parsing form contents has to happen before authentication, because authentication might need that form data to be parsed already. Your example code is looking at the logged in user, so it would need to come after authentication. Where it might fit other than that very much depends on what other middleware you might use. Commented Dec 18, 2020 at 14:28

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.