commerce_api-8.x-1.x-dev/src/EventSubscriber/CartTokenSubscriber.php

src/EventSubscriber/CartTokenSubscriber.php
<?php

namespace Drupal\commerce_api\EventSubscriber;

use Drupal\commerce_api\CartTokenSession;
use Drupal\commerce_cart\CartSessionInterface;
use Drupal\Core\TempStore\SharedTempStore;
use Drupal\Core\TempStore\SharedTempStoreFactory;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

/**
 * Cart token subscriber.
 *
 * This subscriber provides two pieces of functionality.
 *
 * On response, it ensures the Vary header contains the cart token header. This
 * handles browser and reverse proxy caching handling.
 *
 * On request, it checks if the cart token query parameter is available. This
 * ensures cart data is passed to the user's session. For example, a user that
 * created a cart from a decoupled application but visits checkout using the
 * cart token to finish order purchased.
 */
final class CartTokenSubscriber implements EventSubscriberInterface {

  /**
   * The tempstore service.
   *
   * @var \Drupal\Core\TempStore\SharedTempStore
   */
  private SharedTempStore $tempStore;

  /**
   * Constructs a new CartTokenSubscriber object.
   *
   * @param \Drupal\commerce_cart\CartSessionInterface $cartSession
   *   The cart session.
   * @param \Drupal\Core\TempStore\SharedTempStoreFactory $temp_store_factory
   *   The temp store factory.
   */
  public function __construct(private CartSessionInterface $cartSession, SharedTempStoreFactory $temp_store_factory) {
    $this->tempStore = $temp_store_factory->get('commerce_api_tokens');
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    $events = [];
    // Run before router_listener so we execute before access checks, and before
    // dynamic_page_cache so we can populate a session. The ensures proper
    // access to CheckoutController.
    $events[KernelEvents::REQUEST][] = ['onRequest', 100];

    $events[KernelEvents::RESPONSE][] = ['onResponse', -10];
    return $events;
  }

  /**
   * Loads the token cart data and resets it to the session.
   *
   * @param \Symfony\Component\HttpKernel\Event\RequestEvent $event
   *   The request event, which contains the current request.
   */
  public function onRequest(RequestEvent $event) {
    $cart_token = $event->getRequest()->query->get(CartTokenSession::QUERY_NAME);
    if ($cart_token) {
      $token_cart_data = $this->tempStore->get($cart_token);
      foreach ([CartSessionInterface::ACTIVE, CartSessionInterface::COMPLETED] as $cart_type) {
        if (isset($token_cart_data[$cart_type]) && is_array($token_cart_data[$cart_type])) {
          foreach ($token_cart_data[$cart_type] as $token_cart_datum) {
            $this->cartSession->addCartId($token_cart_datum, $cart_type);
          }
        }
      }
    }
  }

  /**
   * Ensures the Vary header contains the cart token header name.
   *
   * @param \Symfony\Component\HttpKernel\Event\ResponseEvent $event
   *   The response event.
   */
  public function onResponse(ResponseEvent $event) {
    if (!$event->isMainRequest()) {
      return;
    }
    $request = $event->getRequest();
    if ($request->headers->has(CartTokenSession::HEADER_NAME)) {
      $response = $event->getResponse();
      // The Vary header gets mangled with CORS.
      // @see https://www.drupal.org/project/commerce_api/issues/3116590
      $vary = array_filter($response->getVary());
      $vary[] = CartTokenSession::HEADER_NAME;
      $response->setVary(implode(', ', $vary));
    }
  }

}

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

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