Add a touch of class to your Auth Flash
Have you ever wondered how to make your Auth messages from the Auth Core component, well more flashy and custom? The answer is fairly simple and straight forward. In this short tutorial, I will explain the traceback that occurs when a flash message is set for Auth.
Working on a project today, I realized that my Auth login error messages weren't being displayed in the custom flash layout I had chosen to use for the project. A bit of digging showed me a secret trail through the rabbit hole, and a simple solution to the problem.
First stop on the trail, was /cake/libs/controllers/components/auth.php to investigate where the flash messages were being set, via
I found 3 locations in the auth file, and each were setting the flash to use the default layout. I was curious at that point to where the default layout for flash was set at. Well as it turns out, there isn't one! rather, it's hard coded into the SessionHelper->flash() method, as seen by line # 22 below.
-
/**
-
* Used to render the message set in Controller::Session::setFlash()
-
*
-
* In your view: $session->flash('somekey');
-
* Will default to flash if no param is passed
-
*
-
* @param string $key The [Message.]key you are rendering in the view.
-
* @return string Will echo the value if $key is set, or false if not set.
-
* @access public
-
*/
-
function flash($key = 'flash') {
-
if ($this->__active === true && $this->__start()) {
-
if (parent::check('Message.' . $key)) {
-
$flash = parent::read('Message.' . $key);
-
-
if ($flash['layout'] == 'default') {
-
$class = $flash['params']['class'];
-
} else {
-
$class = 'message';
-
}
-
$out = '<div id="' . $key . 'Message" class="' . $class . '">' . $flash['message'] . '</div>';
-
} elseif ($flash['layout'] == '' || $flash['layout'] == null) {
-
$out = $flash['message'];
-
} else {
-
$view =& ClassRegistry::getObject('view');
-
$out = $view->renderLayout($flash['message'], $flash['layout']);
-
}
-
parent::del('Message.' . $key);
-
return true;
-
}
-
}
-
return false;
-
}
-
Rather than simply changing this, and perhaps making it more rigid, I decided to simply add in 2 public variables to the Auth Component, which I can then set, with the rest of my Auth properties in the AppController. Below is the Diff of my Auth Component, as it is from the CakePHP 1.2.5 core. I personally chose:
* Flash Layout to use to allow custom layouts.
* Defaults to the layout as used by $session->flash()
*
* @var string
* @access public
*/
var $authFlashLayout = 'default';
/**
* Flash Error Params to use. Defaults to array() as used
* by the Auth component preiviously
*
* @var array
* @access public
*/
var $authFlashError = array();
I can then set the layout I want, and the params to pass to the custom flash message. Below is the complete diff for the Auth Component.
--- cake/libs/controller/components/auth.php 2009-12-01 19:04:51 UTC (rev 55)
+++ cake/libs/controller/components/auth.php 2009-12-01 19:45:38 UTC (rev 56)
@@ -222,6 +222,22 @@
*/
var $_methods = array();
/**
+ * Flash Layout to use to allow custom layouts.
+ * Defaults to the layout as used by $session->flash()
+ *
+ * @var string
+ * @access public
+ */
+ var $authFlashLayout = 'default';
+/**
+ * Flash Error Params to use. Defaults to array() as used
+ * by the Auth component preiviously
+ *
+ * @var array
+ * @access public
+ */
+ var $authFlashError = array();
+/**
* Initializes AuthComponent for use in the controller
*
* @param object $controller A reference to the instantiating controller object
@@ -333,13 +349,13 @@
}
}
- $this->Session->setFlash($this->loginError, 'default', array(), 'auth');
+ $this->Session->setFlash($this->loginError, $this->authFlashLayout, $this->authFlashError, 'auth');
$controller->data[$this->userModel][$this->fields['password']] = null;
return false;
} else {
if (!$this->user()) {
if (!$this->RequestHandler->isAjax()) {
- $this->Session->setFlash($this->authError, 'default', array(), 'auth');
+ $this->Session->setFlash($this->authError, $this->authFlashLayout, $this->authFlashError, 'auth');
if (!empty($controller->params['url']) && count($controller->params['url']) >= 2) {
$query = $controller->params['url'];
unset($query['url'], $query['ext']);
@@ -403,7 +419,7 @@
return true;
}
- $this->Session->setFlash($this->authError, 'default', array(), 'auth');
+ $this->Session->setFlash($this->authError, $this->authFlashLayout, $this->authFlashError, 'auth');
$controller->redirect($controller->referer(), null, true);
return false;
}
I hope this gives you some insight into how to handle these types of situations. Try to keep things flexible, and in the end, all will turn out, just how you want them!


dilan Said:
In the late 1880s, Herman Hollerith invented the recording of data on a medium that could then be read by a machine.1z0-048 Prior uses of machine readable media, above, had been for control, not data. "After some initial trials with paper tape,642-515 he settled on punched cards..."To process these punched cards, first known as "Hollerith cards" he invented the tabulator, and the key punch machines. These three inventions were the foundation of the modern information processing industry. In 1896 he founded the Tabulating Machine Company (which later became the core of IBM).70-631 The addition of a control panel to his 1906 Type I Tabulator allowed it to do different jobs without having to be physically rebuilt. By the late 1940s, there were a variety of plug-board programmable machines, called unit record equipment, to perform data-processing tasks (card reading). Early computer programmers used plug-boards for the variety of complex calculations requested of the newly invented machines.