Created
December 21, 2017 21:37
-
-
Save creover/e2fd7020e6734730ff00246bb2b139b6 to your computer and use it in GitHub Desktop.
Allows for the use of Signature fields in Conditional Logic
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Plugin Name: Gravity Forms Signature Conditional Logic | |
* Plugin URI: http://www.ryanprejean.com/ | |
* Description: Allows for the use of Signature fields in Conditional Logic | |
* Version: 1.1.0 | |
* Author: Ryan Prejean | |
* Author URI: http://www.ryanprejean.com/ | |
* License: GPL2 | |
*/ | |
add_action( 'plugins_loaded', array( 'GFCLSignatureFields', 'init' )); | |
class GFCLSignatureFields { | |
static $script_output = false; | |
static $applicable_fields = array(); | |
public static function init() { | |
$class = __CLASS__; | |
new $class; | |
} | |
function __construct() { | |
// make sure we're running the required minimum version of Gravity Forms | |
if( ! property_exists( 'GFCommon', 'version' ) || ! version_compare( GFCommon::$version, '2.1.1', '>=' ) || ! class_exists( 'GFSignature' ) ) { | |
return; | |
} | |
// handles evaluating signature-based conditional logic | |
add_filter( 'gform_is_value_match', array( $this, 'is_value_match' ), 10, 6 ); | |
add_filter( 'gform_admin_pre_render', array( $this, 'enqueue_admin_inline_scripts' ) ); | |
add_filter( 'gform_pre_render', array( $this, 'enqueue_inline_script' ), 10, 2 ); | |
add_filter( 'gform_field_css_class', array( $this, 'gfconfig_add_class'), 10, 3 ); | |
add_action( 'gform_register_init_scripts', array( $this, 'add_logic_event_to_input' ) ); | |
} | |
public function enqueue_admin_inline_scripts( $form ) { | |
add_filter( 'admin_footer', array( $this, 'allow_signature_fields_in_field_select' ) ); | |
return $form; | |
} | |
/** | |
* Allow Signature fields to be selected in the field select for conditional logic UI. | |
* | |
* @param mixed $form | |
*/ | |
function allow_signature_fields_in_field_select() { | |
?> | |
<script type="text/javascript"> | |
if( window.gform ) { | |
// allow Signature fields in conditional logic field select | |
gform.addFilter( 'gform_is_conditional_logic_field', function( isConditionalLogicField, field ) { | |
// if GF already considers this a conditional field OR if the field type is 'signatue' | |
return isConditionalLogicField || GetInputType( field ) == 'signature'; | |
} ); | |
gform.addFilter('gform_conditional_logic_operators', function (operators, objectType, fieldId) { | |
targetField = GetFieldById(fieldId); | |
if (targetField && targetField['type'] == 'signature') { | |
operators = {"is":"is", "isnot":"isNot"}; | |
} | |
return operators; | |
}); | |
gform.addFilter('gform_conditional_logic_values_input', function (str, objectType, ruleIndex, selectedFieldId, selectedValue) { | |
targetField = GetFieldById(selectedFieldId); | |
if (targetField && targetField['type'] == 'signature') { | |
var dropdownId = objectType + '_rule_value_' + ruleIndex; | |
str = "<input type='text' readonly='readonly' placeholder='Signed' class='gfield_rule_select' id='" + dropdownId + "' name='" + dropdownId + "' value='Signed' onchange='SetRuleProperty(\"" + objectType + "\", " + ruleIndex + ", \"value\", jQuery(this).val());' onkeyup='SetRuleProperty(\"" + objectType + "\", " + ruleIndex + ", \"value\", jQuery(this).val());'>"; | |
} | |
return str; | |
}); | |
} | |
</script> | |
<?php | |
} | |
/** | |
* Add the click event that triggers the conditional logic check when the value of the signature field is changed. | |
* | |
* @param mixed $form | |
*/ | |
function add_logic_event_to_input( $form ) { | |
$applicable_fields = self::get_applicable_signature_fields( $form ); | |
if( empty( $applicable_fields ) ) | |
return $form; | |
$logic_operaters = array(); | |
// loop through fields and add applicable signature fields to array | |
foreach( $applicable_fields as &$field ) { | |
$field_id = 'field_' . $field['formId'] . '_' . $field['id']; | |
$logic_operaters[$field_id] = $field["conditionalLogicFields"]; | |
} | |
ob_start(); | |
?> | |
window['logic_operators'] = <?php echo json_encode($logic_operaters) ?>; | |
( function( $ ) { | |
var logic_operators = window['logic_operators'], | |
$inputs = $( ".gfcls-field" ); | |
$inputs.click( function() { | |
var currentfieldID = $(this).attr('id'); | |
gf_apply_rules(<?php echo $form['id']; ?>, logic_operators[currentfieldID]); | |
}); | |
} )( jQuery ); | |
jQuery(document).bind('gform_post_render', function(event, form_id, current_page){ | |
var logic_operators = window['logic_operators']; | |
$( ".gfcls-field" ).each(function() { | |
var currentfieldID = $(this).attr('id'); | |
gf_apply_rules(form_id, logic_operators[currentfieldID]); | |
}); | |
}); | |
<?php | |
$script = ob_get_clean(); | |
GFFormDisplay::add_init_script( $form['id'], 'gform_signature_logic', GFFormDisplay::ON_PAGE_RENDER, $script ); | |
} | |
/** | |
* Modify the front-end form object by: | |
* Adding the 'gfcls-field' class to all signature fields upon which conditional logic is dependent | |
* | |
* @param mixed $form | |
*/ | |
function gfconfig_add_class( $classes, $field, $form ) { | |
$applicable_fields = self::get_applicable_signature_fields( $form ); | |
if( empty( $applicable_fields ) ) | |
return $classes; | |
$applicable_field_ids = wp_list_pluck( $applicable_fields, 'id' ); | |
if( in_array( $field['id'], $applicable_field_ids ) ) | |
$classes .= ' gfcls-field'; | |
return $classes; | |
} | |
function enqueue_inline_script( $form ) { | |
if( ! self::has_applicable_signature_fields( $form ) || has_filter( 'wp_footer', array( $this, 'output_inline_script' ) ) ) { | |
return $form; | |
} | |
add_filter( 'wp_footer', array( $this, 'output_inline_script' ), 99 ); | |
add_filter( 'gform_preview_footer', array( $this, 'output_inline_script' ) ); | |
return $form; | |
} | |
function output_inline_script() { | |
?> | |
<script type="text/javascript"> | |
gform.addFilter( 'gform_is_value_match', 'gcldfIsValueMatch' ); | |
function gcldfIsValueMatch( isMatch, formId, rule ) { | |
var sourceField = jQuery('#input_' + formId + '_' + rule.fieldId + '_data'), | |
image = jQuery('#input_' + formId + '_' + rule.fieldId + '_signature_filename'); | |
if( ! sourceField.parents( 'li.gfield' ).hasClass( 'gfcls-field' ) ) { | |
return isMatch; | |
} | |
var ruleValue = 'Signed', | |
fieldValue = sourceField.val() || image.val() ? 'Signed' : 'Unsigned'; | |
// must be strings for GF | |
isMatch = gf_matches_operation( fieldValue , ruleValue, rule.operator ); | |
return isMatch; | |
} | |
</script> | |
<?php | |
} | |
function is_value_match( $is_match, $field_value, $target_value, $operation, $source_field, $rule ) { | |
if( GFFormsModel::get_input_type( $source_field ) != 'signature' ) { | |
return $is_match; | |
} | |
$id = $source_field['id']; | |
$form_id = $source_field['formId']; | |
$field_id = 'input_' . $form_id . "_$id"; | |
$signature_filename = ! empty( $field_value ) ? $field_value : rgpost( "{$field_id}_signature_filename" ); | |
$value = ! empty( $signature_filename ) ? 'Signed' : 'Unsigned'; | |
$is_match = GFFormsModel::matches_operation( $value, $target_value, $operation); | |
return $is_match; | |
} | |
// HELPERS | |
/** | |
* Search through each fields conditional logic and look for signature fields. | |
* | |
* @param mixed $form | |
*/ | |
public static function get_applicable_signature_fields( $form ) { | |
$form_id = is_array( $form ) ? $form['id'] : $form; | |
if( isset( self::$applicable_fields[$form_id] ) ) | |
return self::$applicable_fields[$form_id]; | |
if( ! is_array( $form ) ) | |
$form = GFFormsModel::get_form_meta( $form_id ); | |
self::$applicable_fields[$form_id] = self::get_applicable_fields_recursive( $form ); | |
return self::$applicable_fields[$form_id]; | |
} | |
public static function get_applicable_fields_recursive( $object, $form = false, $applicable_fields = array() ) { | |
// if no $form is provided, assume that the $object is the form object | |
if( ! $form ) | |
$form = $object; | |
foreach( $object as $prop => $value ) { | |
if( $prop && $prop == 'conditionalLogic' && ! empty( $value ) ) { | |
foreach( $object[$prop]['rules'] as $rule ) { | |
$ruleField = RGFormsModel::get_field( $form, $rule['fieldId'] ); | |
if( GFFormsModel::get_input_type( $ruleField ) == 'signature' ) { | |
$applicable_fields[] = $ruleField; | |
} | |
} | |
} else if( is_array( $value ) || is_a( $value, 'GF_Field' ) ) { | |
$applicable_fields = self::get_applicable_fields_recursive( $value, $form, $applicable_fields ); | |
} | |
} | |
return $applicable_fields; | |
} | |
public static function has_applicable_signature_fields( $form ) { | |
$applicable_fields = self::get_applicable_signature_fields( $form ); | |
return !empty( $applicable_fields ); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment