I've reverted uc_cart to 6.x-2.0-beta3 and it works now.

Priority:Critical» Normal
Status:Active» Closed (works as designed)

This is intentional. It does this for anonymous users when caching is turned on to prevent caching cart blocks w/ items in them that would be displayed incorrectly to other anonymous users. See

That's quiet bad. This changes make it really hard for me to implement my features. Because to make this work in UC BETA4 i must copy much code from uc_cart_block. I this is not the correct intention for drupal way. I will contact discuss this in ubercart forum.


(1) Turn cache off
(2) Override theme_uc_cart_block_content_cachable and return theme_uc_cart_block_content

For the first time ;- )

Status:Closed (works as designed)» Postponed (maintainer needs more info)

Status:Postponed (maintainer needs more info)» Closed (works as designed)

Your #2 will work just fine.

Sorry for stupid question, but how to:
Override theme_uc_cart_block_content_cachable and return theme_uc_cart_block_content?

First function has no params, but second has them.

I'd written in my template.php:
function {MYTHEME}_uc_cart_block_content_cachable()
return theme_uc_cart_block_content();
And it gave me an error.

Good point... I guess you'd really have to copy/paste the code from the hook_block() function that generates those variables in the first place.

Assigned:Unassigned» Erik Seifert

Yeahh this is really a problem. I tell this the lead developer from ubercart, but they wont change this now.

I had the same issue, and using the cacheexclude module helped me disable the cache for the particular pages where the cart is present.
Hope this helps !

I am an novice user can you give me more details on how to use the option 2?

>>(2) Override theme_uc_cart_block_content_cachable and return theme_uc_cart_block_content

Option 1 is not feasible for me due to performance issues

Use cache exclude module on cart pages.

This still doesn't work for me, I use the cart in a block and it never refeshes even after using the cacheexclude module. I have also tried disabling the cache blocks options.
do i miss anything?

Also given the performance issue with disabling these, is there any other option we can use?

Same here and I'm using the latest dev version and tried disabling block cache with no luck.

If solution #2 is possible, why doesn't it happen by default? Why is it more desirable to have an empty cart shown? Obviously no one is going to use an empty cart block... Seems like a bad design decision to me.

new551 bytes

The reason disabling block cache doesn't work is because the uc_cart.module explicitly looks to see if cache is enabled globally when it decides to show an empty cart.

I don't see why it can't just check to see if the block cache is enabled here.

I have attached a patch against 6.x-2.0-beta5 that works great for me.

@bfcam, your patch works. Patching the uc_cart.module file this way ensures that the block is invisible to anonymous users when block caching is turned off. At the very least, this patch should be committed.

@ubercart, this is just bad design. Block caching is a site wide performance feature and asking admins to switch off this feature in order to hide a block is madness. When users check the "Hide block if cart is empty" option then they should get what they expect.

Status:Closed (works as designed)» Needs review

Status:Needs review» Closed (works as designed)

So, in the words of Andre the Giant, "I do not think it means you think it means."

I need some clarification, and it looks there are confused issues here. This issue started out as a request to have a dynamic cart block for all users, anonymous or authenticated, whether caching was turned off or on for a site. This has traditionally resulted in "ghost" carts for anonymous users, where a page gets cached with a cart block that has items in it and future anonymous users see the cached version before they ever add items to the cart.

All that said, I investigated block caching and found it to be insufficient for what we needed to avoid that error. If cart blocks aren't being hidden properly when empty (I don't recall testing this, so it's quite likely), that's a separate issue and will require its own patch in a separate issue in the tracker here. I don't see how the patch in #16 will affect that.

Can we please have a test case that demonstrates why turning off block-caching is not sufficient to prevent ghosting for anonymous users?

I tested the scenario on my site and could not reproduce the problem.


Did you also have normal page caching turned on at the time? When I looked into the workflow during bootstrap, an entire cached page of HTML was being delivered up before block caching was ever even considered. It bypasses the majority of the page building process. What is cached is the entire HTML result of a rendered page, which doesn't care whether block level caching is on or not.

