URL redirection not working properly: genetates the url http://domain.com/domain.com/ - wordpress

I have a WordPress site in two languages (Hebrew and English) and I need it to redirect according to browser language. I'm using qTranslate plugin to create the content in both languages. This plugin also has a redirection functionality but it creates a redirection only for the homepage and I need the redirection to happen for internal pages as well as the homepage.
Another developer wrote this code for me to create the redirection, but for some reason it creates a funny redirect. It happens only when switching language to Hebrew, then leaving the site and trying to enter directly to http://domain.com/en/ and it redirects you to http://domain.com/domain.com/ (Does not happen when switching to english).
I tried playing with the "header (Location: )" that creates the redirection for Hebrew, but couldn't figure out how to make it work - I tried using the full path instead of relative path, or removing the "/" between $_SERVER['SERVER_NAME'] and $_SERVER['REQUEST_URI'] but got recursive url or url with double "/" (http://domain.com// and also for internal pages http://domain.com//page).
The url structure is:
domain.com/ for Hebrew
domain.com/en/ for English
and when switching language then the parameter $lang=en or $lang=he is being added.
Hope this makes sense, and thanks a lot!
this is the code that is responsible for the redirection:
<?php
if (!isset($_COOKIE["uln"])) :
$lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
setcookie('uln', $lang, time()+86400*365, '/', '.domain.com'); // cookie stored for a year
$_COOKIE['uln'] = $lang;
endif;
//if lang=(value) is not empty
if(isset($_GET['lang'])) {
$lang = $_GET['lang'];
setcookie('uln', $lang, time()-1, '/', '.domain.com'); //this unsets the cookie for random language selection
//set the cookie "uln" again with the selected language.
setcookie('uln', $lang, time()+86400*365, '/', '.domain.com'); // cookie stored for a year
$_COOKIE['uln'] = $lang;
}
if(($_COOKIE["uln"]) == "en") {
$matched = strncmp("/en/", $_SERVER['REDIRECT_URL'], 3);
if ($matched !== 0) :
header('Location: /en'.$_SERVER['REQUEST_URI']);
endif;
} elseif(($_COOKIE["uln"]) == "he") {
$matched = strncmp("/en/", $_SERVER['REDIRECT_URL'], 3);
if ($matched === 0) :
header('Location: '.$_SERVER['SERVER_NAME'].'/'.$_SERVER['REQUEST_URI']);
endif;
}
?>

instead of
header('Location: '.$_SERVER['SERVER_NAME'].'/'.$_SERVER['REQUEST_URI']);
try
header("Location: http://{$_SERVER['SERVER_NAME']}{$_SERVER['REQUEST_URI']}");
URLs, especially those in Location headers, should include a protocol and domain name. I believe relative URLs in Location headers are a violation of the HTTP RFCs.
By omitting a protocol, you're unintentionally specifying a relative url instead of an absolute one.
Edit: REQUEST_URI is already prefixed with a / so including one in the concat is unnecessary.

You're missing an http:// somewhere, probably in the English -> Hebrew redirect code.
Change
header('Location: '.$_SERVER['SERVER_NAME'].'/'.$_SERVER['REQUEST_URI']);
to
header('Location: http://'.$_SERVER['SERVER_NAME'].'/'.$_SERVER['REQUEST_URI']);

Related

Redirect to referring url after login in wordpress sub-directory install

