2

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.

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?

  • 4
  • Thank you for the suggestion. I've already dug through most of those, and they address the header issue, but don't address how to get the redirect to happen before headers are output. I know what that error means, I am in need of a solution. Can you show me which specific question of all of them would help me, please? – cj5 Feb 3 '14 at 17:23
  • Please elaborate where and how the method is called. – Rarst Feb 3 '14 at 17:53
  • I updated the question with more details. – cj5 Feb 3 '14 at 19:04
  • 2
    @Magne I did. I had to move the login check out of the gform_pre_render hook, and into another one called gform_enqueue_scripts, which occurs before the header output, therefore getting past my header output issue. – cj5 Jul 6 '15 at 17:04
5

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.

  • I added more details in the question. – cj5 Feb 3 '14 at 19:03
  • @ChrisWalsh : your edit doesn't change anything. You have to hook in before headers are sent. That isn't a WordPress limitation. It is a PHP/HTTP one. – s_ha_dum Feb 3 '14 at 19:08
  • Sorry! I can't get this answered elsewhere and being as it may that it involves WordPress and GravityForms hooks, this is the only venue, to which I can turn. – cj5 Feb 3 '14 at 21:46
  • @ChrisWalsh : you have the information you need. You must hook in before headers are sent. I provided an example of how that can be done. (Apparently, the Gforms hook is too late.) – s_ha_dum Feb 3 '14 at 21:59
  • Yes, I have the info, but it's not helping. Any other ideas? – cj5 Feb 3 '14 at 22:56
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.

  • 1
    Yeah I've tried that workaround, and it is dirty. Sadly that's not going to be an option. Yes, gfrom_pre_render is too late, unfortunately. More info? What exactly do you need to provide answer? I am limited by my organization's code sharing policies to offer up too much open code, so if you need specifics let me know what they are. – cj5 Feb 4 '14 at 23:27
  • What is Gravity Forms hooking into? At which point is the $form object instantiated? Can't you hook there? Can't you make the object a global variable somehow? If you can't share code, or are unwilling to debug along with us, we can't help you. Personally, I don't appreciate a company unwilling to show its code coming here and asking for our help. – Tomas Buteler Feb 5 '14 at 9:45
1

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!

  • Please add this as an edit, as it is part of your answer :) – fischi Feb 3 '14 at 18:02
  • Okay. I get that. I already tried add_action('init'), which to me seems to be the correct one, but it didn't take. I have also used exit() and die() after the wp_redirect() call, and I am still getting the header modification error. – cj5 Feb 3 '14 at 18:02
  • Okay, since you're getting info from the gform_pre_render function, you won't be able to change the action your function is called on unless you find another way to obtain that info. Ideally it would be no later than the template_redirect action, but as to how you would get your info, I am at a loss as I don't spend that much time with Gravity Forms. – David Feb 3 '14 at 18:34
0

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

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.