What happened?
Description
In Commerce 5.x, calling forgetCart() followed by getCart() in the same request no longer results in a new cart being created. Instead, the original cart is restored from the request cookie, effectively making forgetCart() a no-op when getCart() is called afterwards in the same request.
This is a regression from 4.x behaviour where this sequence worked as expected.
Root Cause
The 5.x getCart() method added a call to $this->loadCookie() at the top of the method ([Carts.php#L261](https://github.com/craftcms/commerce/blob/5.x/src/services/Carts.php#L261)). This method was not present in 4.x.
loadCookie() unconditionally reads the cart number from the request cookies and calls setSessionCartNumber(), overwriting the _cartNumber = false state that forgetCart() sets:
protected function loadCookie(): void
{
// ...
if ($requestCookies->has($this->cartCookie['name'])) {
$this->setSessionCartNumber($requestCookies->getValue($this->cartCookie['name']));
}
}
Steps to Reproduce
Any code that calls forgetCart() then getCart() in the same request will reproduce this:
$cartsService = \craft\commerce\Plugin::getInstance()->getCarts();
// Store original cart number
$originalCartNumber = $cartsService->getSessionCartNumber();
// Forget the current cart
$cartsService->forgetCart();
// Attempt to get a new cart
$cart = $cartsService->getCart(forceSave: true);
// Expected: $cart->number !== $originalCartNumber (new cart)
// Actual: $cart->number === $originalCartNumber (old cart restored by loadCookie)
Expected Behaviour
forgetCart() followed by getCart() should produce a new cart with a new cart number, as it did in Commerce 4.x.
Actual Behaviour
getCart() calls loadCookie() which reads the original cart number from the request cookie (still present for the duration of the current request) and restores it via setSessionCartNumber(), overwriting the forgotten state.
Suggested Fix
loadCookie() should respect the _cartNumber = false state set by forgetCart():
protected function loadCookie(): void
{
// ...
// Don't restore from cookie if the cart was explicitly forgotten
if ($this->_cartNumber === false) {
return;
}
if ($requestCookies->has($this->cartCookie['name'])) {
$this->setSessionCartNumber($requestCookies->getValue($this->cartCookie['name']));
}
}
Environment
- Craft Commerce: 5.x
- Worked in: Commerce 4.x (where
getCart() did not call loadCookie())
Relevant Code
Craft CMS version
5.9.19
Craft Commerce version
5.6.1.1
PHP version
No response
Operating system and version
No response
Database type and version
No response
Image driver and version
No response
Installed plugins and versions
What happened?
Description
In Commerce 5.x, calling
forgetCart()followed bygetCart()in the same request no longer results in a new cart being created. Instead, the original cart is restored from the request cookie, effectively makingforgetCart()a no-op whengetCart()is called afterwards in the same request.This is a regression from 4.x behaviour where this sequence worked as expected.
Root Cause
The 5.x
getCart()method added a call to$this->loadCookie()at the top of the method ([Carts.php#L261](https://github.com/craftcms/commerce/blob/5.x/src/services/Carts.php#L261)). This method was not present in 4.x.loadCookie()unconditionally reads the cart number from the request cookies and callssetSessionCartNumber(), overwriting the_cartNumber = falsestate thatforgetCart()sets:Steps to Reproduce
Any code that calls
forgetCart()thengetCart()in the same request will reproduce this:Expected Behaviour
forgetCart()followed bygetCart()should produce a new cart with a new cart number, as it did in Commerce 4.x.Actual Behaviour
getCart()callsloadCookie()which reads the original cart number from the request cookie (still present for the duration of the current request) and restores it viasetSessionCartNumber(), overwriting the forgotten state.Suggested Fix
loadCookie()should respect the_cartNumber = falsestate set byforgetCart():Environment
getCart()did not callloadCookie())Relevant Code
getCart()withloadCookie()call: [Carts.php#L261](https://github.com/craftcms/commerce/blob/5.x/src/services/Carts.php#L261)loadCookie(): [Carts.php#L502](https://github.com/craftcms/commerce/blob/5.x/src/services/Carts.php#L502)forgetCart(): [Carts.php#L355](https://github.com/craftcms/commerce/blob/5.x/src/services/Carts.php#L355)getCart()withoutloadCookie(): [Carts.php#L197](https://github.com/craftcms/commerce/blob/4.x/src/services/Carts.php#L197)Craft CMS version
5.9.19
Craft Commerce version
5.6.1.1
PHP version
No response
Operating system and version
No response
Database type and version
No response
Image driver and version
No response
Installed plugins and versions