From 70965c10458f89b1af1f1346faa7566230327d45 Mon Sep 17 00:00:00 2001
From: Demian Katz <demian.katz@villanova.edu>
Date: Tue, 28 Aug 2012 13:00:22 -0400
Subject: [PATCH] Replaced singleton nature of VuFind\Cart with use of the ZF2
 service manager; fixed bug with removing items from cart via AJAX.

---
 module/VuFind/config/module.config.php        |  1 +
 module/VuFind/src/VuFind/Cart.php             | 19 +--------
 .../src/VuFind/Controller/AjaxController.php  |  6 +--
 .../src/VuFind/Controller/CartController.php  | 18 +++++++--
 .../src/VuFind/Theme/Root/Helper/Cart.php     | 39 ++++++++++++++++---
 5 files changed, 54 insertions(+), 29 deletions(-)

diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php
index 14fb124005e..a0697ab75be 100644
--- a/module/VuFind/config/module.config.php
+++ b/module/VuFind/config/module.config.php
@@ -103,6 +103,7 @@ $config = array(
     'service_manager' => array(
         'invokables' => array(
             'authmanager' => 'VuFind\Auth\Manager',
+            'cart' => 'VuFind\Cart',
             'sessionmanager' => 'Zend\Session\SessionManager',
         )
     ),
diff --git a/module/VuFind/src/VuFind/Cart.php b/module/VuFind/src/VuFind/Cart.php
index 262427d96bb..73b2d5107de 100644
--- a/module/VuFind/src/VuFind/Cart.php
+++ b/module/VuFind/src/VuFind/Cart.php
@@ -42,7 +42,6 @@ use VuFind\Record;
  */
 class Cart
 {
-    protected static $singleton;
     protected $items;
     protected $maxSize = 100;
     protected $active = false;
@@ -52,9 +51,9 @@ class Cart
     const CART_COOKIE_DELIM = "\t";
 
     /**
-     * Protected constructor to ensure singleton pattern.
+     * Constructor
      */
-    protected function __construct()
+    public function __construct()
     {
         $config = ConfigReader::getConfig();
         if (isset($config->Site->showBookBag)) {
@@ -69,20 +68,6 @@ class Cart
         $this->init();
     }
 
-    /**
-     * Get the current instance of the user's cart, if
-     * it is not initialized, then one will be initialized.
-     *
-     * @return Cart_Model
-     */
-    static function getInstance()
-    {
-        if (!self::$singleton) {
-            self::$singleton = new Cart();
-        }
-        return self::$singleton;
-    }
-
     /**
      * Return the contents of the cart.
      *
diff --git a/module/VuFind/src/VuFind/Controller/AjaxController.php b/module/VuFind/src/VuFind/Controller/AjaxController.php
index 0f8eb54df10..62ed914957f 100644
--- a/module/VuFind/src/VuFind/Controller/AjaxController.php
+++ b/module/VuFind/src/VuFind/Controller/AjaxController.php
@@ -26,7 +26,7 @@
  * @link     http://vufind.org/wiki/building_a_recommendations_module Wiki
  */
 namespace VuFind\Controller;
-use VuFind\Cart, VuFind\Config\Reader as ConfigReader,
+use VuFind\Config\Reader as ConfigReader,
     VuFind\Connection\Manager as ConnectionManager,
     VuFind\Db\Table\Comments as CommentsTable,
     VuFind\Db\Table\Resource as ResourceTable, VuFind\Db\Table\Tags as TagsTable,
@@ -1168,14 +1168,14 @@ class AjaxController extends AbstractBase
     protected function removeItemsCart()
     {
         // Without IDs, we can't continue
-        $ids = $this->params()->fromQuery('ids');
+        $ids = $this->params()->fromPost('ids');
         if (empty($ids)) {
             return $this->output(
                 array('result'=>Translator::translate('bulk_error_missing')),
                 self::STATUS_ERROR
             );
         }
-        Cart::getInstance()->removeItems($ids);
+        $this->getServiceLocator()->get('Cart')->removeItems($ids);
         return $this->output(array('delete' => true), self::STATUS_OK);
     }
 
diff --git a/module/VuFind/src/VuFind/Controller/CartController.php b/module/VuFind/src/VuFind/Controller/CartController.php
index b0715df6d94..8f3280ff842 100644
--- a/module/VuFind/src/VuFind/Controller/CartController.php
+++ b/module/VuFind/src/VuFind/Controller/CartController.php
@@ -26,7 +26,7 @@
  * @link     http://vufind.org   Main Site
  */
 namespace VuFind\Controller;
-use VuFind\Cart, VuFind\Exception\Mail as MailException, VuFind\Export,
+use VuFind\Exception\Mail as MailException, VuFind\Export,
     VuFind\Mailer, VuFind\Record, VuFind\Translator\Translator,
     Zend\Session\Container as SessionContainer;
 
@@ -53,6 +53,16 @@ class CartController extends AbstractBase
         $this->session = new SessionContainer('cart_followup');
     }
 
+    /**
+     * Get the cart object.
+     *
+     * @return \VuFind\Cart
+     */
+    protected function getCart()
+    {
+        return $this->getServiceLocator()->get('Cart');
+    }
+
     /**
      * Process requests for main cart.
      *
@@ -92,18 +102,18 @@ class CartController extends AbstractBase
 
         // Add items if necessary:
         if (strlen($this->params()->fromPost('empty', '')) > 0) {
-            Cart::getInstance()->emptyCart();
+            $this->getCart()->emptyCart();
         } else if (strlen($this->params()->fromPost('delete', '')) > 0) {
             if (empty($ids)) {
                 return $this->redirectToSource('error', 'bulk_noitems_advice');
             } else {
-                Cart::getInstance()->removeItems($ids);
+                $this->getCart()->removeItems($ids);
             }
         } else if (strlen($this->params()->fromPost('add', '')) > 0) {
             if (empty($ids)) {
                 return $this->redirectToSource('error', 'bulk_noitems_advice');
             } else {
-                $addItems = Cart::getInstance()->addItems($ids);
+                $addItems = $this->getCart()->addItems($ids);
                 if (!$addItems['success']) {
                     $msg = Translator::translate('bookbag_full_msg') . ". "
                         . $addItems['notAdded'] . " "
diff --git a/module/VuFind/src/VuFind/Theme/Root/Helper/Cart.php b/module/VuFind/src/VuFind/Theme/Root/Helper/Cart.php
index 99e5c00777d..bffdbd03cfa 100644
--- a/module/VuFind/src/VuFind/Theme/Root/Helper/Cart.php
+++ b/module/VuFind/src/VuFind/Theme/Root/Helper/Cart.php
@@ -26,7 +26,9 @@
  * @link     http://vufind.org/wiki/building_a_recommendations_module Wiki
  */
 namespace VuFind\Theme\Root\Helper;
-use VuFind\Cart as VuFindCart, Zend\View\Helper\AbstractHelper;
+use Zend\ServiceManager\ServiceLocatorInterface,
+    Zend\ServiceManager\ServiceLocatorAwareInterface,
+    Zend\View\Helper\AbstractHelper;
 
 /**
  * Cart view helper
@@ -37,15 +39,42 @@ use VuFind\Cart as VuFindCart, Zend\View\Helper\AbstractHelper;
  * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
  * @link     http://vufind.org/wiki/building_a_recommendations_module Wiki
  */
-class Cart extends AbstractHelper
+class Cart extends AbstractHelper implements ServiceLocatorAwareInterface
 {
+    protected $serviceLocator;
+
     /**
-     * Get the Cart singleton object.
+     * Get the Cart object from the service manager.
      *
-     * @return VuFindCart
+     * @return \VuFind\Cart
      */
     public function __invoke()
     {
-        return VuFindCart::getInstance();
+        return $this->getServiceLocator()->get('Cart');
+    }
+
+    /**
+     * Set the service locator.
+     *
+     * @param ServiceLocatorInterface $serviceLocator Locator to register
+     *
+     * @return Manager
+     */
+    public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
+    {
+        // The service locator passed in here is a Zend\View\HelperPluginManager;
+        // we want to pull out the main Zend\ServiceManager\ServiceManager.
+        $this->serviceLocator = $serviceLocator->getServiceLocator();
+        return $this;
+    }
+
+    /**
+     * Get the service locator.
+     *
+     * @return \Zend\ServiceManager\ServiceLocatorInterface
+     */
+    public function getServiceLocator()
+    {
+        return $this->serviceLocator;
     }
 }
\ No newline at end of file
-- 
GitLab