From d6857b7a5f57aaa983f6b342db3892c77f8567bc Mon Sep 17 00:00:00 2001
From: tinker <tinker@200883.no-reply.drupal.org>
Date: Sep 23, 2015 10:07:05 AM

Issue #955810 by tinker, longwave: Items in a users cart are not removed when the item becomes unpublished.


diff --git a/uc_cart/tests/uc_cart.test b/uc_cart/tests/uc_cart.test
index c6e3458..36c0385 100644
--- a/uc_cart/tests/uc_cart.test
+++ b/uc_cart/tests/uc_cart.test
@@ -178,6 +178,18 @@
     $this->assertFieldByName('items[0][qty]', 2, t('The product quantity is 2.'));
   }
 
+  function testUnpublishedCartItem() {
+    // Add a product to the cart, then unpublish the node.
+    $this->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
+    $this->product->status = 0;
+    node_save($this->product);
+
+    // Test that the cart is empty.
+    $this->drupalGet('cart');
+    $this->assertText($this->product->title . ' is no longer available and has been removed from your shopping cart.');
+    $this->assertText('There are no products in your shopping cart.');
+  }
+
   function testDeletedCartItem() {
     // Add a product to the cart, then delete the node.
     $this->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
diff --git a/uc_cart/uc_cart.module b/uc_cart/uc_cart.module
index c89420c..ba58dc3 100644
--- a/uc_cart/uc_cart.module
+++ b/uc_cart/uc_cart.module
@@ -1047,9 +1047,29 @@
 
         // Create a bare order and attach it to each item as context.
         $order = new UcOrder($cid);
+        $pids = array();
         foreach ($items[$cid] as $item) {
+          $pids[$item->nid] = $item->cart_item_id;
           $item->order = $order;
         }
+
+        // Check for products that have been deleted or unpublished. If any
+        // exist display a warning message and remove them from the cart.
+        if (!empty($pids)) {
+          $remove_items = array();
+          $products = node_load_multiple(array_keys($pids));
+          foreach ($pids as $pid => $cart_item_id) {
+            if (!isset($products[$pid]) || (isset($products[$pid]) && !node_access('view', $products[$pid]))) {
+              $product_title = isset($products[$pid]->title) ? $products[$pid]->title : t('A product');
+              drupal_set_message(t('<strong>@product-title</strong> is no longer available and has been removed from your shopping cart.', array('@product-title' => $product_title)), 'warning');
+              unset($items[$cid][$cart_item_id]);
+              $remove_items[] = $cart_item_id;
+            }
+          }
+          if (!empty($remove_items)) {
+            entity_delete_multiple('uc_cart_item', $remove_items);
+          }
+        }
       }
       else {
         $items[$cid] = array();
