0

I've built this function that allows me to redirect users based on their countries, it seems to work fine for all the pages other than the admin section. Obviously, I don't want redirect if I'm in the admin section but at the moment I get a redirect loop and an error.

This is my function:

function url_get_contents ($Url) {
    if (!function_exists('curl_init')){
        die('CURL is not installed!');
    }
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $Url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $output = curl_exec($ch);
    curl_close($ch);
    return $output;
}




add_action ('after_setup_theme', 'my_redirect_function');

function my_redirect_function() {

    if (!current_user_can('administrator') || ( !is_admin() ) ) {

      $ip = '';

         if (!empty($_SERVER['HTTP_CLIENT_IP']))   //check ip from share internet
         {
           $ip=$_SERVER['HTTP_CLIENT_IP'];
         }
         elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))   //to check ip is pass from proxy
         {
           $ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
         }
         else
         {
           $ip=$_SERVER['REMOTE_ADDR'];
         }

         //echo $ip . "<br>";

         //$country = file_get_contents('http://geoip.maxmind.com/a?l=6QT6fNSdtMVw&i='.$ip);

     $country = url_get_contents('http://geoip.maxmind.com/a?l=6QT6fNSdtMVw&i='.$ip);

         //echo $country;

         if( $country == 'IE'  && ICL_LANGUAGE_CODE != 'ie' ) {
             $current_uri = explode('/', $_SERVER['REQUEST_URI']);
             // CHANGE 2 WITH 1 ONCE THE WEBSITE IS LIVE
             if( $current_uri[1] == 'projects' ) {
               $current_uri[1] = 'projects-ie';
               $current_uri = $current_uri[1];
               // DELET /ROOFING/ ONCE THE WEBISTE IS LIVE
               $current_uri = $current_uri . "/";
               echo $current_uri . "<br>";
               $current_url = 'http://'. $_SERVER['HTTP_HOST'] . $current_uri;
               $translated_url = apply_filters( 'wpml_permalink', $current_url, 'ie' );
               echo $current_url . "<br>";
               echo $translated_url;
               wp_redirect( $translated_url );
               exit;
             } else {
         $current_url = 'http://'. $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
             $translated_url = apply_filters( 'wpml_permalink', $current_url, 'ie' );
             wp_redirect( $translated_url );
             echo $current_url;
             echo $translated_url;
             exit;
     }
         } elseif ( $country == 'CA'  && ICL_LANGUAGE_CODE != 'can' ) {
             $current_uri = explode('/', $_SERVER['REQUEST_URI']);
             // CHANGE 2 WITH 1 ONCE THE WEBSITE IS LIVE
             if( $current_uri[1] == 'projects' ) {
               $current_uri[1] = 'projects-can';
               $current_uri = $current_uri[1];
               // DELET /ROOFING/ ONCE THE WEBISTE IS LIVE
               $current_uri = $current_uri . "/";
               echo $current_uri . "<br>";
               $current_url = 'http://'. $_SERVER['HTTP_HOST'] . $current_uri;
               $translated_url = apply_filters( 'wpml_permalink', $current_url, 'can' );
               echo $current_url . "<br>";
               echo $translated_url;
               wp_redirect( $translated_url );
               exit;
             } else {
             $current_url = 'http://'. $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
             $translated_url = apply_filters( 'wpml_permalink', $current_url, 'can' );
             wp_redirect( $translated_url );
             echo $current_url;
             echo $translated_url;
             exit;
           }
         }

    }

}

I tried to add !is_admin in this part

