PluginProbe ʕ •ᴥ•ʔ
Conditional Fields for Contact Form 7 / 1.4.2
Conditional Fields for Contact Form 7 v1.4.2
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 7 years ago admin-style.css 7 years ago admin-style.css.map 7 years ago admin-style.scss 7 years ago admin.php 7 years ago cf7cf.php 7 years ago contact-form-7-conditional-fields.php 7 years ago init.php 7 years ago readme.txt 7 years ago style.css 7 years ago tg_pane_group.php 7 years ago wpcf7cf-options.php 7 years ago
cf7cf.php
372 lines
1 <?php
2
3 class ContactForm7ConditionalFields {
4 private $hidden_fields = array();
5 private $visible_groups = array();
6 private $hidden_groups = array();
7
8 function __construct() {
9
10 add_action('wpcf7_enqueue_scripts', array(__CLASS__, 'enqueue_js'));
11 add_action('wpcf7_enqueue_styles', array(__CLASS__, 'enqueue_css'));
12
13 // Register shortcodes
14 add_action('wpcf7_init', array(__CLASS__, 'add_shortcodes'));
15
16 // Tag generator
17 add_action('load-contact_page_wpcf7-new', array(__CLASS__, 'tag_generator'));
18 add_action('load-toplevel_page_wpcf7', array(__CLASS__, 'tag_generator'));
19
20 // compatibility with CF7 multi-step forms by Webhead LLC.
21 add_filter( 'wpcf7_posted_data', array($this,'cf7msm_merge_post_with_cookie'), 8, 1 );
22
23 // compatibility with CF7 Multi Step by NinjaTeam https://wordpress.org/plugins/cf7-multi-step/
24 add_action('wp_ajax_cf7mls_validation', array($this,'cf7mls_validation_callback'),9);
25 add_action('wp_ajax_nopriv_cf7mls_validation', array($this,'cf7mls_validation_callback'),9);
26
27 add_filter( 'wpcf7_posted_data', array($this, 'remove_hidden_post_data') );
28 add_filter( 'wpcf7_mail_components', array($this, 'hide_hidden_mail_fields') );
29
30 //add_filter( 'wpcf7_additional_mail', array($this, 'hide_hidden_mail_fields_additional_mail'), 10, 2);
31
32 add_filter( 'wpcf7_validate', array($this, 'skip_validation_for_hidden_fields'), 2, 2 );
33
34 // validation messages
35 add_action('wpcf7_config_validator_validate', array($this,'wpcf7cf_config_validator_validate'));
36
37
38
39 register_activation_hook(__FILE__, array($this, 'activate'));
40
41 if (is_admin()) {
42 require_once dirname(__FILE__) . '/admin.php';
43 }
44 }
45
46 /**
47 * Suppress invalid mailbox syntax errors on fields that contain existing conditional
48 */
49 function wpcf7cf_config_validator_validate(WPCF7_ConfigValidator $wpcf7_config_validator) {
50
51 // TODO: For now we kill every syntax error once a [groupname] tag is detected.
52 // Ideally, this function should check each string inside the group for invalid syntax.
53 // TODO 2: ajax validation not working yet, because $cf->scan_form_tags() does not seem to contain group tags if it's an ajax request. Need to investigate.
54
55 $cf = $wpcf7_config_validator->contact_form();
56 $all_group_tags = $cf->scan_form_tags();
57
58 foreach ($wpcf7_config_validator->collect_error_messages() as $err_type => $err) {
59
60
61 $parts = explode('.',$err_type);
62 $property = $parts[0];
63 $sub_prop = $parts[1];
64 $prop_val = $cf->prop($property)[$sub_prop];
65
66
67 // TODO 2: Dirty hack. Because of TODO 2 we are just going to kill the error message if we detect the string '[/'
68 // Start removing here.
69 if (strpos($prop_val, '[/') !== false) {
70 $wpcf7_config_validator->remove_error($err_type, WPCF7_ConfigValidator::error_invalid_mailbox_syntax);
71 continue;
72 }
73 // TODO 2: Stop removing here. and uncomment code below.
74
75 // foreach ($all_group_tags as $form_tag) {
76 // if (strpos($prop_val, '['.$form_tag->name.']') !== false) {
77 // $wpcf7_config_validator->remove_error($err_type, WPCF7_ConfigValidator::error_invalid_mailbox_syntax);
78 // }
79 // }
80
81 }
82
83 return new WPCF7_ConfigValidator($wpcf7_config_validator->contact_form());
84 }
85
86 function activate() {
87 //add options with add_option and stuff
88 }
89
90 public static function enqueue_js() {
91 // nothing here. We will only load the CF7 script if there is a CF7 form on the page.
92 }
93
94 public static function enqueue_css() {
95 wp_enqueue_style('cf7cf-style', plugins_url('style.css', __FILE__), array(), WPCF7CF_VERSION);
96 }
97
98 public static function add_shortcodes() {
99 if (function_exists('wpcf7_add_form_tag'))
100 wpcf7_add_form_tag('group', array(__CLASS__, 'shortcode_handler'), true);
101 else if (function_exists('wpcf7_add_shortcode')) {
102 wpcf7_add_shortcode('group', array(__CLASS__, 'shortcode_handler'), true);
103 } else {
104 throw new Exception('functions wpcf7_add_form_tag and wpcf7_add_shortcode not found.');
105 }
106 }
107
108 function group_shortcode_handler( $atts, $content = "" ) {
109 return $content;
110 }
111
112 public static function shortcode_handler($tag) {
113 //$tag = new WPCF7_Shortcode($tag);
114 $tag = new WPCF7_FormTag($tag);
115 //ob_start();
116 //print_r($tag);
117 //return print_r($tag, true);
118 return $tag->content;
119 }
120
121
122 public static function tag_generator() {
123 if (! function_exists( 'wpcf7_add_tag_generator'))
124 return;
125
126 wpcf7_add_tag_generator('group',
127 __('Conditional fields Group', 'wpcf7cf'),
128 'wpcf7-tg-pane-group',
129 array(__CLASS__, 'tg_pane')
130 );
131
132 do_action('wpcf7cf_tag_generator');
133 }
134
135 static function tg_pane( $contact_form, $args = '' ) {
136 $args = wp_parse_args( $args, array() );
137 $type = 'group';
138
139 $description = __( "Generate a group tag to group form elements that can be shown conditionally.", 'cf7cf' );
140
141 include 'tg_pane_group.php';
142 }
143
144 /**
145 * Remove validation requirements for fields that are hidden at the time of form submission.
146 * Called using add_filter( 'wpcf7_validate_[tag_type]', array($this, 'skip_validation_for_hidden_fields'), 2, 2 );
147 * where the priority of 2 causes this to kill any validations with a priority higher than 2
148 *
149 * @param $result
150 * @param $tag
151 *
152 * @return mixed
153 */
154 function skip_validation_for_hidden_fields($result, $tags) {
155
156 if (count($this->hidden_fields) == 0) return $result;
157
158 $return_result = new WPCF7_Validation();
159
160 $invalid_fields = $result->get_invalid_fields();
161
162 if (!is_array($invalid_fields) || count($invalid_fields) == 0) return $result;
163
164 foreach ($invalid_fields as $invalid_field_key => $invalid_field_data) {
165 if (!in_array($invalid_field_key, $this->hidden_fields)) {
166 // the invalid field is not a hidden field, so we'll add it to the final validation result
167 $return_result->invalidate($invalid_field_key, $invalid_field_data['reason']);
168 }
169 }
170
171 return $return_result;
172 }
173
174
175 /**
176 * When a CF7 form is posted, check the form for hidden fields, then remove those fields from the post data
177 *
178 * @param $posted_data
179 *
180 * @return mixed
181 */
182 function remove_hidden_post_data($posted_data) {
183 $this->set_hidden_fields_arrays($posted_data);
184
185 foreach( $this->hidden_fields as $name => $value ) {
186 unset( $posted_data[$name] );
187 }
188
189 return $posted_data;
190 }
191
192 function cf7msm_merge_post_with_cookie($posted_data) {
193
194 if (!function_exists('cf7msm_get') || !key_exists('cf7msm_posted_data',$_COOKIE)) return $posted_data;
195
196 if (!$posted_data) {
197 $posted_data = WPCF7_Submission::get_instance()->get_posted_data();
198 }
199
200 // this will temporarily set the hidden fields data to the posted_data.
201 // later this function will be called again with the updated posted_data
202 $this->set_hidden_fields_arrays($posted_data);
203
204 // get cookie data
205 $cookie_data = cf7msm_get('cf7msm_posted_data');
206 $cookie_data_hidden_group_fields = json_decode(stripslashes($cookie_data['_wpcf7cf_hidden_group_fields']));
207 $cookie_data_hidden_groups = json_decode(stripslashes($cookie_data['_wpcf7cf_hidden_groups']));
208 $cookie_data_visible_groups = json_decode(stripslashes($cookie_data['_wpcf7cf_visible_groups']));
209
210 // remove all the currently posted data from the cookie data (we don't wanna add it twice)
211 $cookie_data_hidden_group_fields = array_diff($cookie_data_hidden_group_fields, array_keys($posted_data));
212 $cookie_data_hidden_groups = array_diff((array) $cookie_data_hidden_groups, $this->hidden_groups, $this->visible_groups);
213 $cookie_data_visible_groups = array_diff((array) $cookie_data_visible_groups, $this->hidden_groups, $this->visible_groups);
214
215 // update current post data with cookie data
216 $posted_data['_wpcf7cf_hidden_group_fields'] = addslashes(json_encode(array_merge((array) $cookie_data_hidden_group_fields, $this->hidden_fields)));
217 $posted_data['_wpcf7cf_hidden_groups'] = addslashes(json_encode(array_merge((array) $cookie_data_hidden_groups, $this->hidden_groups)));
218 $posted_data['_wpcf7cf_visible_groups'] = addslashes(json_encode(array_merge((array) $cookie_data_visible_groups, $this->visible_groups)));
219
220 return $posted_data;
221 }
222
223 // compatibility with CF7 Multi Step by NinjaTeam https://wordpress.org/plugins/cf7-multi-step/
224 function cf7mls_validation_callback() {
225 $this->set_hidden_fields_arrays($_POST);
226 }
227
228
229 /**
230 * Finds the currently submitted form and set the hidden_fields variables accoringly
231 *
232 * @param bool|array $posted_data
233 */
234 function set_hidden_fields_arrays($posted_data = false) {
235
236 if (!$posted_data) {
237 $posted_data = WPCF7_Submission::get_instance()->get_posted_data();
238 }
239
240 $hidden_fields = json_decode(stripslashes($posted_data['_wpcf7cf_hidden_group_fields']));
241 if (is_array($hidden_fields) && count($hidden_fields) > 0) {
242 foreach ($hidden_fields as $field) {
243 $this->hidden_fields[] = $field;
244 if (wpcf7cf_endswith($field, '[]')) {
245 $this->hidden_fields[] = substr($field,0,strlen($field)-2);
246 }
247 }
248 }
249 $this->hidden_groups = json_decode(stripslashes($posted_data['_wpcf7cf_hidden_groups']));
250 $this->visible_groups = json_decode(stripslashes($posted_data['_wpcf7cf_visible_groups']));
251 }
252
253 function hide_hidden_mail_fields( $components ) {
254
255 foreach ($components as $key => $val) {
256 $components[$key] = preg_replace_callback(WPCF7CF_REGEX_MAIL_GROUP, array($this, 'hide_hidden_mail_fields_regex_callback'), $val );
257 }
258
259 return $components;
260 }
261
262 // Seems like it was not needed.
263 // function hide_hidden_mail_fields_additional_mail($additional_mail, $contact_form) {
264 // if (!is_array($additional_mail) || !array_key_exists('mail_2', $additional_mail)) return $additional_mail;
265 // $additional_mail['mail_2'] = $this->hide_hidden_mail_fields($additional_mail['mail_2']);
266 // return $additional_mail;
267 // }
268
269 function hide_hidden_mail_fields_regex_callback ( $matches ) {
270 $name = $matches[1];
271 $content = $matches[2];
272 if ( in_array( $name, $this->hidden_groups ) ) {
273 // The tag name represents a hidden group, so replace everything from [tagname] to [/tagname] with nothing
274 return '';
275 } elseif ( in_array( $name, $this->visible_groups ) ) {
276 // The tag name represents a visible group, so remove the tags themselves, but return everything else
277 // instead of just returning the $content, return the preg_replaced content :)
278 return preg_replace_callback(WPCF7CF_REGEX_MAIL_GROUP, array($this, 'hide_hidden_mail_fields_regex_callback'), $content );
279 } else {
280 // The tag name doesn't represent a group that was used in the form. Leave it alone (return the entire match).
281 return $matches[0];
282 }
283 }
284 }
285
286 new ContactForm7ConditionalFields;
287
288 add_filter( 'wpcf7_contact_form_properties', 'wpcf7cf_properties', 10, 2 );
289
290 function wpcf7cf_properties($properties, $wpcf7form) {
291 // TODO: This function is called serveral times. The problem is that the filter is called each time we call get_properties() on a contact form.
292 // TODO: I haven't found a better way to solve this problem yet, any suggestions or push requests are welcome. (same problem in PRO/repeater.php)
293 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.
294 $form = $properties['form'];
295
296 $form_parts = preg_split('/(\[\/?group(?:\]|\s.*?\]))/',$form, -1,PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
297
298 ob_start();
299
300 $stack = array();
301
302 foreach ($form_parts as $form_part) {
303 if (substr($form_part,0,7) == '[group ') {
304 $tag_parts = explode(' ',rtrim($form_part,']'));
305
306 array_shift($tag_parts);
307
308 $tag_id = $tag_parts[0];
309 $tag_html_type = 'div';
310 $tag_html_data = array();
311
312 foreach ($tag_parts as $i => $tag_part) {
313 if ($i==0) continue;
314 else if ($tag_part == 'inline') $tag_html_type = 'span';
315 else if ($tag_part == 'clear_on_hide') $tag_html_data[] = 'data-clear_on_hide';
316 }
317
318 array_push($stack,$tag_html_type);
319
320 echo '<'.$tag_html_type.' data-id="'.$tag_id.'" '.implode(' ',$tag_html_data).' data-class="wpcf7cf_group">';
321 } else if ($form_part == '[/group]') {
322 echo '</'.array_pop($stack).'>';
323 } else {
324 echo $form_part;
325 }
326 }
327
328 $properties['form'] = ob_get_clean();
329 }
330 return $properties;
331 }
332
333 add_action('wpcf7_contact_form', 'wpcf7cf_enqueue_scripts', 10, 1);
334 function wpcf7cf_enqueue_scripts(WPCF7_ContactForm $cf7form) {
335 if (is_admin()) return;
336 wp_enqueue_script('wpcf7cf-scripts', plugins_url('js/scripts.js', __FILE__), array('jquery'), WPCF7CF_VERSION, true);
337 }
338
339 add_action('wpcf7_form_hidden_fields', 'wpcf7cf_form_hidden_fields',10,1);
340
341 function wpcf7cf_form_hidden_fields($hidden_fields) {
342
343 $current_form = wpcf7_get_current_contact_form();
344 $current_form_id = $current_form->id();
345
346 $options = array(
347 'form_id' => $current_form_id,
348 'conditions' => get_post_meta($current_form_id,'wpcf7cf_options', true),
349 'settings' => get_option(WPCF7CF_OPTIONS)
350 );
351
352 return array_merge($hidden_fields, array(
353 '_wpcf7cf_hidden_group_fields' => '',
354 '_wpcf7cf_hidden_groups' => '',
355 '_wpcf7cf_visible_groups' => '',
356 '_wpcf7cf_options' => ''.json_encode($options),
357 ));
358 }
359
360 function wpcf7cf_endswith($string, $test) {
361 $strlen = strlen($string);
362 $testlen = strlen($test);
363 if ($testlen > $strlen) return false;
364 return substr_compare($string, $test, $strlen - $testlen, $testlen) === 0;
365 }
366
367 add_filter( 'wpcf7_form_tag_data_option', 'wpcf7cf_form_tag_data_option', 10, 3 );
368
369 function wpcf7cf_form_tag_data_option($output, $args, $nog) {
370 $data = array();
371 return $data;
372 }