1

I have a simple function to set a cookie to the value of whatever parameter is attached. For example, if I visit http://example.com/?devsource=http://dev.example.com/ it should set the value of the devsourceurl cookie to http://dev.example.com/

This function works great in the WordPress admin, but I cannot get it to work on the front end. I even tried checking to see if headers were already sent at the init action and they weren't. Any ideas what could cause this? Here's the code:

function set_devsource_cookie() {
    if ($_GET['devsource']) {
        $value = $_GET['devsource'];
        setcookie("devsourceurl", $value, time()+3600, COOKIEPATH, COOKIE_DOMAIN, false );
        echo $_COOKIE["devsourceurl"]; /* echo cookie if set */
    }
}
add_action('init', 'set_devsource_cookie', 0);

Thanks for any help!

  • 1
    your code works fine for me as-is, the value is output on the 2nd request. note that you can't access the value of a cookie in the same request you set it. nothing WordPress-specific about that, that's how cookies work. – Milo Mar 27 '14 at 23:29
  • you also probably want some issets in there so you don't generate php warnings. – Milo Mar 27 '14 at 23:32
  • Yeah, i have an isset on the code I was working with, just tried to simplify it. Must be something wrong with my install... – Jeremiah Prummer Mar 27 '14 at 23:34
  • I'm still having trouble with this. Is there anything you know of that might interfere with the cookie being properly set? – Jeremiah Prummer Mar 27 '14 at 23:39
  • if you refresh the page twice with debugging enabled, do you still see Notice: Undefined index: devsourceurl in… on the page? try disabling all plugins and using a core-bundled theme to rule out any conflicts. – Milo Mar 27 '14 at 23:44
3
+50

Some things non-WordPress specific regarding cookies:

  • set cookie fails if some output has been done in the page
  • you can't access to coockie value in the same request you set it (as @Milo pointed out in a comment to OP)

Another general rule is better to use filter_input or filter_intput_array instead of direct accessing to super globals like $_GET or $_COOKIE.

As a direct consequence of the first thing I said (set cookie fails if some output) is better se cookie as soon as possible, and in WordPress even if 'init' is quite early, there are hooks that are earlier, if you are writing a plugin you can use 'plugin_loaded' if you are developing a theme you can use 'after_setup_theme'.

function set_devsource_cookie() {
  global $devsource;
  $get = filter_input( INPUT_GET, 'devsource', FILTER_SANITIZE_STRING );
  if ( ! empty( $get ) ) {
    $devsource = $get;
    setcookie( 'devsourceurl', $devsource, time() + 3600, COOKIEPATH, COOKIE_DOMAIN, false );
  } else {
    $cookie = filter_input( INPUT_COOKIE, 'devsourceurl', FILTER_SANITIZE_STRING );
    if ( ! empty( $cookie ) ) {
      $devsource = $cookie;
    }
  }
  // debug
  // die( '---------------------');
  // uncommenting previous line, the dashes must be the the absolutely first line
  // if there's something first, even an empty line the cookie can't be set!
}

// prefer this on plugin
// add_action( 'plugins_loaded', 'set_devsource_cookie', 0 );
add_action( 'after_setup_theme', 'set_devsource_cookie', 0 );

Now testing if the value was set on wp footer (just as example):

function test_devsource_cookie() {
  global $devsource;
  echo 'Devsource is: ';
  echo ! empty( $devsource ) ? $devsource : 'not set.';
  echo '<br>Set again to random uri: ';
  $random = strtolower( wp_generate_password( 6, FALSE, FALSE ) );
  $url = add_query_arg( array('devsource' => "http://dev.{$random}.com/" ) );
  echo '<a href="' . $url . '">Set</a>';
}

add_action( 'wp_footer', 'test_devsource_cookie' );

If this code does't work, likely something (a plugin, the theme) is output something on the page before the code runs, sometimes even an empty line before the <?php can make fail a cookie to be set, see the commented lines in my set_devsource_cookie function.

If you see some output on the page, disable all plugins and use a default theme, put my code in a plugin and only activate it: the code should work.

After that re-enable your theme and plugins one by one to find the culprit.

Last tip: when you need to pass urls as param to the url be sure to use urlencode, jus I do on my test_devsource_cookie function.

  • Awesome, thanks for this! I'll be testing in an hour or so and I'll let you know what I find. I suspect another plugin may be outputting content too early, as I can't even get plugins_loaded to work for me. – Jeremiah Prummer Mar 28 '14 at 13:18
  • I just opted to use js. Even with default templates and no plugins I couldn't get it to work. Thanks for your help and the great answer. It deserves the 50 rep. – Jeremiah Prummer Mar 31 '14 at 22:07

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.