Custom CakePHP Flash Messages

custom flash messages in CakePHP

UPDATE: I've written an updated version of the article making this one obsolete. Please click here to view the article.

For a new project I'm working on I want to display custom error messages that are enclosed in a coloured box depending on the action, for example if a post was successfully saved i want to display a message inside a green box and if it failed i want to display the message in a red box.

Usually i just use the flash messages that are built into the Session helper, these messages are displayed on the next page after the controller has redirected the user. The major limitation of using setFlash() is that only a single message can be displayed, so when this message is displayed in the view there is no way of knowing whether it is a success or failure message. In this post i'm going to go through the process of creating your own helper which will display a custom flash message.

Mysession Helper

Although this might seem a bit overkill for displaying a simple message to the screen i wanted to keep the functionality of the flash messages so that they are only displayed once and then destroyed. For this to happen my new helper will extend the SessionHelper, in object orientated programming when a class extends another class it will inherit all the methods ( another name for a function in a class file) so my new session helper will automatically be able to read, write and delete to the session.

To create my new flash message i will save an array to the session called "flash" this array will contain 2 things. The message to display and whether the message is a "success" or a "failure". When viewing the message it will either be wrapped in a green or red box depending on the message. This will make it incredibly easy for a user to determine if their action on the site was successful or not.

// this code goes in the controller
// using this
$this->Session->write('flash', array('Success: You have successfully logged in.','success'));
// instead of this
//$this->Session->setFlash('You have successfully logged in.');

Now that we have a custom flash message in the session my new helper will read the array and display the message and finally remove it from the session so that it does not display more than once. My new helper looks like this:

// file: /app/views/helpers/mysession.php
/*
 * Mysession Helper
 * extends the CakePHP session helper
 *
 */
class MysessionHelper extends SessionHelper {
    // init
    var $__active = true;
   
    // constructor
    function __construct($base = null) {
        // copied from the parent SessionHelper
        if (!defined('AUTO_SESSION') || AUTO_SESSION === true) {
            parent::__construct($base, false);
        } else {
            $this->__active = false;
        }
    }
   
    /*
     * flash()
     * flashes a message on the screen with a coloured box indicating success, failure or normal
     */
    function flash() {
        // init
        $output = '';
       
        // get the flash msg array from the session
        $data = parent::read('flash');
       
        // data looks like this
        // $data = array('flash message', 'success');
       
        // delete the session variable
        parent::del('flash');
       
        // if the flash message is not empty
        if(!empty($data[0])) {
        // switch depending on flash type
        switch($data[1]) {
            case 'success':
                // print out a div with a success class
                $output .= '<div class="flash_success">';
                break;
            case 'failure':
                // print out a div with a failure class
                $output .= '<div class="flash_failure">';
                break;
            default:
                // print out a default flash class
                $output .= '<div class="flash">';
                break;
        }
// save the flash message with the closing div
        $output .= $data[0].'</div>';
        }
    return $output;
    }
}

Before we can use our new helper in the view it must be loaded at the top of the controller using:

// load helpers
var $helpers = array('Html', 'Form', 'Mysession');

Finally to print the flash message to the screen we use this piece of code in our view:

// flash customer error msg on screen
echo $mysession->flash();

// cleaner than this
if ($session->check('Message.flash')) {
    $session->flash();
}

And for reference here are my styles for the flash boxes:

.flash { border:3px solid #ff9b00; background:#ffcc80; padding:10px; font-weight:bold; margin:15px 0;}
.flash_success { border:3px solid #bedf5d; background:#e2f1a8; padding:10px; font-weight:bold; margin:15px 0;}
.flash_failure { border:3px solid #990000; background:#f97d88; padding:10px; font-weight:bold; margin:15px 0;}

Wrapping Up

With a little bit of extra effort and code our custom flash messages are complete and have some added benefits:

  • Views are cleaner with no checking involved.
  • Message logic all in one place.
  • Can easily change the functionality of the flash message.

Posted on 21st March 2008
on 21/3/08

comments powered by Disqus