Ryan seems to say here this module would solve the problem of shopping cart being shown to anonymous users even when the cart is empty.

I see 6.x-1.0-rc9 supports UC 2.0 now - so does it also already solve the above problem?

Thanks!

CommentFileSizeAuthor
#6 uc_ajax_cart_with_page_cache.patch1017 byteswimh
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

wimh’s picture

Category: support » feature

It doesn't seem so: the initial cart contents is sent along with the initial page (and is thus also in the page cache, with the same problems as before), the AJAX is only used to update the cart once you press an Add to cart button.

A possible solution here would be to always send an empty (invisible) cart block to anonymous users, and update it with the actual content (bypassing the original cart block's i-don't-like-the-page-cache override so you don't just get the "click here to view your cart" message) through the AJAX call directly on page load.

Does this make sense, and is anyone on this?

Erik Seifert’s picture

No this make sense ;- ). But after reload page, you have a cached content of cart ( click here to see cart ).

asak’s picture

Ohhh... this must be solved...

gsquirrel’s picture

Is there any working solution to this issue? - i have looked around on all the issue queues and documentation but seem to be going around in circles. Is it worth trying the dev version of this module? Anonymous user carts are necessary and am really trying to avoid turning off page caching as it makes the site a LOT slower.

But unfortunately it seems there is no other way - strange as it was suggested that this module was an alternative solution.

douglas.a.hatch’s picture

Subscribing to this thread. I've had to turn off page caching on my site to keep ajax cart working properly and I'd be very interested if someone comes up with a solution to this problem. Thanks!

wimh’s picture

Just to start things going I attached a very crude patch that does sort of what we'd need.
- Disable the cache checking in ubercart/uc_cart/uc_cart.module:uc_cart_block('view'), otherwise we'd never get anything other than the cache-safe "click here to view your cart" out of it.
- Reload the cache block content through AJAX immediately on page load. This updates the cart block contents to that for the current (anonymous or other) user.

Still to do:
- The cart contents sent with the complete page (and cached) now again show the cart contents for the wrong user (since the check in uc_cart_block('view') was removed). It's overwritten immediately by the AJAX stuff, unless JavaScript is disabled or the call fails. What should be done is that the initial page contains the safe version, while the load through AJAX gets the "unsafe" (actual) content. This might need an extra argument to uc_cart_block('view') or something...
- Some stuff to get the collapsible cart block back, and to remember the collapsed state so it behaves just like the normal cart block.
- When the cart block is empty, the AJAX callback can set the block contents to empty, but this doesn't completely hide the block (some borders and white space remain), so a

higher up would need to be hidden.

The first point will require a change in Ubercart core (unless we duplicate all of uc_cart_block('view') by calling and formatting uc_cart_get_contents() ourselves...).
The other two points are not that bad, they can probably be done in jquery.ajax.cart.js without too much difficulty.

douglas.a.hatch’s picture

Nice patch! I just applied it. Couple of observations:

1. There is a short lag between when the page loads and when the ajax call is made to update the cart. Therefore, the cart block flashes old, then new content. Is there anyway to avoid this?
2. The ajax call only seems to happen on my catalog/ pages. On all other pages, the cart block doesn't update. Did I do something wrong? Or is this to be expected?

Thanks!

asak’s picture

hey wimh - thanks for that!

as douglas mentioned above, this only works on certain pages. i don't user the catalog pages, but i noticed it works on product page, doesn't on others.

I tried manually calling jquery.ajax.cart.js from page.tp, but that didn't help.
tried using snippets of code for calling jQuery.getJSON( Drupal.settings.basePath + 'cart/ajax/update',{},updateAjaxCart);
but can't get it working...
I wonder what else must happen for this to function on all pages...

Clues anyone? ;)

Erik Seifert’s picture

I changing forms with following ID's:

uc_product_add_to_cart_form_NODE_ID
uc_catalog_buy_it_now_form_NODE_ID
uc_product_table

It could be that somehting has changed.

j0rd’s picture

Since I don't really know how to replicate this "anonymous ghost cart" bug, could someone please explain in plain english if/how I can resolve this problem using uc_ajax_cart.

I noticed there's a bunch of options related to caching in the block settings, but I'm unclear which I should be setting to resolve the issue, or if it can even currently be fixed with -rc9. I couldn't find any documentation on this.

Are these options here to help?
Rebuild cart cache.
Rebuild cart cache on every ajax call.

Clear cart cache on every ajax call.
With this option enabled, cart content is rebuilded every request.

j0rd’s picture

I've avoided the caching issue by doing this.

