diff --git a/spec/Event/CartPickedUpSpec.php b/spec/Event/CartPickedUpSpec.php
new file mode 100644
index 000000000..c27034905
--- /dev/null
+++ b/spec/Event/CartPickedUpSpec.php
@@ -0,0 +1,20 @@
+beConstructedWith('ORDERTOKEN');
+ }
+
+ function it_has_order_token(): void
+ {
+ $this->orderToken()->shouldReturn('ORDERTOKEN');
+ }
+}
diff --git a/spec/EventListener/Messenger/CartPickedUpListenerSpec.php b/spec/EventListener/Messenger/CartPickedUpListenerSpec.php
new file mode 100644
index 000000000..d0b703d6b
--- /dev/null
+++ b/spec/EventListener/Messenger/CartPickedUpListenerSpec.php
@@ -0,0 +1,53 @@
+beConstructedWith($loggedInShopUserProvider, $bus);
+ }
+
+ function it_assigns_customer_to_cart_when_user_is_logged_in(
+ LoggedInShopUserProviderInterface $loggedInShopUserProvider,
+ MessageBusInterface $bus,
+ ShopUserInterface $shopUser,
+ CustomerInterface $customer
+ ): void {
+ $loggedInShopUserProvider->isUserLoggedIn()->willReturn(true);
+
+ $loggedInShopUserProvider->provide()->willReturn($shopUser);
+ $shopUser->getCustomer()->willReturn($customer);
+ $customer->getEmail()->willReturn('peter@parker.com');
+
+ $assignCustomerToCart = new AssignCustomerToCart('ORDERTOKEN', 'peter@parker.com');
+
+ $bus->dispatch($assignCustomerToCart)->willReturn(new Envelope($assignCustomerToCart))->shouldBeCalled();
+
+ $this(new CartPickedUp('ORDERTOKEN'));
+ }
+
+ function it_does_nothing_if_user_is_not_logged_in(
+ LoggedInShopUserProviderInterface $loggedInShopUserProvider,
+ MessageBusInterface $bus
+ ): void {
+ $loggedInShopUserProvider->isUserLoggedIn()->willReturn(false);
+
+ $bus->dispatch(Argument::any())->shouldNotBeCalled();
+
+ $this(new CartPickedUp('ORDERTOKEN'));
+ }
+}
diff --git a/spec/Handler/Cart/AssignCustomerToCartHandlerSpec.php b/spec/Handler/Cart/AssignCustomerToCartHandlerSpec.php
index 8ff41b3f9..1e6d03ece 100644
--- a/spec/Handler/Cart/AssignCustomerToCartHandlerSpec.php
+++ b/spec/Handler/Cart/AssignCustomerToCartHandlerSpec.php
@@ -8,35 +8,42 @@
use Sylius\Component\Core\Model\CustomerInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
+use Sylius\Component\Order\Processor\OrderProcessorInterface;
use Sylius\ShopApiPlugin\Command\Cart\AssignCustomerToCart;
use Sylius\ShopApiPlugin\Provider\CustomerProviderInterface;
final class AssignCustomerToCartHandlerSpec extends ObjectBehavior
{
- function let(OrderRepositoryInterface $orderRepository, CustomerProviderInterface $customerProvider): void
- {
- $this->beConstructedWith($orderRepository, $customerProvider);
+ function let(
+ OrderRepositoryInterface $cartRepository,
+ OrderProcessorInterface $orderProcessor,
+ CustomerProviderInterface $customerProvider
+ ): void {
+ $this->beConstructedWith($cartRepository, $orderProcessor, $customerProvider);
}
function it_handles_assigning_customer_to_cart(
- CustomerInterface $customer,
+ OrderRepositoryInterface $cartRepository,
+ OrderProcessorInterface $orderProcessor,
CustomerProviderInterface $customerProvider,
- OrderInterface $order,
- OrderRepositoryInterface $orderRepository
+ CustomerInterface $customer,
+ OrderInterface $cart
): void {
- $orderRepository->findOneBy(['tokenValue' => 'ORDERTOKEN'])->willReturn($order);
+ $cartRepository->findOneBy(['tokenValue' => 'ORDERTOKEN'])->willReturn($cart);
$customerProvider->provide('example@customer.com')->willReturn($customer);
- $order->setCustomer($customer)->shouldBeCalled();
+ $cart->setCustomer($customer)->shouldBeCalled();
+
+ $orderProcessor->process($cart);
$this(new AssignCustomerToCart('ORDERTOKEN', 'example@customer.com'));
}
function it_throws_an_exception_if_order_does_not_exist(
- OrderRepositoryInterface $orderRepository
+ OrderRepositoryInterface $cartRepository
): void {
- $orderRepository->findOneBy(['tokenValue' => 'ORDERTOKEN'])->willReturn(null);
+ $cartRepository->findOneBy(['tokenValue' => 'ORDERTOKEN'])->willReturn(null);
$this
->shouldThrow(\InvalidArgumentException::class)
diff --git a/spec/Handler/Cart/PickupCartHandlerSpec.php b/spec/Handler/Cart/PickupCartHandlerSpec.php
index 750ad5ce0..3a3cb33c1 100644
--- a/spec/Handler/Cart/PickupCartHandlerSpec.php
+++ b/spec/Handler/Cart/PickupCartHandlerSpec.php
@@ -13,19 +13,24 @@
use Sylius\Component\Locale\Model\LocaleInterface;
use Sylius\Component\Resource\Factory\FactoryInterface;
use Sylius\ShopApiPlugin\Command\Cart\PickupCart;
+use Sylius\ShopApiPlugin\Event\CartPickedUp;
use Sylius\ShopApiPlugin\Handler\Cart\PickupCartHandler;
+use Symfony\Component\Messenger\Envelope;
+use Symfony\Component\Messenger\MessageBusInterface;
final class PickupCartHandlerSpec extends ObjectBehavior
{
function let(
FactoryInterface $cartFactory,
OrderRepositoryInterface $cartRepository,
- ChannelRepositoryInterface $channelRepository
+ ChannelRepositoryInterface $channelRepository,
+ MessageBusInterface $eventBus
): void {
$this->beConstructedWith(
$cartFactory,
$cartRepository,
- $channelRepository
+ $channelRepository,
+ $eventBus
);
}
@@ -41,7 +46,8 @@ function it_handles_cart_pickup_for_not_logged_in_user(
FactoryInterface $cartFactory,
LocaleInterface $locale,
OrderInterface $cart,
- OrderRepositoryInterface $cartRepository
+ OrderRepositoryInterface $cartRepository,
+ MessageBusInterface $eventBus
): void {
$channelRepository->findOneByCode('CHANNEL_CODE')->willReturn($channel);
$channel->getBaseCurrency()->willReturn($currency);
@@ -58,6 +64,10 @@ function it_handles_cart_pickup_for_not_logged_in_user(
$cartRepository->add($cart)->shouldBeCalledOnce();
+ $cartPickedUp = new CartPickedUp('ORDERTOKEN');
+
+ $eventBus->dispatch($cartPickedUp)->willReturn(new Envelope($cartPickedUp))->shouldBeCalled();
+
$this(new PickupCart('ORDERTOKEN', 'CHANNEL_CODE'));
}
diff --git a/src/Event/CartPickedUp.php b/src/Event/CartPickedUp.php
new file mode 100644
index 000000000..70a3baba2
--- /dev/null
+++ b/src/Event/CartPickedUp.php
@@ -0,0 +1,21 @@
+orderToken = $orderToken;
+ }
+
+ public function orderToken(): string
+ {
+ return $this->orderToken;
+ }
+}
diff --git a/src/EventListener/CartBlamerListener.php b/src/EventListener/CartBlamerListener.php
index d2389f57e..5222a8e0d 100644
--- a/src/EventListener/CartBlamerListener.php
+++ b/src/EventListener/CartBlamerListener.php
@@ -4,39 +4,32 @@
namespace Sylius\ShopApiPlugin\EventListener;
-use Doctrine\Common\Persistence\ObjectManager;
use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTCreatedEvent;
-use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\ShopUserInterface;
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
-use Sylius\Component\Order\Context\CartContextInterface;
-use Sylius\Component\Order\Context\CartNotFoundException;
+use Sylius\ShopApiPlugin\Command\Cart\AssignCustomerToCart;
use Symfony\Component\HttpFoundation\RequestStack;
+use Symfony\Component\Messenger\MessageBusInterface;
use Webmozart\Assert\Assert;
final class CartBlamerListener
{
- /** @var ObjectManager */
- private $cartManager;
-
- /** @var CartContextInterface */
- private $cartContext;
-
/** @var OrderRepositoryInterface */
private $cartRepository;
+ /** @var MessageBusInterface */
+ private $bus;
+
/** @var RequestStack */
private $requestStack;
public function __construct(
- ObjectManager $cartManager,
- CartContextInterface $cartContext,
OrderRepositoryInterface $cartRepository,
+ MessageBusInterface $bus,
RequestStack $requestStack
) {
- $this->cartManager = $cartManager;
- $this->cartContext = $cartContext;
$this->cartRepository = $cartRepository;
+ $this->bus = $bus;
$this->requestStack = $requestStack;
}
@@ -51,33 +44,14 @@ public function onJwtLogin(JWTCreatedEvent $interactiveLoginEvent): void
return;
}
- $cart = $this->getCart($request->request->get('token'));
+ $token = $request->request->get('token');
+
+ $cart = $this->cartRepository->findOneBy(['tokenValue' => $token]);
if (null === $cart) {
return;
}
- $cart->setCustomer($user->getCustomer());
- $this->cartManager->persist($cart);
- $this->cartManager->flush();
- }
-
- private function getCart(?string $token): ?OrderInterface
- {
- if (null !== $token) {
- /** @var OrderInterface $cart */
- $cart = $this->cartRepository->findOneBy(['tokenValue' => $token]);
-
- return $cart;
- }
-
- try {
- /** @var OrderInterface $cart */
- $cart = $this->cartContext->getCart();
-
- return $cart;
- } catch (CartNotFoundException $exception) {
- return null;
- }
+ $this->bus->dispatch(new AssignCustomerToCart($token, $user->getCustomer()->getEmail()));
}
}
diff --git a/src/EventListener/Messenger/CartPickedUpListener.php b/src/EventListener/Messenger/CartPickedUpListener.php
new file mode 100644
index 000000000..ea18b0299
--- /dev/null
+++ b/src/EventListener/Messenger/CartPickedUpListener.php
@@ -0,0 +1,37 @@
+loggedInShopUserProvider = $loggedInShopUserProvider;
+ $this->bus = $bus;
+ }
+
+ public function __invoke(CartPickedUp $cartPickedUp): void
+ {
+ if (!$this->loggedInShopUserProvider->isUserLoggedIn()) {
+ return;
+ }
+
+ $shopUser = $this->loggedInShopUserProvider->provide();
+ $email = $shopUser->getCustomer()->getEmail();
+
+ $this->bus->dispatch(new AssignCustomerToCart($cartPickedUp->orderToken(), $email));
+ }
+}
diff --git a/src/EventListener/UserCartRecalculationListener.php b/src/EventListener/UserCartRecalculationListener.php
deleted file mode 100644
index acf8dead9..000000000
--- a/src/EventListener/UserCartRecalculationListener.php
+++ /dev/null
@@ -1,49 +0,0 @@
-cartContext = $cartContext;
- $this->orderProcessor = $orderProcessor;
- $this->cartManager = $cartManager;
- }
-
- public function recalculateCartWhileLogin(): void
- {
- try {
- $cart = $this->cartContext->getCart();
- } catch (CartNotFoundException $exception) {
- return;
- }
-
- Assert::isInstanceOf($cart, OrderInterface::class);
-
- $this->orderProcessor->process($cart);
-
- $this->cartManager->flush();
- }
-}
diff --git a/src/Handler/Cart/AssignCustomerToCartHandler.php b/src/Handler/Cart/AssignCustomerToCartHandler.php
index d5ce5f6f5..0a8ab0170 100644
--- a/src/Handler/Cart/AssignCustomerToCartHandler.php
+++ b/src/Handler/Cart/AssignCustomerToCartHandler.php
@@ -6,6 +6,7 @@
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
+use Sylius\Component\Order\Processor\OrderProcessorInterface;
use Sylius\ShopApiPlugin\Command\Cart\AssignCustomerToCart;
use Sylius\ShopApiPlugin\Provider\CustomerProviderInterface;
use Webmozart\Assert\Assert;
@@ -13,26 +14,35 @@
final class AssignCustomerToCartHandler
{
/** @var OrderRepositoryInterface */
- private $orderRepository;
+ private $cartRepository;
+
+ /** @var OrderProcessorInterface */
+ private $orderProcessor;
/** @var CustomerProviderInterface */
private $customerProvider;
- public function __construct(OrderRepositoryInterface $orderRepository, CustomerProviderInterface $customerProvider)
- {
- $this->orderRepository = $orderRepository;
+ public function __construct(
+ OrderRepositoryInterface $cartRepository,
+ OrderProcessorInterface $orderProcessor,
+ CustomerProviderInterface $customerProvider
+ ) {
+ $this->cartRepository = $cartRepository;
$this->customerProvider = $customerProvider;
+ $this->orderProcessor = $orderProcessor;
}
public function __invoke(AssignCustomerToCart $assignOrderToCustomer): void
{
- /** @var OrderInterface $order */
- $order = $this->orderRepository->findOneBy(['tokenValue' => $assignOrderToCustomer->orderToken()]);
+ /** @var OrderInterface $cart */
+ $cart = $this->cartRepository->findOneBy(['tokenValue' => $assignOrderToCustomer->orderToken()]);
- Assert::notNull($order, sprintf('Order with %s token has not been found.', $assignOrderToCustomer->orderToken()));
+ Assert::notNull($cart, sprintf('Order with %s token has not been found.', $assignOrderToCustomer->orderToken()));
$customer = $this->customerProvider->provide($assignOrderToCustomer->email());
- $order->setCustomer($customer);
+ $cart->setCustomer($customer);
+
+ $this->orderProcessor->process($cart);
}
}
diff --git a/src/Handler/Cart/PickupCartHandler.php b/src/Handler/Cart/PickupCartHandler.php
index 8fda8edba..2c3d840a6 100644
--- a/src/Handler/Cart/PickupCartHandler.php
+++ b/src/Handler/Cart/PickupCartHandler.php
@@ -10,6 +10,8 @@
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
use Sylius\Component\Resource\Factory\FactoryInterface;
use Sylius\ShopApiPlugin\Command\Cart\PickupCart;
+use Sylius\ShopApiPlugin\Event\CartPickedUp;
+use Symfony\Component\Messenger\MessageBusInterface;
use Webmozart\Assert\Assert;
final class PickupCartHandler
@@ -23,14 +25,19 @@ final class PickupCartHandler
/** @var ChannelRepositoryInterface */
private $channelRepository;
+ /** @var MessageBusInterface */
+ private $eventBus;
+
public function __construct(
FactoryInterface $cartFactory,
OrderRepositoryInterface $cartRepository,
- ChannelRepositoryInterface $channelRepository
+ ChannelRepositoryInterface $channelRepository,
+ MessageBusInterface $eventBus
) {
$this->cartFactory = $cartFactory;
$this->cartRepository = $cartRepository;
$this->channelRepository = $channelRepository;
+ $this->eventBus = $eventBus;
}
public function __invoke(PickupCart $pickupCart): void
@@ -48,5 +55,7 @@ public function __invoke(PickupCart $pickupCart): void
$cart->setTokenValue($pickupCart->orderToken());
$this->cartRepository->add($cart);
+
+ $this->eventBus->dispatch(new CartPickedUp($pickupCart->orderToken()));
}
}
diff --git a/src/Resources/config/app/config.yml b/src/Resources/config/app/config.yml
index 7e1443c38..f13cbfe89 100644
--- a/src/Resources/config/app/config.yml
+++ b/src/Resources/config/app/config.yml
@@ -13,10 +13,13 @@ jms_serializer:
framework:
messenger:
+ default_bus: sylius_shop_api_plugin.command_bus
buses:
sylius_shop_api_plugin.command_bus:
middleware:
- doctrine_transaction
+ sylius_shop_api_plugin.event_bus:
+ default_middleware: allow_no_handlers
sylius_customer:
resources:
diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml
index d1bfa6d5e..01d5bca41 100644
--- a/src/Resources/config/services.xml
+++ b/src/Resources/config/services.xml
@@ -77,23 +77,19 @@
id="sylius.listener.cart_blamer"
class="Sylius\ShopApiPlugin\EventListener\CartBlamerListener"
>
-
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/src/Resources/config/services/handler/cart.xml b/src/Resources/config/services/handler/cart.xml
index 51296e239..6fdbc448d 100644
--- a/src/Resources/config/services/handler/cart.xml
+++ b/src/Resources/config/services/handler/cart.xml
@@ -15,6 +15,7 @@
+
@@ -101,6 +102,7 @@
+
diff --git a/tests/Controller/Cart/CartPickupApiTest.php b/tests/Controller/Cart/CartPickupApiTest.php
index c6fe27580..d95c8e588 100644
--- a/tests/Controller/Cart/CartPickupApiTest.php
+++ b/tests/Controller/Cart/CartPickupApiTest.php
@@ -53,6 +53,12 @@ public function it_only_creates_one_cart_if_user_is_logged_in(): void
$orders = $orderRepository->findAll();
$this->assertCount(1, $orders, 'Only one cart should be created');
+
+ /** @var OrderInterface $order */
+ $order = $orders[0];
+ $customer = $order->getCustomer();
+ $this->assertNotNull($customer, 'Cart should have customer assigned, but it has not.');
+ $this->assertSame('oliver@queen.com', $customer->getEmail());
}
/**