Support » Plugins » Hacks » Making woocommerce session cookie expiring on php session ending

  • I’m working on creating (maintaining actually) a plugin which allow users to create movies.

    This plugin contains many pages. The previous developer used $_SESSION to store datas about the movie creation (images, sound, texts etc) during the process in order not to lose it on the way.

    When the movie is crafted, a virtual product is added to the cart for the created movie. At this moment, woocommerce creates a cookie to store the cart session.

    The problem is that on one side, I now have a $_SESSION containing the datas to use to create the final movie once the user would pay for the order, and on the other hand a cart cookie which handles the cart. And both $_SESSION and woocommerce cookie haven’t the same life time circle : $_SESSION is 1440 seconds starting from the moment the user stops using the website, the woocommerce cookie has a 48 hours long lifetime.

    **My goal is to destroy woocommerce session if my $_SESSION is expired.**

    But many problems are appearing :

    1 – When I want to test if $_SESSION, it is not returned at all in the debug console from phpstorm, whereas I’m able to print it out.
    2 – Session_id() never returns any ID whereas I’m able to get the PHPSESSID cookie name and value.
    3 – Using WC_Session_handler object to check if woocommerce session exists thanks to has_session method, returns false whereas a wp_woocommerce_session cookie exists.

    I’m using both xdebug in phpstorm and google chrome web dev inspector to check out my variables, but still there is something missing to me.

    Here above, my piece of code which is fired on plugin init. I also tried to put it in wp-config.php but still the same :

    // get the current session.gc_maxlifetime for debug
    $session_lifetime = ini_get(‘session.gc_maxlifetime’);
    // Check if a wp_woocommerce_session cookie exists
    if (isset($_COOKIE)) {
    // Get woocommerce cookie
    foreach ($_COOKIE as $key => $value) {
    if (strstr($key, ‘wp_woocommerce_session’)) {
    // The cookie exists, store it as an array to use it later
    $cookieId = $key;
    $cookie[$cookieId] = explode(‘||’, $value);
    }
    }
    // if no session id is defined, and a woocommerce cookie is,
    // trash the woocommerce cookie and set a default session.gc_maxlifetime to 48h
    // else use the current cookie expire time as default session.gc_maxlifetime (cookie expire – time)
    if ( !session_id() && isset($cookie[$cookieId][1])) {
    setcookie($cookieId, “”, time() – 48 * 3600);
    $session_lifetime = 48 * 3600;
    } elseif ( session_id() && isset($cookie[$cookieId][1])) {
    $session_lifetime = $cookie[$cookieId][1] – time();
    } else {
    $session_lifetime = 48 * 3600;
    }
    }
    // define the definitive session.gc_maxlifetime and start the session
    ini_set(‘session.gc_maxlifetime’, $session_lifetime);
    session_set_cookie_params($session_lifetime);
    session_start();

    Thanks for helping me out

    EDIT : I’m not allowed to create a cookie as it would be time consuming, budget matter…

Viewing 2 replies - 1 through 2 (of 2 total)
  • I finaly drastically changed the way to initialize this piece of code.

    First of all, I created an action in my theme functions.php file, then initialized a default session lifetime value.

    Checking the $_SESSION['user'] instead of session_id() was worse doing the job, then I used it instead.

    The last thing which was making things breaking out, was the call of WC_Session_Handler class, which initilizes different actions on the session when instanciated. I then decided to rely on the $_COOKIE superglobale to get the informations I needed to get things done.

    Still some elements remain unknown, like why my $_COOKIE[‘wp_woocommerce_session_HASH’] expiration is not set to 48h ? I’m still investigating.

    By the way, here is the final piece of code. I know this is a bit dirty, so I stay open to any advices.

    
        /**
         * Init session
         */
        add_action('init', 'nm_session_init', 10);
        function nm_session_init()
        {
            // define a default session duration
            $session_lifetime = DAY_IN_SECONDS * 2;
            $session = $_SESSION;
            $time = time();
        
            // get woocommerce session cookie if exists
            if ( isset($_COOKIE) ) {
        
                foreach ($_COOKIE as $key => $value) {
                    if ( strstr($key, 'wp_woocommerce_session')){
                        $cookie = explode('||',$value);
                        $cookie[1] += DAY_IN_SECONDS * 2;
                    }
                }
        
                // Check check if a wp_woocommerce_session cookie exists and > current timestamp
                // if no session user is defined, and a woocommerce cookie is,
                // trash the woocommerce cookie
                if (isset($cookie[1]) && $cookie[1] > $time) {
                    if (isset($session['user'])) {
                        $session_lifetime = $cookie[1] - $time;
                    }
                    else {
                        $sessionHandler = new WC_Session_Handler();
                        $sessionHandler->destroy_session();
                        $sessionHandler->cleanup_sessions();
                    }
                }
            }
        
            // define the definitive session.gc_maxlifetime and start the session
            ini_set('session.gc_maxlifetime', $session_lifetime);
            session_start();
        }
    

    EDIT : using global $woocommerce variable is the best choice to get the session cookie as if you instanciate a new WC_Session_Handler object, it will destroy the previous session cookie.

        /**
         * Init session
         */
        add_action('init', 'nm_session_init', 11);
        function nm_session_init()
        {
            global $woocommerce;
            $wc_session = $woocommerce->session;
            $cookie = $wc_session->get_session_cookie();
    
            // define a default session duration
            $session_lifetime = DAY_IN_SECONDS * 2;
            $session = $_SESSION;
            $time = time();
    
            // Check check if a wp_woocommerce_session cookie expiration exists and > current timestamp
            // if no session user is defined, and a woocommerce cookie is,
            // trash the woocommerce cookie
            if (isset($cookie[1]) && $cookie[1] > $time) {
                if (isset($session['user'])) {
                    $session_lifetime = $cookie[1] - $time;
                }
                else {
                    $sessionHandler = new WC_Session_Handler();
                    $sessionHandler->destroy_session();
                    $sessionHandler->cleanup_sessions();
                }
            }
    
            // define the definitive session.gc_maxlifetime and start the session
            ini_set('session.gc_maxlifetime', $session_lifetime);
            session_start();
        }
Viewing 2 replies - 1 through 2 (of 2 total)
  • The topic ‘Making woocommerce session cookie expiring on php session ending’ is closed to new replies.