So, to put it another way... Page not cached yet? -> Content rendered and block caching delivers cached blocks (instead of rendering them afresh) -> All the resulting HTML cached for the next anonymous visitor.

That's my understanding, but I think I mentioned before, this isn't something I've investigated recently. The last time I had a serious look at is was when I made the change in the way the block worked, probably two months ago now.

I have a test case, a second site I've been working has the same problem.

If one of you wants to look on the admin end, and can give me time to back up before I let you in, I can give you access.


I'm playing with this, and it seems like there should be some more thought put into this issue.
I'll return with my conclusions & 2 cents in a bit ;)

Maybe we should branch this issue into two separate ones.

One issue for the cart block that shows items in the cart that were not selected by the anonymous users.

Another issue for whether the "hide block when cart is empty" feature is designed the best way and if it is functioning correctly.

That might draw clarity to this thread.


Same problem as originally reported, in UC 2.0 rc1... It really is a problem because normal caching has to be on on any sane site but showing 'View your shopping cart' on sites that have a shop but also plenty of other non-commercial sections is rather ugly.

I've ended up not showing the block for anonymous users rather than pushing it in their face even when they are not after shopping and even though the cart is empty anyway.


This also raises an admin UI issue.

Here's what it says currently on the Performance page:

The following enabled modules are incompatible with aggressive mode caching and will not function properly: poormanscron, statistics, uc_cart, uc_store

[emphasis added.]

This thread seems to make it clear that it's not just "aggressive" caching, at least with regard to uc_cart.

I think some of the negative reaction to this may be due to some of us finding this to be unexpected behavior. We see the admonition not to use the shopping cart and the store with aggressive caching; that makes sense. So we take what we think is a safe, conservative strategy of using normal mode caching and if we don't do a fairly extensive regression test after turning on the cache (and so catch the fact that the cart block doesn't behave as expected), we risk getting nastygrams from our users (or worse, our clients) about unexpected block behavior.

Yeah, there's alternate work going on in the Drupalsphere to fix that message about aggressive caching. Not a lot of modules have to deal with normal caching issues, so Ubercart is something of an exception. All I can say is this has been discussed in various places and announced/hashed out on, and I'll be sure that it's in the 2.x user's guide. Getting a 2.0 compatible UC AJAX Cart module going will solve this issue for 95% of people I imagine.


Getting a 2.0 compatible UC AJAX Cart module going will solve this issue for 95% of people I imagine.

But... thre is a UC Ajax Cart going... what must be done there to fix this issue?

If I'm not mistaken, a module like the AJAX Cart module should be able to add Javascript to the page that would display the dynamic cart block for those interested.

It seems like it's the solution...

Has anyone had any success with Ajax Cart displaying products in cart for Anonymous users?

I concur that the default output of theme_uc_cart_block_content_cachable is kind of confusing since everyone is going to assume that checking "Hide block if cart is empty." will cause an empty block to be hidden in all situations, no matter what the intentions are with caching. I just implemented the theme function to return a blank string, and all is good.

I think we should have the ability to disable caching for this particular block. I don't think disabling caching for the entire site is something people would want to do. I will try solution #2 in post #4...but I'm not sure if this re-causes the bad cache issue, which we're trying to fix.

Ideally, we should have some way of easily disabling the cache for uc_cart_block and in my opinion this cache should be turned off by default (even if site caching is turned on).

I'm using UBERCART--2-RC3

EDIT: I've managed to get it working by modifying some things in my themes template.php, but there's no way an ubercart end user which minimal experience will be able to figure this out easily. I believe you'll get more complaints about this until an easy solution for end users is provided.

I think I've explained this before, but again the problem is that "block caching" doesn't refer to cached pages per se. In other words, you could disable the block cache for the cart block, but the real problem is that pages were being cached that contained full cart blocks, and these were being displayed to users who hadn't put anything in their carts (and vice versa). Check the bootstrap functions... page caching circumvents any other page generation, including block caching.

