3
votes

I've been tearing my hair out over this for two days, and every time I think I've solved it, it just pops up again.

In my header.php I have the following code for displaying the number of items in the cart, and a simple show/hide div displaying the items themselves, along with a total:

<a id="miniart" href="<?php echo WC()->cart->get_cart_url(); ?>" class="cart icon red relative">
    <div class="number bold">
        <?php echo sprintf('%d', WC()->cart->cart_contents_count); ?>
    </div>

    <div>
        <?php returnIcon('cart');   // This function simply displays an inline SVG  ?>
    </div>

    <div id="cartcontents">
        <div class="widget_shopping_cart_content">
            <?php woocommerce_mini_cart(); ?>
        </div>
    </div>
</a>

I also have a filter to return the cart fragments via AJAX when a new item is added:

function woocommerce_header_add_to_cart_fragment($fragments) {

    ob_start();

    ?>
        <div class="number bold">
            <?php echo sprintf('%d', WC()->cart->cart_contents_count); ?>
        </div>

    <?php

    $fragments['#minicart .number'] = ob_get_clean();

    return $fragments;
}

add_filter('woocommerce_add_to_cart_fragments', 'woocommerce_header_add_to_cart_fragment');

The filter always works - I've never had a problem with that. What's totally throwing me is that the standard, pre-processed calls in the header (cart_contents_count & woocommerce_mini_cart()) seem to be totally cached. If I add a new item, the AJAX will update both to display 1 and the actual item added; but if I change the page or refresh, it defaults back to 0 and No items. If I go to my cart, despite the mini-cart still saying I have nothing, the actual cart page displays the cart contents correctly.

It only appears to update if I go to my cart page and delete something from my cart; for example, if I've actually got 7 items in my cart but the minicart displays 0, and then delete an item from my cart, suddenly the minicart will corectly display 6. However, from that point it will stay at 6, even if I add another dozen items.

Here's what I've tried:

  • Change the classes/IDs of the elements (i,e, #minicart to #tinycart, etc.) - works once, then immediately starts caching again.
  • Turned off the filters: This has no effect, since the filter is only for returning fragments when new items are added. Also worth noting that there doesn't appear to be any kind of AJAX call fired at page load that would interfere with the minicart display.
  • Turned off all plugins except WooCommerce: made no difference.
  • Turned off 'Enable AJAX add to cart buttons on archives' in WC settings: This kinda works, insofar as it reloads the entire page when an item is added, and the minicart displays number of cart items correctly (hooray!), but obviously disables the ability to add items via AJAX, which is a requirement of the site (boo.)
  • Deleting my own mini-cart.php template file: Just in case, to see if that was an issue. Made no difference.
  • Putting the woocommerce_mini_cart() function literally anywhere else: This, infuriatingly, works. If I take this function and the echo sprintf('%d', WC()->cart->cart_contents_count) line and put them anywhere - within the header, within the page body, even inside the same element that's getting 'cached', they work. They display the correct number of items, and the correct list of items. But the other calls to this function, as noted above, still appear to be cached.

As noted, this occurs even with no other plugins running; it happens both locally (a completely standard XAMPP installation on Windows) and remotely (a niftier nginx setup, slightly newer PHP version), and neither have any kind of caching enabled.

Any suggestions would be very gratefully received, as I have totally lost my mind on this one.

1

1 Answers

3
votes

A bit late but I tried your code and it worked for me with some small modifications. I have changed the a id from miniart to minicart and commented out the returnIcon

<a id="minicart" href="<?php echo WC()->cart->get_cart_url(); ?>" class="cart icon red relative">
                    <div class="number bold">
                        <?php echo sprintf('%d', WC()->cart->cart_contents_count); ?>
                    </div>

                    <div>
                        <?php //returnIcon('cart');   // This function simply displays an inline SVG  ?>
                    </div>

                    <div id="cartcontents">
                        <div class="widget_shopping_cart_content">
                            <?php woocommerce_mini_cart(); ?>
                        </div>
                    </div>
                </a>

Another change was to rename woocommerce_header_add_to_cart_fragment to wif_woocommerce_header_add_to_cart_fragment

    function wif_woocommerce_header_add_to_cart_fragment($fragments) {

    ob_start();

    ?>
    <div class="number bold">
        <?php echo sprintf('%d', WC()->cart->cart_contents_count); ?>
    </div>

    <?php

    $fragments['#minicart .number'] = ob_get_clean();

    return $fragments;
}

add_filter('woocommerce_add_to_cart_fragments', 'wif_woocommerce_header_add_to_cart_fragment');