Setting up flash messages in Zend Framework
This article is part of my Learning Zend Framework series.
It took me a few hours of reading and fiddling with the code to get my flash messages working with Zend Framework so I thought I could help you out by “putting it all together.”
In this example, I’m using Zend_Layout but you could put your flash messages in a view just as easy. My intent for this functionality is to allow the application to call a method that would set a flash message and then redirect the user to another page and display the flash messages. This is much like built in functionality of the Ruby On Rails or CakePHP flash messenger mechanism.
in my bootstrap file (this is not necessary if you are not using layouts):
// setup the "layouts" of MVC Zend_Layout::startMvc(array( 'layoutPath'=>'../application/views/layouts', 'layout'=>'main' ));
I chose to create a custom controller that my other action controllers would extend. This also serves as a central place to add my messaging and redirecting.
MyController.php
class MyController extends Zend_Controller_Action
{
protected $_redirector;
protected $_flashMessenger;
public function init()
{
$this->_flashMessenger = $this->_helper->getHelper('FlashMessenger');
$this->_redirector = $this->_helper->getHelper('Redirector');
}
protected function flash($message,$to)
{
$this->_flashMessenger->addMessage($message);
$this->_redirector->gotoUrl($to);
}
protected function setMessages()
{
$this->view->messages = join("
",$this->_flashMessenger->getMessages());
}
public function postDispatch()
{
$this->setMessages();
parent::postDispatch();
}
}
In the above file, you will notice 4 methods. The init() method initializes the flashMessenger and Redirector helpers. The flash() method is the method your controllers should actually call. This will set the flash message and then redirect to a url. I made this method very simple but you could easily allow it to take in a standard set of parameters for the controller/action and params. The setMessages() method is used to set the flash messages to a variable accessible by your view/layout. The postDispatch() method is called after your action is complete, so I’m using this method to set the flash messages in the view.
In your controller action:
public function login()
{
// do some login stuff here
if($logged_in) {
$this->flash('You are now logged in','/dashboard'); // this will set the message and redirect
}
}
And in your view/layout:
echo $this->messages;
It’s as simple as that.
If you hunt through all of the Zend Framework documentation, you will eventually get here (with trial and error). But, like I said, it took me a while to find a working solution so I thought I would share.
CakePHP default dateTime()
In the FormHelper class of Cake 1.2 there’s a method for generating fields for a datetime. It is not documented very well but you can pass a timestamp into the “selected” parameter and it will default the dropdowns to the date and time of that timestamp.
For instance, if you make this call:
echo $form->dateTime('GiftCard.expire','MDY','NONE',strtotime('+1 month'));
it will result in three select fields; Month, Day, Year; and they will be defaulted to one month from today. strtotime(’+1 month’) returns a timestamp corresponding one month from today.
Extending CakePHP’s beforeFilter()
This is a simple addition to app_controller.php to allow a more customized beforeFilter() callback.
I set out to get a little more functionality out of the controller callback beforeFilter(). I had 2 requirements for this extended functionality:
- Specify which actions to apply the callback to.
- Ability to specify multiple methods beforeFilter would call.
Let me give a very simple example of how to use this snippet:
in your controller define $beforeFilter which is an array of methods to call and the parameters.
class TestingsController extends AppController
{
var $name = 'Testings';
var $beforeFilter = array('requireLogin'=>array('only'=>array('add','edit','delete')));
function index(){}
function view($id){}
function add(){}
function edit($id=null){}
function delete($id){}
}
The $beforeFilter instance variable holds an array of methods to be called before your actions are called. In the example above, it says to call the ‘requireLogin’ method only when the ‘add’,'edit’,'delete’ actions are being called.
This next example shows you how to make certain actions excluded from the callback:
class TestingsController extends AppController
{
var $name = 'Testings';
var $beforeFilter = array('requireLogin'=>array('except'=>array('index')));
function index(){}
function view($id){}
function add(){}
function edit($id=null){}
function delete($id){}
}
You can also send in a parameter called ‘args’ which will call your method with the args
var $beforeFilter = array('requireLogin'=>array('except'=>array('index'),
'args'=>array('arg1','arg2')));
In order to make this all happen you need to place this method in your app_controller.php class.
It will get called before every action. If you have not defined $beforeFilter then it will skip any processing.
function beforeFilter(){
if(empty($this->beforeFilter)) return true;
$failures = false;
foreach($this->beforeFilter as $func_name=>$func){
$call_func = true;
if(!empty($func['only'])){
if(!in_array($this->action,$func['only']))
$call_func = false;
}
if(!empty($func['except'])){
if(in_array($this->action,$func['except']))
$call_func = false;
}
if($call_func){
$args = (isset($func['args'])) ? implode(',',$func['args']) : null;
if(!$this->{$func_name}($args)){
$failures = true;
break;
}
}
}
return !$failures;
}
Recently
- 08.24 Setting up flash messages in Zend Framework
- 09.08 CakePHP default dateTime()
- 03.24 Extending CakePHP’s beforeFilter()
- 03.17 Rails-like Flash messages in CakePHP
- 03.08 CakePHP thumbnails with phpThumb
- 02.15 CakePHP model validation
- 02.10 CakePHP - saving dates in your model
- 09.19 Importing multiple pdf pages and documents into PDFlib - Part 2
- 09.18 Quick Link - Every CSS based layout you could want
- 09.04 Mongrel pid error fixed