in js/jquery.ajax.cart.js

      jQuery.getJSON( Drupal.settings.basePath + 'cart/ajax/update',d,updateAjaxCart);
    return false; 
  });
  // Added this line as per patch #6
  jQuery.getJSON( Drupal.settings.basePath + 'cart/ajax/update',{},updateAjaxCart);
})

function showAjaxCartMessage(content)

in my themes template.php

function mytheme_uc_cart_block_summary($item_count, $item_text, $total, $summary_links) {
  // We have to do this to make sure that jquery.ajax.cart.js is loaded each time the cart is.
  if(module_exists("uc_ajax_cart")) {
    _uc_ajax_cart_load_res();
  }
}

I've made a bunch of other changes in uc_ajax_cart, but I believe this is all that's needed to get your anonymous cache loading on every page. This also avoids the uc_cart.module core modification from patch #6

EDIT: This solution requires that you do not check "hide block when cart is empty"

keesje’s picture

It could be me, but why is uc_cart block cached with the page? Doesn't page caching mean ontly the $content var is cached? Or the whole rendering of page.tpl.php? If the latter, why does D6 have a separate "block cache" anyway??

Why can't this block play nice with: Block Cache Alter, http://drupal.org/project/blockcache_alter
This module makes it possible to rule out blocks from being cached.

The JS cart solutions might be usefull combined with static cache methods like Boost.

Edit: just read some articles about page- vs block caching, I'm stunned Drupal cache works this way, but that's not relevant to this issue :-)

Read: http://www.drupaler.co.uk/blog/page-and-block-caching/114

wimh’s picture

Page cache is for the whole page. Block cache is useful when page cache is not used, i.e. for logged in users or when page cache is turned off completely in the settings.

@j0rd: you said you could do it without changing uc_cart.module, but how did you get to the actual cart contents? I thought that with the page cache turned on (and for anonymous users), uc_cart_block('view') would only give you the safe "click here to view your cart" version...

svihel’s picture

j0rd: Hello, is this solution really working? I tried it and all it did was that the bottom part of cart (summary and links to cart and checkout, or that link in anonymous status) stopped showing. Is this supposed to fix the anonymous caching problem, or did I misunderstood that?

Proposition be Wimh in #1 post seems to me like perfect solution. Anybody working on such thing?

DanielJohnston’s picture

Subscribing.

Jim Kirkpatrick’s picture

Also subscribing. And...

#1 makes really good sense, but I'd make it simpler still:

  1. AJAX/jQuery added to every page. (cached with every page, standard code)
  2. It looks for the existing, standard anonymous Cart block that is cache-safe but feature poor. (no changes or patches to the rest of Ubercart so far)
  3. It tries to AJAX replace it with the full, up to date, sexy and uncached version once the page loads.
  4. Profit!

This way, those without JS still get the safe version already in running Ubercart, but everyone else gets the real deal and we can still do page caching whilst keeping things pretty simple.

We really need this if Ubercart has a chance of being scalable or responsive in shared hosting environments. We need it doubly to get powerful cache modules like Boost, AuthCache and others working properly. Oh and there's Varnish and similar to think about, too.

I'd be glad to help out with this... Should this be a release blocker for UC2.0?

pharoz’s picture

subscribing

keesje’s picture

Ive made some progress in D5, but nothing more than a workaround. I use boost for static caching, dbs page cache = off. I wrote a tiny module that simply invokes the cart and spits it out as a JS variable like this:




function get_carthtml() {
  $block = module_invoke('uc_cart', 'block', 'view', 'uc_cart-0');
  
  $html .= 'var carthtml = \'';
  $html .= '<h2>'.$block['subject'].'</h2>';
  $html .= '<div class="content">'.$block['content'].'</div>\';';
  print $html;
  exit;
}

Now define a menu item that calls back to "get_carthtml", and define a small javascript that overwrites the HTML of the cart.

This is nothing close to a solution, because it does not degrade nicely when JS is not available, and it does not support DBS page caching without hacking Ubercart.

But I hope this opens up other and better solutions in this direction.

--------------
Dekbed overtrek webhop

Erik Seifert’s picture

Status: Active » Postponed (maintainer needs more info)

There will be more options to this issue in 2.0

- Rule based caching

Erik Seifert’s picture

You can try 2.0 - ALPHA 7 . There is no cached cart in this version. In next version there is also a cached variant of ajax cart. This caching is based on roles.

aegnor’s picture