rszrama is right.. this thread is a dead lane. Look at his post #28 -- what we need to achieve this functionality is UC AJAX Cart module... see

So to confirm. Post #4, Solution #2 if implemented, will or will not encounter cache issues?

Is that a temporary fix to resolve this issue?

Please excuse my ignorance, but debugging the cache system of drupal is a bit outside my realm of knowledge.

It will encounter cache issues. It just goes back to functioning w/ ghost carts like UC 1.x did. As #34 linked to, the solution is a dynamically loading cart contents section for anonymous users.

Thanks for the clarification. I'll take a look at uc_ajax_cart and see if it can resolve my issue.

Uc_ajax_cart didn't solve the problem for me. I had to turn off caching for the site which sucks. I can't use cache exclude for only cart pages, b/c I need visitors to see their cart on every page but only when something is in the cart. I have spent a lot of time on this and it is utterly broken.

Could you at least get the patch from #16 above into a release so we don't have to patch it with each incremental dev version? The patch above has been tested to solve a portion of this problem:


Status:Closed (works as designed)» Reviewed & tested by the community

Assigned:Erik Seifert» Unassigned
Status:Reviewed & tested by the community» Closed (works as designed)

I've discussed that patch in comment #19, and my other comments in this issue get at the real fix. These were never answered satisfactorily. I'm checking the global cache on purpose, unless something has changed in Drupal 6 since the time of this code to change the behavior of the global vs. block cache.

Just wondering around ubercart and cache and also noticed this. So the real thing is that there can't be any shopping cart block if cache is enabled, am I right?

I will try out the ajax cart sometime soon, but I am not sure if will fit my purpose. I is there any alternate solution? Overriding the cachable theme function would fix this? I would think not otherwise it should have been used like that in the first place.

And I wonder if the explanation in is accurate?

If I understood correctly, the cart block is not 'safe' with page caching, it simply outputs an empty cart block even if the cart is not empty. I think this should be explained in that page at least to give some clarifications and options for users who search for this kind of information.

I am sure a lot of thoughts have been put into this, just wondering if my conclusions are right or there's something I am missing :s?


That help page is correct in that it's "safe" meaning the same content will be cached for all anonymous users. The reason it wasn't "safe" before is that cached pages were being displayed to customer who had not added products to their cart showing that they had the wrong items in their cart. The point as described on the page isn't it always works the same regardless of whether caching is on or not but that it reverts to a version that is safe for caching if caching is on.

fwiw, I do think some sort of AJAX solution in core is the ideal way forward.



file:/includes/ line:1040
// 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();

new756 bytes

As already mentioned in this thread page caching and dynamic cart block for anonymous users are incompatible by design. The only solution will be an ajax driven cart block if java script is allowed.

But there's a different approach which uses Pressflow's lazy session initialization feature (which will be part of drupal 7 I think).

Using this feature drupal doesn't start a session for anonymous users until it's really required. For example putting something into the cart starts a session for an anonymous user. The trick is that cached pages (with an empty cart) are served to anonymous users only until their session starts. I think that this trade-off regarding performance and dynamics is acceptable and might be the future solution for drupal 7.

Right now you can achieve the same applying the small patch attached to ubercart. Alternatively you can download an already patched ubercart version from

Additionally you have to replace your drupal 6 installation with Pressflow or Cocomore Drupal Core which includes Pressflow and some additional improvements and pending bug fixes from the drupal issue queue .

      // 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();

Version:6.x-2.0-beta4» 7.x-3.x-dev
Category:bug» task
Status:Closed (works as designed)» Active

The issue of anonymous sessions is being addressed in Drupal core. See for a summary of where the issue currently stands.

mkalkbrenner's patch in #47 is interesting, but it only works for Drupal 7 because of the use of

aegnor's patches in #46 and #48 are impractical as they require modifying settings.php, and moreover require testing for the presence of a module-specific variable. That's not going to happen in Drupal core, and is a short-term hack at best.

I'm moving this to the Ubercart 7.x-3.x issue queue because the real fix requires Drupal core changes that are only available in D7.

@mkalkbrenner - Thanks! Your patch does allow the block to work again with Pressflow in use...tho it doesn't use lazy sessions, as the cart block initiates sessions all by itself (when checking for cart contents it currently calls uc_cart_get_id() which sets a session cookie if it's not already there) which of course sends my pressflow site back to the slow lane...(no per session caching here)

I kinda think the fix for this is that uc_cart_get_contents should return NULL if there is no cart id instead of creating one...does that sound about right? since everything else (adding, deleting, updating, this, that) set's cart id (and session)? I don't think the following breaks anything, but let me know if you see issues, what I've done is this:

//inside uc_cart.module
* New function uc_cart_get_id_cachesafe() in my mind it's only for use for uc_cart_get_contents()
* Grab the current uid or cartid but if it's not there we dont least in this context, so send it back NULL
function uc_cart_get_id_cachesafe() {
  if (
$user->uid) {
  elseif (isset(
$_SESSION['uc_cart_id'])) {
* Grab the items in a shopping cart for a user.
* If $cid is not passed in, this function uses the uid of the person currently
* accessing this function, if we don't get any of that, send it back NULL...cause heck there's nothing in the cart, and that's all we wanted to know
function uc_cart_get_contents($cid = NULL, $action = NULL) {
$items = array();
$cid = $cid ? $cid : uc_cart_get_id_cachesafe();
$cid){  return;


@jpstrikesback #50:
You're right. Thanks for pointing this out!

I created a patch based on your idea but respects the current api like returning an emty array instead of NULL.

An already patched version of ubercart including this patch and the one from #47 is available at

@mkalkbrenner Good call! Thanks for rolling that!

Title:Cart block is always empty for anonymous usersif there are any Ubercart global variables... there can be a solution
Version:7.x-3.x-dev» 6.x-2.x-dev

i am a newbie , I don't know whether Ubercart provides variables/functions for getting "number of items in the cart" or the "total amount"... or any other variables... if we can get that, we can override theme_uc_cart_block_content_cachable() function by using these and solve the problem...

Title:if there are any Ubercart global variables... there can be a solutionCart block is always empty for anonymous users
Component:Code» User Interface

@mkalkbrenner & @jpstrikesback

making $cachable = drupal_flush_all_caches(); // works for me , is it same as disabling cache?

can you highlight something on the above code , like,


$cachable = drupal_flush_all_caches();


$cachable = !$user->uid && variable_get('cache', CACHE_DISABLED) != CACHE_DISABLED;

$cachable = drupal_flush_all_caches(); // works for me , is it same as disabling cache?

No you don't disable the cache but clear the cache every time. Not a good idea ...

If you like to disable the cache to get the cart to work simply turn off page caching in the administration back end.


I tried your patch but did not work for me as the function drupal_page_is_cacheable() is not recognized in drupal 6.x . so for me to make cart block viewable u suggest to disable the cache instead of using drupal_flush_all_caches() ? I was just concerned about performance by disabling cache from start.

I tried your patch but did not work for me as the function drupal_page_is_cacheable() is not recognized in drupal 6.x.

Yes, this function doesn't exist in Drupal. It's an improvement introduced by Pressflow. See my post #47:

Additionally you have to replace your drupal 6 installation with Pressflow or Cocomore Drupal Core which includes Pressflow and some additional improvements and pending bug fixes from the drupal issue queue.

Title:Cart block is always empty for anonymous usersCart block always starts a session
Version:6.x-2.x-dev» 7.x-3.x-dev
Component:User Interface» Code
Status:Active» Needs review

There are a dozen thousand things going on in this issue.

The only one I think is actually actionable, at least for me, is lazy session loading. However, I'm not sure that it'll actually work well. From the patch in #51, it looks like you're not getting the cart id unless it already exists. I just don't see how you know it exists unless you go look for it. That sounds like the cart block always needs to load the session to see if it has anything to display, or it will never display anything to anonymous users.

3.x ought to work well enough now for someone to test this.

Despite all this, the real solution is some kind of AJAX-based cart block that gets around ALL of these issues.

However, I'm not sure that it'll actually work well. From the patch in #51, it looks like you're not getting the cart id unless it already exists. I just don't see how you know it exists unless you go look for it.

Putting something into the card starts the session and creates the cart id.

That sounds like the cart block always needs to load the session to see if it has anything to display, or it will never display anything to anonymous users.

No. It doesn't load any session data for anonymous users because there is no session. As soon as the session starts (because you add something to the cart) every anonymous user gets his individual not cached cart block (and pages aren't served from page cache any longer).

It sounds like this issue is closely related to #679422: hook_exit() causes Ubercart "Add to Cart" to fail, so you might want to look in there and try out that solution.

I'm having this issue with 6.x-2.2. As a workaround I changed line 406 of uc_cart.module to:

= FALSE; //!$user->uid && variable_get('cache', CACHE_DISABLED) != CACHE_DISABLED;

Solution in post #62 results in phantom items in the cart. My shopping cart tells me they are there, but when I view cart, they are not there.

I'm not really a big fan of #51 but the idea is fairly sound. In uc_cart_get_contents() and for that matter uc_cart_get_total_qty() without a passed cid, if there isn't already a cart, we don't care and can immediately return the empty case without creating the SESSION variable. I've taken a slightly different approach in my patch that just tells uc_cart_get_id() not to create a id if one doesn't exist. More functionality without more functions.

I've also gone ahead and extended the use to uc_cart_get_total_qty() since there's no reason not to(and I use it in my theme so it scratches my itch).

PS - Caveat, the patch was made against 6.x-2.2 not 7.x-3.x or 6.x-2.x. Apologies if it doesn't apply to HEAD.
PPS - Should we split this into actionable topic issues that don't have tons of random unrelated discussion?

Status:Needs review» Reviewed & tested by the community

Tested patch from #64 on 6.x-2.x-dev with Pressflow 6 and indeed fixed the problem of anonymous users being given a session before they add anything to their cart. For the D7 version of Ubercart this will be critical, as lazy sessions are in core for D7.

It also didn't break anything, as I was able to add an item to the cart and check it out without any problems. The session was (correctly) created at the point where I added a first product to my cart.

Another issue is that when the cart becomes empty (either after checkout completes or because they removed items from their cart), Ubercart doesn't unset the uc_cart_id session var, so the session remains when it could potentially be thrown away at that point. I've addressed this in a hook_init() of a custom module:

  if (!empty($_SESSION)) {
    // Do they have Ubercart stuff?
    if (isset($_SESSION['uc_cart_id'])) {
      // Even when the cart is empty, Ubercart doesn't unset this session var, so we'll do it for them
      if (!uc_cart_get_contents($_SESSION['uc_cart_id'])) {
        // Their cart is empty

I'm not sure whether this has any implications, so I'll test it a bit before submitting it as a patch, but it seems to have the desired effect of the session being deleted by Pressflow once they finish checkout (and their cart becomes empty again). It seems the cart ID isn't even stored in the DB anywhere except uc_cart_products, which obviously has no matching rows for an empty cart anyway.

Version:7.x-3.x-dev» 6.x-2.x-dev
Status:Reviewed & tested by the community» Needs work

neilnz, if your tests work out, I think it would be a good thing to add to this patch. It might even work better to add the unset() when the cart becomes empty than doing it during hook_init().

If it doesn't actually matter, then we can go ahead and commit it. I prefer forward porting, so I'm bumping the version number back.

Status:Needs work» Needs review
new2.13 KB

@Island Usurper, Thanks. I agree that it definitely shouldn't be a hook_init()!

I've rolled it into the original patch, adding it to uc_cart_get_contents(), as this seems to be called with a rebuild action when the cart empties (either because of a completed order, or removing the last item from the cart). It can therefore unset the session cart ID when it notices the cart go empty.

New version of the patch attached.

Status:Needs review» Reviewed & tested by the community

Looks like a pretty solid addition. Works as advertised (very clever fix too. much better than the init check).

Think this is RTBC from my stand point.

Version:6.x-2.x-dev» 7.x-3.x-dev
Status:Reviewed & tested by the community» Patch (to be ported)

OK, it doesn't look like it has any adverse effects on stock Drupal either, so I think I can commit it. Thanks for everyone's efforts in getting this figured out.

Status:Patch (to be ported)» Fixed

And the patch worked as-is for 7.x-3.x, so committed that as well.


EDIT: I just tested the latest dev, and it still has no effect to fix my issue, seeing as how I'm not using a Cart Block. Lyle, if you can, please take a look at that other issue here: #679422-49: hook_exit() causes Ubercart "Add to Cart" to fail

It's looking like torgosPizza's issue has more to do with Boost than with Ubercart, so if you're still having problems, take a look in that issue.

Yeah, Boost and any other module that invokes hook_exit() or does something else similar to abort scripts (in this case, the POST from a form).

Status:Fixed» Closed (fixed)

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

This patch results in serious issues for anonymous users after upgrade to UC2.3: see #858816: Unsetting cart session causes cart contents to be lost and #862348: Cart emptied on login ... complete rework of the $_SESSION unsetting thing is needed.

(thx to @fenstrat for finding this thread)

After upgrading to UC2.3 anonymous users couldn't add products to cart on my website. Revert to UC2.3 fixed the problem.

@alexku check #858816: Unsetting cart session causes cart contents to be lost. There is the place where we are solving that.

There are a lot of issues in here and I noticed that one of them was not addressed in the most recent update to the UC package. It seems that there are a lot of issues going on in this thread so, the issue that the empty shopping cart always displays to anonymous users has been pulled out to a separate thread to discuss there.

Feel free to disagree, but there is a patch that will bandage this problem for most people until UC can get the greater cart issues worked out.

Is it correct that this problem is not occuring when the AJAX_shopping_cart module is being used? ( I'm testing the dev version of that module now and it seems that anonymous users see the correct contents of their shoppingcarts in the ajax cart block.

Does anybody else have experience with this?

Correct. uc_ajax_cart is a different project and was created to address issues such as this one.

Thanks for you reply torgosPizza. I have installed and tested the ajax cart and it works like a charm! I can recommend it to others who need functioning shoppingcart blocks for anonymous users.

Let me ask a question, I know there are many issues described here and I somehow thought this fix would allow us to use page cache and have the cart block work properly, but is that still not possible?

I understand the idea of using a custom AJAX solution or maybe trying out, is that the only way?

What I am experiencing is the following:

Say I browsed to a product category with the cart empty, then I browse to a product and add it to the cart, the cart block is displayed properly there, then I browse back to the previous category browsing, I again see the cached version of the cart block (which is empty).

So there's no other way around this? Maybe worth documenting this on the project page? or somewhere else?

Also, have you tried the ajax cart module? What were your experiences with it?

#83, If you are using block caching, and the cart block is showing you phantom items (or showing you a cached version of the block) then yes, you need an ajax block solution.

@torgosPizza: Not specifically block caching, but I am using page caching which in the ends, I guess it's the same, isn't it?

I think so, though I could be wrong. I think the main issue was with anonymous users, an ajax block gets called after the page is rendered, which means each user should be unaffected by whatever caching you have enabled.

I think the problem lies in the way the cart is tied to the user: With logged in users, the cart is tied to a user ID and can therefor be pulled from the database with each pageload. With anonymous users the cartcontents are stored in a cookie (if I'm correct). And this gives trouble with loading the cart on pageload.

But as stated above: when using the Ajax cart module you can serve anonymous users with a fully functioning cart without problems! It's even better themable then the regular cart!

Solution #62 works fine so far



Solution in post #62 worked for me in ubercart 2. It also worked in UC Pictured Cart Block Module in uc_pic_cart_block.module file, line # 509.