|
| 1 | +<?php |
| 2 | +/** |
| 3 | + * Gravity Wiz // Gravity Forms // Conditional Logic Operator: "Does Not Contain" |
| 4 | + * |
| 5 | + * Instruction Video: https://www.loom.com/share/8e1b27ec47b341dbb4f0da2bec6a960b |
| 6 | + * |
| 7 | + * Check if a source field value does NOT contain a specific substring using the "does not contain" conditional logic operator. |
| 8 | + * |
| 9 | + * Plugin Name: GF Conditional Logic Operator: "Does Not Contain" |
| 10 | + * Plugin URI: https://gravitywiz.com/ |
| 11 | + * Description: Adds support for the "does not contain" conditional logic operator in Gravity Forms. |
| 12 | + * Author: Gravity Wiz |
| 13 | + * Version: 1.0 |
| 14 | + * Author URI: https://gravitywiz.com |
| 15 | + */ |
| 16 | +class GF_CLO_Does_Not_Contain { |
| 17 | + |
| 18 | + public function __construct() { |
| 19 | + add_action( 'init', array( $this, 'init' ) ); |
| 20 | + } |
| 21 | + |
| 22 | + public function init() { |
| 23 | + |
| 24 | + add_filter( 'admin_footer', array( $this, 'output_admin_inline_script' ) ); |
| 25 | + add_filter( 'gform_is_valid_conditional_logic_operator', array( $this, 'whitelist_operator' ), 10, 2 ); |
| 26 | + add_filter( 'gpeu_field_filters_from_conditional_logic', array( $this, 'convert_conditional_logic_to_field_filters' ) ); |
| 27 | + |
| 28 | + add_filter( 'gform_pre_render', array( $this, 'load_form_script' ), 10, 2 ); |
| 29 | + add_filter( 'gform_register_init_scripts', array( $this, 'add_init_script' ), 10, 2 ); |
| 30 | + add_filter( 'gform_is_value_match', array( $this, 'evaluate_operator' ), 10, 6 ); |
| 31 | + |
| 32 | + } |
| 33 | + |
| 34 | + public function output_admin_inline_script() { |
| 35 | + if ( ! GFForms::get_page() && ! is_admin() && ! in_array( rgget( 'page' ), array( 'gp-email-users' ) ) ) { |
| 36 | + return; |
| 37 | + } |
| 38 | + ?> |
| 39 | + <script> |
| 40 | + if ( window.gf_vars ) { |
| 41 | + gf_vars['does_not_contain'] = '<?php esc_html_e( 'does not contain' ); ?>'; |
| 42 | + } |
| 43 | + |
| 44 | + gform.addFilter( 'gform_conditional_logic_operators', function( operators ) { |
| 45 | + operators.does_not_contain = 'does not contain'; |
| 46 | + return operators; |
| 47 | + } ); |
| 48 | + </script> |
| 49 | + <?php |
| 50 | + } |
| 51 | + |
| 52 | + public function load_form_script( $form, $is_ajax_enabled ) { |
| 53 | + |
| 54 | + if ( $this->is_applicable_form( $form ) && ! has_action( 'wp_footer', array( $this, 'output_script' ) ) ) { |
| 55 | + add_action( 'wp_footer', array( $this, 'output_script' ) ); |
| 56 | + add_action( 'gform_preview_footer', array( $this, 'output_script' ) ); |
| 57 | + } |
| 58 | + |
| 59 | + return $form; |
| 60 | + } |
| 61 | + |
| 62 | + public function output_script() { |
| 63 | + ?> |
| 64 | + <script type="text/javascript"> |
| 65 | + ( function( $ ) { |
| 66 | + |
| 67 | + window.GWCLODoesNotContain = function( args ) { |
| 68 | + |
| 69 | + var self = this; |
| 70 | + |
| 71 | + for ( var prop in args ) { |
| 72 | + if ( args.hasOwnProperty( prop ) ) { |
| 73 | + self[ prop ] = args[ prop ]; |
| 74 | + } |
| 75 | + } |
| 76 | + |
| 77 | + self.init = function() { |
| 78 | + gform.addFilter( 'gform_is_value_match', function( isMatch, formId, rule ) { |
| 79 | + |
| 80 | + if ( rule.operator !== 'does_not_contain' ) { |
| 81 | + return isMatch; |
| 82 | + } |
| 83 | + |
| 84 | + var fieldValue = ''; |
| 85 | + var $field = $( '#input_' + formId + '_' + rule.fieldId ); |
| 86 | + |
| 87 | + // Handle different field types |
| 88 | + if ( $field.is(':checkbox') || $field.is(':radio') ) { |
| 89 | + fieldValue = $field.filter(':checked').map(function() { |
| 90 | + return this.value; |
| 91 | + }).get().join(','); |
| 92 | + } else if ( $field.is('select[multiple]') ) { |
| 93 | + fieldValue = $field.val() ? $field.val().join(',') : ''; |
| 94 | + } else { |
| 95 | + fieldValue = $field.val() || ''; |
| 96 | + } |
| 97 | + isMatch = typeof fieldValue === 'string' && fieldValue.indexOf( rule.value ) === -1; |
| 98 | + |
| 99 | + return isMatch; |
| 100 | + } ); |
| 101 | + }; |
| 102 | + |
| 103 | + self.init(); |
| 104 | + |
| 105 | + } |
| 106 | + |
| 107 | + } )( jQuery ); |
| 108 | + </script> |
| 109 | + <?php |
| 110 | + } |
| 111 | + |
| 112 | + public function add_init_script( $form ) { |
| 113 | + |
| 114 | + if ( ! $this->is_applicable_form( $form ) ) { |
| 115 | + return; |
| 116 | + } |
| 117 | + |
| 118 | + $script = 'new GWCLODoesNotContain();'; |
| 119 | + $slug = implode( '_', array( 'gwclo_does_not_contain', $form['id'] ) ); |
| 120 | + |
| 121 | + GFFormDisplay::add_init_script( $form['id'], $slug, GFFormDisplay::ON_PAGE_RENDER, $script ); |
| 122 | + } |
| 123 | + |
| 124 | + public function whitelist_operator( $is_valid, $operator ) { |
| 125 | + if ( $operator === 'does_not_contain' ) { |
| 126 | + $is_valid = true; |
| 127 | + } |
| 128 | + return $is_valid; |
| 129 | + } |
| 130 | + |
| 131 | + public function evaluate_operator( $is_match, $field_value, $target_value, $operation, $source_field, $rule ) { |
| 132 | + |
| 133 | + if ( $rule['operator'] !== 'does_not_contain' || rgar( $rule, 'gwclodncEvaluatingOperator' ) ) { |
| 134 | + return $is_match; |
| 135 | + } |
| 136 | + |
| 137 | + $rule['gwclodncEvaluatingOperator'] = true; |
| 138 | + |
| 139 | + // If the field contains the target value, it's not a match. |
| 140 | + $is_match = strpos( $field_value, $target_value ) === false; |
| 141 | + |
| 142 | + $rule['gwclodncEvaluatingOperator'] = false; |
| 143 | + |
| 144 | + return $is_match; |
| 145 | + } |
| 146 | + |
| 147 | + public function convert_conditional_logic_to_field_filters( $field_filters ) { |
| 148 | + |
| 149 | + foreach ( $field_filters as &$field_filter ) { |
| 150 | + if ( ! is_array( $field_filter ) ) { |
| 151 | + continue; |
| 152 | + } |
| 153 | + |
| 154 | + switch ( $field_filter['operator'] ) { |
| 155 | + case 'does_not_contain': |
| 156 | + $field_filter['operator'] = 'NOT LIKE'; |
| 157 | + $field_filter['value'] = '%' . $field_filter['value'] . '%'; |
| 158 | + break; |
| 159 | + } |
| 160 | + } |
| 161 | + |
| 162 | + return $field_filters; |
| 163 | + } |
| 164 | + |
| 165 | + public function is_applicable_form( $form ) { |
| 166 | + return GFFormDisplay::has_conditional_logic( $form ); |
| 167 | + } |
| 168 | +} |
| 169 | + |
| 170 | +# Configuration |
| 171 | + |
| 172 | +new GF_CLO_Does_Not_Contain(); |
0 commit comments