So it seems that the old code I had didn’t work in debug mode, although on the current CakePHP 1.2 RC2, I’m not even sure it works at all. However, I decided to take some time to revisit the code. Last time, I simply hacked up the missingAction and missingController calls and it felt kludgy. It looked kludgy.

This time I took a closer look at how the dispatch was being handled. Daniel Hofstetter made mentioned how using the error handler seemed inappropriate since it’s for handling errors. Unfortunately, the Dispatcher looks for a missing action or controller and if it can’t find them, it sends it off to the AppError class well before anything else. As a result, it seems that overriding the AppError is really the approach that I want to take. I think you’ll see, though, that the new code is more straightforward.

It uses the constructor to capture what kind of error is being called. If it’s a missingAction or missingController then I look for the missing file. If the file doesn’t exist, the flow continues on to the parent error class and the missingAction and missingController calls happen as they normally would. The old code actually handled both scenarios creating bulky code.

If the page exists then the AppController is instantiated and the view is rendered. The only problem currently is that CakePHP doesn’t seem to load the custom AppController, if it exists. I’ve filed a ticket but I’m not entirely sure if this is by design, so this may not ultimately get resolved.

Without further ado, here’s my AppError:

class AppError extends ErrorHandler {

	function __construct($method, $messages) {

		$params = Router::getParams();

		if (($method == 'missingController' || $method == 'missingAction')
           && file_exists(VIEWS . DS . $params['controller'] . DS . $params['action'] . ".ctp")) {
			$this->controller =& new AppController();
			$this->controller->_set(Router::getPaths());
			$this->controller->params = $params;
			$this->controller->constructClasses();
			$this->controller->viewPath = $params['controller'];
			$this->controller->render($params['action']);
			e($this->controller->output);
			exit;
		}

		parent::__construct($method, $messages);
		exit();
	}

}
  • No Related Post