In Drupal Commerce I want to display multiple prices on a product, regardless of what price the user is entitled to:
- The normal price (for people without membership)
- The user price
- The maximum discount price (for people with the most expensive membership)
I fixed this using a custom rules action and an accompanying custom field formatter (as was confirmed to be the correct way), but I have some doubts regarding the way I implemented it. Below the code:
/**
* hook_rules_action_info()
*
* Create custom Rules action to save discount value.
* see callback (multipriceformatter_calculate_full_discount_price) for more info.
*/
function multipriceformatter_rules_action_info() {
$defaults = array(
'group' => t('Commerce pricing')
);
$actions = array(
'multipriceformatter_calculate_full_discount_price' => $defaults + array(
'label' => t('Calculate Full Discount Price'),
'parameter' => array(
'line_item_label' => array( // Line item LABEL necessary to store full discount price in SESSION
'type' => 'text',
'label' => t('Enter line item label'),
'description' => t('Line item label - NOT line item id, that one is always empty..'),
),
'calculate_full_discount_price' => array(
'type' => 'text',
'label' => t('Full discounted product price'),
'description' => t('The full discounted price should be calculated in an action BEFORE this action.'.
'Then the outputted value is available here.'),
),
),
)
);
return $actions;
}
/**
* Callback as defined by multipriceformatter_rules_action_info()
* The function name is necessarily the same as the action-name
*
***
* Store full_discount_price in a session, to access it
* later on for display
* see: multipriceformatter_field_formatter_view
*/
function multipriceformatter_calculate_full_discount_price($line_item_label, $calculate_full_discount_price){
// Use $line_item_label as unique id for the calculated price. Line_item_label equals
// the product SKU
// There exists some functionality to return variables from this function,
// but I don't know where these values end up - they're probably only available
// to Rules UI..
// Also, don't use variable_set/_get methods because that stores into the database, and we need to
// unset those variables when deleting products/disabling the module/etc. etc.
// Bottomline: SESSION is the easy way :)
$_SESSION['discount_prices'][$line_item_label] = $calculate_full_discount_price;
}
function multipriceformatter_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display){
// Obtain SESSION['discount_prices'] here to process it further/display it..
}
The point: shouldn't there be a better way to move the discount value than by using SESSIONs?
Comments
Comment #1
tr commentedYes. Your action needs to "provide" a variable value, which will then be passed in the context to subsequent rules. For an example, see how the core Rules data_calc action does this. The hook_rules_action_info() for this action is in modules/data.rules.inc, and the implementation is in modules/data.eval.inc.
Comment #2
tr commented