PluginProbe ʕ •ᴥ•ʔ
Conditional Fields for Contact Form 7 / 2.7.8
Conditional Fields for Contact Form 7 v2.7.8
2.7.8 2.7.7 2.7.6 2.7.5 2.7.4 2.7.3 2.7.2 0.2.4 0.2.5 0.2.6 0.2.7 0.2.8 0.2.9 1.0 1.1 1.2 1.2.1 1.2.2 1.2.3 1.3 1.3.1 1.3.2 1.3.3 1.3.4 1.4 1.4.1 1.4.2 1.4.3 1.5 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.6.1 1.6.2 1.6.3 1.6.5 1.7 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.8 1.7.9 1.8 1.8.1 1.8.2 1.8.3 1.8.5 1.8.6 1.8.7 1.9 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.15 1.9.16 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.2 2.2.1 2.2.10 2.2.11 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 2.3 2.3.1 2.3.10 2.3.11 2.3.12 2.3.2 2.3.3 2.3.4 2.3.5 2.3.6 2.3.7 2.3.8 2.3.9 2.4 2.4.1 2.4.10 2.4.11 2.4.12 2.4.13 2.4.14 2.4.15 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.4.8 2.4.9 2.5 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.14 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6 2.6.1 2.6.2 2.6.3 2.6.4 2.6.5 2.6.6 2.6.7 2.6.8 2.7 2.7.1 trunk 0.1 0.1.1 0.1.2 0.1.3 0.1.4 0.1.5 0.1.6 0.1.7 0.2 0.2.1 0.2.2 0.2.3
cf7-conditional-fields / cf7cf.php
cf7-conditional-fields Last commit date
js 1 week ago jsdoc-out 1 week ago test-results 2 months ago Wpcf7cfMailParser.php 1 month ago admin-style.css 2 years ago admin-style.css.map 2 years ago admin-style.scss 4 years ago admin.php 2 years ago cf7cf.php 1 week ago conditional-fields.php 1 week ago contact-form-7-conditional-fields.php 1 year ago init.php 1 week ago readme.txt 1 week ago style.css 2 months ago tg_pane_group.php 2 months ago wpcf7cf-options.php 2 months ago
cf7cf.php
542 lines
1 <?php
2
3 class CF7CF {
4 private $hidden_fields = array();
5 private $visible_groups = array();
6 private $hidden_groups = array();
7 private $repeaters = array();
8 private $steps = array();
9
10 function __construct() {
11
12 // compatibility with CF7 multi-step forms by Webhead LLC.
13 add_filter( 'wpcf7_posted_data', array($this,'cf7msm_merge_post_with_cookie'), 8, 1 );
14
15 // compatibility with CF7 Multi Step by NinjaTeam https://wordpress.org/plugins/cf7-multi-step/
16 add_action('wp_ajax_cf7mls_validation', array($this,'cf7mls_validation_callback'),9);
17 add_action('wp_ajax_nopriv_cf7mls_validation', array($this,'cf7mls_validation_callback'),9);
18
19 add_filter( 'wpcf7_validate', array($this, 'skip_validation_for_hidden_fields'), 2, 2 );
20
21 add_filter( 'wpcf7_validate_file*', array($this, 'skip_validation_for_hidden_file_field'), 30, 3);
22 add_filter( 'wpcf7_validate_multifile*', array($this, 'skip_validation_for_hidden_file_field'), 30, 3);
23
24 // If acceptance_as_validation is on, then Acceptance fields inside hidden groups should not trigger an error
25 add_filter( 'wpcf7_acceptance', function($accepted, $submission) {
26 $acceptance_as_validation = $submission->get_contact_form()->additional_setting('acceptance_as_validation');
27 return $accepted || (is_array($acceptance_as_validation) && in_array('on', $acceptance_as_validation));
28 }, 20, 2 );
29
30 // validation messages
31 add_action('wpcf7_config_validator_validate', array($this,'wpcf7cf_config_validator_validate'));
32
33 add_action("wpcf7_before_send_mail", [$this, 'hide_hidden_mail_fields'], 10, 3);
34
35 register_activation_hook(__FILE__, array($this, 'activate'));
36
37 if (is_admin()) {
38 require_once dirname(__FILE__) . '/admin.php';
39 }
40 }
41
42
43
44 /**
45 * Suppress invalid mailbox syntax errors on fields that contain existing conditional groups.
46 * Fields to check:
47 * - mail.recipient, mail.sender, mail.additional_headers
48 * - mail2.recipient, mail2.sender, mail2.additional_headers
49 */
50 function wpcf7cf_config_validator_validate(WPCF7_ConfigValidator $wpcf7_config_validator) {
51
52 $errors = $wpcf7_config_validator->collect_error_messages();
53
54 if (empty($errors)) {
55 return; // no errors, nothing to do
56 }
57
58 $cf = $wpcf7_config_validator->contact_form();
59
60 // find all group names from the form tags
61 $all_group_tags = array_filter($cf->scan_form_tags(), function($tag) { return $tag['type'] == 'group'; });
62 $all_group_names = array_map(function($tag) { return $tag['name']; }, $all_group_tags);
63
64 $available_error_codes = (array) apply_filters(
65 'wpcf7_config_validator_available_error_codes',
66 WPCF7_ConfigValidator::error_codes,
67 $cf
68 );
69
70 foreach ($errors as $err_type => $err) {
71
72 $parts = explode('.',$err_type);
73
74 $property = $parts[0];
75 $sub_prop = $parts[1];
76
77 $is_emailadress_property = in_array($property, ['mail', 'mail_2']) && in_array($sub_prop, ['recipient', 'sender', 'additional_headers']);
78
79 if ( !$is_emailadress_property ) {
80 continue; // only check email address properties
81 }
82
83 if (!isset($cf->prop($property)[$sub_prop]) || empty($cf->prop($property)[$sub_prop])) {
84 continue; // skip if the property is not set
85 }
86
87 // get the value of the property
88 $prop_val = $cf->prop($property)[$sub_prop];
89
90 // strip all [group_name] and [/group_name] tags from the prop_value
91 foreach ($all_group_names as $group_name) {
92 $prop_val = str_replace("[$group_name]", '', $prop_val);
93 $prop_val = str_replace("[/$group_name]", '', $prop_val);
94 }
95
96 // remove all current errors on the property, and then run the validation function again with the group tags stripped from the prop_value
97 if (in_array($sub_prop, ['recipient', 'sender', 'additional_headers'])) {
98 foreach ($available_error_codes as $error_code) {
99 $wpcf7_config_validator->remove_error($err_type, $error_code);
100 }
101 $validation_function = 'validate_mail_' . $sub_prop;
102 $wpcf7_config_validator->$validation_function($property, $prop_val);
103 }
104
105 }
106 }
107
108 function activate() {
109 //add options with add_option and stuff
110 }
111
112 /**
113 * Remove validation requirements for fields that are hidden at the time of form submission.
114 * Required/invalid fields should never trigger validation errors if they are inside a hidden group during submission.
115 * Called using add_filter( 'wpcf7_validate', array($this, 'skip_validation_for_hidden_fields'), 2, 2 );
116 * where the priority of 2 causes this to kill any validations with a priority higher than 2
117 *
118 * NOTE: CF7 is weirdly designed when it comes to validating a form with files.
119 * Only the non-file fields are considered during the wpcf7_validate filter.
120 * When validation passes for all fields (except the file fields), the files fields are validated individually.
121 * ( see skip_validation_for_hidden_file_field )
122 *
123 * @param $result
124 * @param $tag
125 *
126 * @return mixed
127 */
128 function skip_validation_for_hidden_fields($result, $tags, $args = []) {
129
130 if(isset($_POST)) {
131 $this->set_hidden_fields_arrays($_POST);
132 }
133
134 $invalid_fields = $result->get_invalid_fields();
135 $return_result = new WPCF7_Validation();
136
137 if (count($this->hidden_fields) == 0 || !is_array($invalid_fields) || count($invalid_fields) == 0) {
138 $return_result = $result;
139 } else {
140 foreach ($invalid_fields as $invalid_field_key => $invalid_field_data) {
141 if (!in_array($invalid_field_key, $this->hidden_fields)) {
142 foreach ($tags as $tag) {
143 if ($tag['name'] === $invalid_field_key) {
144 $return_result->invalidate($tag, $invalid_field_data['reason']);
145 }
146 }
147 }
148 }
149 }
150
151 return apply_filters('wpcf7cf_validate', $return_result, $tags);
152
153 }
154
155 /**
156 * Does the same thing as skip_validation_for_hidden_fields, but CF7 will check files again later
157 * via the wpcf7_unship_uploaded_files function
158 * so we need to skip validation a second time for individual file fields
159 */
160 function skip_validation_for_hidden_file_field($result, $tag, $args=[]) {
161
162 if (!count($result->get_invalid_fields())) {
163 return $result;
164 }
165 if(isset($_POST)) {
166 $this->set_hidden_fields_arrays($_POST);
167 }
168
169 $invalid_field_keys = array_keys($result->get_invalid_fields());
170
171 // if the current file is the only invalid tag in the result AND if the file is hidden: return a valid (blank) object
172 if (isset($this->hidden_fields) && is_array($this->hidden_fields) && in_array($tag->name, $this->hidden_fields) && count($invalid_field_keys) == 1) {
173 return new WPCF7_Validation();
174 }
175
176 // if the current file is not hidden, we'll just return the result (keep it invalid).
177 // (Note that this might also return the hidden files as invalid, but that shouldn't matter because the form is invalid, and the notification will be inside a hidden group)
178 return $result;
179 }
180
181 function cf7msm_merge_post_with_cookie($posted_data) {
182
183 if (!function_exists('cf7msm_get') || !key_exists('cf7msm_posted_data',$_COOKIE)) return $posted_data;
184
185 if (!$posted_data) {
186 $posted_data = WPCF7_Submission::get_instance()->get_posted_data();
187 }
188
189 // this will temporarily set the hidden fields data to the posted_data.
190 // later this function will be called again with the updated posted_data
191 $this->set_hidden_fields_arrays($_POST);
192
193 // get cookie data
194 $cookie_data = cf7msm_get('cf7msm_posted_data');
195 $cookie_data_hidden_group_fields = json_decode(stripslashes($cookie_data['_wpcf7cf_hidden_group_fields']));
196 $cookie_data_hidden_groups = json_decode(stripslashes($cookie_data['_wpcf7cf_hidden_groups']));
197 $cookie_data_visible_groups = json_decode(stripslashes($cookie_data['_wpcf7cf_visible_groups']));
198
199 // remove all the currently posted data from the cookie data (we don't wanna add it twice)
200 $cookie_data_hidden_group_fields = array_diff($cookie_data_hidden_group_fields, array_keys($posted_data));
201 $cookie_data_hidden_groups = array_diff((array) $cookie_data_hidden_groups, $this->hidden_groups, $this->visible_groups);
202 $cookie_data_visible_groups = array_diff((array) $cookie_data_visible_groups, $this->hidden_groups, $this->visible_groups);
203
204 // update current post data with cookie data
205 $posted_data['_wpcf7cf_hidden_group_fields'] = addslashes(json_encode(array_merge((array) $cookie_data_hidden_group_fields, $this->hidden_fields)));
206 $posted_data['_wpcf7cf_hidden_groups'] = addslashes(json_encode(array_merge((array) $cookie_data_hidden_groups, $this->hidden_groups)));
207 $posted_data['_wpcf7cf_visible_groups'] = addslashes(json_encode(array_merge((array) $cookie_data_visible_groups, $this->visible_groups)));
208
209 return $posted_data;
210 }
211
212 // compatibility with CF7 Multi Step by NinjaTeam https://wordpress.org/plugins/cf7-multi-step/
213 function cf7mls_validation_callback() {
214 $this->set_hidden_fields_arrays($_POST);
215 }
216
217 /**
218 * Finds the currently submitted form and set the hidden_fields variables accoringly
219 *
220 * @param bool|array $posted_data
221 */
222 function set_hidden_fields_arrays($posted_data = false) {
223
224 if (!$posted_data) $posted_data = $_POST;
225
226 // keys may be absent on REST API submissions, fall back to defaults to avoid PHP 8 undefined-key warnings
227 $hidden_fields = json_decode(stripslashes($posted_data['_wpcf7cf_hidden_group_fields'] ?? '[]'));
228 if (is_array($hidden_fields) && count($hidden_fields) > 0) {
229 foreach ($hidden_fields as $field) {
230 $this->hidden_fields[] = $field;
231 if (wpcf7cf_endswith($field, '[]')) {
232 $this->hidden_fields[] = substr($field,0,strlen($field)-2);
233 }
234 }
235 }
236 $this->hidden_groups = json_decode(stripslashes($posted_data['_wpcf7cf_hidden_groups'] ?? '[]'));
237 $this->visible_groups = json_decode(stripslashes($posted_data['_wpcf7cf_visible_groups'] ?? '[]'));
238 $this->repeaters = json_decode(stripslashes($posted_data['_wpcf7cf_repeaters'] ?? '[]'));
239 $this->steps = json_decode(stripslashes($posted_data['_wpcf7cf_steps'] ?? '{}'));
240 }
241
242 function hide_hidden_mail_fields($form,$abort,$submission) {
243 $props = $form->get_properties();
244 $mails = ['mail','mail_2','messages'];
245 foreach ($mails as $mail) {
246 if (!is_array($props[$mail])) { continue; }
247 foreach ($props[$mail] as $key=>$val) {
248
249 // remove unwanted whitespace between closing and opening groups from email
250 $count = 1;
251 while ($count) {
252 $val = preg_replace(WPCF7CF_REGEX_MAIL_UNWANTED_WHITESPACE, '$1$2', $val, -1, $count);
253 }
254
255 // remove hiddden groups from email
256 $parser = new Wpcf7cfMailParser($val, $this->visible_groups, $this->hidden_groups, $this->repeaters, $_POST);
257 $props[$mail][$key] = $parser->getParsedMail();
258 }
259 }
260
261
262 //$props['mail']['body'] = 'xxx';
263 $form->set_properties($props);
264 }
265
266 function hide_hidden_mail_fields_regex_callback ( $matches ) {
267 $name = $matches[1];
268 $content = $matches[2];
269 if ( in_array( $name, $this->hidden_groups ) ) {
270 // The tag name represents a hidden group, so replace everything from [tagname] to [/tagname] with nothing
271 return '';
272 } elseif ( in_array( $name, $this->visible_groups ) ) {
273 // The tag name represents a visible group, so remove the tags themselves, but return everything else
274 // instead of just returning the $content, return the preg_replaced content :)
275 return preg_replace_callback(WPCF7CF_REGEX_MAIL_GROUP, array($this, 'hide_hidden_mail_fields_regex_callback'), $content );
276 } else {
277 // The tag name doesn't represent a group that was used in the form. Leave it alone (return the entire match).
278 return $matches[0];
279 }
280 }
281
282 public static function parse_conditions($string, $format='array') {
283 // Parse stuff like "show [g1] if [field] equals 2" to Array
284
285 preg_match_all(WPCF7CF_REGEX_CONDITIONS, $string, $matches);
286
287 $conditions = [];
288
289 $prev_then_field = '';
290 foreach ($matches[0] as $i=>$line) {
291 $then_field = $matches[1][$i];
292 $if_field = $matches[2][$i];
293 $operator = $matches[3][$i];
294 $if_value = $matches[4][$i];
295
296 $index = count($conditions);
297
298 if ($then_field == '') {
299 $index = $index -1;
300 $then_field = $prev_then_field;
301 } else {
302 $conditions[$index]['then_field'] = $then_field;
303 }
304
305 $conditions[$index]['and_rules'][] = [
306 'if_field' => $if_field,
307 'operator' => $operator,
308 'if_value' => $if_value,
309 ];
310
311 $prev_then_field = $then_field;
312
313 }
314
315 $conditions = array_values($conditions);
316
317 if ($format == 'array') {
318 return $conditions;
319 } else if ($format == 'json') {
320 return json_encode($conditions);
321 }
322 }
323
324 /**
325 * load the conditions from the form's post_meta
326 *
327 * @param string $form_id
328 * @return array
329 */
330 public static function getConditions($form_id) {
331 // make sure conditions are an array.
332 $options = get_post_meta($form_id,'wpcf7cf_options',true);
333 if (!is_array($options)) {
334 return array();
335 }
336 if (isset($options[0]['if_field'])) {
337 // this is a legacy condition format, so we need to convert it to the new format
338 foreach ($options as $i => $option) {
339 $options[$i]['and_rules'] = [
340 [
341 'if_field' => $option['if_field'],
342 'operator' => $option['operator'],
343 'if_value' => $option['if_value'],
344 ]
345 ];
346 unset($options[$i]['if_field']);
347 unset($options[$i]['operator']);
348 unset($options[$i]['if_value']);
349 }
350 }
351 return $options; // the meta key 'wpcf7cf_options' is a bit misleading at this point, because it only holds the form's conditions, no other options/settings
352 }
353
354 /**
355 * load the conditions from the form's post_meta as plain text
356 *
357 * @param string $form_id
358 * @return void
359 */
360 public static function getConditionsPlainText($form_id) {
361 return CF7CF::serializeConditions(CF7CF::getConditions($form_id));
362 }
363
364 public static function serializeConditions($array) {
365
366 $lines = [];
367
368 foreach ($array as $entry) {
369 $then_field = $entry['then_field'];
370 $and_rules = $entry['and_rules'];
371 $indent = strlen($then_field) + 4;
372 foreach ($and_rules as $i => $rule) {
373 $if_field = $rule['if_field'];
374 $operator = $rule['operator'];
375 $if_value = $rule['if_value'];
376
377 if ($i == 0) {
378 $lines[] = "show [$then_field] if [$if_field] $operator \"$if_value\"";
379 } else {
380 $lines[] = str_repeat(' ',$indent)."and if [$if_field] $operator \"$if_value\"";
381 }
382 }
383 }
384
385 return implode("\n", $lines);
386 }
387
388 /**
389 * save the conditions to the form's post_meta
390 *
391 * @param string $form_id
392 * @return void
393 */
394 public static function setConditions($form_id, $conditions) {
395 return update_post_meta($form_id,'wpcf7cf_options',$conditions); // the meta key 'wpcf7cf_options' is a bit misleading at this point, because it only holds the form's conditions, no other options/settings
396 }
397 }
398
399 new CF7CF;
400
401 add_filter( 'wpcf7_contact_form_properties', 'wpcf7cf_properties', 10, 2 );
402
403 function wpcf7cf_properties($properties, $wpcf7form) {
404 // Before CF7 5.5.3, this function was called each time we call get_properties() on a contact form. Since CF7 5.5.3 this function is called only once in the WPCF7_ContactForm
405 if (!is_admin() || (defined('DOING_AJAX') && DOING_AJAX)) { // TODO: kind of hacky. maybe find a better solution. Needed because otherwise the group tags will be replaced in the editor as well.
406 $form = $properties['form'];
407
408 $form_parts = preg_split('/(\[\/?group(?:\]|\s.*?\]))/',$form, -1,PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
409
410 ob_start();
411
412 $stack = array();
413
414 foreach ($form_parts as $form_part) {
415 if (substr($form_part,0,7) == '[group ') {
416 $tag_parts = explode(' ',rtrim($form_part,']'));
417
418 array_shift($tag_parts);
419
420 $tag_id = $tag_parts[0];
421 $tag_html_type = 'div';
422 $tag_html_data = array();
423 $tag_classes = array();
424
425 foreach ($tag_parts as $i => $tag_part) {
426 if ($i==0) continue;
427 $tag_part = explode(':',$tag_part);
428 if ($tag_part[0] == 'inline') {
429 $tag_html_type = 'span';
430 } else if ($tag_part[0] == 'clear_on_hide') {
431 $tag_html_data[] = 'data-clear_on_hide';
432 } else if ($tag_part[0] == 'disable_on_hide' && WPCF7CF_IS_PRO) {
433 $tag_html_data[] = 'data-disable_on_hide';
434 } else if ($tag_part[0] == 'class') {
435 $tag_classes[] = $tag_part[1] ?? '';
436 }
437 }
438
439 $class_html = 'class="' . implode(' ', array_filter($tag_classes)) . '"';
440
441 array_push($stack,$tag_html_type);
442
443 echo '<'.$tag_html_type.' data-id="'.$tag_id.'" data-orig_data_id="'.$tag_id.'" '.implode(' ',$tag_html_data).' '.$class_html.' data-class="wpcf7cf_group">';
444 } else if ($form_part == '[/group]') {
445 echo '</'.array_pop($stack).'>';
446 } else {
447 echo $form_part;
448 }
449 }
450
451 $properties['form'] = ob_get_clean();
452 }
453 return $properties;
454 }
455
456 add_filter('wpcf7_form_hidden_fields', 'wpcf7cf_form_hidden_fields',10,1);
457
458 function wpcf7cf_form_hidden_fields($hidden_fields) {
459
460 $current_form = wpcf7_get_current_contact_form();
461 $current_form_id = $current_form->id();
462
463 $options = array(
464 'form_id' => $current_form_id,
465 'conditions' => CF7CF::getConditions($current_form_id),
466 'settings' => wpcf7cf_get_settings()
467 );
468
469 unset($options['settings']['license_key']); // don't show license key in the source code duh.
470
471 return array_merge($hidden_fields, array(
472 '_wpcf7cf_hidden_group_fields' => '[]',
473 '_wpcf7cf_hidden_groups' => '[]',
474 '_wpcf7cf_visible_groups' => '[]',
475 '_wpcf7cf_repeaters' => '[]',
476 '_wpcf7cf_steps' => '{}',
477 '_wpcf7cf_options' => ''.json_encode($options),
478 ));
479 }
480
481 function wpcf7cf_endswith($string, $test) {
482 $strlen = strlen($string ?? '');
483 $testlen = strlen($test ?? '');
484 if ($testlen > $strlen) return false;
485 return substr_compare($string, $test, $strlen - $testlen, $testlen) === 0;
486 }
487
488 add_filter( 'wpcf7_form_tag_data_option', 'wpcf7cf_form_tag_data_option', 10, 3 );
489
490 function wpcf7cf_form_tag_data_option($output, $args, $nog) {
491 $data = array();
492 return $data;
493 }
494
495 /* Scripts & Styles */
496
497 function wpcf7cf_load_js() {
498 return apply_filters( 'wpcf7cf_load_js', WPCF7CF_LOAD_JS );
499 }
500
501 function wpcf7cf_load_css() {
502 return apply_filters( 'wpcf7cf_load_css', WPCF7CF_LOAD_CSS );
503 }
504
505 add_action( 'wp_enqueue_scripts', 'wpcf7cf_do_enqueue_scripts', 20, 0 );
506
507 function wpcf7cf_do_enqueue_scripts() {
508 if ( wpcf7cf_load_js() ) {
509 wpcf7cf_enqueue_scripts();
510 }
511
512 if ( wpcf7cf_load_css() ) {
513 wpcf7cf_enqueue_styles();
514 }
515 }
516
517 function wpcf7cf_enqueue_scripts() {
518 if (is_admin()) return;
519 wp_enqueue_script('wpcf7cf-scripts', plugins_url('js/scripts.js', __FILE__), array('jquery', 'contact-form-7'), WPCF7CF_VERSION, true);
520 wp_localize_script('wpcf7cf-scripts', 'wpcf7cf_global_settings',
521 array(
522 'ajaxurl' => admin_url('admin-ajax.php'),
523 )
524 );
525
526 }
527
528 function wpcf7cf_enqueue_styles() {
529 if (is_admin()) return;
530 wp_enqueue_style('cf7cf-style', plugins_url('style.css', __FILE__), array(), WPCF7CF_VERSION);
531 }
532
533 // Make sure CF7 doesn't target any disabled fields for validation
534 // (HTML standard: "disabled fields don't get submitted", so no need to validate them)
535 add_filter( 'wpcf7_feedback_response', function($response, $result) {
536 foreach ($response['invalid_fields'] as $i => $inv) {
537 if (isset($response['invalid_fields'][$i]['into'])) {
538 $response['invalid_fields'][$i]['into'] .= ':not(.wpcf7cf-disabled)';
539 }
540 }
541 return $response;
542 }, 2, 10 );