14

I am trying to set cookies to re-route returning users to my a specific page within my Wordpress site.

I'd like some advice with these 2 things:

  1. Where in the Wordpress php files should cookies be checked before loading any content to handle a redirect? Is there a good file this should exist in over others?
  2. How do I properly set a cookie within Wordpress? setcookie('cookie_name', 'cookie_value', time()+4000); doesn't seem to be saving any cookies to my system.
5
  • 1
    Ah, realized I needed to hook this into the init(). SOLUTION: I created a function in functions.php that would set and check the cookie. for this to work properly, after defining the function, outside the function call this: add_action('init', 'function-name'); – Atticus Jul 2 '11 at 4:07
  • 4
    You are allowed to answer your own question... – 40XUserNotFound Jul 2 '11 at 4:12
  • 2
    In fact, it's explicitly encouraged. Please do answer it yourself. I'm also sending this to WordPress.SE, since it seems more appropriate there. – Michael Myers Jul 2 '11 at 4:49
  • Thanks guys -- i did not realize there was a Wordpress area. And thanks for the tip to answer myself :) APpreciated, +1s. – Atticus Jul 5 '11 at 4:34
  • Make sure you use the pre-baked cookie constants WordPress offers, check this article out for more info on how to set, get & delete cookies properly benmarshall.me/setting-cookies-in-wordpress – Ben Marshall Jul 31 '20 at 2:20
20

1 - You can check for cookies and do your redirect using hooks that are called before any output like the 'init' hook:

<?php

// Hook the function "redirect()" on to the "init" action
add_action('init', 'redirect');

// redirect() may redirect the user depending on the cookies he has
function redirect(){
  /* CODE */
}

?>

2 - The best way to set cookies would be using the 'init' hook like this:

<?php

add_action('init', 'my_setcookie');

// my_setcookie() set the cookie on the domain and directory WP is installed on
function my_setcookie(){
  $path = parse_url(get_option('siteurl'), PHP_URL_PATH);
  $host = parse_url(get_option('siteurl'), PHP_URL_HOST);
  $expiry = strtotime('+1 month');
  setcookie('my_cookie_name_1', 'my_cookie_value_1', $expiry, $path, $host);
  /* more cookies */
  setcookie('my_cookie_name_2', 'my_cookie_value_2', $expiry, $path, $host);
}

?>

This is more consistent, if you have a blog at www.example.com/blog, the coockie(s) will not be available at

  • www.example.com
  • www.example.com/store
  • example.com
  • www2.example.com
  • ...

Update

you should also be able to use the COOKIE_PATH and COOKIEDOMAIN constants rather than figuring them out yourself, which I just noticed in Andre R Kohl's answer – drzaus

5
  • How you you put multiple varibles, for example Firstname, LastName, Random1, Random2 instead of just the 'my_cookie_1' variable.? – Damainman Oct 27 '13 at 0:14
  • 1
    Just add more setcookie() – Nabil Kadimi Oct 27 '13 at 0:33
  • Oh, I didn't know cookies only hold one variable per cookie. Is there a way to set multiple cookies without needing to have the time and url code above so that it amounts to less code? Would they be put into a variable? – Damainman Oct 27 '13 at 0:34
  • 1
    you should also be able to use the COOKIEPATH and COOKIEDOMAIN constants rather than figuring them out yourself, which I just noticed in Andre R Kohl's answer – drzaus Dec 11 '15 at 20:07
  • correction: COOKIE_DOMAIN – drzaus Dec 11 '15 at 21:13
13

You probably should use the constants COOIKEPATH and COOKIE_DOMAIN, existing since WP 3.0

setcookie("your_cookie", $your_value, time()+3600, COOKIEPATH, COOKIE_DOMAIN);
7

Ah, realized I needed to hook this into the init().

SOLUTION: I created a function in functions.php that would set and check the cookie. for this to work properly, after defining the function, outside the function call this:

add_action('init', 'function-name'); 
1
  • this is not a solution, please add the full code of your function, furthermore hyphens in function names will not work. – Aurovrata Sep 11 '20 at 8:36
1

This way worked :

    add_action( 'init', 'function-to-setcookie' ); 

    function function-to-setcookie(){

        //use condition here , in which page you eant to set cookie
        //choose a page where you want the cookie to be set
        $pageurl = get_option('siteurl').'/set-cookie-page'; 

       // use a function to get current page url and use condition 
       //to match it with the desired page where you want to set cookie 
       if ( $pageurl === current_page_url() ) {
           setcookie( 'cookie_name', 'cookie_value', $expiryTime, $cookiepath, $siteurl );
         }

    }
3
  • 1
    Please fix your code formatting. – Jevuska May 27 '16 at 8:53
  • Also a small content about the source is really helpful. – bueltge May 27 '16 at 10:40
  • 1
    Dashes in function names definitely won't work. – alpipego Apr 10 '20 at 4:03
1

You will want to delete your cookie before any content is written to the page (before headers are sent).

To set the cookie, include the path, domain, and I also recommend setting the last 2 parameters to true ($secure and $httponly). You will also need to supply the same parameters to setcookie() when deleting, aside from the $expiry (which should be negative) and the $value (which should be empty '').

If you are passing json through the cookie, it seems like you need to base64_encode it as well, or it won't properly decode.

All of this should be done in a class so you can access the value of the cookie later on in your code. The class can be added to a plugin or functions.php.

Here is an example where we use a cookie to store an action response to then display it to the user after we redirect them:

class my_custom_class {

    const MY_COOKIE_NAME_JSON = 'my_cookie_name_json';
    const COOKIE_LIFETIME = 3600;

    private $cookie_value;

    function __construct() {
        // ensure you are deleting cookie before headers are sent
        add_action('init', [$this, 'process_cookie_json'], 10);
        // uses bootstrap alert to format return message
        add_filter('the_content', [$this, 'filter_the_content_in_the_main_loop'], 1);
    }
    
    static function some_action_that_sets_the_cookie($message, $response_type = 'success') {
        $responses = [];
        if (isset($_COOKIE[self::MY_COOKIE_NAME_JSON]))
            $responses = json_decode(base64_decode($_COOKIE[self::MY_COOKIE_NAME_JSON]));
        $responses[$response_type][] = $message;
        self::set_cookie_json($responses);
    }
    
    static function set_cookie_json(array $cookie_value) {
        setcookie(self::MY_COOKIE_NAME_JSON, base64_encode(json_encode($cookie_value)), time() + self::COOKIE_LIFETIME, "/", $_SERVER['HTTP_HOST'], true, true);
    }
    
    function process_cookie_json() {
        if (!isset($_COOKIE[self::MY_COOKIE_NAME_JSON]))
            return false;
        $this->cookie_value = json_decode(base64_decode($_COOKIE[self::MY_COOKIE_NAME_JSON]), true);
        setcookie(self::MY_COOKIE_NAME_JSON, '', -1, "/", $_SERVER['HTTP_HOST'], true, true);
        unset($_COOKIE[self::MY_COOKIE_NAME_JSON]);
    }

    function filter_the_content_in_the_main_loop($content) {
        if (!$this->cookie_value || !is_array($this->cookie_value))
            return $content;
        $alerts = [];
        foreach ($this->cookie_value as $response_type => $messages)
            $alerts[] = '<div class="alert alert-' . $response_type . '" role="alert">' . implode(PHP_EOL, $messages) . '</div>';
        return implode(null, $alerts) . $content;
    }

}

$my_custom_class = my_custom_class;

You can then set the cookie via:

my_custom_class::some_action_that_sets_the_cookie('the message');

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.