Search code examples
cakephpcakephp-2.6cakephp-2.7

How to define FlashHelper/Component element for general authError message


After updating CakePHP from 2.6.2 to 2.7.2 I get an missing key error when the auth flash message is created. How can I define the element template for the default authError?

Since SessionComponent::setFlash() has been deprecated I added the FlashComponent in app/Controller/AppController.php and modified all Flash messages from this:

// Controller
$this->Session->setFlash('Done', 'succeed');
$this->Session->setFlash('There is an error', 'failure');
$this->Session->setFlash('Please log in', 'auth');
// View (default Layout)
echo $this->Session->flash();
echo $this->Session->flash('auth');

to this:

// Controller
$this->Flash->succeed('Done');
$this->Flash->failure('There is an error');
$this->Flash->auth('Please log in');
// View (default Layout)
echo $this->Flash->render();
echo $this->Session->flash();       // keep temporarily?
echo $this->Session->flash('auth'); // keep temporarily?

I also copied the flash related templates from App/View/Elements/succeed.ctp to App/View/Elements/Flash/succeed.ctp

This is working – but if I am not logged in and try to access an admin page I get the default authError message defined in app/Controller/AppController.php shown without the according template. With debug mode 2 I get the following error:

// Undefined variable: key [CORE\Cake\View\Elements\Flash\default.ctp, line 1]
// include - CORE\Cake\View\Elements\Flash\default.ctp, line 1
// View::_evaluate() - CORE\Cake\View\View.php, line 971
// View::_render() - CORE\Cake\View\View.php, line 933
// View::_renderElement() - CORE\Cake\View\View.php, line 1227
// View::element() - CORE\Cake\View\View.php, line 418
// SessionHelper::flash() - CORE\Cake\View\Helper\SessionHelper.php, line 159
// include - APP\View\Layouts\default.ctp, line 142
// View::_evaluate() - CORE\Cake\View\View.php, line 971
// View::_render() - CORE\Cake\View\View.php, line 933
// View::renderLayout() - CORE\Cake\View\View.php, line 546
// View::render() - CORE\Cake\View\View.php, line 481
// Controller::render() - CORE\Cake\Controller\Controller.php, line 960
// Dispatcher::_invoke() - CORE\Cake\Routing\Dispatcher.php, line 200
// Dispatcher::dispatch() - CORE\Cake\Routing\Dispatcher.php, line 167
// [main] - APP\webroot\index.php, line 118
// Message" class="message">

What changes in AppController.php are necessary to get the default authError rendered with my own element template "auth"?

Here the part of the AppController.php:

public $components = array(
  'Flash',
  'Session',
  'Security',
  'Auth' => array(
    'authenticate' => array('Form' => array('passwordHasher' => 'Blowfish')),
    'authError' => 'My default auth error message.', // How do I have to modify this line?
    'loginAction' => array('controller' => 'users', 'action' => 'login'),
    'loginRedirect' => array('controller' => 'users', 'action' => 'welcome'),
    'logoutRedirect' => array('controller' => 'users', 'action' => 'goodbye'),
  )
);

And are these two lines still necessary when changing all flash messages in all Controllers to the Flash compoment and helper? Where else are they used by CakePHP?

echo $this->Session->flash();
echo $this->Session->flash('auth');

I also had a look at the Authentication tutorial. But it seems to be not up to date since $this->Session->setFlash() is still heavily in use...


Solution

  • in your Auth component setting array add something like

    'Auth' = [
        ...
        'flash' => ['element' => 'auth_error'],
        ...
    ]
    

    then create a template named auth_error.ctp in your Element/Flash directory. In this file the only variable you use should be $message, because when cake calls Flash from the Auth components does not pass any other variable (i.e. the $key variable)

    Maybe this answer is not 100% correct (so any suggestion is welcome) but it worked for me.