commerce_donation_flow-1.0.x-dev/src/Controller/DonationController.php

src/Controller/DonationController.php
<?php

namespace Drupal\commerce_donation_flow\Controller;

use Drupal\commerce_cart\CartSession;
use Drupal\commerce_cart\CartSessionInterface;
use Drupal\commerce_checkout\CheckoutOrderManagerInterface;
use Drupal\commerce_donation_flow\Form\DonationSettingsForm;
use Drupal\commerce_donation_flow\NewOrder;
use Drupal\commerce_donation_flow\Plugin\Commerce\CheckoutFlow\DonationCheckoutFlow;
use Drupal\commerce_donation_flow\Routing\DonationSecuredRedirectResponse;
use Drupal\commerce_store\CurrentStoreInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;

/**
 * Controller for /donate and  donation customized checkout.
 */
class DonationController implements ContainerInjectionInterface {

  /**
   * Drupal\commerce_checkout\CheckoutOrderManagerInterface definition.
   *
   * @var \Drupal\commerce_checkout\CheckoutOrderManagerInterface
   */
  protected $checkoutOrderManager;

  /**
   * Drupal\Core\Form\FormBuilderInterface definition.
   *
   * @var \Drupal\Core\Form\FormBuilderInterface
   */
  protected $formBuilder;

  /**
   * The current user.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected $currentUser;

  /**
   * Injected service.
   *
   * @var \Symfony\Component\HttpFoundation\RequestStack
   */
  protected $requestStack;

  /**
   * The current store.
   *
   * @var \Drupal\commerce_store\CurrentStoreInterface
   */
  protected $currentStore;

  /**
   * The cart session is used for access to the order on the thank you pane.
   *
   * @var \Drupal\commerce_cart\CartSessionInterface
   */
  protected $cartSession;

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Injected config service.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected ConfigFactoryInterface $configFactory;

  /**
   * Injected service.
   *
   * @var \Drupal\commerce_donation_flow\NewOrder
   */
  protected $newOrders;

