1

I have a WordPress site hosted on an Azure App Service (not a dedicated VM) and I need people to access the front page via a URL like: http://www.example.com/?tracking.id=12345

However, WordPress is re-writing the URL by replacing the dot in tracking.id with an underscore: http://www.example.com/?tracking_id=12345

How can I prevent WordPress from doing this?

Kcoder
  • 3,422
  • 4
  • 37
  • 56
  • It seems that many of the tricks I've tried like changing `$config['uri_protocol'] ` don't seem to work or apply on an Azure App. – Kcoder Jan 29 '16 at 04:27
  • 1
    not necessarily how, but [this](http://stackoverflow.com/questions/68651/get-php-to-stop-replacing-characters-in-get-or-post-arrays) explains why. one of the workarounds might work for you. – vidja Jan 29 '16 at 07:40
  • I need to track down where the redirection itself is taking place. I found a function being used called "wp_safe_redirect" but not where to edit the code for that function (didn't think it was a built-in thing for PHP given the wp_ extension to the name). I'm not even sure if I'm approaching that the right way. (I'm not a PHP developer, so I'm falling over this like a junior coder trying to fix a legacy bug.) – Kcoder Jan 29 '16 at 22:52

3 Answers3

1

what's interesting is that this only happens on the home page, query vars stay intact everywhere else. you might be able to figure out what's going on if you take a look at wp-includes/canonical.php (that's also where the redirect_canonical filter is located)

function prevent_underscores( $redirect_url, $requested_url ) {

    if( isset( $_GET['tracking_id'] ) ) {
        return $requested_url;
    }   
    return $redirect_url;   
}

add_filter( 'redirect_canonical', 'prevent_underscores', 10, 2 );
vidja
  • 152
  • 1
  • 7
  • Sounds like you might be on the right track with this one. I'll investigate it more tonight. – Kcoder Jan 31 '16 at 18:05
0

You may check whether you have chosen and set the permalinks_type in the setting tab of your WordPress site. You can refer to https://codex.wordpress.org/Using_Permalinks for details.

Moreover, you can leverage the 3rd part Wordpress Plugin, refer to https://wordpress.org/plugins/custom-permalinks/.

Gary Liu
  • 13,758
  • 1
  • 17
  • 32
  • This doesn't appear to have any effect on the automatic redirection when it comes to renaming query string parameters. If I had to guess, it has something to with [this](http://stackoverflow.com/a/18057773/1068128) but I'm not sure where in the code it's stripping out and changing the URL. – Kcoder Jan 29 '16 at 22:45
0

@vidja is very close and definitely on the right track with redirect_canonical.

I dug into this issue a bit further myself to figure out that this is a combination of issues between both PHP itself and this redirect logic in WordPress. If you have a look at the php global $_GET directly, you'll find that is where the query string params are being parsed "incorrectly". For instance:

// For a url like: /some/path/?tracking.id=123
var_dump($_GET);
// array(1) { ["tracking_id"]=> string(3) "123" }

If you continue to dig through the redirect_canonical code you'll eventually find the culprit to be a stack of function calls, ending with php's parse_str method:

// https://developer.wordpress.org/reference/functions/_remove_qs_args_if_not_in_url/
_remove_qs_args_if_not_in_url()
// https://developer.wordpress.org/reference/functions/remove_query_arg/
remove_query_arg()
// https://developer.wordpress.org/reference/functions/add_query_arg/
add_query_arg()
// https://developer.wordpress.org/reference/functions/wp_parse_str/
wp_parse_str()
// https://www.php.net/manual/en/function.parse-str.php
parse_str()

Testing out parse_str directly gives you the same result as looking at $_GET:

$arr = [];
parse_str('tracking.id=123', $arr);
var_dump( $arr );
// array(1) { ["tracking_id"]=> string(3) "123" }

All this to say that there is a slightly better way to setup your own filter so that you get a more robust result. For instance, the way that @vidja wrote his filter would result in pages not being properly redirected when you'd want them to be (and as a result, WordPress showing a 404 not found page). Say you had a page with a slug of /sample-page and you tried visiting your site through a url like: /sampl?tracking.id=123. Wordpress would want to redirect that to /sample-page/?tracking_id=123, but @vidja's code would instead return the original (bad) url since tracking_id is set in $_GET. So, a better way to handle this, in my opinion, would be to replace the specific query string param you care about inside the redirect url, that way Wordpress can do it's thing to redirect pages as it see's fit, but you can also maintain your tracking.id properly. Here is what that would look like:

add_filter( 'redirect_canonical', function ( $redirect_url, $requested_url ) {
  return preg_replace( '/tracking_id=/', 'tracking.id=', $redirect_url );
}, 10, 2 );

You could even do something like the following if you had multiple query string parameters with period's that you needed to maintain:

add_filter( 'redirect_canonical', function ( $redirect_url, $requested_url ) {
  $query_params = [
    'tracking_id' => 'tracking.id',
    'foo_bar' => 'foo.bar',
  ];

  foreach ( $query_params as $search => $replace ) {
    $redirect_url = preg_replace( '/'.$search.'=/', $replace.'=', $redirect_url );
  }

  return $redirect_url;
}, 10, 2 );
andersryanc
  • 939
  • 7
  • 19