You are here

function commerce_cart_order_refresh in Commerce Core 7

Refreshes the contents of a shopping cart by finding the most current prices for any product line items on the order.

Parameters

$order: The order object whose line items should be refreshed.

Return value

The updated order's wrapper.

3 calls to commerce_cart_order_refresh()
commerce_cart_commerce_order_load in modules/cart/commerce_cart.module
Implements hook_commerce_order_load().
commerce_cart_handler_field_edit_attributes::views_form in modules/cart/includes/views/handlers/commerce_cart_handler_field_edit_attributes.inc
Returns the form which replaces the placeholder from render().
commerce_cart_order_refresh_form_submit in modules/cart/includes/commerce_cart.admin.inc
Form submit callback for commerce_cart_order_refresh_form().

File

modules/cart/commerce_cart.module, line 1103
Implements the shopping cart system and add to cart features.

Code

function commerce_cart_order_refresh($order) {
  $order_wrapper = entity_metadata_wrapper('commerce_order', $order);

  // Allow other modules to act on the order prior to the refresh logic.
  module_invoke_all('commerce_cart_order_pre_refresh', $order);

  // Loop over every line item on the order...
  $line_item_changed = FALSE;
  foreach ($order_wrapper->commerce_line_items as $delta => $line_item_wrapper) {

    // If the current line item actually no longer exists...
    if (!$line_item_wrapper
      ->value()) {

      // Remove the reference from the order and continue to the next value.
      $order_wrapper->commerce_line_items
        ->offsetUnset($delta);
      continue;
    }

    // Knowing it exists, clone the line item now.
    $cloned_line_item = clone $line_item_wrapper
      ->value();

    // If the line item is a product line item...
    if (in_array($cloned_line_item->type, commerce_product_line_item_types())) {
      $product = $line_item_wrapper->commerce_product
        ->value();

      // If this price has already been calculated, reset it to its original
      // value so it can be recalculated afresh in the current context.
      if (isset($product->commerce_price[LANGUAGE_NONE][0]['original'])) {
        $original = $product->commerce_price[LANGUAGE_NONE][0]['original'];
        foreach ($product->commerce_price as $langcode => $value) {
          $product->commerce_price[$langcode] = array(
            0 => $original,
          );
        }
      }

      // Repopulate the line item array with the default values for the product
      // as though it had not been added to the cart yet, but preserve the
      // current quantity and display URI information.
      commerce_product_line_item_populate($cloned_line_item, $product);

      // Process the unit price through the sell price calculation callback
      // so it reflects the user's actual current purchase price.
      commerce_product_pricing_invoke($cloned_line_item);
    }

    // Allow other modules to alter line items on a shopping cart refresh.
    module_invoke_all('commerce_cart_line_item_refresh', $cloned_line_item, $order_wrapper);

    // Delete this line item if it no longer has a valid price.
    $current_line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $cloned_line_item);
    if (is_null($current_line_item_wrapper->commerce_unit_price
      ->value()) || is_null($current_line_item_wrapper->commerce_unit_price->amount
      ->value()) || is_null($current_line_item_wrapper->commerce_unit_price->currency_code
      ->value())) {
      commerce_cart_order_product_line_item_delete($order, $cloned_line_item->line_item_id, TRUE);
      $line_item_changed = TRUE;
    }
    else {

      // Compare the refreshed unit price to the original unit price looking for
      // differences in the amount, currency code, or price components.
      $data = $line_item_wrapper->commerce_unit_price->data
        ->value() + array(
        'components' => array(),
      );
      $current_data = (array) $current_line_item_wrapper->commerce_unit_price->data
        ->value() + array(
        'components' => array(),
      );
      if ($line_item_wrapper->commerce_unit_price->amount
        ->value() != $current_line_item_wrapper->commerce_unit_price->amount
        ->value() || $line_item_wrapper->commerce_unit_price->currency_code
        ->value() != $current_line_item_wrapper->commerce_unit_price->currency_code
        ->value() || $data['components'] != $current_data['components']) {

        // Adjust the unit price accordingly if necessary.
        $line_item_wrapper->commerce_unit_price->amount = $current_line_item_wrapper->commerce_unit_price->amount
          ->value();
        $line_item_wrapper->commerce_unit_price->currency_code = $current_line_item_wrapper->commerce_unit_price->currency_code
          ->value();

        // Only migrate the price components in the data to preserve other data.
        $data['components'] = $current_data['components'];
        $line_item_wrapper->commerce_unit_price->data = $data;

        // Save the updated line item.
        commerce_line_item_save($line_item_wrapper
          ->value());
        $line_item_changed = TRUE;
      }
    }
  }

  // Store a copy of the original order to see if it changes later.
  $original_order = clone $order_wrapper
    ->value();

  // Allow other modules to alter the entire order on a shopping cart refresh.
  module_invoke_all('commerce_cart_order_refresh', $order_wrapper);

  // Save the order once here if it has changed or if a line item was changed.
  if ($order_wrapper
    ->value() != $original_order || $line_item_changed) {
    commerce_order_save($order_wrapper
      ->value());
  }
  return $order_wrapper;
}