Conditional Fields for Contact Form 7 - Version 0.2.3

Version Description

  • Added support for conditional fields in the other email fields (subject, sender, recipient, additional_headers). Thanks @stevish!
  • WP 4.7 broke the required conditional fields inside hidden groups, implemented in version 0.2. Thanks again to @stevish for pointing this out.
  • Got rid of checking which groups are hidden both on the front-end (JS) and in the back-end (PHP). Now this is only done in the front-end.
  • Tested the plugin with WP 4.7
Download this release

Release Info

Developer Jules Colle
Plugin Icon 128x128 Conditional Fields for Contact Form 7
Version 0.2.3
Comparing to
See all releases

Code changes from version 0.2.2 to 0.2.3

Files changed (3) hide show
  1. contact-form-7-conditional-fields.php +34 -113
  2. js/scripts.js +20 -2
  3. readme.txt +7 -1
contact-form-7-conditional-fields.php CHANGED
@@ -1,13 +1,10 @@
1
  <?php
2
-
3
-
4
-
5
  /**
6
  Plugin Name: Contact Form 7 Conditional Fields
7
  Plugin URI: http://bdwm.be/
8
  Description: Adds support for conditional fields to Contact Form 7. This plugin depends on Contact Form 7.
9
  Author: Jules Colle
10
- Version: 0.2.2
11
  Author URI: http://bdwm.be/
12
  */
13
 
@@ -29,7 +26,7 @@ Author URI: http://bdwm.be/
29
  ?>
30
  <?php
31
 
32
- define( 'WPCF7CF_VERSION', '0.2.2' );
33
  define( 'WPCF7CF_REQUIRED_WP_VERSION', '4.1' );
34
  define( 'WPCF7CF_PLUGIN', __FILE__ );
35
  define( 'WPCF7CF_PLUGIN_BASENAME', plugin_basename( WPCF7CF_PLUGIN ) );
@@ -84,8 +81,7 @@ class ContactForm7ConditionalFields {
84
  }
85
 
86
  public static function enqueue_css() {
87
-
88
- wp_enqueue_style('cf7cf-style', plugins_url('style.css', __FILE__));
89
  }
90
 
