Search code examples
wordpresswordpress-hookwordpress-action

WordPress: how to get the full path on 'init' hook? or is it another hook preferable?


I would like to redirect users if they are not administrators, and I do within an add_action('init'... function

However, I would like NOT to redirect users if the URL path is something like /wp-json(v1/... (so not a user but a custom REST API request)

How could I grab the requested URL and decide on that? Should I do this within the init hook?

        function redirect_users()
        {

            global $wp;
// $url = get_url();
// if ($url === 'whatever') {
//  return;
// }

            if (get_current_user_id()) {
                $user = get_userdata(get_current_user_id());
                $user_roles = $user->roles;
                if (!in_array('administrator', (array) $user_roles)) {
                    wp_logout();
                    wp_redirect($url);
                    exit;
                }
            }
        }
        add_action('init', '\kw_signup\redirect_non_admin_users', 15);

From the accepted answer

            if (!preg_match('/^wp-json\//', $wp->request)) {
                if (!get_current_user_id()) {
                    wp_redirect($url);
                    exit();
                }
                if (get_current_user_id()) {
                    $user = get_userdata(get_current_user_id());
                    $user_roles = $user->roles;
                    if (!in_array('administrator', (array) $user_roles)) {
                        wp_redirect($url);
                        exit();
                    }
                }
            }
        }
        add_action('parse_request', '\kw_signup\redirect_non_admin_users', 15);

I works with the hooks parse_request or template_redirect, with the former you receive the wp object as an argument


Solution

  • How could I grab the requested URL and decide on that?

    To get the requested URL, you could use the $_SERVER superglobal. Though, in your situation, I'd prefer to use $wp->request, which includes the path part of your URL.

    Should I do this within the init hook?

    I'd say the most appropriate hook for redirects is template_redirect.

    So, putting it all together:

    <?php
    namespace kw_signup;
    
    add_action( 'template_redirect', __NAMESPACE__ . '\redirect_non_admin_users' );
    
    function redirect_non_admin_users() {
      global $wp;
    
      // Check if the requested URL does not start with a specific string
      if ( ! preg_match( '/^wp-json\//', $wp->request ) ) {
        // URL is not a custom REST API request
        // Check if user is an administrator, redirect, …
      }
    }