diff --git a/modules/product_pricing/commerce_product_pricing.module b/modules/product_pricing/commerce_product_pricing.module index ba42440..e480e66 100644 --- a/modules/product_pricing/commerce_product_pricing.module +++ b/modules/product_pricing/commerce_product_pricing.module @@ -111,53 +111,60 @@ function commerce_product_pricing_commerce_price_field_formatter_prepare_view($e function commerce_product_calculate_sell_price($product, $precalc = FALSE) { $prices = &drupal_static(__FUNCTION__, array()); - if (isset($prices[$product->product_id])) { - return $prices[$product->product_id]; - } - // First create a pseudo product line item that we will pass to Rules. $line_item = commerce_product_line_item_new($product); // Allow modules to prepare this as necessary. drupal_alter('commerce_product_calculate_sell_price_line_item', $line_item); - // Attempt to fetch a database stored price if specified. - if ($precalc) { - $module_key = commerce_product_pre_calculation_key(); - - $result = db_select('commerce_calculated_price') - ->fields('commerce_calculated_price', array('amount', 'currency_code', 'data')) - ->condition('module', 'commerce_product_pricing') - ->condition('module_key', $module_key) - ->condition('entity_type', 'commerce_product') - ->condition('entity_id', $product->product_id) - ->condition('field_name', 'commerce_price') - ->execute() - ->fetchObject(); - - // If a pre-calculated price was found... - if (!empty($result)) { - // Wrap the line item and swap in the price. - $wrapper = entity_metadata_wrapper('commerce_line_item', $line_item); - $wrapper->commerce_unit_price->amount = $result->amount; - $wrapper->commerce_unit_price->currency_code = $result->currency_code; - - // Unserialize the saved prices data array and initialize to an empty - // array if the column was empty. - $result->data = unserialize($result->data); - $wrapper->commerce_unit_price->data = !empty($result->data) ? $result->data : array(); - - $prices[$product->product_id] = $wrapper->commerce_unit_price->value(); + // Generate a cache ID based on product ID, line item hash, and precalc. + $static_cid = implode(':', array( + $product->product_id, + md5($line_item), + (string) $precalc, + )); + + // Check if product price has been cached. + if (!isset($prices[$static_cid])) { + + // Attempt to fetch a database stored price if specified. + if ($precalc) { + $module_key = commerce_product_pre_calculation_key(); + + $result = db_select('commerce_calculated_price') + ->fields('commerce_calculated_price', array('amount', 'currency_code', 'data')) + ->condition('module', 'commerce_product_pricing') + ->condition('module_key', $module_key) + ->condition('entity_type', 'commerce_product') + ->condition('entity_id', $product->product_id) + ->condition('field_name', 'commerce_price') + ->execute() + ->fetchObject(); + + // If a pre-calculated price was found... + if (!empty($result)) { + // Wrap the line item and swap in the price. + $wrapper = entity_metadata_wrapper('commerce_line_item', $line_item); + $wrapper->commerce_unit_price->amount = $result->amount; + $wrapper->commerce_unit_price->currency_code = $result->currency_code; + + // Unserialize the saved prices data array and initialize to an empty + // array if the column was empty. + $result->data = unserialize($result->data); + $wrapper->commerce_unit_price->data = !empty($result->data) ? $result->data : array(); + + $prices[$static_cid] = $wrapper->commerce_unit_price->value(); + } } - } - else { - // Pass the line item to Rules. - rules_invoke_event('commerce_product_calculate_sell_price', $line_item); + else { + // Pass the line item to Rules. + rules_invoke_event('commerce_product_calculate_sell_price', $line_item); - $prices[$product->product_id] = entity_metadata_wrapper('commerce_line_item', $line_item)->commerce_unit_price->value(); + $prices[$static_cid] = entity_metadata_wrapper('commerce_line_item', $line_item)->commerce_unit_price->value(); + } } - return $prices[$product->product_id]; + return $prices[$static_cid]; } /**