file:/includes/bootstrap.inc line:1040
------------------------------------------
case DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE:
// Initialize configuration variables, using values from settings.php if available.
$conf = variable_init(isset($conf) ? $conf : array());
$cache_mode = variable_get('cache', CACHE_DISABLED);
+ if($_SESSION['uc_cart_id']) {
+ $cache_mode = CACHE_DISABLED;
+ }
// Get the page from the cache.
$cache = $cache_mode == CACHE_DISABLED ? '' : page_get_cache();

aegnor’s picture

    case DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE:
      // Initialize configuration variables, using values from settings.php if available.
      $conf = variable_init(isset($conf) ? $conf : array());
      $cache_mode = variable_get('cache', CACHE_DISABLED);
+      if($_SESSION['uc_cart_id']) {
+        $result = db_query("SELECT c.*, n.title, n.vid FROM {node} n INNER JOIN {uc_cart_products} c ON n.nid = c.nid WHERE c.cart_id = '%s'", $_SESSION['uc_cart_id']);
+        while ($item = db_fetch_object($result)) {
+          $items[] = $item;
+        }
+        if (count($items)) {
+          $cache_mode = CACHE_DISABLED;
+        }
+      }
      // Get the page from the cache.
      $cache = $cache_mode == CACHE_DISABLED ? '' : page_get_cache();
Erik Seifert’s picture

Version: 6.x-1.0-rc9 » 6.x-2.x-dev
Status: Postponed (maintainer needs more info) » Fixed

Should work with new Version 2.0-beta1

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

j0rd’s picture

Not working for me, Ubercart 2.2 and uc_ajax_cart 6.2-beta2 and Drupal 6.16. I always see "View your shopping cart."

Is there still not proper solution for this? I think it's kind of a big deal and Ubercart should really implement something directly. Or there should be a stand alone module which simply fixes this bug. I don't know of a single shopping cart, which doesn't display at least the amount of total of the order. Disable cache to fix, simply isn't a solution. With out cache my web server pushes 1.5 requests / second. With cache, I get around 32 requests / second. Displaying "click here to view your cart" isn't a solution. I need cache and I need my cart info.

Not this modules fault, just ranting.

j0rd’s picture

As for my solution. I did get cache + anonymous cart working for oldgoldboutique.com .

I believe along with installing uc_ajax_cart I also had to override theme_uc_cart_block_content_cachable and return theme_uc_cart_block_content

This was a solution I found from Post #4, Solution #2: http://drupal.org/node/377798

As for this issue, it seems to be on going in this thread:
http://drupal.org/node/377798

916Designs’s picture

I think I've come up with something acceptable... Boost with standard Ubercart shopping cart block. Check out http://www.ubercart.org/forum/support/15908/boost_module_and_shopping_ca...

MakeOnlineShop’s picture

Version: 6.x-2.x-dev » 6.x-2.0-rc4
Status: Closed (fixed) » Active

Hi,

I am using the latest Drupal 6 + Ubercart + Ajax cart and when ANONYMOUS users add products to the cart they are not added in the cart block in the menu.

It works when I disable all caching for the shop, but it is not a good solution, so can you tell me if you have any other way to properly use AJAX CART with anonymous users ?

At permissions pages "show uncached cart" for anonymous users is enabled.

Thanks a lot.

j0rd’s picture

The only solution I've found is to load the cart for anonymous users via AJAX.

You're going to need to write something custom to do so.

Mine looks something like this


function MYMODULE_menu() {
  $items['MYMODULE/ajax_cart'] = array(
      'title' => 'Ajax Cart',
      'page callback' => 'MYMODULE_ajax_cart_block',
      'type'=> MENU_CALLBACK,
      'access arguments' => array('access content'),
      );
}

function MYMODULE_ajax_cart_block() {
  print theme('cart_block'); // or what ever the theme function is
  exit;
}

Then I have JS like this

$(function() {
    if($('#block-MYMODULE-0 #ajax_cart').length) {
      var blank_cart = $(this);
      $.get('/cwg_theme/ajax_cart', {}, function(data) {
          $('#MYMODULE-0 #ajax_cart').replaceWith(data);
          });
    }
}

This is my no means a full example, but should give you an idea of what needs to be done.

Jim Kirkpatrick’s picture

I've got around it with http://drupal.org/project/ajaxblocks

tunic’s picture

Status: Active » Closed (fixed)

This issue appears only with last Ubercart 2.7 version. Please use Ubercart 2.6 (AFAIK 2.7 does no make any update changes so you may downgrade Ubercart from 2.7 to 2.6).

Please check this issue:
#1317986: Updating to Ubercart 6.x-2.7 breaks Ajax Cart