if (!current_user_can('administrator') || ( !is_admin() ) ) {

to avoid executing the function when I'm in the admin area but I still get the redirect loop.

I've tried different solutions but I've always got the redirect loop when I tried to accesses to the admin area.

Which statement could I use to avoid running this function on the admin area but just on the website?

New code with one more if statement:

add_action ('after_setup_theme', 'my_redirect_function');

function my_redirect_function() {
if ( !is_admin() ) {
    if (!current_user_can('administrator') ) {

      $ip = '';

         if (!empty($_SERVER['HTTP_CLIENT_IP']))   //check ip from share internet
         {
           $ip=$_SERVER['HTTP_CLIENT_IP'];
         }
         elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))   //to check ip is pass from proxy
         {
           $ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
         }
         else
         {
           $ip=$_SERVER['REMOTE_ADDR'];
         }

         //echo $ip . "<br>";

         //$country = file_get_contents('http://geoip.maxmind.com/a?l=6QT6fNSdtMVw&i='.$ip);

     $country = url_get_contents('http://geoip.maxmind.com/a?l=6QT6fNSdtMVw&i='.$ip);

         //echo $country;

         if( $country == 'IE'  && ICL_LANGUAGE_CODE != 'ie' ) {
             $current_uri = explode('/', $_SERVER['REQUEST_URI']);
             // CHANGE 2 WITH 1 ONCE THE WEBSITE IS LIVE
             if( $current_uri[1] == 'projects' ) {
               $current_uri[1] = 'projects-ie';
               $current_uri = $current_uri[1];
               // DELET /ROOFING/ ONCE THE WEBISTE IS LIVE
               $current_uri = $current_uri . "/";
               echo $current_uri . "<br>";
               $current_url = 'http://'. $_SERVER['HTTP_HOST'] . $current_uri;
               $translated_url = apply_filters( 'wpml_permalink', $current_url, 'ie' );
               echo $current_url . "<br>";
               echo $translated_url;
               wp_redirect( $translated_url );
               exit;
             } else {
         $current_url = 'http://'. $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
             $translated_url = apply_filters( 'wpml_permalink', $current_url, 'ie' );
             wp_redirect( $translated_url );
             echo $current_url;
             echo $translated_url;
             exit;
     }
         } elseif ( $country == 'CA'  && ICL_LANGUAGE_CODE != 'can' ) {
             $current_uri = explode('/', $_SERVER['REQUEST_URI']);
             // CHANGE 2 WITH 1 ONCE THE WEBSITE IS LIVE
             if( $current_uri[1] == 'projects' ) {
               $current_uri[1] = 'projects-can';
               $current_uri = $current_uri[1];
               // DELET /ROOFING/ ONCE THE WEBISTE IS LIVE
               $current_uri = $current_uri . "/";
               echo $current_uri . "<br>";
               $current_url = 'http://'. $_SERVER['HTTP_HOST'] . $current_uri;
               $translated_url = apply_filters( 'wpml_permalink', $current_url, 'can' );
               echo $current_url . "<br>";
               echo $translated_url;
               wp_redirect( $translated_url );
               exit;
             } else {
             $current_url = 'http://'. $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
             $translated_url = apply_filters( 'wpml_permalink', $current_url, 'can' );
             wp_redirect( $translated_url );
             echo $current_url;
             echo $translated_url;
             exit;
           }
         }

    }
}
}
  • just to make sure, have you tested when you are logged out? Because !current_user_can('administrator') will return false in the frontend/public facing site only you are logged out as admin – Celso Bessa May 2 '18 at 14:07
  • Hi thank you for answering me, this is driving me crazy, I just updated the code and edited my question I create new parent IF statement with (!is_admin) so the first check is for the admin page and after there is the !current_user_can('administrator') check. Now I don't get the redirect loop anymore but I get redirected when I get /wp-login.php and as a result I get a 404 error because the URL is redirected to /ie/ (www.mydomain.com/ie/wp-login.php/?redirect_to=http%3A%2F%2Fwww.deaneroofing.com%2Fwp-admin%2F&reauth=1). How can I avoid /ie/ at this stage? – Crashy May 2 '18 at 14:22
0

There isn't a WordPress core function to check if we are in the login or register page, but we can create one using the $pagenow global as mentioned in this answer.

function is_login_page() {
    return in_array( $GLOBALS['pagenow'], array( 'wp-login.php', 'wp-register.php' ) );
}

Then we can use this function in a Guard Clause, which, is a nice way to avoid nested conditionals:

function my_redirect_function() {

    // exit early if is in admin site or login/register pages
    if ( is_admin() || is_login_page() ) {
        return;
    }

    // check for a specific capability is a better practice as we can have
    // a more granular control of who can or can't do something
    if ( !current_user_can( 'manage_options' ) ) {
        // do your thing in here
    }
}

I hope it helps. Please note that I checked for a specific capability instead of a role because it allows a more granular control of who can or can't do something.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.