Forum Replies Created

Viewing 10 replies - 1 through 10 (of 10 total)
  • Thread Starter arnolp

    (@arnolp)

    HPOS is around till 2023
    HPOS is enabled by default for new installations from WooCommerce 8.2 onward
    non-HPOS is being phased out, so having a “non-hpos-compatible” plugin is becoming a critical bug,
    Please hurry up

    Thread Starter arnolp

    (@arnolp)

    Additional technical information

    The issue probably occurs in the add_to_cart_items() method in class-wooco.php. When adding component products, each call to WC()->cart->add_to_cart() triggers an intermediate session save via WC_Cart::set_session(), which stores an incomplete cart state.

    // class-wooco.php, line ~1162
    foreach ( $items as $item ) {
        // This triggers WC()->session->set('cart', ...) internally
        $item_key = WC()->cart->add_to_cart( $item_id, $item_qty * $quantity, ... );
        
        // wooco_keys is updated AFTER the session save already happened
        WC()->cart->cart_contents[ $cart_item_key ]['wooco_keys'][] = $item_key;
    }

    Probable problem flow:

    1. User adds composite → woocommerce_add_to_cart hook fires
    2. add_to_cart_items() loops through components
    3. First component added → WC()->cart->add_to_cart() → triggers set_session()
    4. Session now contains cart with incomplete wooco_keys array
    5. More components added, each triggering session saves with different incomplete states
    6. On shutdown, WC_Session_Handler::save_data() saves the final $this->_data
    7. Due to timing/HPOS interactions, $this->_data['cart'] may contain stale/empty data

    Clues

    • Manual $wpdb->replace() successfully persists complete cart data
    • WooCommerce’s save_data() on shutdown overwrites it with empty/corrupted data
    • Setting WC()->session->_dirty = false via reflection after manual save prevents the corruption

    This probably indicates the issue is not with serialization itself, but with what data is being serialized – WooCommerce is saving an incomplete/empty cart state.

    Thread Starter arnolp

    (@arnolp)

    Update :
    the fix above is NOT working properly

    Root Cause:

    When ⁠WC()->session->save_data() is called with HPOS enabled and a composite product in cart for anonymous users, it writes empty/corrupted session data instead of the actual cart contents. This happens silently without errors.

    Evidence:

    • Manual ⁠$wpdb->replace() successfully writes composite data

    But WooCommerce’s ⁠save_data() on shutdown overwrites it with empty data Setting ⁠_dirty = false after manual save prevents the corruption

    Workaround:

    Manually save session and mark it as “clean” to prevent WooCommerce from re-saving with corrupted data.

    I don’t know if it’s related or not to a WooCommerce HPOS bug
    Maybe, or not, should you Explicitly call manual session save for anonymous users with HPOS
    At least that fixed the issue for me :

    <?php
    /**

    • Fix: WooCommerce HPOS session corruption with composite products for anonymous users
      • Issue: WC()->session->save_data() writes corrupted/empty data when cart contains
    • composite products for anonymous users with HPOS enabled.
      • Solution: Manually save session and prevent WooCommerce from overwriting it.
        */
        add_action(‘woocommerce_add_to_cart’, function($cart_item_key, $product_id) {
        // Only for anonymous users
        if (is_user_logged_in()) {
        return;
        }
      // Check if cart contains composite product
      $has_composite = false;
      foreach (WC()->cart->get_cart() as $item) {
      if (isset($item[‘wooco_ids’])) {
      $has_composite = true;
      break;
      }
      } // Only apply fix if composite is in cart
      if (!$has_composite) {
      return;
      } // Manually save session to database
      global $wpdb; $session_id = WC()->session->get_customer_id();
      WC()->session->set_customer_session_cookie(true); $cart_for_session = WC()->cart->get_cart_for_session(); $session_data = array(
      ‘cart’ => serialize($cart_for_session),
      ‘cart_totals’ => maybe_serialize(WC()->cart->get_totals()),
      ); $session_value = maybe_serialize($session_data);
      $session_expiry = time() + (60 * 60 * 47); $wpdb->replace(
      $wpdb->prefix . ‘woocommerce_sessions’,
      array(
      ‘session_key’ => $session_id,
      ‘session_value’ => $session_value,
      ‘session_expiry’ => $session_expiry,
      ),
      array(‘%s’, ‘%s’, ‘%d’)
      ); // Prevent WooCommerce from overwriting our save with corrupted data
      $reflection = new ReflectionObject(WC()->session);
      $dirty_prop = $reflection->getProperty(‘_dirty’);
      $dirty_prop->setAccessible(true);
      $dirty_prop->setValue(WC()->session, false);

    }, 99, 2);

    arnolp

    (@arnolp)

    Funny @cochwbc I was in the middle of going the same way, using hook woocommerce_package_rates
    I had rather the idea of using a mockup deactivated Flexible Shipping provider, and looking up how I can programatically retrieve the weight+price list


    arnolp

    (@arnolp)

    Indeed you can’t without subscribing to their service
    Once configured on their side, Their plugin injects a new delivery method for pickup , that handles the pickup point selection on a map

    Flexible shipping option shows, like on any delivery method, but values are not saved.
    https://share.cleanshot.com/JZZwpfSx

    I guess your only options are

    • figure out blindly why options might not be saved, to avoid frustration

    I will also contact them and direct them to this ticket

    • This reply was modified 12 months ago by arnolp.
    arnolp

    (@arnolp)

    It’s a free plugin
    https://wordpress.org/plugins/sendcloud-shipping/
    for a paid shipping service (tags generation, tracking, ..)
    In fact they do promotion of your plugin https://www.sendcloud.com/woocommerce-shipping/

    right now, it’s a critical bug. I just spent dozens of minutes setting up “flexible shipping” shipping table for it not to be saved, in the standard flexible shipping interface of this Service Point Delivery shipping method created by sendcloud.

    Thread Starter arnolp

    (@arnolp)

    PHP Fatal error: Uncaught Error: Call to undefined function show_message() in wp-content/plugins/e-transactions-wc/class/wc-etransactions-encrypt.php:154
    Stack trace: 0 wp-content/plugins/e-transactions-wc/class/wc-etransactions-encrypt.php(192): ET_ransactions_Encrypt->_decrypt(’97e43175a032927…’, ’05e2eb599d32d0c…’, ‘\x81\xB9\xCB\xC8\xDC\xD6\x8F\xDE_BXS\xF9<\x05…’) 1 wp-content/plugins/e-transactions-wc/trait/wc-etransactions-config-get-options.php(112): ET_ransactions_Encrypt->decrypt(‘\x81\xB9\xCB\xC8\xDC\xD6\x8F\xDE_BXS\xF9<\x05…’) 2 wp-content/plugins/e-transactions-wc/class/wc-etransactions.php(682): WC_Etransactions_Config->getHmacKey() 3 wp-content/plugins/e-transactions-wc/class/wc-etransactions.php(404): WC_Etransactions->signValues(Array) 4 wp-content/plugins/e-transactions-wc/class/wc-etransac” while reading response header from upstream, client: 2a01:cb19:ddf:ec00:84bd:3e67:9d4c:26e7, server: xx.com, request: “GET /checkout/order-received/13490/?key=wc_order_27vCDkYsL3ieE&order-pay=13490 HTTP/2.0”, upstream: “fastcgi://unix:/var/run/php8.1-fpm-casaalberta.sock:”, host: “xx.com:35723”, referrer: “https://xx.com/checkout/&#8221;

    C’est une honte, on est pas sur une asso bénévole, le CA gère 8,26 milliards d’euros de bénéfice net par an et n’est pas foutu de mettre un support client et 2 devs compétents pour respecter les petits ecommercants qui essayent de créer leur activité ecommerce ..

    en témoigne l’absence totale de réaction aux messages précédents, comme probablement à celui là.
    L’équipe derriere devrait avoir honte , et changer de métier.

    Thread Starter arnolp

    (@arnolp)

    Hi John,
    thank you very much for quick reply and deploy !
    First issue : Perfect, ‘disc’ symbol is now displayed for li
    Second issue : well, I understand. I guess I don’t change type every day, so it’s a one-shot job to reedit all fields, not such a big deal, thanks anyway for investigating.

    – Arnaud

    Thread Starter arnolp

    (@arnolp)

    Hi,

    The change I made recently was migrating to a child theme.

    I tried to downgrade to 3.1, it works fine.
    I tried to re-update to latest version .. and now it works fine again ?!
    I’m still doing addition tests to confirm there is no issue anymore.

    Thanks
    – Arnaud

    That’s a pain … have to disable auto save passwords on all my wordpresses just because of this settings page crap UX.
    Just add a button to validate instead !

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