91
  public static function add_shortcodes() {
@@ -163,20 +159,24 @@ class ContactForm7ConditionalFields {
163
  *
164
  * @return mixed
165
  */
166
- function skip_validation_for_hidden_fields($result, $tag) {
167
- global $wp_filter;
168
  $hidden_fields = $this->get_hidden_fields();
169
 
170
- // If this field is hidden, skip the rest of the validation hooks
171
- if( in_array($tag['name'], $hidden_fields) ) {
172
- // end() skips to the end of the $wp_filter array, effectively skipping any filters with a priority
173
- // lower than whatever priority this function was given.
174
- // In our case, this means that a hidden field won't be marked as "Invalid", regardless of its contents
175
- // unless it's done by a filter of priority 1 or 2
176
- end( $wp_filter[ current_filter() ] );
 
 
 
 
177
  }
178
 
179
- return $result;
180
  }
181
 
182
 
@@ -204,115 +204,30 @@ class ContactForm7ConditionalFields {
204
  * @return mixed
205
  */
206
  function get_hidden_fields($posted_data = false) {
207
- if ( isset( $posted_data['_wpcf7'] ) ) {
208
- // When called by wpcf7cf_remove_hidden_post_data() and $posted_data is available
209
- $form_id = $posted_data['_wpcf7'];
210
- } else {
211
- // When called from skip_validation_for_hidden_fields(), use WPCF7_Submission object to get form id
212
- $form_id = WPCF7_Submission::get_instance()->get_posted_data( '_wpcf7' );
213
- }
214
-
215
- // We only need to run through this once, so check to see if the global variable exists.
216
- if ( 0 == count( $this->hidden_fields ) ) {
217
- // Get the WPCF7_ContactForm object for this form
218
- $contact_form = WPCF7_ContactForm::get_instance( $form_id );
219
 
220
- // While we have the contact form object, find all used tags so we can add our validation filter
221
- foreach( (array) $contact_form->form_scan_shortcode() as $tag ) {
222
- //Priority of 2 allows other filters at priority 1 or 2 to actually validate hidden fields (just in case)
223
- add_filter( 'wpcf7_validate_' . $tag['type'], array($this, 'skip_validation_for_hidden_fields'), 2, 2 );
224
- }
225
-
226
- // Get the form properties so we have access to the form itself
227
- $form_properties = $contact_form->get_properties();
228
-
229
- //Find out which tags are in which groups
230
- $dom = new DOMDocument();
231
- libxml_use_internal_errors(true); //suppress warnings if invalid HTML markup. (We are not doing anything else with this for now)
232
- $dom->loadHTML($form_properties['form']);
233
- $divs = $dom->getElementsByTagName('div');
234
- $groups = array();
235
- foreach ($divs as $div) {
236
- $is_group = false;
237
- $id = 0;
238
- foreach($div->attributes as $attribute) {
239
- if ( 'data-class' == $attribute->name && 'wpcf7cf_group' == $attribute->value ) {
240
- // Group divs will have a data-class of wpcf7cf_group
241
- $is_group = true;
242
- }
243
- if ( 'id' == $attribute->name ) {
244
- $id = $attribute->value;
245
- }
246
- }
247
- if ( $is_group ) {
248
- $groups[$id] = array();
249
- // Match all tag names (format = [tag_type tag_name] or [tag_type tag_name options values etc...])
250
- preg_match_all("/\[[^\s\]]* ([^\s\]]*)[^\]]*\]/", $div->textContent, $matches);
251
- foreach( $matches[1] as $tag ) {
252
- $groups[$id][] = $tag;
253
- }
254
- }
255
- }
256
- // $groups is now an array of groups (by id) with an array of the name of each tag that is inside that group.
257
 
 
 
 
258
 
259
- $visible_groups = $this->get_visible_groups($posted_data);
260
-
261
- // Iterate through the groups.
262
- // When we find one that's not in the $visible_groups array, add its tags to our list of hidden tags
263
- foreach( $groups as $group => $fields ) {
264
- if ( ! in_array($group, $visible_groups) ) {
265
- $this->hidden_groups[] = $group;
266
- $this->hidden_fields = array_merge($this->hidden_fields, $fields);
267
- }
268
- }
269
 
 
270
 
271
- }
272
  return $this->hidden_fields;
273
  }
274
 
275
- function get_visible_groups($posted_data) {
276
- // Groups are hidden by default. Find all the visible ones and mark them.
277
- // This is a duplicate of the logic in js/scripts.js and needs to be included
278
- // so our verification is done server-side. If we ran this verification in
279
- // javascript, then all the form's normal validation could be overridden.
280
- //
281
- // Unfortunately, separate javascript and php validation is probably necessary since to use only php
282
- // would mean that every onChange() would require an ajax call, and that'd get too slow.
283
- $form_id = $posted_data['_wpcf7'];
284
- if( $this->visible_groups ) {
285
- return $this->visible_groups;
286
- }
287
- $this->visible_groups = array();
288
- $conditions = get_post_meta($form_id,'wpcf7cf_options', true);
289
- if (is_array($conditions)) {
290
- foreach( $conditions as $condition ) {
291
- if ( $condition['then_visibility'] == 'show' ) {
292
- if ( is_array($posted_data[ $condition['if_field'] ]) ) {
293
- if ( 'not equals' == $condition['operator'] && ! in_array( $condition['if_value'], $posted_data[ $condition['if_field'] ] ) ) {
294
- $this->visible_groups[] = $condition['then_field'];
295
- } elseif ( 'equals' == $condition['operator'] && in_array( $condition['if_value'], $posted_data[ $condition['if_field'] ] ) ) {
296
- $this->visible_groups[] = $condition['then_field'];
297
- }
298
- } else {
299
- if ( 'not equals' == $condition['operator'] && $condition['if_value'] != $posted_data[ $condition['if_field'] ] ) {
300
- $this->visible_groups[] = $condition['then_field'];
301
- } elseif ( 'equals' == $condition['operator'] && $condition['if_value'] == $posted_data[ $condition['if_field'] ] ) {
302
- $this->visible_groups[] = $condition['then_field'];
303
- }
304
- }
305
- }
306
- }
307
- }
308
- return $this->visible_groups;
309
- }
310
-
311
  function hide_hidden_mail_fields( $components ) {
312
  $regex = '@\[[\t ]*([a-zA-Z_][0-9a-zA-Z:._-]*)[\t ]*\](.*?)\[[\t ]*/[\t ]*\1[\t ]*\]@s';
313
  // [1] = name [2] = contents
314
 
315
  $components['body'] = preg_replace_callback($regex, array($this, 'hide_hidden_mail_fields_regex_callback'), $components['body'] );
 
 
 
 
 
316
  return $components;
317
  }
318
 
@@ -400,3 +315,9 @@ function wpcf7cf_enqueue_scripts(WPCF7_ContactForm $cf7form) {
400
  wp_enqueue_script('cf7cf-scripts', plugins_url('js/scripts.js', __FILE__), array('jquery'), WPCF7CF_VERSION, true);
401
  wp_localize_script('cf7cf-scripts', 'wpcf7cf_options_'.$global_count, $options);
402
  }
 
 
 
 
 
 
1
  <?php
 
 
 
2
  /**
3
  Plugin Name: Contact Form 7 Conditional Fields
4
  Plugin URI: http://bdwm.be/
5
  Description: Adds support for conditional fields to Contact Form 7. This plugin depends on Contact Form 7.
6
  Author: Jules Colle
7
+ Version: 0.2.3
8
  Author URI: http://bdwm.be/
9
  */
10
 
26
  ?>
27
  <?php
28
 
29
+ define( 'WPCF7CF_VERSION', '0.2.3' );
30
  define( 'WPCF7CF_REQUIRED_WP_VERSION', '4.1' );
31
  define( 'WPCF7CF_PLUGIN', __FILE__ );
32
  define( 'WPCF7CF_PLUGIN_BASENAME', plugin_basename( WPCF7CF_PLUGIN ) );
81
  }
82
 
83
  public static function enqueue_css() {
84
+ wp_enqueue_style('cf7cf-style', plugins_url('style.css', __FILE__), array(), WPCF7CF_VERSION);
 
85
  }
86
 
87
  public static function add_shortcodes() {
159
  *
160
  * @return mixed
161
  */
162
+ function skip_validation_for_hidden_fields($result, $tags) {
163
+ //global $wp_filter;
164
  $hidden_fields = $this->get_hidden_fields();
165
 
166
+ $return_result = new WPCF7_Validation();
167
+
168
+ $invalid_fields = $result->get_invalid_fields();
169
+
170
+ $invalid_shown_fields = array();
171
+
172
+ foreach ($invalid_fields as $invalid_field_key => $invalid_field_data) {
173
+ if (!in_array($invalid_field_key, $hidden_fields)) {
174
+ // the invalid field is not a hidden field, so we'll add it to the final validation result
175
+ $return_result->invalidate($invalid_field_key, $invalid_field_data['reason']);
176
+ }
177
  }
178
 
179
+ return $return_result;
180
  }
181
 
182
 
204
  * @return mixed
205
  */
206
  function get_hidden_fields($posted_data = false) {
 
 
 
 
 
 
 
 
 
 
 
 
207
 
208
+ if (count( $this->hidden_fields ) > 0) return $this->hidden_fields;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
 
210
+ if (!$posted_data) {
211
+ $posted_data = WPCF7_Submission::get_instance()->get_posted_data();
212
+ }
213
 
214
+ $this->hidden_fields = json_decode(stripslashes($posted_data['_wpcf7cf_hidden_group_fields']));
 
 
 
 
 
 
 
 
 
215
 
216
+ add_filter( 'wpcf7_validate', array($this, 'skip_validation_for_hidden_fields'), 2, 2 );
217
 
 
218
  return $this->hidden_fields;
219
  }
220
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  function hide_hidden_mail_fields( $components ) {
222
  $regex = '@\[[\t ]*([a-zA-Z_][0-9a-zA-Z:._-]*)[\t ]*\](.*?)\[[\t ]*/[\t ]*\1[\t ]*\]@s';
223
  // [1] = name [2] = contents
224
 
225
  $components['body'] = preg_replace_callback($regex, array($this, 'hide_hidden_mail_fields_regex_callback'), $components['body'] );
226
+ $components['subject'] = preg_replace_callback($regex, array($this, 'hide_hidden_mail_fields_regex_callback'), $components['subject'] );
227
+ $components['sender'] = preg_replace_callback($regex, array($this, 'hide_hidden_mail_fields_regex_callback'), $components['sender'] );
228
+ $components['recipient'] = preg_replace_callback($regex, array($this, 'hide_hidden_mail_fields_regex_callback'), $components['recipient'] );
229
+ $components['additional_headers'] = preg_replace_callback($regex, array($this, 'hide_hidden_mail_fields_regex_callback'), $components['additional_headers'] );
230
+
231
  return $components;
232
  }
233
 
315
  wp_enqueue_script('cf7cf-scripts', plugins_url('js/scripts.js', __FILE__), array('jquery'), WPCF7CF_VERSION, true);
316
  wp_localize_script('cf7cf-scripts', 'wpcf7cf_options_'.$global_count, $options);
317
  }
318
+
319
+ add_action('wpcf7_form_hidden_fields', 'wpcf7cf_form_hidden_fields',10,1);
320
+
321
+ function wpcf7cf_form_hidden_fields($hidden_fields) {
322
+ return array('_wpcf7cf_hidden_group_fields' => '');
323
+ }
js/scripts.js CHANGED
@@ -100,6 +100,26 @@ var cf7signature_resized = 0; // for compatibility with contact-form-7-signature
100
  });
