Yii Framework Forum: Add a 404 event to CWebApplication runController - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Add a 404 event to CWebApplication runController Rate Topic: -----

#1 User is offline   acorncom 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 100
  • Joined: 25-February 11
  • Location:CO, USA

Posted 01 May 2012 - 03:52 PM

Hi Guys,
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.
0

#2 User is offline   seb 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 240
  • Joined: 29-June 09

Posted 02 May 2012 - 06:35 AM

Look here (see attached pdf) or here (full article in russian).
I think configuring error handler component and setting error action to your controller action should work in your situation.
0

#3 User is offline   acorncom 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 100
  • Joined: 25-February 11
  • Location:CO, USA

Posted 02 May 2012 - 09:26 AM

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:

	public function handleException($exception)
	{
		// disable error capturing to avoid recursive errors
		restore_error_handler();
		restore_exception_handler();

-		$category='exception.'.get_class($exception);
-		if($exception instanceof CHttpException)
-			$category.='.'.$exception->statusCode;
-		// php <5.2 doesn't support string conversion auto-magically
-		$message=$exception->__toString();
-		if(isset($_SERVER['REQUEST_URI']))
-			$message.="\nREQUEST_URI=".$_SERVER['REQUEST_URI'];
-		if(isset($_SERVER['HTTP_REFERER']))
-			$message.="\nHTTP_REFERER=".$_SERVER['HTTP_REFERER'];
-		$message.="\n---";
-		Yii::log($message,CLogger::LEVEL_ERROR,$category);

		try
		{
			$event=new CExceptionEvent($this,$exception);
			$this->onException($event);
			if(!$event->handled)
			{
+				$category='exception.'.get_class($exception);
+				if($exception instanceof CHttpException)
+					$category.='.'.$exception->statusCode;
+				// php <5.2 doesn't support string conversion auto-magically
+				$message=$exception->__toString();
+				if(isset($_SERVER['REQUEST_URI']))
+					$message.="\nREQUEST_URI=".$_SERVER['REQUEST_URI'];
+				if(isset($_SERVER['HTTP_REFERER']))
+					$message.="\nHTTP_REFERER=".$_SERVER['HTTP_REFERER'];
+				$message.="\n---";
+				Yii::log($message,CLogger::LEVEL_ERROR,$category);
				// try an error handler
				if(($handler=$this->getErrorHandler())!==null)
					$handler->handle($event);
				else
					$this->displayException($exception);
			}
		}
		catch(Exception $e)
		{
			$this->displayException($e);
		}


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?
0

#4 User is offline   Maurizio Domba Cerin 

  • Yii - Yesss It Is !!!
  • Yii
  • Group: Yii Dev Team
  • Posts: 4,359
  • Joined: 12-October 09
  • Location:Croatia

Posted 02 May 2012 - 11:30 AM

Link to github issue for this - https://github.com/y.../yii/issues/669
Find more about me.... btw. Do you know your WAN IP?
0

#5 User is offline   hwm 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 4
  • Joined: 14-December 12

Posted 18 March 2013 - 08:06 AM

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.
0

#6 User is offline   Samir IZZA 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 21
  • Joined: 07-August 12
  • Location:Algeria

Posted 08 December 2013 - 09:02 AM

Hi all,
I have the same problem than the original post
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.
Can you explain this for me?
Thanks a lot in advance.
0

#7 User is offline   acorncom 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 100
  • Joined: 25-February 11
  • Location:CO, USA

Posted 09 December 2013 - 10:21 AM

@Samir, take a look at this Github repository. I have the basic items roughed in in that repository:
https://github.com/a...ess-integration

Also the Yii wiki article I link to from that repo has more details.
1

#8 User is offline   Samir IZZA 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 21
  • Joined: 07-August 12
  • Location:Algeria

Posted 12 December 2013 - 01:54 AM

View Postacorncom, on 09 December 2013 - 10:21 AM, said:

@Samir, take a look at this Github repository. I have the basic items roughed in in that repository:
https://github.com/a...ess-integration

Also the Yii wiki article I link to from that repo has more details.


Thanks a lot acorncom,
I'll check this and get back to you ASAP.
Thanks again.
0

#9 User is offline   hungtran 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 3
  • Joined: 08-December 13

Posted 15 December 2013 - 12:34 AM

this is good for customer and for SEO
some error can use too
0

#10 User is offline   Samir IZZA 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 21
  • Joined: 07-August 12
  • Location:Algeria

Posted 01 January 2014 - 11:19 AM

View Postacorncom, on 09 December 2013 - 10:21 AM, said:

@Samir, take a look at this Github repository. I have the basic items roughed in in that repository:
https://github.com/a...ess-integration

Also the Yii wiki article I link to from that repo has more details.

Dear acorncom,
You really helped me, I used your handleException function.
Thank you so much my friend.

Samir IZZA
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users