We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 22656
    • 121 Posts
    Hi guys, updated to 2.2.2 last night...
    all is well and working fine up to now, however i've just noticed something weird:

    I have the following rule in my .htaccess which rewrites urls and the rule is placed before the modx main rule for index.php

    I've noticed when opening the pages built into the site in this form,
    /x/x/x/name.html (these used to work fine before the upgrade)
    now all of a sudden server issues a 301 and serves the
    details.html?a=x&b=x&c=x&d=name page instead!?!?
    almost like the rewrite rule is still enforced, but somehow reversed!

    how do i rectify this? i havent changed anyting in htaccess during/before the upgrade/!?

    this is my rule

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+).html /details.html?country=$1&region=$2&area=$3&name=$4 [NC,L]
      • 22656
      • 121 Posts
      truth is, i would like a 301 going the other way, so when someone does go through to
      details.html?a=x&b=x&c=x&d=name
      they are automatically redirected to
      /x/x/x/name.html

      however, i'd like to revert the site to the way it should be first.
        • 22656
        • 121 Posts
        this is my full rule, for ease of understanding. What im trying to do is first rewrite anything for details.html to be rewritten in the following form /x/x/x/name.html thren below this is the normal modx rule.
        this used to work just fine up to now on several different sites and different rules:

        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+).html /details.html?country=$1®ion=$2&area=$3&name=$4 [NC,L]
        
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]


        I am also noticing the exact same problem on a WAMP test upgrade install before the site was pushed live...Live site is on IIS using Helicon Ape for rewrites [ed. note: papachumba last edited this post 14 years, 5 months ago.]
          • 22656
          • 121 Posts
          Ok, just tested this on several Modx installs:

          2.2.0 - above rule works fine, urls are resolved to
          /x/x/x/name.html
          2.2.1 - rule breaks, url's redirected to
          name.html?a=x&b=x&c=x
          2.2.2 - rule breaks, url's redirected to
          name.html?a=x&b=x&c=x

          it seems like something was changed in modx rewrite handlers which causes an extra 301 to be issued and the masked url to be shown. Does anyone have any further info on this and what I might do to resolve the problem?

          I have tried changing ALL the furl settings without much luck. I am 100% certain it is nothing in .htaccess or snippets causing teh redirect as simply downgrading back to 2.2.0 resolves the problem.
            • 22303 MODX Staff
            • 10,725 Posts
            I can confirm that the strict URL enhancements in 2.2 have broken what you are trying to do. This will only work in 2.2.2+ and only if the actual URL of the Resource exactly matches the first part of the actual custom URL being requested, e.g.

            Custom URL
            /name/x/x/x.html

            Actual Resource URL
            /name/


            We'll have to create a setting to disable this feature for cases where you want to do custom rewrites that do not match a pattern like this. Can you enter a ticket in the tracker for this if there is not already an appropriate one?

            Or you could ditch the custom rewrite rules altogether and implement your custom logic using a plugin to forward requests to the Resource OnPageNotFound.
              • 22656
              • 121 Posts
              Thank you opengeek, I've been scouring the net for the resolution whilst modifying .htaccess in all ways imaginable. I will add to tracker, no problem.

              However Im in a bit of a sticky situation. I've upgraded the live site to 2.2.2 in order to gain all the latest improvements etc. I really do not want to downgrade that now. Im hoping google is not going to start indexing these URLs because then Im going to have to create custom redirect rules back to friendly URL versions using subfolder notation. I have added noindex,nofollow for the time being.
              Is there a piece of code I can roll back, or disable, or reuse from 2.2.0 in order to gain this functionality back until new version with a setting comes out? If this is even possible.

              On the other hand, using a plugin - would you have any sample code which I can reuse as my starting point?
              Pseudocode something like this?

              • If PageNotFound
              • Check URL if contains /x/x/x/name.html structure
              • Explode URL and stick into $array
              • SendForward to appropriate page -> /details.html?a=$array[0]&b=$array[1]&c=$array[2]


              Also, would using a plugin be slower as it is handled a layer below mod rewrite? I have a site which uses around 6 separate blocks of rules like the above one, before the modx rule... [ed. note: papachumba last edited this post 14 years, 5 months ago.]
                • 22303 MODX Staff
                • 10,725 Posts
                Take a look at this commit. If you undo that commit and it works you should be good.

                If not, we can explore which of these commits to modRequest broke this behavior.
                  • 22303 MODX Staff
                  • 10,725 Posts
                  Quote from: papachumba at May 18, 2012, 09:26 AM
                  On the other hand, using a plugin - would you have any sample code which I can reuse as my starting point?
                  Pseudocode something like this?

                  • If PageNotFound
                  • Check URL if contains /x/x/x/name.html structure
                  • Explode URL and stick into $array
                  • SendForward to appropriate page -> /details.html?a=$array[0]&b=$array[1]&c=$array[2]


                  Also, would using a plugin be slower as it is handled a layer below mod rewrite? I have a site which uses around 6 separate blocks of rules like the above one, before the modx rule...

                  OnPageNotFound is the event and will only be triggered in the case that a request is made to a non-existent Resource in MODX. So the pseudocode would be:

                  • Explode the identifier into an array, i.e. q=x/x/x/name.html
                  • See if the appropriate array element contains name.html (or similar)
                  • If so, set the $_GET values expected by the Resource
                  • Then sendForward to the id of the actual Resource

                  The URL will not change, the request will be handled, and no rewrite rules required. This works in more environments easily, but it may not be as performant as a rewrite solution. It may be worth trying both approaches to see which performs better in your specific situation.
                    • 22656
                    • 121 Posts
                    Yes bloodfire!
                    Site back to normality, furls working fine.
                    Resolved by commenting out one line (the redirect) in modrequest.class.php
                    Line 353:

                    if ($fullId !== $requestUri && strpos($requestUri, $fullId) !== 0) {
                                        $parameters = $this->getParameters();
                                        unset($parameters[$this->modx->getOption('request_param_alias')]);
                                        $url = $this->modx->makeUrl($this->modx->aliasMap[$identifier], '', $parameters, 'full');
                                        //$this->modx->sendRedirect($url, array('responseCode' => 'HTTP/1.1 301 Moved Permanently'));
                                    }


                    Opengeek, once again a big thank you for pointing me in the right direction!
                    I've submitted the ticket in hope we can get a setting added to furl section, however I feel most users will be confused by the said setting.
                    I like doing rules in htaccess as it is a centralized place for all of them including all the redirects, so I'll skip the plugin coding unless im forced to. smiley [ed. note: papachumba last edited this post 14 years, 5 months ago.]
                      • 22656
                      • 121 Posts
                      Let me just explain further for those interested:

                      using the rule above you can use 3 modx pages to serve as a SEO friendly URL subfolder structure.
                      So if you want to have following url structure derived from a separate database rather than the modx resource tree (or there are just too many categories and subcategories to easily manage it in the resource tree):
                      /category1/friendly-name.html
                      /category1/category2/friendly-name.html
                      /category1/category2/category3/friendly-name.html
                      you can do so using the combination of the rule above, ie for the above example:

                      create 3 pages in modx (category1-page.html,cat2 & cat3) and let them handle each of the categories as per below rewrite rules, which will present this whole structure in the same URL format as above. (pages can all use the same snippet which does the processing and display of data, up to you)
                      you can access each of the categories in the url by simple $_GET['categoryx'] for further processing.

                      RewriteCond %{REQUEST_FILENAME} !-f
                      RewriteCond %{REQUEST_FILENAME} !-d
                      RewriteRule ^([^/]+)/([^/]+).html /category1-page.html?category1=$1&friendly-name=$2 [NC,L]
                      
                      RewriteCond %{REQUEST_FILENAME} !-f
                      RewriteCond %{REQUEST_FILENAME} !-d
                      RewriteRule ^([^/]+)/([^/]+)/([^/]+).html /category2-page.html?category1=$1&category2=$2&friendly-name=$3 [NC,L]
                      
                      RewriteCond %{REQUEST_FILENAME} !-f
                      RewriteCond %{REQUEST_FILENAME} !-d
                      RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+).html /category3-page.html?category1=$1&category2=$2&category3=$3&friendly-name=$4 [NC,L]
                       
                      RewriteCond %{REQUEST_FILENAME} !-f
                      RewriteCond %{REQUEST_FILENAME} !-d
                      RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]