WordPress/WC session not carried to next page

Viewed 8123

Simply trying to store and retrieve unregistered customer data from page to page in a custom checkout template. I've stripped it down to the bare bones to try to pinpoint the issue.

This

<?php
    $customer = WC()->customer;
    $customer->set_billing_first_name("WORKING!!!");
    $customer->save();
    var_dump($customer->get_billing());
?>

Outputs this

array (size=2)
'country' => string 'US' (length=2)
'first_name' => string 'WORKING!!!' (length=10)

But then this

<?php
    $customer = WC()->customer;
    //$customer->set_billing_first_name("WORKING!!!");
    //$customer->save();
    var_dump($customer->get_billing());
?>

Outputs this

array (size=1)
'country' => string 'US' (length=2)

Even though I should still be firmly within the same session, and therefore should get the data stored before the comments. All I did was refresh the page after commenting out those two lines.

Am I completely wrong about these methods?


Checked

  1. Environment is configured entirely correctly. Even had someone else double-check it for me. URLs, caches, etc.

  2. It does appear to work when logged in, but the vast majority of users never do so that's not very helpful.

  3. Have tried this on two different servers (one local, one remote) and have the same issue.

  4. Started fresh with a new WP+WC install, created a blank theme, functions.php that does the above on init code. Same exact issue.

2 Answers

If $customer->save() doesn't persist the changes you made to the customer's data (e.g. $customer->set_billing_first_name('Test')), then it's likely because the customer is not registered to the site or not logged-in, where $customer->get_id() is 0.

And that is normal because the user's ID or the session's ID is required in order to properly save the changes and make it persistent across different pages.

So when the user is not registered/logged-in, WooCommerce doesn't start its session until the user logs in, or that he/she added a product into the cart.

But you can manually start the session, like so: (add the code to the active theme's functions.php file)

add_action( 'woocommerce_init', function(){
    if ( ! WC()->session->has_session() ) {
        WC()->session->set_customer_session_cookie( true );
    }
} );

And then, changes to the customer's data would then be carried on to other pages so long as cookies are enabled on the browser, because just like WordPress, WooCommerce stores its session ID (the user ID or an auto-generated ID/hash) in the cookies — and the session ID is used to set/retrieve the session data in the database — the table name is woocommerce_sessions if without any table prefix.

Try this after starting the WooCommerce session:

$customer = WC()->customer;
// Change 'Test' if necessary - e.g. 'Something unique 123'
if ( 'Test' !== $customer->get_billing_first_name() ) {
    $customer->set_billing_first_name( 'Test' );
    echo 'First name added to session<br>';
} else {
    echo 'First name read from session<br>';
}

And this one — you should see a new date on each page load: (well, the one you've set previously)

echo WC()->session->get( 'test', 'None set' ) . '<br>';
WC()->session->set( 'test', current_time( 'mysql' ) );
echo WC()->session->get( 'test', 'It can\'t be empty' );
Related