vendor/ibexa/checkout/src/bundle/EventSubscriber/CheckoutWorkflowSubscriber.php line 35

Open in your IDE?
  1. <?php
  2. /**
  3. * @copyright Copyright (C) Ibexa AS. All rights reserved.
  4. * @license For full copyright and license information view LICENSE file distributed with this source code.
  5. */
  6. declare(strict_types=1);
  7. namespace Ibexa\Bundle\Checkout\EventSubscriber;
  8. use Ibexa\Contracts\Cart\CartServiceInterface;
  9. use Ibexa\Contracts\Cart\Value\CartInterface;
  10. use Ibexa\Contracts\Checkout\Value\CheckoutInterface;
  11. use Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException;
  12. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  13. use Symfony\Component\Workflow\Event\GuardEvent;
  14. use Symfony\Component\Workflow\TransitionBlocker;
  15. final class CheckoutWorkflowSubscriber implements EventSubscriberInterface
  16. {
  17. private CartServiceInterface $cartService;
  18. public function __construct(CartServiceInterface $cartService)
  19. {
  20. $this->cartService = $cartService;
  21. }
  22. public static function getSubscribedEvents(): array
  23. {
  24. return [
  25. 'workflow.guard' => ['guardTransition'],
  26. ];
  27. }
  28. public function guardTransition(GuardEvent $event): void
  29. {
  30. $transition = $event->getTransition();
  31. $subject = $event->getSubject();
  32. if (!$subject instanceof CheckoutInterface) {
  33. return;
  34. }
  35. try {
  36. $cart = $this->cartService->getCart($subject->getCartIdentifier());
  37. } catch (NotFoundException $exception) {
  38. return;
  39. }
  40. $hasVirtualProductsOnly = $this->hasVirtualProductsOnly($cart);
  41. if (!$hasVirtualProductsOnly && $event->getMetadata('virtual_products_step', $transition)) {
  42. $event->addTransitionBlocker(
  43. new TransitionBlocker(
  44. 'Cannot make transition for virtual products when cart contains mixed or physical products.',
  45. '0'
  46. )
  47. );
  48. }
  49. if ($hasVirtualProductsOnly && $event->getMetadata('physical_products_step', $transition)) {
  50. $event->addTransitionBlocker(
  51. new TransitionBlocker(
  52. 'Cannot make transition for physical products when cart contains only virtual products.',
  53. '0'
  54. )
  55. );
  56. }
  57. }
  58. private function hasVirtualProductsOnly(CartInterface $cart): bool
  59. {
  60. foreach ($cart->getEntries() as $entry) {
  61. if (!$entry->getProduct()->getProductType()->isVirtual()) {
  62. return false;
  63. }
  64. }
  65. return true;
  66. }
  67. }