You are here

public function AvailabilityOrderProcessor::process in Commerce Core 8.2

Processes an order.

Parameters

\Drupal\commerce_order\Entity\OrderInterface $order: The order.

Overrides OrderProcessorInterface::process

File

modules/order/src/AvailabilityOrderProcessor.php, line 44

Class

AvailabilityOrderProcessor
Provides an order processor that removes entities that are no longer available.

Namespace

Drupal\commerce_order

Code

public function process(OrderInterface $order) {

  // @todo Get $context as an argument to process().
  $context = new Context($order
    ->getCustomer(), $order
    ->getStore());
  $order_items_to_remove = [];
  foreach ($order
    ->getItems() as $order_item) {
    $purchased_entity = $order_item
      ->getPurchasedEntity();
    if (!$purchased_entity) {
      continue;
    }
    $availability_result = $this->availabilityManager
      ->check($order_item, $context);
    if ($availability_result
      ->isUnavailable()) {

      // We collect the order item ids to remove here instead of directly
      // calling $order->removeItem(), mostly for performance reasons since
      // that allows us to remove multiple order items at a time and
      // recalculate the order total only once.
      $order_items_to_remove[$order_item
        ->id()] = $order_item;
    }
  }
  if (!$order_items_to_remove) {
    return;
  }
  $order_item_storage = $this->entityTypeManager
    ->getStorage('commerce_order_item');
  $order_item_ids = array_keys($order_items_to_remove);
  $order
    ->get('order_items')
    ->filter(function ($item) use ($order_item_ids) {
    return !in_array($item->target_id, $order_item_ids);
  });
  $order_item_storage
    ->delete($order_items_to_remove);

  // Since we don't call removeItem(), we manually have to recalculate the
  // order total.
  $order
    ->recalculateTotalPrice();
}