Contact Form 7 - Version 4.8.1

Version Description

  • wpcf7.initForm JavaScript function added to isolate form initialization process.
  • Fix response message duplication caused by repeated click on submit button.
  • Clear $phpmailer->AltBody to avoid unintended inheritance from previous wp_mail() calls.
  • Fix incorrect character count of textarea input.
  • Akismet: Exclude the comment_author, comment_author_email, and comment_author_url values from the comment_content value.
  • REST API: More reliable approach to build route URLs.
  • Include free_text inputs into event.detail.inputs.
Download this release

Release Info

Developer takayukister
Plugin Icon 128x128 Contact Form 7
Version 4.8.1
Comparing to
See all releases

Code changes from version 4.8 to 4.8.1

includes/controller.php CHANGED
@@ -56,7 +56,7 @@ function wpcf7_enqueue_scripts() {
56
 
57
  $wpcf7 = array(
58
  'apiSettings' => array(
59
- 'root' => esc_url_raw( get_rest_url() ),
60
  'namespace' => 'contact-form-7/v1',
61
  ),
62
  'recaptcha' => array(
56
 
57
  $wpcf7 = array(
58
  'apiSettings' => array(
59
+ 'root' => esc_url_raw( rest_url( 'contact-form-7/v1' ) ),
60
  'namespace' => 'contact-form-7/v1',
61
  ),
62
  'recaptcha' => array(
includes/functions.php CHANGED
@@ -330,6 +330,7 @@ function wpcf7_count_code_units( $string ) {
330
  }
331
 
332
  $string = (string) $string;
 
333
 
334
  $encoding = mb_detect_encoding( $string, mb_detect_order(), true );
335
 
330
  }
331
 
332
  $string = (string) $string;
333
+ $string = str_replace( "\r\n", "\n", $string );
334
 
335
  $encoding = mb_detect_encoding( $string, mb_detect_order(), true );
336
 
includes/js/scripts.js CHANGED
@@ -30,151 +30,156 @@
30
 
31
  $( 'div.wpcf7 > form' ).each( function() {
32
  var $form = $( this );
 
33
 
34
- $form.submit( function( event ) {
35
- if ( typeof window.FormData !== 'function' ) {
36
- return;
37
- }
 
38
 
39
- wpcf7.submit( $form );
40
- event.preventDefault();
41
- } );
42
 
43
- $( '.wpcf7-submit', $form ).after( '<span class="ajax-loader"></span>' );
 
 
 
 
 
 
 
 
 
 
44
 
 
 
 
 
 
45
  wpcf7.toggleSubmit( $form );
 
46
 
47
- $form.on( 'click', '.wpcf7-acceptance', function() {
48
- wpcf7.toggleSubmit( $form );
49
- } );
 
 
50
 
51
- // Exclusive Checkbox
52
- $( '.wpcf7-exclusive-checkbox', $form ).on( 'click', 'input:checkbox', function() {
53
- var name = $( this ).attr( 'name' );
54
- $form.find( 'input:checkbox[name="' + name + '"]' ).not( this ).prop( 'checked', false );
55
- } );
56
 
57
- // Free Text Option for Checkboxes and Radio Buttons
58
- $( '.wpcf7-list-item.has-free-text', $form ).each( function() {
59
- var $freetext = $( ':input.wpcf7-free-text', this );
60
- var $wrap = $( this ).closest( '.wpcf7-form-control' );
 
61
 
62
- if ( $( ':checkbox, :radio', this ).is( ':checked' ) ) {
63
- $freetext.prop( 'disabled', false );
 
 
 
64
  } else {
65
  $freetext.prop( 'disabled', true );
66
  }
 
 
67
 
68
- $wrap.on( 'change', ':checkbox, :radio', function() {
69
- var $cb = $( '.has-free-text', $wrap ).find( ':checkbox, :radio' );
 
 
 
70
 
71
- if ( $cb.is( ':checked' ) ) {
72
- $freetext.prop( 'disabled', false ).focus();
73
- } else {
74
- $freetext.prop( 'disabled', true );
75
  }
76
  } );
77
- } );
78
-
79
- // Placeholder Fallback
80
- if ( ! wpcf7.supportHtml5.placeholder ) {
81
- $( '[placeholder]', $form ).each( function() {
82
- $( this ).val( $( this ).attr( 'placeholder' ) );
83
- $( this ).addClass( 'placeheld' );
84
 
85
- $( this ).focus( function() {
86
- if ( $( this ).hasClass( 'placeheld' ) ) {
87
- $( this ).val( '' ).removeClass( 'placeheld' );
88
- }
89
- } );
90
-
91
- $( this ).blur( function() {
92
- if ( '' === $( this ).val() ) {
93
- $( this ).val( $( this ).attr( 'placeholder' ) );
94
- $( this ).addClass( 'placeheld' );
95
- }
96
- } );
97
  } );
98
- }
 
99
 
100
- if ( wpcf7.jqueryUi && ! wpcf7.supportHtml5.date ) {
101
- $form.find( 'input.wpcf7-date[type="date"]' ).each( function() {
102
- $( this ).datepicker( {
103
- dateFormat: 'yy-mm-dd',
104
- minDate: new Date( $( this ).attr( 'min' ) ),
105
- maxDate: new Date( $( this ).attr( 'max' ) )
106
- } );
107
  } );
108
- }
 
109
 
110
- if ( wpcf7.jqueryUi && ! wpcf7.supportHtml5.number ) {
111
- $form.find( 'input.wpcf7-number[type="number"]' ).each( function() {
112
- $( this ).spinner( {
113
- min: $( this ).attr( 'min' ),
114
- max: $( this ).attr( 'max' ),
115
- step: $( this ).attr( 'step' )
116
- } );
117
  } );
118
- }
 
119
 
120
- // Character Count
121
- $( '.wpcf7-character-count', $form ).each( function() {
122
- var $count = $( this );
123
- var name = $count.attr( 'data-target-name' );
124
- var down = $count.hasClass( 'down' );
125
- var starting = parseInt( $count.attr( 'data-starting-value' ), 10 );
126
- var maximum = parseInt( $count.attr( 'data-maximum-value' ), 10 );
127
- var minimum = parseInt( $count.attr( 'data-minimum-value' ), 10 );
128
-
129
- var updateCount = function( target ) {
130
- var $target = $( target );
131
- var length = $target.val().length;
132
- var count = down ? starting - length : length;
133
- $count.attr( 'data-current-value', count );
134
- $count.text( count );
135
-
136
- if ( maximum && maximum < length ) {
137
- $count.addClass( 'too-long' );
138
- } else {
139
- $count.removeClass( 'too-long' );
140
- }
141
 
142
- if ( minimum && length < minimum ) {
143
- $count.addClass( 'too-short' );
144
- } else {
145
- $count.removeClass( 'too-short' );
146
- }
147
- };
148
 
149
- $( ':input[name="' + name + '"]', $form ).each( function() {
150
- updateCount( this );
151
 
152
- $( this ).keyup( function() {
153
- updateCount( this );
154
- } );
155
  } );
156
  } );
 
157
 
158
- $form.on( 'change', '.wpcf7-validates-as-url', function() {
159
- var val = $.trim( $( this ).val() );
160
-
161
- // check the scheme part
162
- if ( val && ! val.match( /^[a-z][a-z0-9.+-]*:/i ) ) {
163
- val = val.replace( /^\/+/, '' );
164
- val = 'http://' + val;
165
- }
166
-
167
- $( this ).val( val );
168
- } );
169
 
170
- if ( wpcf7.cached ) {
171
- wpcf7.refill( $form );
 
 
172
  }
173
- } );
174
- } );
175
 
176
- wpcf7.getId = function( form ) {
177
- return parseInt( $( 'input[name="_wpcf7"]', form ).val(), 10 );
178
  };
179
 
180
  wpcf7.submit = function( form ) {
@@ -211,6 +216,12 @@
211
  detail.unitTag = field.value;
212
  } else if ( '_wpcf7_container_post' == field.name ) {
213
  detail.containerPostId = field.value;
 
 
 
 
 
 
214
  } else if ( field.name.match( /^_/ ) ) {
215
  // do nothing
216
  } else {
@@ -285,7 +296,7 @@
285
  $( n ).val( $( n ).attr( 'placeholder' ) );
286
  } );
287
 
288
- $message.append( data.message ).slideDown( 'fast' );
289
  $message.attr( 'role', 'alert' );
290
 
291
  $( '.screen-reader-response', $form.closest( '.wpcf7' ) ).each( function() {
@@ -314,8 +325,8 @@
314
 
315
  $.ajax( {
316
  type: 'POST',
317
- url: wpcf7.apiSettings.root + wpcf7.apiSettings.namespace +
318
- '/contact-forms/' + wpcf7.getId( $form ) + '/feedback',
319
  data: formData,
320
  dataType: 'json',
321
  processData: false,
@@ -384,7 +395,7 @@
384
  }, 'fast', function() {
385
  $( this ).css( { 'z-index': -100 } );
386
  } );
387
- }
388
 
389
  $target.on( 'mouseover', '.wpcf7-not-valid-tip', function() {
390
  fadeOut( this );
@@ -394,7 +405,7 @@
394
  fadeOut( $( '.wpcf7-not-valid-tip', $target ) );
395
  } );
396
  }
397
- }
398
 
