Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 33 additions & 5 deletions src/services/Carts.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,33 @@ public function init()
* Get the current cart for this session.
*
* @param bool $forceSave Force the cart.
* @param bool $readOnly Whether to retrieve the cart in read-only mode.
* @throws ElementNotFoundException
* @throws Exception
* @throws Throwable
*/
public function getCart(bool $forceSave = false): Order
public function getCart(bool $forceSave = false, bool $readOnly = false): ?Order
{
if ($readOnly) {
if (isset($this->_cart)) {
return $this->_cart;
}

if (!$this->getHasSessionCartNumber()) {
return null;
}

$request = Craft::$app->getRequest();
$number = $request->getCookies()->getValue($this->cartCookie['name'], false);
if (!$number) {
return null;
}

$this->_cartNumber = $number;
$this->_cart = $this->_getCart(false, false);
return $this->_cart;
}

$this->loadCookie(); // TODO: need to see if this should be added to other runtime methods too

$this->_getCartCount++; //useful when debugging
Expand Down Expand Up @@ -212,7 +233,7 @@ public function getCart(bool $forceSave = false): Order
/**
* Get the current cart for this session.
*/
private function _getCart(): ?Order
private function _getCart(bool $forgetInvalidCart = true, bool $checkAnonymousCartSession = true): ?Order
{
$number = $this->getSessionCartNumber();
/** @var Order|null $cart */
Expand All @@ -227,7 +248,9 @@ private function _getCart(): ?Order

// If the cart is already completed or trashed, forget the cart and start again.
if ($cart && ($cart->isCompleted || $cart->trashed)) {
$this->forgetCart();
if ($forgetInvalidCart) {
$this->forgetCart();
}
return null;
}

Expand All @@ -237,7 +260,10 @@ private function _getCart(): ?Order

// Did an anonymous user provide an email that belonged to a credentialed user?
// See CartController::actionUpdate()
$anonymousCartWithCredentialedCustomer = $cart && Craft::$app->getSession()->get('commerce:anonymousCartWithCredentialedCustomer:' . $cart->number, false);
$anonymousCartWithCredentialedCustomer = false;
if ($checkAnonymousCartSession && $cart) {
$anonymousCartWithCredentialedCustomer = Craft::$app->getSession()->get('commerce:anonymousCartWithCredentialedCustomer:' . $cart->number, false);
}

if ($cart && $cartCustomer && $cartCustomer->getIsCredentialed() &&
(
Expand All @@ -248,7 +274,9 @@ private function _getCart(): ?Order
($currentUser && $currentUser->id != $cartCustomer->id)
)
) {
$this->forgetCart();
if ($forgetInvalidCart) {
$this->forgetCart();
}
return null;
}

Expand Down
26 changes: 26 additions & 0 deletions tests/unit/services/CartsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use craftcommercetests\fixtures\CustomerAddressFixture;
use craftcommercetests\fixtures\CustomerFixture;
use UnitTester;
use yii\web\Cookie;

/**
* CartsTest.
Expand Down Expand Up @@ -140,4 +141,29 @@ public function testGetCartSwitchCustomer(): void
Craft::$app->getUser()->setIdentity($originalIdentity);
Craft::$app->getElements()->deleteElement($cart, true);
}

public function testGetCartReadOnlyModeDoesNotStartCartSession(): void
{
$cartNumber = Plugin::getInstance()->getCarts()->generateCartNumber();

$order = new Order();
$order->number = $cartNumber;
Craft::$app->getElements()->saveElement($order, false);

$carts = $this->make(Carts::class, [
'setSessionCartNumber' => function() {
self::fail('Read-only cart retrieval should not update the cart session.');
},
]);
Plugin::getInstance()->set('carts', $carts);
Craft::$app->getRequest()->getCookies()->add(new Cookie([
'name' => $carts->cartCookie['name'],
'value' => $cartNumber,
]));

$cart = Plugin::getInstance()->getCarts()->getCart(readOnly: true);

self::assertNotNull($cart);
self::assertSame($cartNumber, $cart->number);
}
}
Loading