Gravity Wiz // Gravity Forms Calculation Range
<?php
# Default Usage
new GW_Calculation_Range( array(
'form_id' => 437,
'field_id' => 1,
'min' => 3,
'max' => 4
) );
# Auto-enforce Enabled
new GW_Calculation_Range( array(
'form_id' => 437,
'field_id' => 2,
'min' => 3,
'max' => 4,
'auto_enforce' => true
) );
<?php
/**
* Gravity Wiz // Gravity Forms Calculation Range
*
* Set a minimum and maximum range for your calculation fields.
*
* @version 1.0
* @author David Smith <david@gravitywiz.com>
* @license GPL-2.0+
* @link http://gravitywiz.com/...
* @copyright 2013 Gravity Wiz
*/
class GW_Calculation_Range {
public static $script_output = false;
public function __construct( $args = array() ) {
// make sure we're running the required minimum version of Gravity Forms
if( ! property_exists( 'GFCommon', 'version' ) || ! version_compare( GFCommon::$version, '1.8', '>=' ) )
return;
// set our default arguments, parse against the provided arguments, and store for use throughout the class
$this->_args = wp_parse_args( $args, array(
'form_id' => false,
'field_id' => false,
'min' => false,
'max' => false,
'auto_enforce' => false
) );
extract( $this->_args );
if( $auto_enforce && ! in_array( GFForms::get_page(), array( 'entry_detail', 'entry_detail_edit' ) ) ) {
add_action( 'gform_save_field_value', array( $this, 'auto_enforce_range' ), 10, 5 );
add_action( "gform_pre_render_{$form_id}", array( $this, 'maybe_output_script' ) );
add_action( "gform_register_init_scripts_{$form_id}", array( $this, 'add_init_script' ) );
} else {
add_action( "gform_field_validation_{$form_id}_{$field_id}", array( $this, 'validate_field' ), 10, 4 );
}
}
public function maybe_output_script( $form ) {
if( ! self::$script_output ) {
$this->script();
self::$script_output = true;
}
return $form;
}
public function script() {
?>
<script type="text/javascript">
var GWCalcRange;
(function($){
GWCalcRange = function( args ) {
var self = this;
// copy all args to current object: formId, fieldId
for( prop in args ) {
if( args.hasOwnProperty( prop ) )
self[prop] = args[prop];
}
self.init = function() {
gform.addFilter( 'gform_calculation_result', function( result, field, formId, GFCalcObj ) {
if( field.field_id != self.fieldId )
return result;
if( self.hasMin() && result < self.min ) {
result = self.min;
} else if( self.hasMax() && result > self.max ) {
result = self.max;
}
return result;
} );
}
self.hasMin = function() {
return self.min !== false;
}
self.hasMax = function() {
return self.max !== false;
}
self.init();
}
})(jQuery);
</script>
<?php
}
public function add_init_script( $form ) {
$args = array(
'formId' => $this->_args['form_id'],
'fieldId' => $this->_args['field_id'],
'min' => $this->_args['min'],
'max' => $this->_args['max']
);
$script = '; new GWCalcRange( ' . json_encode( $args ) . ' );';
$slug = "gw_calc_range_{$this->_args['form_id']}_{$this->_args['field_id']}";
GFFormDisplay::add_init_script( $this->_args['form_id'], $slug, GFFormDisplay::ON_PAGE_RENDER, $script );
}
public function auto_enforce_range( $value, $lead, $field, $form, $input_id ) {
if( $form['id'] != $this->_args['form_id'] )
return $value;
if( $field['id'] != $this->_args['field_id'] )
return $value;
$input_type = GFFormsModel::get_input_type( $field );
if( $input_type == 'calculation' && $input_id != "{$field['id']}.2" )
return $value;
$value = $this->get_clean_value( GFFormsModel::get_field_value( $field ), $field );
if( $this->is_min_subceeded( $value ) ) {
$value = $this->get_min();
} else if( $this->is_max_exceeded( $value ) ) {
$value = $this->get_max();
}
if( GFFormsModel::get_input_type( $field ) == 'calculation' )
$value = GFCommon::to_money( $value );
return $value;
}
public function validate_field( $result, $value, $form, $field ) {
$value = $this->get_clean_value( $value, $field );
if( $this->is_min_subceeded( $value ) || $this->is_max_exceeded( $value ) ) {
$result = array(
'is_valid' => false,
'message' => $this->get_validation_message()
);
}
return $result;
}
/**
* Check if the minimum range has not been met. I know "subceeded" isn't a real word...
*
* @param $value
*
* @return bool
*/
public function is_min_subceeded( $value ) {
return $this->has_min() && $value < $this->get_min();
}
public function is_max_exceeded( $value ) {
return $this->has_max() && $value > $this->get_max();
}
public function get_clean_value( $value, $field ) {
if( GFFormsModel::get_input_type( $field ) != 'calculation' )
return $value;
if( is_array( $value ) )
$value = rgar( $value, "{$field['id']}.2" );
$value = GFCommon::to_number( $value );
return $value;
}
public function get_validation_message() {
if( $this->has_max() && $this->has_min() )
return sprintf( __( 'Please enter a value between <strong>%1$d</strong> and <strong>%2$d</strong>.' ), $this->get_min(), $this->get_max() );
if( $this->has_min() )
return sprintf( __( 'Please enter a value greater than or equal to <strong>%d</strong>.' ), $this->get_min() );
if( $this->has_max() )
return sprintf( __( 'Please enter a value less than or equal to <strong>%d</strong>.' ), $this->get_max() );
return false;
}
public function has_max() {
return $this->get_max() !== false;
}
public function get_max() {
return $this->_args['max'];
}
public function has_min() {
return $this->get_min() !== false;
}
public function get_min() {
return $this->_args['min'];
}
}