Quantcast
Viewing all articles
Browse latest Browse all 196

Subtotal Merge Tag (for Calculations)

A simple (but hacky) way of getting the subtotal for your Gravity Form calculations.

Currently, there is no easy way to get the current total (let’s call it the subtotal) of the form for use in calculations. It’s possible but you’ll have to enter all of your product merge tags into a long and complicated formula to get the subtotal.

This snippet helps you avoid that hassle by providing a {subtotal} merge tag for use in your Gravity Form calculations.

Please note: The {subtotal} merge tag is only available in for fields that support calculations.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
<?php
/**
* Calculation Subtotal Merge Tag
* http://gravitywiz.com/
*/
class GWCalcSubtotal {
public static $merge_tag = '{subtotal}';
function __construct() {
// front-end
add_filter( 'gform_pre_render', array( $this, 'maybe_replace_subtotal_merge_tag' ) );
add_filter( 'gform_pre_submission_filter', array( $this, 'maybe_replace_subtotal_merge_tag' ) );
// back-end
add_filter( 'gform_admin_pre_render', array( $this, 'add_merge_tags' ) );
}
/**
* Look for {subtotal} merge tag in form fields 'calculationFormula' property. If found, replace with the
* aggregated subtotal merge tag string.
*
* @param mixed $form
*/
function maybe_replace_subtotal_merge_tag( $form ) {
foreach( $form['fields'] as &$field ) {
if( !self::has_subtotal_merge_tag( $field ) )
continue;
$subtotal_merge_tags = self::get_subtotal_merge_tag_string( $form, $field );
$field['calculationFormula'] = str_replace( self::$merge_tag, $subtotal_merge_tags, $field['calculationFormula'] );
}
return $form;
}
/**
* Get all the pricing fields on the form, get their corresponding merge tags and aggregate them into a formula that
* will yeild the form's subtotal.
*
* @param mixed $form
*/
static function get_subtotal_merge_tag_string( $form, $current_field ) {
$pricing_fields = self::get_pricing_fields( $form );
$product_tag_groups = array();
foreach( $pricing_fields['products'] as $product ) {
$product_field = rgar( $product, 'product' );
$option_fields = rgar( $product, 'options' );
$quantity_field = rgar( $product, 'quantity' );
// do not include current field in subtotal
if( $product_field['id'] == $current_field['id'] )
continue;
$product_tags = GFCommon::get_field_merge_tags( $product_field );
$quantity_tag = 1;
// if a single product type, only get the "price" merge tag
if( in_array( GFFormsModel::get_input_type( $product_field ), array( 'singleproduct', 'calculation' ) ) ) {
// single products provide quantity merge tag
if( empty( $quantity_field ) )
$quantity_tag = $product_tags[2]['tag'];
$product_tags = array( $product_tags[1] );
}
// if quantity field is provided for product, get merge tag
if( !empty( $quantity_field ) ) {
$quantity_tag = GFCommon::get_field_merge_tags( $quantity_field );
$quantity_tag = $quantity_tag[0]['tag'];
}
$product_tags = wp_list_pluck( $product_tags, 'tag' );
$option_tags = array();
foreach( $option_fields as $option_field ) {
$new_options_tags = GFCommon::get_field_merge_tags( $option_field );
if( !is_array( $new_options_tags ) )
continue;
if( GFFormsModel::get_input_type( $option_field ) == 'checkbox' ) {
array_shift( $new_options_tags );
} else {
$new_options_tags = array( array_shift( $new_options_tags ) );
}
$option_tags = array_merge( $option_tags, $new_options_tags );
}
$option_tags = wp_list_pluck( $option_tags, 'tag' );
$product_tag_groups[] = '( ( ' . implode( ' + ', array_merge( $product_tags, $option_tags ) ) . ' ) * ' . $quantity_tag . ' )';
}
$shipping_tag = 0;
if( rgar( $pricing_fields, 'shipping' ) ) {
$shipping_tag = GFCommon::get_field_merge_tags( rgars( $pricing_fields, 'shipping/0' ) );
$shipping_tag = $shipping_tag[0]['tag'];
}
$pricing_tag_string = '( ( ' . implode( ' + ', $product_tag_groups ) . ' ) + ' . $shipping_tag . ' )';
return $pricing_tag_string;
}
/**
* Get all pricing fields from a given form object grouped by product and shipping with options nested under their
* respective products.
*
* @param mixed $form
*/
static function get_pricing_fields( $form ) {
$product_fields = array();
 
foreach( $form["fields"] as $field ) {
if( $field["type"] != 'product' )
continue;
$option_fields = GFCommon::get_product_fields_by_type($form, array("option"), $field['id'] );
// can only have 1 quantity field
$quantity_field = GFCommon::get_product_fields_by_type( $form, array("quantity"), $field['id'] );
$quantity_field = rgar( $quantity_field, 0 );
$product_fields[] = array(
'product' => $field,
'options' => $option_fields,
'quantity' => $quantity_field
);
}
 
$shipping_field = GFCommon::get_fields_by_type($form, array("shipping"));
 
return array( "products" => $product_fields, "shipping" => $shipping_field );
}
function add_merge_tags( $form ) {
$label = __('Subtotal', 'gravityforms');
?>
<script type="text/javascript">
// for the future (not yet supported for calc field)
gform.addFilter("gform_merge_tags", "gwcs_add_merge_tags");
function gwcs_add_merge_tags( mergeTags, elementId, hideAllFields, excludeFieldTypes, isPrepop, option ) {
console.log( elementId );
mergeTags["pricing"].tags.push({ tag: '<?php echo self::$merge_tag; ?>', label: '<?php echo $label; ?>' });
return mergeTags;
}
// hacky, but only temporary
jQuery(document).ready(function($){
var calcMergeTagSelect = $('#field_calculation_formula_variable_select');
calcMergeTagSelect.find('optgroup').eq(0).append( '<option value="<?php echo self::$merge_tag; ?>"><?php echo $label; ?></option>' );
});
</script>
<?php
//return the form object from the php hook
return $form;
}
static function has_subtotal_merge_tag( $field ) {
// check if form is passed
if( isset( $field['fields'] ) ) {
$form = $field;
foreach( $form['fields'] as $field ) {
if( self::has_subtotal_merge_tag( $field ) )
return true;
}
} else {
if( isset( $field['calculationFormula'] ) && strpos( $field['calculationFormula'], self::$merge_tag ) !== false )
return true;
}
return false;
}
}
 
new GWCalcSubtotal();
view raw gistfile1.php This Gist brought to you by GitHub.

How do I install this snippet?

Easy peasy. Just copy and paste the code above into your theme's functions.php file.

How do I use this functionality?

This snippet will add a new “Subtotal” merge tag to the merge tag select available for the “Formula” setting on Calculation fields. Selecting this option will insert the {subtotal} merge tag into your “Formula” setting. You can then use all available mathematical operations available to this field to manipulate this subtotal as needed.

Image may be NSFW.
Clik here to view.
formula-subtotal-merge-tag
Formula Setting: Subtotal Merge Tag
Image may be NSFW.
Clik here to view.
formula-subtotal-tax
Formula Setting: Subtotal Used to Calculate Tax

The post Subtotal Merge Tag (for Calculations) appeared first on Gravity Wiz.


Viewing all articles
Browse latest Browse all 196

Trending Articles