I’ve been working on integrating Yii with some other systems (an old legacy system, WordPress, Drupal) where I’d like to have a controller action called before a 404 Exception is thrown. It would kind of be a catchAll controller action, but would be called after all other routes were tried.
I’ve looked through CWebApplication fairly thoroughly (catchAllRequest doesn’t work, as it’s used to redirect all pages to a temporary site down page or equivalent) and I think what I’m after is a new event added to CWebApplication’s runController:
public function runController($route)
{
if(($ca=$this->createController($route))!==null)
{
list($controller,$actionID)=$ca;
$oldController=$this->_controller;
$this->_controller=$controller;
$controller->init();
$controller->run($actionID);
$this->_controller=$oldController;
}
else
+ {
+ $event=new CEvent($this,$route);
+ $this->on404Error($event);
+ if(!$event->handled)
throw new CHttpException(404,Yii::t('yii','Unable to resolve the request "{route}".',
array('{route}'=>$route===''?$this->defaultController:$route)));
+ }
}
+ public function on404Error($event)
+ {
+ $this->raiseEvent('on404Error', $event);
+ }
This would allow a preloaded CApplicationComponent to catch 404 errors, try to run them through it’s own routing schema and then either handle the event or let Yii handle it. Unlike using the errorComponent, this could catch the CHttpException before it’s logged and handle it differently. Does that seem reasonable?
I know I can override CWebApplication for my app, but I wonder if this might be useful to have as part of the overall framework for other people to hook as well. Thoughts? Is there a better way to do this? I’m happy to submit a pull request on Github if you think it’s worth it.
I currently do set the error action, which does allow me to route to my default action. But my problem is that I’m getting errors in my logs (and via email) when in fact there are no errors. Thinking through it further (and thanks for the PDF, it was quite helpful), it looks like my problem is the placement of the Yii::log line in CApplication.php
A fix like this would patch it so I could catch 404 errors, try re-routing them through my own router and then not handle them if I couldn’t resolve things properly:
This would then allow the exception handler to disable the exception (as it had been successfully caught and dealt with) or let it fall through. Does that seem like a reasonble solution?
I also was in need for a custom 404 handling (without triggering exceptions) for redirection purposes and have overridden CWebApplication for that purpose.
So I second the implementation of some hook function like suggested here by the original poster.
I want to handle the 404 error before it throw the exception, made some treatment to redirect the user to other link or suggest some pages. That’s why I need to override the runController function or handleException function. I am new with the behaviors and components.