We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 32645
    • 377 Posts
    I’m trying to build a 404 router plugin which should redirect to my offers page(62), but I always get the following message;


    ERROR: Too many forward attempts!

    The request could not be completed due to too many unsuccessful forward attempts.

    Here is the code. This is a plugin, not a snippet, with the OnParseDocument checked.

    The reason I have opted to use a plugin is to catch the 404 error before it reaches the 404 page.

    When I try the following code in a snippet, it works fine. Ideally I want to catch the 404 before it reaches the page.

    Question: Is having a 404 router snippet on the page better than having a plugin? My client is concerned that if we use a snippet on the 404 page it will cause SEO problems because the 404 page is showing first.

    // Plugin: 404Router
    // Aim: To redirect to my offers page if there is a /offer/ segment
    /**
     * 404Router
     * @updated: 15 March 2009
     */
    $debug = false;
    $offerDocID = 62; 
    
    // Getting the requested URL:
    $RequestURL = $_SERVER['REQUEST_URI'];
    
    // Testing if the requested URL points to the celebrities "folder":
    if (strpos($RequestURL, "offers/") <> 0)
    {
    	// Isolating the FileName portion of the URL from the Document one:
    	$url = str_replace("http://", "", $RequestURL);
    	$split_url = explode('/', $url);
    
    	if (sizeof($split_url ==3) )
    	{
    		$offerDocument = $split_url[3];
    
    		$modx->offerDocument = $offerDocument;
    
    		if ($debug==true) print '<p><b>'.$modx->offerDocument .'</b></p>';
    
    		// Rerouting request to index.php without changing requested URL:
    		//die("Do redirect to: $offerDocID");
    	    $modx->sendForward( 62 );
    	}
    }
    



      • 32645
      • 377 Posts
      I think I might of fixed the issue.

      It turns out I had to blank the server request uri, then it worked fine. Can someone confirm whether blanking the request uri is safe or ok to do?

      		// Rerouting request to index.php without changing requested URL:
      		//die("Do redirect to: $offerDocID");
      	        $_SERVER['REQUEST_URI'] = '';
                     $modx->sendForward( $offerDocID ); 
      
        • 22303 MODX Staff
        • 10,725 Posts
        I can’t imagine why that would have made a difference. However, make sure the page you are trying to forward the request to is published and not protected by permissions.
          • 32645
          • 377 Posts
          Okay. Thanks for your help.

          I couldn’t get rewrite rules to work on my specific problem, and because of time constrictions I’ve opted for a 404 router that checks for the existance of the /offer/ part of the URL.

          Thanks again!
            • 32645
            • 377 Posts
            I have realised there is a bug with my 404 Router.

            Do not use: OnParseDocument
            Use: OnWebPagePrerender

            The reason is that in IE6 and some later versions of IE, the page will never redirect, either take forever to load -- or cause the browser to stop responding.

            Thanks.
              • 32645
              • 377 Posts
              Hi there.

              I built a 404 Router to redirect on a 404 error, capturing a specific section of the URI and then redirecting based upon this entry.

              However I’ve now discovered a really big problem -- Google webmaster tools always reports:


              myexample.com/latest-deals/offer/ACE161350C
              404 (Not found)

              My 404 Router is as follows:

              /**
               * 404Router
               * @updated: 10 June 2009
               */
              
              $debug = false;
              
              // Getting the requested URL
              $RequestURL = $_SERVER['REQUEST_URI'];
              
              // Find position of first occurrence of a string
              $pos = strpos($RequestURL, "offer/" );
              
              if ($pos <> 0)
              {
              	// Single offer handling -----------------------
              	$offerDocID = 23;
              	$url = str_replace("http://", "", $RequestURL);
              	$split_url = explode('/', $url);
              	if ($debug == true) print "URL SPLIT: " . print_r($split_url);
              	$offerDocument = $split_url[3];
              	if ($debug == true) print $offerDocument;
              
              	$modx->offerDocument = $offerDocument;
              
              	// Rerouting request to index.php without changing requested URL:
              	if ($debug == true) ("<p>Do redirect to: $offerDocID</p>");
              	
              	// Redirect
              	$_SERVER['REQUEST_URI'] = '';
              	$modx->sendForward( $offerDocID ); 
              } // end if
              


              The problem is that because it is a 404 error, Google will then assume it can’t be found, even though the page is there.

              Is there a way to fix this so that I can use the RewriteRules?

              # The Friendly URLs part
              RewriteCond %{REQUEST_FILENAME} !-f
              RewriteCond %{REQUEST_FILENAME} !-d
              RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
              


              I’ve tried using RewriteRules before but got nowhere because MODX always complained it could not find the relevant page.

              Any help on this would be greatly appreciated!

              # This is the rewrite rule I tried:
              RewriteCond %{REQUEST_FILENAME} !-f
              RewriteCond %{REQUEST_FILENAME} !-d
              RewriteRule ^offer/([a-zA-Z0-9]+)/$ index.php?q=offer&offer_id=$1 [R=301,L]
              


              But MODX won’t play ball.
                • 32645
                • 377 Posts
                I’ve noted in my previous threads that I used 404 as a routing service, this is obviously bad SEO.

                But what I was wondering is, which of the System Events is a system event dedicated to handling the URLs?

                Could one of these be the key to resolving this?

                System Settings
                + OnFriendlyURLSettingsRender	 -- What does this do?
                + OnInterfaceSettingsRender
                + OnMiscSettingsRender	
                + OnSiteSettingsRender
                + OnUserSettingsRender
                
                Parser Service Events
                + OnFileManagerUpload	
                + OnPageNotFound
                + OnPageUnauthorized	
                + OnSiteRefresh
                [i]There appears to be no parser service event for URL handling[/i]
                


                Summary of question: Is it possible to use System Events to produce FURLs on the fly without resorting to a 404 Router, or relying upon a 404/other server codes?

                Thanks.
                  • 22303 MODX Staff
                  • 10,725 Posts
                  Just return the appropriate header if you are routing them OnPageNotFound. You obviously don’t want to send the 404 Not Found header if you are finding it for them. The standard 302 Found should be what you are wanting, or possibly just a simple 200 OK.

                  Otherwise, there is no practical way to supplement the routing built-in to MODx without completely reproducing it.
                    • 32645
                    • 377 Posts
                    Hi.


                    Just return the appropriate header if you are routing them OnPageNotFound. You obviously don’t want to send the 404 Not Found header if you are finding it for them. The standard 302 Found should be what you are wanting, or possibly just a simple 200 OK.

                    In my original code I just did a MODX->sendForward command, not a 404, 302 or 200 redirect.

                    I am not sure how to do the above.

                    Anyway, I did the following hack, I know you’re not meant to hack the core but I really had no other choice:

                    Edited the document.parser.class.inc.php and added the lines at 1128:

                    			// Find position of first occurrence of `offer` in the requested URL
                    			$RequestURL = $this->documentIdentifier;
                    			$pos = strpos($RequestURL, "offer/" );
                    			if ($pos <> 0)
                    			{
                    				$url = str_replace("http://", "", $RequestURL);
                    				$split_url = explode('/', $url);
                    				if ($debug == true)
                    				{
                    					print "<br />URL SPLIT: " . print_r($split_url);
                    				} // end if
                    					
                    				// Build URL of page without the offer code
                    				if ( (is_array($split_url)) && (sizeof($split_url)>0) )
                    				{
                    					if (!$this->is_str_empty($split_url[0]))
                    					{
                    						$this->documentIdentifier = $split_url[0];
                    					}
                    					if (!$this->is_str_empty($split_url[1]))
                    					{
                    						$this->documentIdentifier .= '/' . $split_url[1];
                    					}
                    				} // end if
                    			} // end if
                    


                    Basically I find the occurrence of /latest-offers/offer/ and consider it as being a request for latest-offers/offer/ page, then the offer page itself does all the handling, including any 404 redirection.

                    Although, a 302/200 redirection could possibly work in a plug-in but I am concerned that it will still be considered a 404 because the page doesn’t really exist, and is all handled inside the offer page.

                    Anyway, this hack is working for the moment; if it doesn’t do the job then I will change it to a 302/200 redirection.

                    Any notes on how to accomplish a 302/200 redirection in a plugin working on "OnPageNotFound" please let me know.

                    Thanks.