Multiple flashes with different classes

By Danny Ferguson (personman)
There were a couple of things I didn't like about using $this->Session->setFlash(), so I wrote my own method for saving flashes and helper for displaying them.
While it's a step up from the old flash method, using $this->Session->setFlash() has two problems:

  1. You can only do one flash message.
  2. It's always the same color. I want to use red for problems, green for success and grey for neutral status messages.

I added this to my AppController:

Controller Class:

Download code <?php 
class AppController extends Controller
{
  
  var 
$helpers = array('Flash');
  
/*
   * Add a message to the messages array in the session like this:
   * $this->flash( 'You are logged in.', 'success' );
   */ 
  
function flash$message$class 'status' )
  {
    
$old $this->Session->read('messages');
    
$old[$class][] = $message;
    
$this->Session->write'messages'$old );
  }

}
?>

Then I added this to app/views/helpers/flash.php:

Helper Class:

Download code <?php 
class FlashHelper extends Helper
{
  var 
$helpers = array( 'Session' );
  function 
show()
  {
    
// Get the messages from the session
    
$messages $this->Session->read'messages' );
    
$html '';
    
    
// Add a div for each message using the type as the class
    
foreach ($messages as $type => $msgs)
    {
      foreach (
$msgs as $msg)
      {
        if (!empty(
$msg)) {
          
$html .= "<div class='$type'><p>$msg</p></div>";
        }        
      }
    }
    
$html .= "</div>";
    
    
// Clear the messages array from the session
    
$this->Session->del'messages' );
    
    return 
$this->output$html );
  }
  
}
?>

Now in my controllers I do this:

Download code
$this->flash( 'Something normal happened.' );
$this->flash( 'Something good happened.', 'success' );
$this->flash( 'Danger!', 'error' );

And in my layout I added this:

Download code
<?php echo $flash->show(); ?>

Now you can us css to style your messages. The classes are 'status', 'success' and 'error'.

This is inspired by the set_message() function in Drupal.

 

Comments 533

CakePHP Team Comments Author Comments
 

Comment

1 Cake already does this for you

Why not use the $key-param in SessionComponent::setFlash() and SessionHelper::flash()???

Regards, Christoph
Posted Sep 26, 2007 by Christoph Schwaiger
 

Comment

2 cake already does that for you x2

You can specify a layout for the flash message (second param of Session::setFlash) :)
Posted Sep 26, 2007 by Marcin Domanski
 

Comment

3 Sorry

Sorry for posting code that isn't needed. I would prefer to use the built-in way of doing this. Can someone show me how to use it? I tried using setFlash() multiple times in one controller, but the second time always overwrote the first message. What was I doing wrong?
Posted Oct 1, 2007 by Danny Ferguson
 

Comment

4 User of setFlash

In your controller:

$this->Session->setFlash('my error message', 'default', array(), 'errorKey');
$this->Session->setFlash('my success message', 'default', array(), 'successKey');

In your view:

$session->flash('errorKey');
$session->flash('successKey');

API is your friend:
http://api.cakephp.org/1.2
Search for SessionComponent and SessionHelper.

Regards, Christoph :-)
Posted Oct 1, 2007 by Christoph Schwaiger
 

Comment

5 Thank you

Thanks for explaining. But what if I do

$this->Session->setFlash('Your user profile is incomplete.', 'default', array(), 'errorKey');

$this->Session->setFlash('Your hair is on fire.', 'default', array(), 'errorKey');

Will both messages show? Or will the second overwrite the first? I generally won't show more than one message at a time, but I'd like to be able to set messages without worrying about whether I've already done it.
Posted Oct 1, 2007 by Danny Ferguson
 

Comment

6 Messages with the same key ...

... will be overwritten.

Why not simply try it? ;-)

Also: $session->flash('someKey'); returns false, if no message was set, so you could do "conditional messages" with different keys.

Regards, Christoph
Posted Oct 1, 2007 by Christoph Schwaiger
 

Comment

7 I did

I did try the default way and it works fine. For the 99% of the time when I only set one message, it wouldn't be a problem. If I did try to set two, then it would fail silently and the first message would never get to the user. My method requires a bit less code and I think it's more flexible, or at least it works the way I want it to.
Posted Oct 1, 2007 by Danny Ferguson
 

Comment

8 To Nate

Nate said (in PM):I don't know who approved this article, but if you had read the API for either setFlash() or flash(), you'd see that what you're doing here is completely redundant, since all this and much more is already supported in the core framework.
Nate, are you sure that the core provides this functionality? Please see my discussion with Christoph. I'll concede that it's generally better to use the default way of doing things and that the default way would work for me most of the time. But will anyone admit that I've added a bit of functionality, not to mention made the code required to set the message in the controller a bit shorter? You can say that the functionality is not an improvement, but it certainly makes it possible to do something that can't be done with the core method (set two messages without having different keys).

And yes, I looked at the API. It wasn't very clear what the key does without looking at the source code. But I could tell from testing that the second message overwrites the first.
Posted Oct 1, 2007 by Danny Ferguson
 

Comment

9 problem still exists

i thought, this little "bug" already found its way into the core.. (almost 1 year later)
but it doesnt seem like that..

i tried to solve this using the functions already present. but i would have to change core files. thats no good.

does your helper work on reload as well as without reloading?

mark
Posted Jul 12, 2008 by Mark
 

Bug

10 header() nicht vergessen

es müssen übrigens alle header(), die caching unterbinden, in die bootstrap.php (oder dergleichen),
weil sonst machner browser die meldungen noch wo anzeigt, wo sie gar nich mehr sein sollten...
hatte ne weile gebraucht diesen fehler zu finden...

sonst wundert sich echt noch jemand über meldungen an der falschen stellen
also einfach einbauen, dann passts
Posted Jul 13, 2008 by Mark
 

Comment

11 Multiple Messages with setFlash()

I know this code is a few years old, but I still don't see a way to set multiple flash messages with core components without having to specify a unique key for each message.

I'd like to submit an update for this though. I've tweaked it a little to be a little more robust.
Posted May 19, 2009 by Seth Cardoza