399
  wpcf7.refill = function( form, data ) {
400
  var $form = $( form );
@@ -419,8 +430,8 @@
419
  if ( typeof data === 'undefined' ) {
420
  $.ajax( {
421
  type: 'GET',
422
- url: wpcf7.apiSettings.root + wpcf7.apiSettings.namespace +
423
- '/contact-forms/' + wpcf7.getId( $form ) + '/refill',
424
  dataType: 'json'
425
  } ).done( function( data, status, xhr ) {
426
  if ( data.captcha ) {
@@ -457,6 +468,16 @@
457
  .removeClass( 'wpcf7-mail-sent-ok wpcf7-mail-sent-ng wpcf7-validation-errors wpcf7-spam-blocked' );
458
  };
459
 
 
 
 
 
 
 
 
 
 
 
460
  } )( jQuery );
461
 
462
  /*
30
 
31
  $( 'div.wpcf7 > form' ).each( function() {
32
  var $form = $( this );
33
+ wpcf7.initForm( $form );
34
 
35
+ if ( wpcf7.cached ) {
36
+ wpcf7.refill( $form );
37
+ }
38
+ } );
39
+ } );
40
 
41
+ wpcf7.getId = function( form ) {
42
+ return parseInt( $( 'input[name="_wpcf7"]', form ).val(), 10 );
43
+ };
44
 
45
+ wpcf7.initForm = function( form ) {
46
+ var $form = $( form );
47
+
48
+ $form.submit( function( event ) {
49
+ if ( typeof window.FormData !== 'function' ) {
50
+ return;
51
+ }
52
+
53
+ wpcf7.submit( $form );
54
+ event.preventDefault();
55
+ } );
56
 
57
+ $( '.wpcf7-submit', $form ).after( '<span class="ajax-loader"></span>' );
58
+
59
+ wpcf7.toggleSubmit( $form );
60
+
61
+ $form.on( 'click', '.wpcf7-acceptance', function() {
62
  wpcf7.toggleSubmit( $form );
63
+ } );
64
 
65
+ // Exclusive Checkbox
66
+ $( '.wpcf7-exclusive-checkbox', $form ).on( 'click', 'input:checkbox', function() {
67
+ var name = $( this ).attr( 'name' );
68
+ $form.find( 'input:checkbox[name="' + name + '"]' ).not( this ).prop( 'checked', false );
69
+ } );
70
 
71
+ // Free Text Option for Checkboxes and Radio Buttons
72
+ $( '.wpcf7-list-item.has-free-text', $form ).each( function() {
73
+ var $freetext = $( ':input.wpcf7-free-text', this );
74
+ var $wrap = $( this ).closest( '.wpcf7-form-control' );
 
75
 
76
+ if ( $( ':checkbox, :radio', this ).is( ':checked' ) ) {
77
+ $freetext.prop( 'disabled', false );
78
+ } else {
79
+ $freetext.prop( 'disabled', true );
80
+ }
81
 
82
+ $wrap.on( 'change', ':checkbox, :radio', function() {
83
+ var $cb = $( '.has-free-text', $wrap ).find( ':checkbox, :radio' );
84
+
85
+ if ( $cb.is( ':checked' ) ) {
86
+ $freetext.prop( 'disabled', false ).focus();
87
  } else {
88
  $freetext.prop( 'disabled', true );
89
  }
90
+ } );
91
+ } );
92
 
93
+ // Placeholder Fallback
94
+ if ( ! wpcf7.supportHtml5.placeholder ) {
95
+ $( '[placeholder]', $form ).each( function() {
96
+ $( this ).val( $( this ).attr( 'placeholder' ) );
97
+ $( this ).addClass( 'placeheld' );
98
 
99
+ $( this ).focus( function() {
100
+ if ( $( this ).hasClass( 'placeheld' ) ) {
101
+ $( this ).val( '' ).removeClass( 'placeheld' );
 
102
  }
103
  } );
 
 
 
 
 
 
 
104
 
105
+ $( this ).blur( function() {
106
+ if ( '' === $( this ).val() ) {
107
+ $( this ).val( $( this ).attr( 'placeholder' ) );
108
+ $( this ).addClass( 'placeheld' );
109
+ }
 
 
 
 
 
 
 
110
  } );
111
+ } );
112
+ }
113
 
114
+ if ( wpcf7.jqueryUi && ! wpcf7.supportHtml5.date ) {
115
+ $form.find( 'input.wpcf7-date[type="date"]' ).each( function() {
116
+ $( this ).datepicker( {
117
+ dateFormat: 'yy-mm-dd',
118
+ minDate: new Date( $( this ).attr( 'min' ) ),
119
+ maxDate: new Date( $( this ).attr( 'max' ) )
 
120
  } );
121
+ } );
122
+ }
123
 
124
+ if ( wpcf7.jqueryUi && ! wpcf7.supportHtml5.number ) {
125
+ $form.find( 'input.wpcf7-number[type="number"]' ).each( function() {
126
+ $( this ).spinner( {
127
+ min: $( this ).attr( 'min' ),
128
+ max: $( this ).attr( 'max' ),
129
+ step: $( this ).attr( 'step' )
 
130
  } );
131
+ } );
132
+ }
133
 
134
+ // Character Count
135
+ $( '.wpcf7-character-count', $form ).each( function() {
136
+ var $count = $( this );
137
+ var name = $count.attr( 'data-target-name' );
138
+ var down = $count.hasClass( 'down' );
139
+ var starting = parseInt( $count.attr( 'data-starting-value' ), 10 );
140
+ var maximum = parseInt( $count.attr( 'data-maximum-value' ), 10 );
141
+ var minimum = parseInt( $count.attr( 'data-minimum-value' ), 10 );
142
+
143
+ var updateCount = function( target ) {
144
+ var $target = $( target );
145
+ var length = $target.val().length;
146
+ var count = down ? starting - length : length;
147
+ $count.attr( 'data-current-value', count );
148
+ $count.text( count );
149
+
150
+ if ( maximum && maximum < length ) {
151
+ $count.addClass( 'too-long' );
152
+ } else {
153
+ $count.removeClass( 'too-long' );
154
+ }
155
 
156
+ if ( minimum && length < minimum ) {
157
+ $count.addClass( 'too-short' );
158
+ } else {
159
+ $count.removeClass( 'too-short' );
160
+ }
161
+ };
162
 
163
+ $( ':input[name="' + name + '"]', $form ).each( function() {
164
+ updateCount( this );
165
 
166
+ $( this ).keyup( function() {
167
+ updateCount( this );
 
168
  } );
169
  } );
170
+ } );
171
 
172
+ $form.on( 'change', '.wpcf7-validates-as-url', function() {
173
+ var val = $.trim( $( this ).val() );
 
 
 
 
 
 
 
 
 
174
 
175
+ // check the scheme part
176
+ if ( val && ! val.match( /^[a-z][a-z0-9.+-]*:/i ) ) {
177
+ val = val.replace( /^\/+/, '' );
178
+ val = 'http://' + val;
179
  }
 
 
180
 
181
+ $( this ).val( val );
182
+ } );
183
  };
184
 
185
  wpcf7.submit = function( form ) {
216
  detail.unitTag = field.value;
217
  } else if ( '_wpcf7_container_post' == field.name ) {
218
  detail.containerPostId = field.value;
219
+ } else if ( field.name.match( /^_wpcf7_\w+_free_text_/ ) ) {
220
+ var owner = field.name.replace( /^_wpcf7_\w+_free_text_/, '' );
221
+ detail.inputs.push( {
222
+ name: owner + '-free-text',
223
+ value: field.value
224
+ } );
225
  } else if ( field.name.match( /^_/ ) ) {
226
  // do nothing
227
  } else {
296
  $( n ).val( $( n ).attr( 'placeholder' ) );
297
  } );
298
 
299
+ $message.html( '' ).append( data.message ).slideDown( 'fast' );
300
  $message.attr( 'role', 'alert' );
301
 
302
  $( '.screen-reader-response', $form.closest( '.wpcf7' ) ).each( function() {
325
 
326
  $.ajax( {
327
  type: 'POST',
328
+ url: wpcf7.apiSettings.getRoute(
329
+ '/contact-forms/' + wpcf7.getId( $form ) + '/feedback' ),
330
  data: formData,
331
  dataType: 'json',
332
  processData: false,
395
  }, 'fast', function() {
396
  $( this ).css( { 'z-index': -100 } );
397
  } );
398
+ };
399
 
400
  $target.on( 'mouseover', '.wpcf7-not-valid-tip', function() {
401
  fadeOut( this );
405
  fadeOut( $( '.wpcf7-not-valid-tip', $target ) );
406
  } );
407
  }
408
+ };
409
 
410
  wpcf7.refill = function( form, data ) {
411
  var $form = $( form );
430
  if ( typeof data === 'undefined' ) {
431
  $.ajax( {
432
  type: 'GET',
433
+ url: wpcf7.apiSettings.getRoute(
434
+ '/contact-forms/' + wpcf7.getId( $form ) + '/refill' ),
435
  dataType: 'json'
436
  } ).done( function( data, status, xhr ) {
437
  if ( data.captcha ) {
468
  .removeClass( 'wpcf7-mail-sent-ok wpcf7-mail-sent-ng wpcf7-validation-errors wpcf7-spam-blocked' );
469
  };
470
 
471
+ wpcf7.apiSettings.getRoute = function( path ) {
472
+ var url = wpcf7.apiSettings.root;
473
+
474
+ url = url.replace(
475
+ wpcf7.apiSettings.namespace,
476
+ wpcf7.apiSettings.namespace + path );
477
+
478
+ return url;
479
+ };
480
+
481
  } )( jQuery );
482
 
483
  /*
includes/mail.php CHANGED
@@ -207,17 +207,25 @@ function wpcf7_mail_replace_tags( $content, $args = '' ) {
207
  add_action( 'phpmailer_init', 'wpcf7_phpmailer_init' );
208
 
209
  function wpcf7_phpmailer_init( $phpmailer ) {
 
 
210
  $wpcf7_content_type = false;
211
 
212
- foreach ( (array) $phpmailer->getCustomHeaders() as $custom_header ) {
213
- if ( 'X-WPCF7-Content-Type' == $custom_header[0] ) {
214
- $wpcf7_content_type = trim( $custom_header[1] );
215
- break;
 
 
 
 
216
  }
217
  }
218
 
219
- if ( 'text/html' == $wpcf7_content_type ) {
220
  $phpmailer->msgHTML( $phpmailer->Body );
 
 
221
  }
222
  }
223
 
207
  add_action( 'phpmailer_init', 'wpcf7_phpmailer_init' );
208
 
209
  function wpcf7_phpmailer_init( $phpmailer ) {
210
+ $custom_headers = $phpmailer->getCustomHeaders();
211
+ $phpmailer->clearCustomHeaders();
212
  $wpcf7_content_type = false;
213
 
214
+ foreach ( (array) $custom_headers as $custom_header ) {
215
+ $name = $custom_header[0];
216
+ $value = $custom_header[1];
217
+
218
+ if ( 'X-WPCF7-Content-Type' === $name ) {
219
+ $wpcf7_content_type = trim( $value );
220
+ } else {
221
+ $phpmailer->addCustomHeader( $name, $value );
222
  }
223
  }
224
 
225
+ if ( 'text/html' === $wpcf7_content_type ) {
226
  $phpmailer->msgHTML( $phpmailer->Body );
227
+ } elseif ( 'text/plain' === $wpcf7_content_type ) {
228
+ $phpmailer->AltBody = '';
229
  }
230
  }
231
 
modules/akismet.php CHANGED
@@ -99,8 +99,10 @@ function wpcf7_akismet_submitted_params() {
99
 
100
  if ( 'author' == $akismet ) {
101
  $params[$akismet] = trim( $params[$akismet] . ' ' . $val );
 
102
  } elseif ( '' == $params[$akismet] ) {
103
  $params[$akismet] = $val;
 
104
  }
105
  }
106
  }
99
 
100
  if ( 'author' == $akismet ) {
101
  $params[$akismet] = trim( $params[$akismet] . ' ' . $val );
102
+ continue;
103
  } elseif ( '' == $params[$akismet] ) {
104
  $params[$akismet] = $val;
105
+ continue;
106
  }
107
  }
108
  }
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://contactform7.com/donate/
4
  Tags: contact, form, contact form, feedback, email, ajax, captcha, akismet, multilingual
5
  Requires at least: 4.7
6
  Tested up to: 4.8
7
- Stable tag: 4.8
8
  License: GPLv2 or later
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -62,6 +62,16 @@ Do you have questions or issues with Contact Form 7? Use these support channels
62
 
63
  For more information, see [Releases](https://contactform7.com/category/releases/).
64
 
 
 
 
 
 
 
 
 
 
 
65
  = 4.8 =
66
 
67
  * Stopped using jquery.form.js.
@@ -71,12 +81,3 @@ For more information, see [Releases](https://contactform7.com/category/releases/
71
  * New form-tag features: do-not-store, display-block, and display-hidden
72
  * Removed inappropriate content from h1 headings.
73
  * Added the support of size:invisible option to the reCAPTCHA form-tag.
74
-
75
- = 4.7 =
76
-
77
- * Added REST API custom endpoints to manipulate contact form data.
78
- * Config Validator: Added test items for field names and attachment file paths.
79
- * Added custom DOM events: `wpcf7invalid`, `wpcf7spam`, `wpcf7mailsent`, `wpcf7mailfailed` and `wpcf7submit`.
80
- * New action hook: `wpcf7_after_flamingo`.
81
- * Added `size` option to `select` and `select*` form-tag types.
82
- * Made it possible to use the 3rd parameter of `wpcf7_add_form_tag()` to specify "features" of the form-tag type.
4
  Tags: contact, form, contact form, feedback, email, ajax, captcha, akismet, multilingual
5
  Requires at least: 4.7
6
  Tested up to: 4.8
7
+ Stable tag: 4.8.1
8
  License: GPLv2 or later
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
10
 
62
 
63
  For more information, see [Releases](https://contactform7.com/category/releases/).
64
 
65
+ = 4.8.1 =
66
+
67
+ * wpcf7.initForm JavaScript function added to isolate form initialization process.
68
+ * Fix response message duplication caused by repeated click on submit button.
69
+ * Clear $phpmailer->AltBody to avoid unintended inheritance from previous wp_mail() calls.
70
+ * Fix incorrect character count of textarea input.
71
+ * Akismet: Exclude the comment_author, comment_author_email, and comment_author_url values from the comment_content value.
72
+ * REST API: More reliable approach to build route URLs.
73
+ * Include free_text inputs into event.detail.inputs.
74
+
75
  = 4.8 =
76
 
77
  * Stopped using jquery.form.js.
81
  * New form-tag features: do-not-store, display-block, and display-hidden
82
  * Removed inappropriate content from h1 headings.
83
  * Added the support of size:invisible option to the reCAPTCHA form-tag.
 
 
 
 
 
 
 
 
 
wp-contact-form-7.php CHANGED
@@ -7,10 +7,10 @@ Author: Takayuki Miyoshi
7
  Author URI: https://ideasilo.wordpress.com/
8
  Text Domain: contact-form-7
9
  Domain Path: /languages/
10
- Version: 4.8
11
  */
12
 
13
- define( 'WPCF7_VERSION', '4.8' );
14
 
15
  define( 'WPCF7_REQUIRED_WP_VERSION', '4.7' );
16
 
7
  Author URI: https://ideasilo.wordpress.com/
8
  Text Domain: contact-form-7
9
  Domain Path: /languages/
10
+ Version: 4.8.1
11
  */
12
 
13
+ define( 'WPCF7_VERSION', '4.8.1' );
14
 
15
  define( 'WPCF7_REQUIRED_WP_VERSION', '4.7' );
16