4 Dec
2010
In Zend framework flash messages feature is implemented as the controller action and I often used it like this:
Add message to flash messenger.
$flashMessenger = $this->_helper->getHelper('FlashMessenger');
$flashMessenger->addMessage('We did something in the last request');
… later on, in another page, retrieve it.
$flashMessenger = $this->_helper->getHelper('FlashMessenger');
$messages = $flashMessenger->getMessages();
If I need to specify the status of my message – success, error or something else the messenger namespaces can be used:
$flashMessenger->setNamespace('success');
$flashMessenger->addMessage('Success!');
$flashMessenger->setNamespace('notice');
$flashMessenger->addMessage('Some notice');
Namespace has to be set before adding or retreiving messages from helper. So, we have to manually retrieve messages from all namespaces, then we can pass them to view and style them according to their status.
To simplify my work with flash messenger I created the view helper that can set namespace and add message in one line. Also it can retrieve and display messages in a view automatically. You can use it as follows:
public function editAction(){
$form = new User_Form();
if ($this->_request->isPost()) {
if ($form->isValid($_POST)) {
$this->view->flashMessenger('success')->addMessage('Data successfully saved');
$this->view->flashMessenger('notice')->addMessage('Note! This is a test data.');
$this->_redirect('/user/list');
}
}
}
The example show the edit action whery the user data is validated, saved and then we use flash messenger helper to set success message. After that the redirect occurs to the ‘/user/list’ action. To show message in the list action we use the same flash messenger view helper:
// file views/scripts/user/list.phtml
<?= $this->flashMessenger() ?>
The flash messenger automatically scan through all defined namespaces and shows messages in the following form:
<ul class="flashSuccess">
<li>Data successfully saved</li>
</ul>
<ul class="flashNotice">
<li>Note! This is a test data.</li>
</ul>
The class name for each block has prefix “flash” followed by the name of namespace, which you can choose on your own – error, success, notice, info etc. Also you can pass the namespace as a parameter for the helper to show only its messages:
<?= $this->flashMessenger('info'); ?>
To use the view helper you need 2 files:
1. App/View/Helper/FlashMessenger.php
<?php
class App_View_Helper_FlashMessenger extends Zend_View_Helper_Placeholder_Container_Standalone
{
protected $_namespace;
protected $_classPrefix = 'flash';
protected $_flashMessenger;
public function __construct()
{
parent::__construct();
$this->_flashMessenger = new App_Controller_Action_Helper_FlashMessenger();
}
public function flashMessenger($namespace = null)
{
$this->setNamespace($namespace !== null ? $namespace : 'default');
$this->_namespace = $namespace;
return $this;
}
public function setNamespace($namespace)
{
$this->_flashMessenger->setNamespace($namespace);
}
public function addMessage($msg)
{
$this->_flashMessenger->addMessage($msg);
}
public function toString($indent = null)
{
$str = $this->getPrefix();
if ($this->_namespace) {
$namespaces = array($this->_namespace);
} else {
$namespaces = $this->_flashMessenger->getAvailableNamespaces();
}
foreach ($namespaces as $namespace) {
$str .= $this->render($namespace);
}
$str .= $this->getPostfix();
return $indent.$str;
}
public function render($namespace)
{
$str = '';
$this->_flashMessenger->setNamespace($namespace);
$messages = $this->_flashMessenger->getMessages();
if (count($messages) > 0) {
$str .= '<ul class="'.$this->_classPrefix.ucfirst($namespace).'">';
foreach ($messages as $message) {
$str .= '<li>'.$message.'</li>';
}
$str .= '</ul>';
}
return $str;
}
}
2. App/Controller/Action/Helper/FlashMessenger.php
<?php
class App_Controller_Action_Helper_FlashMessenger
extends Zend_Controller_Action_Helper_FlashMessenger {
public function getAvailableNamespaces()
{
$namespaces = array();
if (count(self::$_messages) > 0) {
foreach (self::$_messages as $namespace=>$values) {
$namespaces[] = $namespace;
}
}
return $namespaces;
}
}
The action helper is needed to be able to get list of defined namespaces. Both files have to be in library path and the App/View/Helper plugin path has to be defined for Zend_View instance.
Another solution that solve the same problem in slightly different way can be found at ZFSnippets web site: Grouped FlashMessenger View Helper