diff --git a/module/VuFind/src/VuFind/Cart.php b/module/VuFind/src/VuFind/Cart.php index 3c4a06d85097e5e33fa911aef58b99f598b81b97..3195c10216dd81402f1e35cb2ca5f59bff363a91 100644 --- a/module/VuFind/src/VuFind/Cart.php +++ b/module/VuFind/src/VuFind/Cart.php @@ -306,6 +306,16 @@ class Cart return $this->cookieManager->getDomain(); } + /** + * Get cookie path ('/' if unset). + * + * @return string + */ + public function getCookiePath() + { + return $this->cookieManager->getPath(); + } + /** * Process parameters and return the cart content. * diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/CartTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/CartTest.php index b764b190676bd39e14eefa1052bc257b10b17459..d08ce4056287ca9fd2b816e3bd560c552efd342c 100644 --- a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/CartTest.php +++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/CartTest.php @@ -427,6 +427,34 @@ class CartTest extends \VuFindTest\Unit\MinkTestCase $this->assertEquals('0', $this->findCss($page, '#cartItems strong')->getText()); } + /** + * Test that we can put items in the cart and then remove them outside of + * the lightbox. + * + * @return void + */ + public function testFillAndEmptyCartWithoutLightbox() + { + // Turn on limit by path setting; there used to be a bug where cookie + // paths were set inconsistently between JS and server-side code. This + // test should catch any regressions in that area. + $page = $this->setUpGenericCartTest( + ['config' => ['Cookies' => ['limit_by_path' => 1]]] + ); + + // Go to the cart page and activate the "empty" control: + $session = $this->getMinkSession(); + $session->visit($this->getVuFindUrl() . '/Cart'); + $empty = $this->findCss($page, '#cart-empty-label'); + $empty->click(); + $emptyConfirm = $this->findCss($page, '#cart-confirm-empty'); + $emptyConfirm->click(); + + // Confirm that the cart has truly been emptied: + $this->snooze(); // wait for display to update + $this->assertEquals('0', $this->findCss($page, '#cartItems strong')->getText()); + } + /** * Test that the email control works. * diff --git a/themes/bootstrap3/js/cart.js b/themes/bootstrap3/js/cart.js index 3d2474241b6b2f0db3c0743f078745f64b5506a3..15cd6201d104bc8cc4270f84c8762b18ed6a21eb 100644 --- a/themes/bootstrap3/js/cart.js +++ b/themes/bootstrap3/js/cart.js @@ -6,11 +6,16 @@ VuFind.register('cart', function Cart() { var _COOKIE_SOURCES = 'vufind_cart_src'; var _COOKIE_DELIM = "\t"; var _COOKIE_DOMAIN = false; + var _COOKIE_PATH = '/'; function setDomain(domain) { _COOKIE_DOMAIN = domain; } + function setCookiePath(path) { + _COOKIE_PATH = path; + } + function _uniqueArray(op) { var ret = []; for (var i = 0; i < op.length; i++) { @@ -70,11 +75,11 @@ VuFind.register('cart', function Cart() { // Add source to source cookie cartItems[cartItems.length] = String.fromCharCode(65 + cartSources.length) + id; cartSources[cartSources.length] = source; - Cookies.setItem(_COOKIE_SOURCES, cartSources.join(_COOKIE_DELIM), false, '/', _COOKIE_DOMAIN); + Cookies.setItem(_COOKIE_SOURCES, cartSources.join(_COOKIE_DELIM), false, _COOKIE_PATH, _COOKIE_DOMAIN); } else { cartItems[cartItems.length] = String.fromCharCode(65 + sIndex) + id; } - Cookies.setItem(_COOKIE, _uniqueArray(cartItems).join(_COOKIE_DELIM), false, '/', _COOKIE_DOMAIN); + Cookies.setItem(_COOKIE, _uniqueArray(cartItems).join(_COOKIE_DELIM), false, _COOKIE_PATH, _COOKIE_DOMAIN); updateCount(); return true; } @@ -109,11 +114,11 @@ VuFind.register('cart', function Cart() { } } if (cartItems.length > 0) { - Cookies.setItem(_COOKIE, _uniqueArray(cartItems).join(_COOKIE_DELIM), false, '/', _COOKIE_DOMAIN); - Cookies.setItem(_COOKIE_SOURCES, _uniqueArray(cartSources).join(_COOKIE_DELIM), false, '/', _COOKIE_DOMAIN); + Cookies.setItem(_COOKIE, _uniqueArray(cartItems).join(_COOKIE_DELIM), false, _COOKIE_PATH, _COOKIE_DOMAIN); + Cookies.setItem(_COOKIE_SOURCES, _uniqueArray(cartSources).join(_COOKIE_DELIM), false, _COOKIE_PATH, _COOKIE_DOMAIN); } else { - Cookies.removeItem(_COOKIE, '/', _COOKIE_DOMAIN); - Cookies.removeItem(_COOKIE_SOURCES, '/', _COOKIE_DOMAIN); + Cookies.removeItem(_COOKIE, _COOKIE_PATH, _COOKIE_DOMAIN); + Cookies.removeItem(_COOKIE_SOURCES, _COOKIE_PATH, _COOKIE_DOMAIN); } updateCount(); return true; @@ -211,6 +216,7 @@ VuFind.register('cart', function Cart() { getFullItems: getFullItems, updateCount: updateCount, setDomain: setDomain, + setCookiePath: setCookiePath, // Init init: init }; diff --git a/themes/bootstrap3/templates/layout/layout.phtml b/themes/bootstrap3/templates/layout/layout.phtml index e42f5ceaa91465d71a090fe8542a2d872d41c8ff..fd89ef37d49d3b2bcc39621a9cd8262219ccbf62 100644 --- a/themes/bootstrap3/templates/layout/layout.phtml +++ b/themes/bootstrap3/templates/layout/layout.phtml @@ -75,6 +75,12 @@ 'VuFind.cart.setDomain("' . $domain . '");' ); } + $cookiePath = $cart->getCookiePath(); + if (!empty($cookiePath)) { + $this->headScript()->appendScript( + 'VuFind.cart.setCookiePath("' . $cookiePath . '");' + ); + } $this->jsTranslations()->addStrings( [ 'addBookBag' => 'Add to Book Bag',