• Resolved denisgomesfranco

    (@denisgomesfranco)


    Recently Woocommerce launched the 10.1 update and in this version they changed the way user carts for logged in users are stored. Previously, carts were saved in the usermeta table but now they are saved in the woocommerce_sessions table.

    This is a change aimed at improving store performance but it caused some issues in specific scenarios. The issues are being reported here: https://github.com/woocommerce/woocommerce/issues/60392 and I even commented about my specific scenarios.

    But as for the User Switching plugin, I’m experiencing lost carts when switching to an user. I understand this is probably a problem with Woocommerce and not the plugin, but I’d like to report it anyway so you’re aware of what is going on. I tested it like this: I log in to a user, then add some products, then log back to the admin user, then log back in to the user, the cart is gone.

Viewing 15 replies - 1 through 15 (of 15 total)
  • Plugin Author John Blackbourn

    (@johnbillion)

    WordPress Core Developer

    Thanks for the report. Let’s keep an eye on that WooCommerce issue and see if it ends up being resolved. There seem to be a few issues related to that change.

    Joan

    (@jllorca)

    Hi, I’m also experiencing the same issue described by Denis.

    If you still have the cart data available in the persistent cart, you can use the following snippet to restore it and move the lines back into the session cart:

    add_filter('woocommerce_persistent_cart_enabled', '__return_true');

    add_action('woocommerce_cart_loaded_from_session', function($cart) {
    if ( ! is_user_logged_in() || ! function_exists('WC') ) {
    return;
    }

    $user_id = get_current_user_id();

    // If the session cart already has items, do nothing.
    if ( ! $cart->is_empty() ) {
    return;
    }

    $key = '_woocommerce_persistent_cart_' . get_current_blog_id();
    $saved = get_user_meta($user_id, $key, true);

    if ( empty($saved) || empty($saved['cart']) || ! is_array($saved['cart']) ) {
    return;
    }

    WC()->cart->empty_cart(true);

    foreach ( $saved['cart'] as $item ) {
    $product_id = isset($item['product_id']) ? (int) $item['product_id'] : 0;
    $variation_id = isset($item['variation_id']) ? (int) $item['variation_id'] : 0;
    $quantity = isset($item['quantity']) ? (int) $item['quantity'] : 1;
    $variation = isset($item['variation']) ? (array) $item['variation'] : [];

    $cart_item_data = $item;
    unset($cart_item_data['product_id'], $cart_item_data['variation_id'], $cart_item_data['quantity'], $cart_item_data['variation'], $cart_item_data['data_hash']);

    if ( $product_id > 0 && $quantity > 0 ) {
    WC()->cart->add_to_cart($product_id, $quantity, $variation_id, $variation, $cart_item_data);
    }
    }

    WC()->cart->calculate_totals();
    }, 20);

    After adding the snippet, you need to switch to the user account that lost the cart, and the cart data should be restored.

    Once you’ve recovered the data, I recommend removing this snippet and also disabling the “Switch To” plugin until a proper fix for this issue is released — or alternatively, avoid switching to another user in the meantime.

    For reference, here’s a link to the latest changes related to cart handling on GitHub:

    https://github.com/woocommerce/woocommerce/pull/57961

    • This reply was modified 10 months ago by Joan.
    Thread Starter denisgomesfranco

    (@denisgomesfranco)

    Hey @jllorca , thanks for the snippet!

    However please note that it loads a cart from the woocommerce_sessions table, the problem we are having with Woocommerce is that it is actually wiping out the data in that table for that user. That is, the persistent cart that should never be erased from the table, is being erased somehow.

    We are discussing this problem in this thread.

    Plugin Author John Blackbourn

    (@johnbillion)

    WordPress Core Developer

    Does the issue occur if you manually log in and out between your admin account and your customer?

    This doesn’t sound like it’s specific to User Switching but I’m not yet sure (I’ll keep this issue open anyway while the issue is investigated).

    Thread Starter denisgomesfranco

    (@denisgomesfranco)

    Yes I’m almost sure this isn’t your plugin’s fault. This issue also happens if I log out the user via WordPress’ users screen, and it’s been happening randomly for users even in normal usage. See my linked thread.

    I’m having the same problem here. WooCommerce now handles orders/sessions differently. A shopping cart created with the Switch User plugin is no longer permanently saved to the user (as it used to be). I think it will stay this way. WooCommerce won’t change this.

    Thread Starter denisgomesfranco

    (@denisgomesfranco)

    @mojoclub A user on Github said he downgraded to 10.0.4 in the meantime. Woocommerce says the change is due to enhancing store performance, which I believe. But the core of the problem is that something that should be treated as permanent is being treated as disposable by WordPress and/or Woocommerce. At least that’s my impression of the issue.

    Hi @johnbillion

    Steps to reproduce the issue

    • In an incognito window, log in with a customer role account, browse the shop, add items to the cart, and then log out.
    • Check the session_key record for the same customer (user_id) in the wp_woocommerce_sessions table. Inside the session_value, you will see the data structure containing the items you added to the cart.
    • Now log in with your administrator account and use the “Switch To” function to switch into the same customer account.
    • At this point, the cart appears empty. If you check the session_value again, you’ll notice that the cart item data has disappeared.

    If you don’t use “Switch To” and simply log in as the customer directly, the cart data is preserved (until the session naturally expires).

    Thread Starter denisgomesfranco

    (@denisgomesfranco)

    @jllorca Same thing happens if you log in with a customer account in an incognito window, and with the admin dashboard open in the main window you go to WordPress users, then find the customer, then click the “Log out of all other sessions” button (which is a native function of WordPress).

    I was able to solve the problem by changing the forget_woocommerce_session which is hooked to both switch_to_user and switch_back_user actions. This method originally deletes the WooCommerce session for the user being switched to, resulting in the cart being cleared.

    The fix prevents WooCommerce from clearing the session when switching users. Instead of deleting the session, it transfers the WooCommerce session data from the old user to the new user during the switch. This way, the cart and other session data will persist across user switches.

    	/**
    * Preserves WooCommerce session data (cart, etc.) when switching users.
    * Instead of deleting the session, transfer it to the new user.
    */
    public function forget_woocommerce_session(): void {
    if ( ! function_exists( 'WC' ) || ! WC()->session ) {
    return;
    }

    $session_handler = WC()->session;
    // Get current session data
    if ( method_exists( $session_handler, 'get_session_data' ) ) {
    $session_data = $session_handler->get_session_data();
    } else {
    $session_data = [];
    }

    // Store session data in a temporary cookie for transfer
    if ( ! empty( $session_data ) ) {
    setcookie( 'user_switching_wc_session', wp_json_encode( $session_data ), time() + 60, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true );
    }

    // On switch, restore session data if available
    if ( isset( $_COOKIE['user_switching_wc_session'] ) ) {
    $restored_data = json_decode( stripslashes( $_COOKIE['user_switching_wc_session'] ), true );
    if ( is_array( $restored_data ) ) {
    foreach ( $restored_data as $key => $value ) {
    $session_handler->set( $key, $value );
    }
    }
    // Remove the cookie after restoring
    setcookie( 'user_switching_wc_session', '', time() - 3600, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true );
    }
    }

    @bzadmin Your solution works partially, because if I do a second “Switch to” for the same user, the cart is deleted.

    Plugin Author John Blackbourn

    (@johnbillion)

    WordPress Core Developer

    Here’s a bit of background info on what User Switching does when WooCommerce is active and why it does it:

    Years ago WooCommerce suffered from a problem where a user’s cart and other session information such as their tax region would get contaminated if another user logged into their account to manage their cart on their behalf. Back in 2019 I worked with the WooCommerce team to introduce a method that could be called by other plugins to instruct WooCommerce to “forget” the current session and cart contents, which means the session and cart remain in place but the connection to them are forgotten by the browser.

    User Switching calls this method when switching between users. This allows the safe switching between users and eliminates a whole class of bug reports about session and cart contamination.

    WooCommerce 10.1 has switched to storing cart info in the WooCommerce session. I’ve yet to investigate exactly what this change means and how it affects the cart.

    Recent comments on the WooCommerce issue indicates that this change might get reverted. We’ll need to wait and see.

    Looks like WooCommerce might have rolled back the cart change.

    Thread Starter denisgomesfranco

    (@denisgomesfranco)

    Yes they rolled it back and testers said that the User Switching plugin is working correctly now.

    Plugin Author John Blackbourn

    (@johnbillion)

    WordPress Core Developer

Viewing 15 replies - 1 through 15 (of 15 total)

The topic ‘Possible problem with empty carts in Woocommerce 10.1’ is closed to new replies.