101
  }
102
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  });
104
 
105
  //reset the form completely
@@ -113,6 +133,4 @@ var cf7signature_resized = 0; // for compatibility with contact-form-7-signature
113
  }
114
  });
115
 
116
- console.log('cf7cf code loaded');
117
-
118
  })( jQuery );
100
  });
101
  }
102
 
103
+ // before the form values are serialized to submit via ajax, we quickly add all invisible fields in the hidden
104
+ // _wpcf7cf_hidden_group_fields field, so the PHP code knows which fields were inside hidden groups.
105
+ // TODO: maybe modify this code so it only takes fields which are strictly inside hidden group tags.
106
+ // TODO: For now the hidden field is filled with all hidden form elements.
107
+
108
+ $('form.wpcf7-form').on('form-pre-serialize', function(form,options,veto) {
109
+ $form = $(form.target);
110
+
111
+ $hidden_group_fields = $form.find('[name="_wpcf7cf_hidden_group_fields"]');
112
+
113
+ var hidden_fields = [];
114
+
115
+ $form.find('input:hidden,select:hidden,textarea:hidden').each(function () {
116
+ hidden_fields.push($(this).attr('name'));
117
+ });
118
+
119
+ $($hidden_group_fields).val(JSON.stringify(hidden_fields));
120
+
121
+ return true;
122
+ });
123
  });
