commerce_api-8.x-1.x-dev/src/Plugin/Field/FieldType/ShippingMethodItemList.php

src/Plugin/Field/FieldType/ShippingMethodItemList.php
<?php

declare(strict_types=1);

namespace Drupal\commerce_api\Plugin\Field\FieldType;

use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\commerce_shipping\Entity\ShipmentInterface;
use Drupal\Core\Field\FieldItemList;
use Drupal\Core\TypedData\ComputedItemListTrait;
use Drupal\Core\TypedData\DataDefinitionInterface;
use Drupal\Core\TypedData\TypedDataInterface;
use Symfony\Component\HttpKernel\Exception\HttpException;

final class ShippingMethodItemList extends FieldItemList {

  use ComputedItemListTrait;

  /**
   * The shipment manager.
   *
   * @var \Drupal\commerce_shipping\ShipmentManagerInterface
   */
  private $shipmentManager;

  /**
   * The shipping order manager.
   *
   * @var \Drupal\commerce_shipping\ShippingOrderManagerInterface
   */
  private $shippingOrderManager;

  /**
   * {@inheritdoc}
   */
  public function __construct(DataDefinitionInterface $definition, $name = NULL, ?TypedDataInterface $parent = NULL) {
    parent::__construct($definition, $name, $parent);
    // @note TypedData API does not support dependency injection.
    // @see \Drupal\Core\TypedData\TypedDataManager::createInstance
    $this->shipmentManager = \Drupal::service('commerce_shipping.shipment_manager');
    $this->shippingOrderManager = \Drupal::service('commerce_shipping.order_manager');
  }

  /**
   * {@inheritdoc}
   */
  protected function computeValue() {
    $order = $this->getEntity();
    assert($order instanceof OrderInterface);
    if (!$order->hasField('shipments')) {
      return;
    }

    $shipping_rate_option = '';
    /** @var \Drupal\commerce_shipping\Entity\ShipmentInterface[] $shipments */
    $shipments = $order->get('shipments')->referencedEntities();
    if (!empty($shipments)) {
      $first_shipment = reset($shipments);
      $shipping_rate_option = sprintf('%s--%s', $first_shipment->getShippingMethodId(), $first_shipment->getShippingService());
    }
    $this->list[0] = $this->createItem(0, [
      'value' => $shipping_rate_option,
    ]);
  }

  /**
   * {@inheritdoc}
   */
  public function setValue($values, $notify = TRUE) {
    parent::setValue($values, $notify);

    // Make sure that subsequent getter calls do not try to compute the values
    // again.
    $this->valueComputed = TRUE;

    $order = $this->getEntity();
    assert($order instanceof OrderInterface);
    $rate_id = $this->list[0]->value;
    if (!empty($rate_id)) {
      $this->applyShippingRateToShipments($order, $rate_id);
    }
  }

  /**
   * Apply a shipping rate to an order's shipments.
   *
   * @param \Drupal\commerce_order\Entity\OrderInterface $order
   *   The order.
   * @param string $rate_id
   *   The shipping rate ID.
   *
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  private function applyShippingRateToShipments(OrderInterface $order, string $rate_id) {
    $shipments = $this->getOrderShipments($order);

    foreach ($shipments as $shipment) {
      assert($shipment instanceof ShipmentInterface);
      $rates = $this->shipmentManager->calculateRates($shipment);
      // Skip applying the rate if not available.
      if (!isset($rates[$rate_id])) {
        throw new HttpException(422, sprintf('The specified rate "%s" is not available.', $rate_id));
      }
      $this->shipmentManager->applyRate($shipment, $rates[$rate_id]);
      $shipment->save();
    }
    $order->set('shipments', $shipments);
  }

  /**
   * Get the shipments for an order.
   *
   * The shipments may or may not be saved.
   *
   * @param \Drupal\commerce_order\Entity\OrderInterface $order
   *   The order.
   *
   * @return array
   *   The array of shipments.
   */
  private function getOrderShipments(OrderInterface $order): array {
    /** @var \Drupal\commerce_shipping\Entity\ShipmentInterface[] $shipments */
    $shipments = $order->get('shipments')->referencedEntities();
    if (empty($shipments)) {
      $shipping_profile = $order->get('shipping_information')->entity;
      $shipments = $this->shippingOrderManager->pack($order, $shipping_profile);
    }
    return $shipments;
  }

}

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

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