Getting redirect to happen before header output

Anyone know of a way to trick WordPress into doing a header location redirect. I have to check whether users are logged in or not, and if not redirect them to our organizations authorization system which is an external site.

I am getting output before my header() call, from WordPress outputting the queued scripts.

Read More
Warning: Cannot modify header information - headers already sent by (output started at /.../wp-includes/class.wp-scripts.php:128) in ...

I have a plugin, that had a class handler, that handles this with this method:

...
public function populateInfo($form) {
    $email = $this->hasEmail($form);
    /*$name = $this->hasName($form);
    $address = $this->hasAddress($form);
    $phone = $this->hasPhone($form);*/

    // let's get some auth info
    if($email !== false || $name !== false || $address !== false || $phone !== false) {
        $ldap = new LDAP();
        $webAuth = new Auth();
        $curPage = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
        $webAuth->url = $curPage;
        if($webAuth->isLoggedIn()) {
            $ldap->search($webAuth->getID());

            // set up form variables
            $form['fields'][$email['key']]['defaultValue'] = $ldap->getEmail();
        } else {
            // this is where redirect fails
            wp_redirect($webAuth->login_url);
            return;
        }
    }

    return $form;
}
...

Update:

This method is called via a GravityForms filter:

add_filter('gform_pre_render', array($this, 'populateInfo'));

Which basically loads up info into a page form. The user must be logged in, in order for this form to populate (thus the $webAuth->isLoggedIn() check). Obviously I am aware that the headers are being output beforehand, my question is, how to properly workaround this in WordPress, so that I can redirect unauthorized users to the log in, without being brick-walled by preceding headers?

Related posts

4 comments

  1. Your method is called too late. I don’t know how you call this method but you need to run it before output is sent to the browser– usually that means before get_header(). There are a number of hooks that can be used. For example (from https://wordpress.stackexchange.com/a/131210/21376):

    add_action(
      'template_redirect',
      function() {
        if (is_single()) {
          wp_safe_redirect(home_url());
          exit;
        }
      }
    );
    

    Without more context, it is impossible to say exactly what the right hook is.

  2. I don’t know anything about Gravity Forms, but it’s hard to believe there isn’t an earlier hook you can use to put the redirect logic. It might force you to change some of the code, dig through source code, etc, but it’s really a logic problem on your end.

    Having said that, there is a workaround which I personally would advise you not to use, but it might work until you have more time to look into the problem. It’s called output buffering: you basically ask PHP to hold onto the output until you tell it to ‘release’ it — namely, after you’ve exhausted all possible redirections. It has many caveats, so be advised.

    You might put something along these lines on your theme’s functions.php:

    add_action('init', 'my_prefix_start_buffer');
    function my_prefix_start_buffer() {
        ob_start();
    }
    
    add_action('wp_footer', 'my_prefix_flush_buffer');
    function my_prefix_flush_buffer() {
        ob_end_flush();
    }
    

    I’m assuming gform_pre_render is triggered after init and before wp_footer, but you might have to adjust accordingly.

    With more info, we’d might be able to give you a better answer.

  3. The primary issue you are most likely encountering is not calling your function soon enough in the WP load process. This depends on what action hook you are using to call your function. See the WordPress Action reference for the appropriate order.

    One other comment on your code, you should call exit; instead of return; after wp_redirect(); as per the WordPress Codex

    EDIT: To clarify the action reference stuff, the more context you can provide about when, where and how your function is called the more help everyone can be!

  4. The correct hook to use is template_redirect which allows you to have the necessary info available to do checks while also early enough to actually redirect. As per the example on the codex page:

    function my_page_template_redirect()
        {
        if( is_page( 'goodies' ) && ! is_user_logged_in() )
        {
            wp_redirect( home_url( '/signup/' ) );
            exit();
        }
    }
    add_action( 'template_redirect', 'my_page_template_redirect' );
    

    Codex page here – template_redirect

Comments are closed.