124
 
125
  //reset the form completely
133
  }
134
  });
135
 
 
 
136
  })( jQuery );
readme.txt CHANGED
@@ -6,7 +6,7 @@ Website: http://bdwm.be
6
  Tags: wordpress, contact form 7, forms, conditional fields
7
  Requires at least: 3.6.1
8
  Tested up to: 4.6.1
9
- Stable tag: 0.2.2
10
  License: GPLv2 or later
11
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
 
@@ -47,6 +47,12 @@ Because no questions have been asked frequently about this plugin.
47
 
48
  == Changelog ==
49
 
 
 
 
 
 
 
50
  = 0.2.2 =
51
  * Prevent strict standards notice to appear while adding new group via the "Conditional Fields Group" popup.
52
  * Only load cf7cf admin styles and scripts on cf7 pages.
6
  Tags: wordpress, contact form 7, forms, conditional fields
7
  Requires at least: 3.6.1
8
  Tested up to: 4.6.1
9
+ Stable tag: 0.2.3
10
  License: GPLv2 or later
11
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
 
47
 
48
  == Changelog ==
49
 
50
+ = 0.2.3 =
51
+ * Added support for conditional fields in the other email fields (subject, sender, recipient, additional_headers). Thanks @stevish!
52
+ * WP 4.7 broke the required conditional fields inside hidden groups, implemented in version 0.2. Thanks again to @stevish for pointing this out.
53
+ * Got rid of checking which groups are hidden both on the front-end (JS) and in the back-end (PHP). Now this is only done in the front-end.
54
+ * Tested the plugin with WP 4.7
55
+
56
  = 0.2.2 =
57
  * Prevent strict standards notice to appear while adding new group via the "Conditional Fields Group" popup.
58
  * Only load cf7cf admin styles and scripts on cf7 pages.