Skip to content
Snippets Groups Projects
Select Git revision
  • 8.x-2.x
  • 3.x default
  • 3.0.x
  • 7.x-1.x
  • order-comments
  • 3.1.0
  • 3.0.2
  • 3.0.1
  • 3.0.0
  • 3.0.0-beta2
  • 3.0.0-beta1
  • 3.0.0-alpha1
  • 8.x-2.40
  • 8.x-2.39
  • 8.x-2.38
  • 8.x-2.37
  • 8.x-2.36
  • 8.x-2.35
  • 8.x-2.34
  • 8.x-2.33
  • 8.x-2.32
  • 8.x-2.31
  • 8.x-2.30
  • 7.x-1.17
  • 8.x-2.29
25 results

CheckoutController.php

Blame
  • jsacksick's avatar
    Issue #2994356 by jsacksick, AaronBauman, Anybody, rszrama: Add a /checkout...
    Jonathan Sacksick authored and Jonathan Sacksick committed
    Issue #2994356 by jsacksick, AaronBauman, Anybody, rszrama: Add a /checkout route to support single-store/single-cart use case.
    c6677d02
    History
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    CheckoutController.php 6.20 KiB
    <?php
    
    namespace Drupal\commerce_checkout\Controller;
    
    use Drupal\commerce_cart\CartProviderInterface;
    use Drupal\commerce_cart\CartSession;
    use Drupal\commerce_cart\CartSessionInterface;
    use Drupal\commerce_checkout\CheckoutOrderManagerInterface;
    use Drupal\Core\Access\AccessResult;
    use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
    use Drupal\Core\DependencyInjection\DependencySerializationTrait;
    use Drupal\Core\Form\FormBuilderInterface;
    use Drupal\Core\Messenger\MessengerInterface;
    use Drupal\Core\Messenger\MessengerTrait;
    use Drupal\Core\Routing\RouteMatchInterface;
    use Drupal\Core\Session\AccountInterface;
    use Drupal\Core\StringTranslation\StringTranslationTrait;
    use Drupal\Core\Url;
    use Symfony\Component\DependencyInjection\ContainerInterface;
    use Symfony\Component\HttpFoundation\RedirectResponse;
    
    /**
     * Provides the checkout form page.
     */
    class CheckoutController implements ContainerInjectionInterface {
    
      use DependencySerializationTrait;
      use MessengerTrait;
      use StringTranslationTrait;
    
      /**
       * The checkout order manager.
       *
       * @var \Drupal\commerce_checkout\CheckoutOrderManagerInterface
       */
      protected $checkoutOrderManager;
    
      /**
       * The form builder.
       *
       * @var \Drupal\Core\Form\FormBuilderInterface
       */
      protected $formBuilder;
    
      /**
       * The cart session.
       *
       * @var \Drupal\commerce_cart\CartSessionInterface
       */
      protected $cartSession;
    
      /**
       * The cart provider.
       *
       * @var \Drupal\commerce_cart\CartProviderInterface
       */
      protected $cartProvider;
    
      /**
       * Constructs a new CheckoutController object.
       *
       * @param \Drupal\commerce_checkout\CheckoutOrderManagerInterface $checkout_order_manager
       *   The checkout order manager.
       * @param \Drupal\Core\Form\FormBuilderInterface $form_builder
       *   The form builder.
       * @param \Drupal\commerce_cart\CartSessionInterface $cart_session
       *   The cart session.
       * @param \Drupal\commerce_cart\CartProviderInterface $cart_provider
       *   The cart session.
       * @param \Drupal\Core\Messenger\MessengerInterface $messenger
       *   The messenger.
       */
      public function __construct(CheckoutOrderManagerInterface $checkout_order_manager, FormBuilderInterface $form_builder, CartSessionInterface $cart_session, CartProviderInterface $cart_provider, MessengerInterface $messenger) {
        $this->checkoutOrderManager = $checkout_order_manager;
        $this->formBuilder = $form_builder;
        $this->cartSession = $cart_session;
        $this->cartProvider = $cart_provider;
        $this->messenger = $messenger;
      }
    
      /**
       * {@inheritdoc}
       */
      public static function create(ContainerInterface $container) {
        return new static(
          $container->get('commerce_checkout.checkout_order_manager'),
          $container->get('form_builder'),
          $container->get('commerce_cart.cart_session'),
          $container->get('commerce_cart.cart_provider'),
          $container->get('messenger')
        );
      }
    
      /**
       * Convenience method to send user to checkout via a parameter-free route.
       *
       * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
       *   The checkout page.
       */
      public function checkoutRedirect() {
        $carts = $this->cartProvider->getCarts();
        $carts = array_filter($carts, function ($cart) {
          /** @var \Drupal\commerce_order\Entity\OrderInterface $cart */
          return $cart->hasItems();
        });
        // If there are more than one cart, or no carts, redirect to the cart page.
        if (!$carts) {
          $this->messenger->addMessage($this->t('Add some items to your cart and then try checking out.'));
          $redirect_url = Url::fromRoute('commerce_cart.page');
        }
        elseif (count($carts) > 1) {
          $redirect_url = Url::fromRoute('commerce_cart.page');
        }
        else {
          $cart = reset($carts);
          $redirect_url = Url::fromRoute('commerce_checkout.form', ['commerce_order' => $cart->id()]);
        }
    
        return new RedirectResponse($redirect_url->toString());
      }
    
      /**
       * Builds and processes the form provided by the order's checkout flow.
       *
       * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
       *   The route match.
       *
       * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
       *   The render form.
       */
      public function formPage(RouteMatchInterface $route_match) {
        /** @var \Drupal\commerce_order\Entity\OrderInterface $order */
        $order = $route_match->getParameter('commerce_order');
        $requested_step_id = $route_match->getParameter('step');
        $step_id = $this->checkoutOrderManager->getCheckoutStepId($order, $requested_step_id);
        if ($requested_step_id != $step_id) {
          $url = Url::fromRoute('commerce_checkout.form', ['commerce_order' => $order->id(), 'step' => $step_id]);
          return new RedirectResponse($url->toString());
        }
        $checkout_flow = $this->checkoutOrderManager->getCheckoutFlow($order);
        $checkout_flow_plugin = $checkout_flow->getPlugin();
    
        return $this->formBuilder->getForm($checkout_flow_plugin, $step_id);
      }
    
      /**
       * Checks access for the form page.
       *
       * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
       *   The route match.
       * @param \Drupal\Core\Session\AccountInterface $account
       *   The current user account.
       *
       * @return \Drupal\Core\Access\AccessResult
       *   The access result.
       */
      public function checkAccess(RouteMatchInterface $route_match, AccountInterface $account) {
        /** @var \Drupal\commerce_order\Entity\OrderInterface $order */
        $order = $route_match->getParameter('commerce_order');
        if ($order->getState()->getId() == 'canceled') {
          return AccessResult::forbidden()->addCacheableDependency($order);
        }
    
        // The user can checkout only their own non-empty orders.
        if ($account->isAuthenticated()) {
          $customer_check = $account->id() == $order->getCustomerId();
        }
        else {
          $active_cart = $this->cartSession->hasCartId($order->id(), CartSession::ACTIVE);
          $completed_cart = $this->cartSession->hasCartId($order->id(), CartSession::COMPLETED);
          $customer_check = $active_cart || $completed_cart;
        }
    
        $access = AccessResult::allowedIf($customer_check)
          ->andIf(AccessResult::allowedIf($order->hasItems()))
          ->andIf(AccessResult::allowedIfHasPermission($account, 'access checkout'))
          ->addCacheableDependency($order);
    
        return $access;
      }
    
    }