You are here

function commerce_product_pricing_commerce_price_field_formatter_prepare_view in Commerce Core 7

Implements hook_commerce_price_field_formatter_prepare_view().

It isn't until the point of display that we know whether a particular price field should be altered to display the current user's purchase price of the product. Therefore, instead of trying to calculate dynamic prices on load, we calculate them prior to display but at the point where we know the full context of the display, including the display formatter settings for the pertinent view mode.

The hook is invoked before a price field is formatted, so this implementation lets us swap in the calculated sell price of a product for a given point of display. The way it calculates the price is by creating a pseudo line item for the current product that is passed to Rules for transformation. Rule configurations may then use actions to set and alter the unit price of the line item, which, being an object, is passed by reference through all the various actions. Upon completion of the Rules execution, the unit price data is then swapped in for the data of the current field for display.

File

modules/product_pricing/commerce_product_pricing.module, line 68
Enables Rules based product sell price calculation for dynamic product pricing.

Code

function commerce_product_pricing_commerce_price_field_formatter_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $displays) {

  // If this is a single value purchase price field attached to a product...
  if ($entity_type == 'commerce_product' && $field['field_name'] == 'commerce_price' && $field['cardinality'] == 1) {

    // Prepare the items for each entity passed in.
    foreach ($entities as $product_id => $product) {

      // If this price should be calculated...
      if (!empty($displays[$product_id]['settings']['calculation']) && $displays[$product_id]['settings']['calculation'] == 'calculated_sell_price') {

        // 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($items[$product_id][0]['original'])) {
          $original = $items[$product_id][0]['original'];
          $items[$product_id] = array(
            0 => $original,
          );

          // Reset the price field value on the product object used to perform
          // the calculation.
          foreach ($product->commerce_price as $langcode => $value) {
            $product->commerce_price[$langcode] = $items[$product_id];
          }
        }
        else {

          // Save the original value for use in subsequent calculations.
          $original = isset($items[$product_id][0]) ? $items[$product_id][0] : NULL;
        }

        // Replace the data being displayed with data from a calculated price.
        if (!empty($original)) {
          $items[$product_id] = array();
          $items[$product_id][0] = commerce_product_calculate_sell_price($product);
          $items[$product_id][0]['original'] = $original;
        }
      }
    }
  }
}