I've read couple of previous post here but none of them is working in my case.. Basically, my blogging site is installed in a sub-directory of main website.. Main website in plain php and sub-directory is wordpress.. I allow users to read my blogs only after logged in. So, the thing is I frequently share the blog links in facebook where lots of new users come in from the link.
Main website is installed in => example.com
wordpress sub-directory in => example.com/blog
As I'm using the custom template login page (login.php), whenever the non-logged in users comes- first they are redirected to example.com/blog/login. I'm using this function to redirect to login page:
function redirect_user() {
if ( ! is_user_logged_in() && !is_page( 'login' ) ) {
$return_url = esc_url('http://www.example.com/blog/login');
wp_redirect( $return_url );
exit;
}
}
add_action( 'template_redirect', 'redirect_user' );
It redirect fine, without problem.. Then the main task of redirecting to the referrer url, I'm using the similar code above to direct to every logged in users to the referring url irrespective or post or page.. Again in the functions.php
if(is_user_logged_in())
wp_redirect('' . $_SERVER["REQUEST_URI"]);
I thought they would work but can't seems to understand that referring url is appending the sub-directory name... For example; the above code show result as:
example.com/blog/blog/blabla-blahblah.. You see the directory name is doubling..
Anyone's advice would be highly appreciated..
Having your WordPress website in a subdirectory will have no impact on what you are trying to do. Why? Because WordPress knows where it's located at, as you set the home and site URLs either in your wp-config.php file like this:
define('WP_HOME','http://example.com/blog');
define('WP_SITEURL','http://example.com/blog');
or by setting both in the Settings > General admin page:
Therefore, all of the rewrites and URLs will be relative to these URLs.
Handling the Referer Capture
When someone comes to one of the pages on your site, you want to capture that original request and add it as a redirect_to= query arg. Then you can send them to the login page.
add_action( 'wp', 'redirect_to_login_if_unauthorized', 3 );
/**
* Redirect the user to the login, but capture the original
* referer and add to the query arg.
*
* #since 1.0.0
*
* #param WP $wp_environment Current WordPress environment instance (passed by reference).
*
* #return void
*/
function redirect_to_login_if_unauthorized( WP $wp_environment ) {
if ( is_user_logged_in() ) {
return;
}
if ( $wp_environment->request ) {
$request = home_url( add_query_arg( array(), $wp_environment->request ) );
} else {
$request = home_url();
}
$redirect = home_url() . '/wp-login.php?redirect_to=' . $request;
wp_redirect( $redirect );
die();
}
How it Works
The event wp fires in wp-includes/class-wp.php. It passes the object instance of the WordPress environment setup. Here is the code from WordPress Core:
do_action_ref_array( 'wp', array( &$this ) );
This environment object has a property that we want called request. That property has the URL request (minus the blog's home URL).
If the $wp_environment->request has a value, we'll add it to the home URL as a query arg; else, we just want the home URL. Now we have the referer.
Next, you create the redirect URL, which has the path to the login page and the redirect_to query arg.
An Example
Let's say you have a post called Why I Love WordPress and the path to that post is http://example.com/blog/why-i-love-wordpress.
The value in the $request would be:
http://example.com/blog/why-i-love-wordpress
and the redirect URL would be:
http://example.com/blog/wp-login.php?redirect_to=http://example.com/why-i-love-wordpress
Upon logging in, the user is then redirected to the original page request.
Tip - Handle Logout Too
You'll want to think about the pathing after a user logs out and then build a proper request to it too.

Wordpress URL is replacing with load balancer URL

I am using one wordpress site. In this wordpress URL I am using 2 load balancing URL in my production.
For Example My actual URL is
www.myurl.com
My load blancer URL's are
www.myurl01.drd.myurl.com
www.myurl02.drd.myurl.com
For wordpress current URL I am using the following function in function.php
function current_url() {
$pageURL = 'http';
if( isset($_SERVER["HTTPS"]) ) {
if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";}
}
$pageURL .= "://";
if ($_SERVER["SERVER_PORT"] != "80") {
$pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
} else {
$pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
}
return $pageURL;
}
This function returning www.myurl01.drd.myurl.com load balancer URL instead of www.myurl.com. how can get my actual URL using this function.
Any one please suggest
Your implementation of current_url() does not handle the case where WordPress is running behind a proxy. Values in the SERVER array corresponding to the keys: HTTPS, SERVER_PORT and SERVER_NAME relate to the back-end server only.
The front-end proxy server may set specific headers to enable the back-end to detect that it is running behind a proxy. The WordPress core functions already support these extra settings and you may wish to look at those implementations before you make changes to your code.
If you want a quick fix (and assuming that your proxy server sets the value correctly) using HTTP_HOST in the place of SERVER_NAME may solve the immediate problem.
For a complete fix, you may want to look at using HTTP_X_FORWARDED_PROTO and HTTP_X_FORWARDED_PORT. If these values are defined, they should be use instead of the local equivalent.

Infinite loop on Geo Redirect

I have 3 websites for different regions having their own location specific content:
French website: http://dev.logichub.net/demo/fr/
German website: http://dev.logichub.net/demo/de/
Default website: http://dev.logichub.net/demo/
I would like to redirect the visitors to the respective website on the basis of their IP address. For example, if a user lands on http://dev.logichub.net/demo/fr/ from Germany, then he/she must be redirected to German website i.e. http://dev.logichub.net/demo/de/. I would like to implement this same behaviour on all the 3 websites.
I put the following code on the homepage on these 3 websites:
// get visitor IP address and process
$geo_data = unserialize( file_get_contents('http://www.geoplugin.net/php.gp?ip=' . $_SERVER['REMOTE_ADDR']) );
if ( ! empty( $geo_data ) ) {
switch ( $geo_data['geoplugin_countryCode'] ) {
// redirect French visitors to FR website
case "FR":
echo '<script>window.location.replace( "http://dev.logichub.net/demo/fr/" );</script>';
break;
// redirect German visitors to DE website
case "DE":
echo '<script>window.location.replace( "http://dev.logichub.net/demo/de/" );</script>';
break;
// redirect all others to international website
default:
echo '<script>window.location.replace( "http://dev.logichub.net/demo/" );</script>';
}
}
It works fine exactly like I want except the infinite loop on the redirected website. The visitor is redirected perfectly, but the new website load forever. How can I stop the infinite loop so once visitor redirected to the correct website, no more redirection occurs?
You have to check if the user is on the right domain before trying to redirect. Here's a solution fully made in PHP:
<?php
session_start();
$currentUrl = explode('/', "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]");
$currentCountry = isset($currentUrl[4]) ? $currentUrl[4] : '';
if(empty($_SESSION['country'])) {
$geo_data = unserialize( file_get_contents('http://www.geoplugin.net/php.gp?ip=' . $_SERVER['REMOTE_ADDR']) );
if(!empty($geo_data)) {
$country = $geo_data['geoplugin_countryCode'];
$_SESSION['country'] = $country = ($country != 'FR' || $country != 'DE') ? '' : $country;
}
}
if($currentCountry != $_SESSION['country'])
header('Location: http://dev.logichub.net/demo/'.$country);
You could improve this code by getting the current country without searching it in the URL (by defining it in the file, for example), but actually, it should work better.

Loading Google Maps API with wp_enqueue_script

I'm trying to load the Google Maps API using the following syntax:
add_action('admin_enqueue_scripts', 'load_google_maps');
...
function load_google_maps()
{
// The actual API key is configured in an options page
$key = get_option('google_maps_api_key');
$gmaps_url = 'http://maps.googleapis.com/maps/api/js?key=' . $key . '&sensor=false';
wp_enqueue_script('google-maps', $gmaps_url, NULL, NULL);
}
WordPress is escaping the "&" to "&#038". This actually makes the Google server reject the request. When I type it directly into browser address bar with "&sensor=false" at the end, it loads fine.
I saw a bug of this kind mentioned in the WordPress trac system: http://core.trac.wordpress.org/ticket/9243 but it was dismissed as invalid, and the admin responding to the request showed somehow that the "&#038" approach was fine. It is definitely not fine from Google's point of view.
I could of course just get the function to echo the HTML as a script tag, but I'd rather use the wp_enqueue_script system if possible.
Anyone know of a solution to this?
Cheers,
raff
I've got something similar in our code, and it's working fine (even encoded as &#038). I suspect your problem is that it's being double-encoded, as you already have &. Trying changing it to:
$gmaps_url = 'http://maps.googleapis.com/maps/api/js?key=' . $key . '&sensor=false';
For what it's worth, our (working) code is:
wp_register_script('googlemaps', 'http://maps.googleapis.com/maps/api/js?' . $locale . '&key=' . GOOGLE_MAPS_V3_API_KEY . '&sensor=false', false, '3');
wp_enqueue_script('googlemaps');
($locale in this case is set to hl=en)
Edit
Looks like the behaviour's changed in the latest version of WordPress - the above doesn't work (but I'll leave it for people on legacy versions). The only alternative I can see to echoing the script is to add a clean_url filter, something like this:
add_filter('clean_url', 'so_handle_038', 99, 3);
function so_handle_038($url, $original_url, $_context) {
if (strstr($url, "googleapis.com") !== false) {
$url = str_replace("&", "&", $url); // or $url = $original_url
}
return $url;
}
Pretty ugly, but perhaps marginally better than echoing the script, as it'll still use the WordPress dependency management.

WordPress custom url without parameters

I have create a custom url for my plugin in WordPress that I don't like to have any argument.
Lets say that my URL us that
http://www.mysite.ext/test/
How can I know from my code that the users in on /test/ and not in any other page from within my code ?
This is my code:
add_action('init', 'add_rewrite_rule');
function add_rewrite_rule()
{
add_rewrite_rule('test/?', 'index.php', 'top');
}
if you only want to test whether the current pages ends with /test/, can you do it in php like this:
//get host name, this returns www.mysite.ext
host = $_SERVER['HTTP_HOST'];
//get full path, this returns /test
$script = $_SERVER['SCRIPT_NAME'];
This is not test, but worth trying.

Resources