  /**
   * DonationController constructor.
   *
   * @param \Drupal\Core\Form\FormBuilderInterface $form_builder
   *   Injected service.
   * @param \Drupal\Core\Session\AccountInterface $current_user
   *   Injected service.
   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
   *   Injected service.
   * @param \Drupal\commerce_store\CurrentStoreInterface $current_store
   *   Injected service.
   * @param \Drupal\commerce_checkout\CheckoutOrderManagerInterface $commerce_order_manager
   *   Injected service.
   * @param \Drupal\commerce_cart\CartSessionInterface $session
   *   Injected service.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   Injected service.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
   *   Injected service.
   * @param \Drupal\commerce_donation_flow\NewOrder $newOrder
   *   Injected service.
   */
  final public function __construct(
    FormBuilderInterface $form_builder,
    AccountInterface $current_user,
    RequestStack $request_stack,
    CurrentStoreInterface $current_store,
    CheckoutOrderManagerInterface $commerce_order_manager,
    CartSessionInterface $session,
    EntityTypeManagerInterface $entity_type_manager,
    ConfigFactoryInterface $configFactory,
    NewOrder $newOrder,
  ) {
    $this->formBuilder = $form_builder;
    $this->currentUser = $current_user;
    $this->requestStack = $request_stack;
    $this->currentStore = $current_store;
    $this->checkoutOrderManager = $commerce_order_manager;
    $this->cartSession = $session;
    $this->entityTypeManager = $entity_type_manager;
    $this->configFactory = $configFactory;
    $this->newOrders = $newOrder;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('form_builder'),
      $container->get('current_user'),
      $container->get('request_stack'),
      $container->get('commerce_store.current_store'),
      $container->get('commerce_checkout.checkout_order_manager'),
      $container->get('commerce_cart.cart_session'),
      $container->get('entity_type.manager'),
      $container->get('config.factory'),
      $container->get('commerce_donation_flow.new_order')
    );
  }

  /**
   * Builds the initial presentation of the form provided by the donation flow.
   *
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   *   The route match.
   *
   * @return \Drupal\commerce_donation_flow\Routing\DonationSecuredRedirectResponse
   *   Redirect to an order specific flow.
   */
  public function frontController(RouteMatchInterface $route_match) {
    $config = $this->configFactory->get('commerce_donation_flow.settings');
    $orderIds = $this->cartSession->getCartIds();
    // If the requested step is not available, both this controller and the
    // default Commerce controller redirect to the order's indicated step.
    // We need a default value in case our checkout flow has not been used.
    $stepId = 'placeholder';
    if (empty($orderIds)) {
      // Create an order to get the flow plugin.
      $order = $this->newOrders->get('single', $config->get('donate_item_type') ?? 'donation');
      $order->save();
      $this->cartSession->addCartId($order->id());
    }
    else {
      $order = $this->entityTypeManager->getStorage('commerce_order')->load(reset($orderIds));
    }
    // Always start at the first available step.
    $checkoutFlow = $this->checkoutOrderManager->getCheckoutFlow($order);
    $checkoutFlowPlugin = $checkoutFlow->getPlugin();
    // There are no order parameters so CheckoutFlowBase misses the order.
    if ($checkoutFlowPlugin instanceof DonationCheckoutFlow) {
      $checkoutFlowPlugin->conditionalOrderValue($order);
      $stepId = $this->checkoutOrderManager->getCheckoutStepId($order);
    }
    $parameters = [
      'commerce_order' => $order->id(),
      'step' => $stepId,
    ];
    return $this->constructStepRedirect($parameters);
  }

  /**
   * Builds and processes the form provided by the order's checkout flow.
   *
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   *   The route match.
   *
   * @return array|\Drupal\commerce_donation_flow\Routing\DonationSecuredRedirectResponse
   *   The render form.
   */
  public function nextStep(RouteMatchInterface $route_match) {
    /** @var \Drupal\commerce_order\Entity\OrderInterface $order */
    $order = $route_match->getParameter('commerce_order');
    $requestedStepId = $route_match->getParameter('step');
    $parameters = [
      'commerce_order' => $order->id(),
    ];
    $stepId = $this->checkoutOrderManager->getCheckoutStepId($order, $requestedStepId);
    if ($requestedStepId != $stepId) {
      $parameters['step'] = $stepId;
      return $this->constructStepRedirect($parameters);
    }

    $checkout_flow = $this->checkoutOrderManager->getCheckoutFlow($order);
    $checkout_flow_plugin = $checkout_flow->getPlugin();

    return $this->formBuilder->getForm($checkout_flow_plugin, $stepId);
  }

  /**
   * Builds and processes a quick donation flow.
   *
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   *   The route match.
   *
   * @return \Drupal\commerce_donation_flow\Routing\DonationSecuredRedirectResponse
   *   Our own redirection into the flow with order prepared.
   */
  public function quickDonation(RouteMatchInterface $route_match) {
    // Create an order.
    // Go directly to payment..
    $stepId = 'payment';
    $order = $this->newOrders->get('single');
    $order->set('checkout_step', $stepId);
    $order->save();
    $orderItems = $order->getItems();
    // Should only be one.
    $donation = reset($orderItems);
    $donationAmount = $donation->field_donation_amount;
    $amount = $route_match->getParameter('amount');
    $donationAmount->setValue([
      'number' => $amount,
      'currency_code' => $this->currentStore->getStore()
        ->getDefaultCurrencyCode(),
    ]);
    $donation->save();
    $this->cartSession->addCartId($order->id());
    $checkoutFlow = $this->checkoutOrderManager->getCheckoutFlow($order);
    $checkoutFlowPlugin = $checkoutFlow->getPlugin();
    if ($checkoutFlowPlugin instanceof DonationCheckoutFlow) {
      $checkoutFlowPlugin->conditionalOrderValue($order);
    }
    $parameters = [
      'commerce_order' => $order->id(),
      'step' => $stepId,
    ];
    return $this->constructStepRedirect($parameters);
  }

  /**
   * Checks access for the donation flow.
   *
   * Assigned as custom access for route
   * `commerce_donation_flow.donation_controller_formPage`.
   *
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   *   Drupal route match service.
   * @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,
  ) {
    $config = $this->configFactory->get('commerce_donation_flow.settings');
    $use_route = $config->get('donation_route');
    $route_check = $use_route === DonationSettingsForm::DONATE_ROUTE_OPTION || $use_route === DonationSettingsForm::COMBINED_ROUTE_OPTION;

    $details_check = AccessResult::allowed();
    if ($route_match->getRouteName() === 'commerce_donation_flow.donation_controller_formPage') {
      // Check existing order characteristics.
      /** @var \Drupal\commerce_order\Entity\OrderInterface $order */
      $order = $route_match->getParameter('commerce_order');
      if ($order->getState()->value == 'canceled') {
        return AccessResult::forbidden()->addCacheableDependency($order);
      }// The user can check out 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;
      }
      $details_check = AccessResult::allowedIf($customer_check)
        ->andIf(AccessResult::allowedIf($order->hasItems()))
        ->addCacheableDependency($order);
    }

    $access = AccessResult::allowedIf($route_check)
      ->andIf($details_check)
      ->andIf(
        AccessResult::allowedIfHasPermission($account, 'make donation')
      );

    return $access;
  }

  /**
   * Utility method to build a redirect.
   *
   * @param array $parameters
   *   The url parameters.
   *
   * @return \Drupal\commerce_donation_flow\Routing\DonationSecuredRedirectResponse
   *   The prepared redirect.
   */
  protected function constructStepRedirect(array $parameters) {
    $url = Url::fromRoute('commerce_donation_flow.donation_controller_formPage', $parameters);
    $query = $this->requestStack->getCurrentRequest()->query;
    if ($query->has('donate_return')) {
      $url->setOption('query', ['donate_return' => $query->get('donate_return')]);
    }
    return new DonationSecuredRedirectResponse($url->toUriString());
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc