Contact Form 7 - Version 5.3

Version Description

  • Block Editor: Introduces the contact form selector block type.
  • Renames the 'images' directory to 'assets'.
  • New filter hook: wpcf7_form_tag_date_option.
  • Date: Makes all DateTime date formats available for min and max options.
  • Date: Converts the default value to Y-m-d date format string.
  • Disallowed list: Deprecates the wpcf7_submission_is_blacklisted filter hook in favor of wpcf7_submission_has_disallowed_words.
  • Accessibility: Sets the aria-describedby attribute for invalid fields.
  • Default form template: Removes the "(required)" labels from required fields. Adds "(optional)" to optional fields instead.
  • Default mail template: Uses site-related special mail-tags.
Download this release

Release Info

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

Code changes from version 5.2.2 to 5.3

admin/admin.php CHANGED
@@ -15,25 +15,27 @@ function wpcf7_admin_init() {
15
  add_action( 'admin_menu', 'wpcf7_admin_menu', 9, 0 );
16
 
17
  function wpcf7_admin_menu() {
18
- global $_wp_last_object_menu;
19
-
20
- $_wp_last_object_menu++;
21
-
22
  do_action( 'wpcf7_admin_menu' );
23
 
24
- add_menu_page( __( 'Contact Form 7', 'contact-form-7' ),
 
25
  __( 'Contact', 'contact-form-7' )
26
  . wpcf7_admin_menu_change_notice(),
27
- 'wpcf7_read_contact_forms', 'wpcf7',
28
- 'wpcf7_admin_management_page', 'dashicons-email',
29
- $_wp_last_object_menu );
 
 
 
30
 
31
  $edit = add_submenu_page( 'wpcf7',
32
  __( 'Edit Contact Form', 'contact-form-7' ),
33
  __( 'Contact Forms', 'contact-form-7' )
34
  . wpcf7_admin_menu_change_notice( 'wpcf7' ),
35
- 'wpcf7_read_contact_forms', 'wpcf7',
36
- 'wpcf7_admin_management_page' );
 
 
37
 
38
  add_action( 'load-' . $edit, 'wpcf7_load_contact_form_admin', 10, 0 );
39
 
@@ -41,8 +43,10 @@ function wpcf7_admin_menu() {
41
  __( 'Add New Contact Form', 'contact-form-7' ),
42
  __( 'Add New', 'contact-form-7' )
43
  . wpcf7_admin_menu_change_notice( 'wpcf7-new' ),
44
- 'wpcf7_edit_contact_forms', 'wpcf7-new',
45
- 'wpcf7_admin_add_new_page' );
 
 
46
 
47
  add_action( 'load-' . $addnew, 'wpcf7_load_contact_form_admin', 10, 0 );
48
 
@@ -53,8 +57,10 @@ function wpcf7_admin_menu() {
53
  __( 'Integration with Other Services', 'contact-form-7' ),
54
  __( 'Integration', 'contact-form-7' )
55
  . wpcf7_admin_menu_change_notice( 'wpcf7-integration' ),
56
- 'wpcf7_manage_integration', 'wpcf7-integration',
57
- 'wpcf7_admin_integration_page' );
 
 
58
 
59
  add_action( 'load-' . $integration, 'wpcf7_load_integration_page', 10, 0 );
60
  }
@@ -165,8 +171,9 @@ function wpcf7_dark_mode_support( $user_id ) {
165
  array( 'contact-form-7-admin' ), WPCF7_VERSION, 'screen' );
166
  }
167
 
168
- add_filter( 'set-screen-option', 'wpcf7_set_screen_options', 10, 3 );
169
- add_filter( 'set_screen_option_wpcf7_contact_forms_per_page', 'wpcf7_set_screen_options', 10, 3 );
 
170
 
171
  function wpcf7_set_screen_options( $result, $option, $value ) {
172
  $wpcf7_screens = array(
15
  add_action( 'admin_menu', 'wpcf7_admin_menu', 9, 0 );
16
 
17
  function wpcf7_admin_menu() {
 
 
 
 
18
  do_action( 'wpcf7_admin_menu' );
19
 
20
+ add_menu_page(
21
+ __( 'Contact Form 7', 'contact-form-7' ),
22
  __( 'Contact', 'contact-form-7' )
23
  . wpcf7_admin_menu_change_notice(),
24
+ 'wpcf7_read_contact_forms',
25
+ 'wpcf7',
26
+ 'wpcf7_admin_management_page',
27
+ 'dashicons-email',
28
+ 30
29
+ );
30
 
31
  $edit = add_submenu_page( 'wpcf7',
32
  __( 'Edit Contact Form', 'contact-form-7' ),
33
  __( 'Contact Forms', 'contact-form-7' )
34
  . wpcf7_admin_menu_change_notice( 'wpcf7' ),
35
+ 'wpcf7_read_contact_forms',
36
+ 'wpcf7',
37
+ 'wpcf7_admin_management_page'
38
+ );
39
 
40
  add_action( 'load-' . $edit, 'wpcf7_load_contact_form_admin', 10, 0 );
41
 
43
  __( 'Add New Contact Form', 'contact-form-7' ),
44
  __( 'Add New', 'contact-form-7' )
45
  . wpcf7_admin_menu_change_notice( 'wpcf7-new' ),
46
+ 'wpcf7_edit_contact_forms',
47
+ 'wpcf7-new',
48
+ 'wpcf7_admin_add_new_page'
49
+ );
50
 
51
  add_action( 'load-' . $addnew, 'wpcf7_load_contact_form_admin', 10, 0 );
52
 
57
  __( 'Integration with Other Services', 'contact-form-7' ),
58
  __( 'Integration', 'contact-form-7' )
59
  . wpcf7_admin_menu_change_notice( 'wpcf7-integration' ),
60
+ 'wpcf7_manage_integration',
61
+ 'wpcf7-integration',
62
+ 'wpcf7_admin_integration_page'
63
+ );
64
 
65
  add_action( 'load-' . $integration, 'wpcf7_load_integration_page', 10, 0 );
66
  }
171
  array( 'contact-form-7-admin' ), WPCF7_VERSION, 'screen' );
172
  }
173
 
174
+ add_filter( 'set_screen_option_wpcf7_contact_forms_per_page',
175
+ 'wpcf7_set_screen_options', 10, 3
176
+ );
177
 
178
  function wpcf7_set_screen_options( $result, $option, $value ) {
179
  $wpcf7_screens = array(
admin/css/styles-rtl.css CHANGED
@@ -12,7 +12,7 @@
12
  text-align: right;
13
  }
14
 
15
- .tag-generator-panel .control-box > fieldset legend {
16
  border: 1px solid #dfdfdf;
17
  border-right: 4px solid #00a0d2;
18
  }
12
  text-align: right;
13
  }
14
 
15
+ .tag-generator-panel .control-box > fieldset > legend {
16
  border: 1px solid #dfdfdf;
17
  border-right: 4px solid #00a0d2;
18
  }
admin/css/styles.css CHANGED
@@ -202,25 +202,27 @@ ul.config-error li {
202
  }
203
 
204
  .tag-generator-panel {
205
- position: relative;
206
  height: 495px;
 
 
207
  }
208
 
209
  .tag-generator-panel .control-box {
210
  padding: 0;
211
  margin: 0;
212
- height: 380px;
213
  overflow: auto;
 
214
  }
215
 
216
- .tag-generator-panel .control-box > fieldset legend {
217
  border: 1px solid #dfdfdf;
218
  border-left: 4px solid #00a0d2;
219
  background: #f7fcfe;
220
  padding: 4px 12px;
221
  margin: 4px 0;
222
  line-height: 1.4em;
223
- width: 95%;
 
224
  }
225
 
226
  .tag-generator-panel table {
@@ -273,13 +275,7 @@ ul.config-error li {
273
  }
274
 
275
  .tag-generator-panel .insert-box {
276
- position: absolute;
277
- left: -15px;
278
- right: -15px;
279
- bottom: -15px;
280
- width: 100%;
281
- height: 84px;
282
- margin: 0;
283
  padding: 8px 16px;
284
  background-color: #fcfcfc;
285
  border-top: 1px solid #dfdfdf;
@@ -287,14 +283,14 @@ ul.config-error li {
287
  }
288
 
289
  .tag-generator-panel .insert-box input.tag {
290
- width: 480px;
291
  float: left;
292
  background-color: transparent;
293
  box-shadow: none;
294
  }
295
 
296
  .tag-generator-panel .insert-box .submitbox {
297
- padding: 2px 4px;
298
  }
299
 
300
  .tag-generator-panel .insert-box .submitbox input[type="button"] {
202
  }
203
 
204
  .tag-generator-panel {
 
205
  height: 495px;
206
+ display: flex;
207
+ flex-direction: column;
208
  }
209
 
210
  .tag-generator-panel .control-box {
211
  padding: 0;
212
  margin: 0;
 
213
  overflow: auto;
214
+ flex-grow: 1;
215
  }
216
 
217
+ .tag-generator-panel .control-box > fieldset > legend {
218
  border: 1px solid #dfdfdf;
219
  border-left: 4px solid #00a0d2;
220
  background: #f7fcfe;
221
  padding: 4px 12px;
222
  margin: 4px 0;
223
  line-height: 1.4em;
224
+ width: 100%;
225
+ box-sizing: border-box;
226
  }
227
 
228
  .tag-generator-panel table {
275
  }
276
 
277
  .tag-generator-panel .insert-box {
278
+ margin: 0 -15px -15px;
 
 
 
 
 
 
279
  padding: 8px 16px;
280
  background-color: #fcfcfc;
281
  border-top: 1px solid #dfdfdf;
283
  }
284
 
285
  .tag-generator-panel .insert-box input.tag {
286
+ width: 510px;
287
  float: left;
288
  background-color: transparent;
289
  box-shadow: none;
290
  }
291
 
292
  .tag-generator-panel .insert-box .submitbox {
293
+ padding: 0;
294
  }
295
 
296
  .tag-generator-panel .insert-box .submitbox input[type="button"] {
admin/includes/welcome-panel.php CHANGED
@@ -25,7 +25,7 @@ function wpcf7_welcome_panel() {
25
 
26
  <p><?php
27
  echo sprintf(
28
- /* translators: links labeled 1: 'Akismet', 2: 'reCAPTCHA', 3: 'comment blacklist' */
29
  esc_html( __( 'Contact Form 7 supports spam-filtering with %1$s. Intelligent %2$s blocks annoying spambots. Plus, using %3$s, you can block messages containing specified keywords or those sent from specified IP addresses.', 'contact-form-7' ) ),
30
  wpcf7_link(
31
  __( 'https://contactform7.com/spam-filtering-with-akismet/', 'contact-form-7' ),
@@ -37,7 +37,7 @@ function wpcf7_welcome_panel() {
37
  ),
38
  wpcf7_link(
39
  __( 'https://contactform7.com/comment-blacklist/', 'contact-form-7' ),
40
- __( 'comment blacklist', 'contact-form-7' )
41
  )
42
  );
43
  ?></p>
25
 
26
  <p><?php
27
  echo sprintf(
28
+ /* translators: links labeled 1: 'Akismet', 2: 'reCAPTCHA', 3: 'disallowed list' */
29
  esc_html( __( 'Contact Form 7 supports spam-filtering with %1$s. Intelligent %2$s blocks annoying spambots. Plus, using %3$s, you can block messages containing specified keywords or those sent from specified IP addresses.', 'contact-form-7' ) ),
30
  wpcf7_link(
31
  __( 'https://contactform7.com/spam-filtering-with-akismet/', 'contact-form-7' ),
37
  ),
38
  wpcf7_link(
39
  __( 'https://contactform7.com/comment-blacklist/', 'contact-form-7' ),
40
+ __( 'disallowed list', 'contact-form-7' )
41
  )
42
  );
43
  ?></p>
admin/js/scripts.js CHANGED
@@ -150,9 +150,11 @@
150
 
151
  var section = $( this ).attr( 'data-config-field' );
152
 
 
 
153
  if ( errors[ section ] ) {
154
  var $list = $( '<ul></ul>' ).attr( {
155
- 'role': 'alert',
156
  'class': 'config-error'
157
  } );
158
 
150
 
151
  var section = $( this ).attr( 'data-config-field' );
152
 
153
+ $( this ).attr( 'aria-describedby', 'wpcf7-config-error-for-' + section );
154
+
155
  if ( errors[ section ] ) {
156
  var $list = $( '<ul></ul>' ).attr( {
157
+ 'id': 'wpcf7-config-error-for-' + section,
158
  'class': 'config-error'
159
  } );
160
 
{images → assets}/ajax-loader.gif RENAMED
File without changes
assets/icon.png ADDED
Binary file
assets/icon.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 242.5 239.46"><defs><style>.cls-1,.cls-6{fill:none;}.cls-2{clip-path:url(#clip-path);}.cls-3{fill:#33c6f4;}.cls-4{fill:#1b447e;}.cls-5{fill:#fff;}.cls-6{stroke:#221e1f;stroke-miterlimit:10;stroke-width:7.16px;}</style><clipPath id="clip-path" transform="translate(1.72)"><circle class="cls-1" cx="119.73" cy="119.73" r="116.15"/></clipPath></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1" data-name="Layer 1"><g class="cls-2"><circle class="cls-3" cx="121.45" cy="119.73" r="116.15"/><path class="cls-4" d="M239.32,167.79c-53.41-24-108.37-91.46-113-94.55s-10.84.77-10.84.77c-3.87-6.19-10.06.77-10.06.77C76.77,123.55.14,170.11.14,170.11S36.94,237.79,122,237.79C208.48,237.79,239.32,167.79,239.32,167.79Z" transform="translate(1.72)"/><path class="cls-5" d="M67.48,116.58s15.48-7,12.38,4.65-15.48,28.64-11.61,29.41S83,140.58,86.06,142.12s5.42.78,3.87,6.2-3.1,9.29,0,9.29,5.42-7,9.29-13.94,10.06-3.87,12.38-1.55,9.29,15.49,14.71,13.94,8.51-8.52,6.19-24,1.55-20.12,1.55-20.12,4.64-2.32,13.16,8.51,24,27.09,26.31,26.32-10.83-17.8-7.74-19.35,15.48,2.32,21.68,7.74c0,0,2.12,8.87,2.12.36L126.31,73.24,115.47,74l-10.06.77S80.64,111.94,67.48,116.58Z" transform="translate(1.72)"/><path class="cls-6" d="M239.32,170.11c-53.41-24-108.37-93.78-113-96.87s-10.84.77-10.84.77c-3.87-6.19-10.06.77-10.06.77C76.77,123.55.14,170.11.14,170.11" transform="translate(1.72)"/></g><circle class="cls-6" cx="121.45" cy="119.73" r="116.15"/></g></g></svg>
includes/block-editor/block-editor.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ add_action( 'init', 'wpcf7_init_block_editor_assets', 10, 0 );
4
+
5
+ function wpcf7_init_block_editor_assets() {
6
+ $assets = array();
7
+
8
+ $asset_file = wpcf7_plugin_path(
9
+ 'includes/block-editor/index.asset.php'
10
+ );
11
+
12
+ if ( file_exists( $asset_file ) ) {
13
+ $assets = include( $asset_file );
14
+ }
15
+
16
+ $assets = wp_parse_args( $assets, array(
17
+ 'src' => wpcf7_plugin_url( 'includes/block-editor/index.js' ),
18
+ 'dependencies' => array(
19
+ 'wp-api-fetch',
20
+ 'wp-components',
21
+ 'wp-compose',
22
+ 'wp-blocks',
23
+ 'wp-element',
24
+ 'wp-i18n',
25
+ ),
26
+ 'version' => WPCF7_VERSION,
27
+ ) );
28
+
29
+ wp_register_script(
30
+ 'contact-form-7-block-editor',
31
+ $assets['src'],
32
+ $assets['dependencies'],
33
+ $assets['version']
34
+ );
35
+
36
+ wp_set_script_translations(
37
+ 'contact-form-7-block-editor',
38
+ 'contact-form-7'
39
+ );
40
+
41
+ register_block_type(
42
+ 'contact-form-7/contact-form-selector',
43
+ array(
44
+ 'editor_script' => 'contact-form-7-block-editor',
45
+ )
46
+ );
47
+ }
includes/block-editor/index.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(t){var e={};function r(n){if(e[n])return e[n].exports;var c=e[n]={i:n,l:!1,exports:{}};return t[n].call(c.exports,c,c.exports,r),c.l=!0,c.exports}r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var c in t)r.d(n,c,function(e){return t[e]}.bind(null,c));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=12)}([function(t,e){!function(){t.exports=this.wp.element}()},function(t,e){!function(){t.exports=this.wp.i18n}()},function(t,e){!function(){t.exports=this.wp.blocks}()},function(t,e,r){var n=r(7),c=r(8),o=r(9),a=r(11);t.exports=function(t,e){return n(t)||c(t,e)||o(t,e)||a()}},function(t,e){!function(){t.exports=this.wp.apiFetch}()},function(t,e){!function(){t.exports=this.wp.compose}()},function(t,e){!function(){t.exports=this.wp.components}()},function(t,e){t.exports=function(t){if(Array.isArray(t))return t}},function(t,e){t.exports=function(t,e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(t)){var r=[],n=!0,c=!1,o=void 0;try{for(var a,i=t[Symbol.iterator]();!(n=(a=i.next()).done)&&(r.push(a.value),!e||r.length!==e);n=!0);}catch(t){c=!0,o=t}finally{try{n||null==i.return||i.return()}finally{if(c)throw o}}return r}}},function(t,e,r){var n=r(10);t.exports=function(t,e){if(t){if("string"==typeof t)return n(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?n(t,e):void 0}}},function(t,e){t.exports=function(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r<e;r++)n[r]=t[r];return n}},function(t,e){t.exports=function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}},function(t,e,r){"use strict";r.r(e);var n=r(0),c=r(1),o=r(2),a=Object(n.createElement)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 242.5 239.46"},Object(n.createElement)("defs",null,Object(n.createElement)("clipPath",{id:"clip-path",transform:"translate(1.72)"},Object(n.createElement)("circle",{class:"cls-1",cx:"119.73",cy:"119.73",r:"116.15",fill:"none"}))),Object(n.createElement)("g",{id:"Layer_2","data-name":"Layer 2"},Object(n.createElement)("g",{id:"Layer_1","data-name":"Layer 1"},Object(n.createElement)("g",{class:"cls-2","clip-path":"url(#clip-path)"},Object(n.createElement)("circle",{class:"cls-3",cx:"121.45",cy:"119.73",r:"116.15",fill:"#33c6f4"}),Object(n.createElement)("path",{class:"cls-4",d:"M239.32,167.79c-53.41-24-108.37-91.46-113-94.55s-10.84.77-10.84.77c-3.87-6.19-10.06.77-10.06.77C76.77,123.55.14,170.11.14,170.11S36.94,237.79,122,237.79C208.48,237.79,239.32,167.79,239.32,167.79Z",transform:"translate(1.72)",fill:"#1b447e"}),Object(n.createElement)("path",{class:"cls-5",d:"M67.48,116.58s15.48-7,12.38,4.65-15.48,28.64-11.61,29.41S83,140.58,86.06,142.12s5.42.78,3.87,6.2-3.1,9.29,0,9.29,5.42-7,9.29-13.94,10.06-3.87,12.38-1.55,9.29,15.49,14.71,13.94,8.51-8.52,6.19-24,1.55-20.12,1.55-20.12,4.64-2.32,13.16,8.51,24,27.09,26.31,26.32-10.83-17.8-7.74-19.35,15.48,2.32,21.68,7.74c0,0,2.12,8.87,2.12.36L126.31,73.24,115.47,74l-10.06.77S80.64,111.94,67.48,116.58Z",transform:"translate(1.72)",fill:"#fff"}),Object(n.createElement)("path",{class:"cls-6",d:"M239.32,170.11c-53.41-24-108.37-93.78-113-96.87s-10.84.77-10.84.77c-3.87-6.19-10.06.77-10.06.77C76.77,123.55.14,170.11.14,170.11",transform:"translate(1.72)",fill:"none",stroke:"#221e1f","stroke-miterlimit":"10","stroke-width":"8px"})),Object(n.createElement)("circle",{class:"cls-6",cx:"121.45",cy:"119.73",r:"116.15",fill:"none",stroke:"#1b447e","stroke-miterlimit":"10","stroke-width":"8px"})))),i=r(3),l=r.n(i),s=r(4),f=r.n(s),u=r(5),p=r(6),m=new Map;f()({path:"contact-form-7/v1/contact-forms?per_page=20"}).then((function(t){Object.entries(t).forEach((function(t){var e=l()(t,2),r=(e[0],e[1]);m.set(r.id,r)}))}));var d={from:[{type:"shortcode",tag:"contact-form-7",attributes:{id:{type:"integer",shortcode:function(t){var e=t.named.id;return parseInt(e)}},title:{type:"string",shortcode:function(t){return t.named.title}}}}],to:[{type:"block",blocks:["core/shortcode"],transform:function(t){return Object(o.createBlock)("core/shortcode",{text:'[contact-form-7 id="'.concat(t.id,'" title="').concat(t.title,'"]')})}}]};Object(o.registerBlockType)("contact-form-7/contact-form-selector",{title:Object(c.__)("Contact Form 7","contact-form-7"),description:Object(c.__)("Insert a contact form you have created with Contact Form 7.","contact-form-7"),category:"widgets",attributes:{id:{type:"integer"},title:{type:"string"}},icon:a,transforms:d,edit:function t(e){var r=e.attributes,o=e.setAttributes;if(!m.size&&!r.id)return Object(n.createElement)("div",{className:"components-placeholder"},Object(n.createElement)("p",null,Object(c.__)("No contact forms were found. Create a contact form first.","contact-form-7")));var a=Array.from(m.values(),(function(t){return{value:t.id,label:t.title}}));if(r.id)a.length||a.push({value:r.id,label:r.title});else{var i=a[0];o({id:parseInt(i.value),title:i.label})}var l=Object(u.useInstanceId)(t),s="contact-form-7-contact-form-selector-".concat(l);return Object(n.createElement)("div",{className:"components-placeholder"},Object(n.createElement)("label",{htmlFor:s,className:"components-placeholder__label"},Object(c.__)("Select a contact form:","contact-form-7")),Object(n.createElement)(p.SelectControl,{id:s,options:a,value:r.id,onChange:function(t){return o({id:parseInt(t),title:m.get(parseInt(t)).title})}}))},save:function(t){var e=t.attributes;return Object(n.createElement)("div",null,'[contact-form-7 id="',e.id,'" title="',e.title,'"]')}})}]);
includes/contact-form-functions.php CHANGED
@@ -62,6 +62,18 @@ function wpcf7_get_validation_error( $name ) {
62
  return $contact_form->validation_error( $name );
63
  }
64
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  function wpcf7_get_message( $status ) {
66
  if ( ! $contact_form = wpcf7_get_current_contact_form() ) {
67
  return '';
62
  return $contact_form->validation_error( $name );
63
  }
64
 
65
+ function wpcf7_get_validation_error_reference( $name ) {
66
+ $contact_form = wpcf7_get_current_contact_form();
67
+
68
+ if ( $contact_form and $contact_form->validation_error( $name ) ) {
69
+ return sprintf(
70
+ '%1$s-ve-%2$s',
71
+ $contact_form->unit_tag(),
72
+ $name
73
+ );
74
+ }
75
+ }
76
+
77
  function wpcf7_get_message( $status ) {
78
  if ( ! $contact_form = wpcf7_get_current_contact_form() ) {
79
  return '';
includes/contact-form-template.php CHANGED
@@ -21,57 +21,64 @@ class WPCF7_ContactFormTemplate {
21
  public static function form() {
22
  $template = sprintf(
23
  '
24
- <label> %2$s %1$s
25
  [text* your-name] </label>
26
 
27
- <label> %3$s %1$s
28
  [email* your-email] </label>
29
 
30
  <label> %4$s
31
- [text your-subject] </label>
32
 
33
- <label> %5$s
34
  [textarea your-message] </label>
35
 
36
  [submit "%6$s"]',
37
- __( '(required)', 'contact-form-7' ),
38
- __( 'Your Name', 'contact-form-7' ),
39
- __( 'Your Email', 'contact-form-7' ),
40
  __( 'Subject', 'contact-form-7' ),
41
- __( 'Your Message', 'contact-form-7' ),
42
- __( 'Send', 'contact-form-7' ) );
 
43
 
44
  return trim( $template );
45
  }
46
 
47
  public static function mail() {
48
  $template = array(
49
- 'subject' =>
 
 
 
 
 
 
 
 
 
 
 
50
  sprintf(
51
- /* translators: 1: blog name, 2: [your-subject] */
52
- _x( '%1$s "%2$s"', 'mail subject', 'contact-form-7' ),
53
- get_bloginfo( 'name' ),
 
 
 
 
54
  '[your-subject]'
55
- ),
56
- 'sender' => sprintf( '%s <%s>',
57
- get_bloginfo( 'name' ), self::from_email() ),
58
- 'body' =>
59
- /* translators: %s: [your-name] <[your-email]> */
60
- sprintf( __( 'From: %s', 'contact-form-7' ),
61
- '[your-name] <[your-email]>' ) . "\n"
62
- /* translators: %s: [your-subject] */
63
- . sprintf( __( 'Subject: %s', 'contact-form-7' ),
64
- '[your-subject]' ) . "\n\n"
65
  . __( 'Message Body:', 'contact-form-7' )
66
- . "\n" . '[your-message]' . "\n\n"
67
  . '-- ' . "\n"
68
  . sprintf(
69
  /* translators: 1: blog name, 2: blog URL */
70
  __( 'This e-mail was sent from a contact form on %1$s (%2$s)', 'contact-form-7' ),
71
- get_bloginfo( 'name' ),
72
- get_bloginfo( 'url' )
73
  ),
74
- 'recipient' => get_option( 'admin_email' ),
75
  'additional_headers' => 'Reply-To: [your-email]',
76
  'attachments' => '',
77
  'use_html' => 0,
@@ -84,28 +91,32 @@ class WPCF7_ContactFormTemplate {
84
  public static function mail_2() {
85
  $template = array(
86
  'active' => false,
87
- 'subject' =>
88
- sprintf(
89
- /* translators: 1: blog name, 2: [your-subject] */
90
- _x( '%1$s "%2$s"', 'mail subject', 'contact-form-7' ),
91
- get_bloginfo( 'name' ),
92
- '[your-subject]'
93
- ),
94
- 'sender' => sprintf( '%s <%s>',
95
- get_bloginfo( 'name' ), self::from_email() ),
 
 
96
  'body' =>
97
  __( 'Message Body:', 'contact-form-7' )
98
- . "\n" . '[your-message]' . "\n\n"
99
  . '-- ' . "\n"
100
  . sprintf(
101
  /* translators: 1: blog name, 2: blog URL */
102
  __( 'This e-mail was sent from a contact form on %1$s (%2$s)', 'contact-form-7' ),
103
- get_bloginfo( 'name' ),
104
- get_bloginfo( 'url' )
105
  ),
106
  'recipient' => '[your-email]',
107
- 'additional_headers' => sprintf( 'Reply-To: %s',
108
- get_option( 'admin_email' ) ),
 
 
109
  'attachments' => '',
110
  'use_html' => 0,
111
  'exclude_blank' => 0,
21
  public static function form() {
22
  $template = sprintf(
23
  '
24
+ <label> %2$s
25
  [text* your-name] </label>
26
 
27
+ <label> %3$s
28
  [email* your-email] </label>
29
 
30
  <label> %4$s
31
+ [text* your-subject] </label>
32
 
33
+ <label> %5$s %1$s
34
  [textarea your-message] </label>
35
 
36
  [submit "%6$s"]',
37
+ __( '(optional)', 'contact-form-7' ),
38
+ __( 'Your name', 'contact-form-7' ),
39
+ __( 'Your email', 'contact-form-7' ),
40
  __( 'Subject', 'contact-form-7' ),
41
+ __( 'Your message', 'contact-form-7' ),
42
+ __( 'Submit', 'contact-form-7' )
43
+ );
44
 
45
  return trim( $template );
46
  }
47
 
48
  public static function mail() {
49
  $template = array(
50
+ 'subject' => sprintf(
51
+ /* translators: 1: blog name, 2: [your-subject] */
52
+ _x( '%1$s "%2$s"', 'mail subject', 'contact-form-7' ),
53
+ '[_site_title]',
54
+ '[your-subject]'
55
+ ),
56
+ 'sender' => sprintf(
57
+ '%s <%s>',
58
+ '[_site_title]',
59
+ self::from_email()
60
+ ),
61
+ 'body' =>
62
  sprintf(
63
+ /* translators: %s: [your-name] <[your-email]> */
64
+ __( 'From: %s', 'contact-form-7' ),
65
+ '[your-name] <[your-email]>'
66
+ ) . "\n"
67
+ . sprintf(
68
+ /* translators: %s: [your-subject] */
69
+ __( 'Subject: %s', 'contact-form-7' ),
70
  '[your-subject]'
71
+ ) . "\n\n"
 
 
 
 
 
 
 
 
 
72
  . __( 'Message Body:', 'contact-form-7' )
73
+ . "\n" . '[your-message]' . "\n\n"
74
  . '-- ' . "\n"
75
  . sprintf(
76
  /* translators: 1: blog name, 2: blog URL */
77
  __( 'This e-mail was sent from a contact form on %1$s (%2$s)', 'contact-form-7' ),
78
+ '[_site_title]',
79
+ '[_site_url]'
80
  ),
81
+ 'recipient' => '[_site_admin_email]',
82
  'additional_headers' => 'Reply-To: [your-email]',
83
  'attachments' => '',
84
  'use_html' => 0,
91
  public static function mail_2() {
92
  $template = array(
93
  'active' => false,
94
+ 'subject' => sprintf(
95
+ /* translators: 1: blog name, 2: [your-subject] */
96
+ _x( '%1$s "%2$s"', 'mail subject', 'contact-form-7' ),
97
+ '[_site_title]',
98
+ '[your-subject]'
99
+ ),
100
+ 'sender' => sprintf(
101
+ '%s <%s>',
102
+ '[_site_title]',
103
+ self::from_email()
104
+ ),
105
  'body' =>
106
  __( 'Message Body:', 'contact-form-7' )
107
+ . "\n" . '[your-message]' . "\n\n"
108
  . '-- ' . "\n"
109
  . sprintf(
110
  /* translators: 1: blog name, 2: blog URL */
111
  __( 'This e-mail was sent from a contact form on %1$s (%2$s)', 'contact-form-7' ),
112
+ '[_site_title]',
113
+ '[_site_url]'
114
  ),
115
  'recipient' => '[your-email]',
116
+ 'additional_headers' => sprintf(
117
+ 'Reply-To: %s',
118
+ '[_site_admin_email]'
119
+ ),
120
  'attachments' => '',
121
  'use_html' => 0,
122
  'exclude_blank' => 0,
includes/contact-form.php CHANGED
@@ -75,23 +75,21 @@ class WPCF7_ContactForm {
75
  }
76
 
77
  public static function get_template( $args = '' ) {
78
- global $l10n;
79
-
80
- $defaults = array( 'locale' => null, 'title' => '' );
81
- $args = wp_parse_args( $args, $defaults );
82
 
83
  $locale = $args['locale'];
84
  $title = $args['title'];
85
 
86
- if ( $locale ) {
87
- $mo_orig = $l10n['contact-form-7'];
88
- wpcf7_load_textdomain( $locale );
89
  }
90
 
91
- self::$current = $contact_form = new self;
92
- $contact_form->title =
93
- ( $title ? $title : __( 'Untitled', 'contact-form-7' ) );
94
- $contact_form->locale = ( $locale ? $locale : get_user_locale() );
95
 
96
  $properties = $contact_form->get_properties();
97
 
@@ -102,12 +100,15 @@ class WPCF7_ContactForm {
102
  $contact_form->properties = $properties;
103
 
104
  $contact_form = apply_filters( 'wpcf7_contact_form_default_pack',
105
- $contact_form, $args );
 
106
 
107
- if ( isset( $mo_orig ) ) {
108
- $l10n['contact-form-7'] = $mo_orig;
109
  }
110
 
 
 
111
  return $contact_form;
112
  }
113
 
@@ -373,34 +374,13 @@ class WPCF7_ContactForm {
373
  if ( $this->is_posted() ) {
374
  $submission = WPCF7_Submission::get_instance();
375
 
376
- switch ( $submission->get_status() ) {
377
- case 'init':
378
- $class .= ' init';
379
- break;
380
- case 'validation_failed':
381
- $class .= ' invalid';
382
- break;
383
- case 'acceptance_missing':
384
- $class .= ' unaccepted';
385
- break;
386
- case 'spam':
387
- $class .= ' spam';
388
- break;
389
- case 'aborted':
390
- $class .= ' aborted';
391
- break;
392
- case 'mail_sent':
393
- $class .= ' sent';
394
- break;
395
- case 'mail_failed':
396
- $class .= ' failed';
397
- break;
398
- default:
399
- $class .= sprintf( ' custom-%s',
400
- preg_replace( '/[^0-9a-z]+/i', '-', $submission->get_status() )
401
- );
402
- }
403
  } else {
 
404
  $class .= ' init';
405
  }
406
 
@@ -423,7 +403,8 @@ class WPCF7_ContactForm {
423
  $autocomplete = apply_filters( 'wpcf7_form_autocomplete', '' );
424
 
425
  $novalidate = apply_filters( 'wpcf7_form_novalidate',
426
- wpcf7_support_html5() );
 
427
 
428
  $atts = array(
429
  'action' => esc_url( $url ),
@@ -432,6 +413,7 @@ class WPCF7_ContactForm {
432
  'enctype' => wpcf7_enctype_value( $enctype ),
433
  'autocomplete' => $autocomplete,
434
  'novalidate' => $novalidate ? 'novalidate' : '',
 
435
  );
436
 
437
  if ( '' !== $id_attr ) {
@@ -458,6 +440,39 @@ class WPCF7_ContactForm {
458
  return $html;
459
  }
460
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
461
  private function form_hidden_fields() {
462
  $hidden_fields = array(
463
  '_wpcf7' => $this->id(),
@@ -503,7 +518,6 @@ class WPCF7_ContactForm {
503
 
504
  $atts = array(
505
  'class' => trim( $class ),
506
- 'role' => 'alert',
507
  'aria-hidden' => 'true',
508
  );
509
 
@@ -522,48 +536,56 @@ class WPCF7_ContactForm {
522
  }
523
 
524
  public function screen_reader_response() {
525
- $class = 'screen-reader-response';
526
- $content = '';
527
 
528
  if ( $this->is_posted() ) { // Post response output for non-AJAX
529
  $submission = WPCF7_Submission::get_instance();
530
-
531
- if ( $response = $submission->get_response() ) {
532
- $content = esc_html( $response );
533
- }
534
 
535
  if ( $invalid_fields = $submission->get_invalid_fields() ) {
536
- $content .= "\n" . '<ul>' . "\n";
537
-
538
  foreach ( (array) $invalid_fields as $name => $field ) {
 
 
539
  if ( $field['idref'] ) {
540
- $link = sprintf( '<a href="#%1$s">%2$s</a>',
 
541
  esc_attr( $field['idref'] ),
542
- esc_html( $field['reason'] ) );
543
- $content .= sprintf( '<li>%s</li>', $link );
544
- } else {
545
- $content .= sprintf( '<li>%s</li>',
546
- esc_html( $field['reason'] )
547
  );
548
  }
549
 
550
- $content .= "\n";
551
- }
 
 
 
 
 
 
 
 
 
552
 
553
- $content .= '</ul>' . "\n";
 
554
  }
555
  }
556
 
557
- $atts = array(
558
- 'class' => trim( $class ),
559
- 'role' => 'alert',
560
- 'aria-live' => 'polite',
561
  );
562
 
563
- $atts = wpcf7_format_atts( $atts );
 
 
 
564
 
565
- $output = sprintf( '<div %1$s>%2$s</div>',
566
- $atts, $content
 
 
567
  );
568
 
569
  return $output;
@@ -586,7 +608,6 @@ class WPCF7_ContactForm {
586
 
587
  $atts = array(
588
  'class' => 'wpcf7-not-valid-tip',
589
- 'role' => 'alert',
590
  'aria-hidden' => 'true',
591
  );
592
 
@@ -637,14 +658,16 @@ class WPCF7_ContactForm {
637
 
638
  public function form_scan_shortcode( $cond = null ) {
639
  wpcf7_deprecated_function( __METHOD__, '4.6',
640
- 'WPCF7_ContactForm::scan_form_tags' );
 
641
 
642
  return $this->scan_form_tags( $cond );
643
  }
644
 
645
  public function form_elements() {
646
  return apply_filters( 'wpcf7_form_elements',
647
- $this->replace_all_form_tags() );
 
648
  }
649
 
650
  public function collect_mail_tags( $args = '' ) {
@@ -699,14 +722,18 @@ class WPCF7_ContactForm {
699
  $mail = array_filter( $mail );
700
 
701
  foreach ( (array) $this->collect_mail_tags() as $mail_tag ) {
702
- $pattern = sprintf( '/\[(_[a-z]+_)?%s([ \t]+[^]]+)?\]/',
703
- preg_quote( $mail_tag, '/' ) );
 
 
 
704
  $used = preg_grep( $pattern, $mail );
705
 
706
  echo sprintf(
707
  '<span class="%1$s">[%2$s]</span>',
708
  'mailtag code ' . ( $used ? 'used' : 'unused' ),
709
- esc_html( $mail_tag ) );
 
710
  }
711
  }
712
 
@@ -725,7 +752,8 @@ class WPCF7_ContactForm {
725
  'status' => 'error',
726
  'message' => __(
727
  "This contact form is available only for logged in users.",
728
- 'contact-form-7' ),
 
729
  );
730
 
731
  return $result;
75
  }
76
 
77
  public static function get_template( $args = '' ) {
78
+ $args = wp_parse_args( $args, array(
79
+ 'locale' => '',
80
+ 'title' => __( 'Untitled', 'contact-form-7' ),
81
+ ) );
82
 
83
  $locale = $args['locale'];
84
  $title = $args['title'];
85
 
86
+ if ( ! $switched = wpcf7_load_textdomain( $locale ) ) {
87
+ $locale = determine_locale();
 
88
  }
89
 
90
+ $contact_form = new self;
91
+ $contact_form->title = $title;
92
+ $contact_form->locale = $locale;
 
93
 
94
  $properties = $contact_form->get_properties();
95
 
100
  $contact_form->properties = $properties;
101
 
102
  $contact_form = apply_filters( 'wpcf7_contact_form_default_pack',
103
+ $contact_form, $args
104
+ );
105
 
106
+ if ( $switched ) {
107
+ wpcf7_load_textdomain();
108
  }
109
 
110
+ self::$current = $contact_form;
111
+
112
  return $contact_form;
113
  }
114
 
374
  if ( $this->is_posted() ) {
375
  $submission = WPCF7_Submission::get_instance();
376
 
377
+ $data_status_attr = $this->form_status_class_name(
378
+ $submission->get_status()
379
+ );
380
+
381
+ $class .= sprintf( ' %s', $data_status_attr );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
382
  } else {
383
+ $data_status_attr = 'init';
384
  $class .= ' init';
385
  }
386
 
403
  $autocomplete = apply_filters( 'wpcf7_form_autocomplete', '' );
404
 
405
  $novalidate = apply_filters( 'wpcf7_form_novalidate',
406
+ wpcf7_support_html5()
407
+ );
408
 
409
  $atts = array(
410
  'action' => esc_url( $url ),
413
  'enctype' => wpcf7_enctype_value( $enctype ),
414
  'autocomplete' => $autocomplete,
415
  'novalidate' => $novalidate ? 'novalidate' : '',
416
+ 'data-status' => $data_status_attr,
417
  );
418
 
419
  if ( '' !== $id_attr ) {
440
  return $html;
441
  }
442
 
443
+ private function form_status_class_name( $status ) {
444
+ switch ( $status ) {
445
+ case 'init':
446
+ $class = 'init';
447
+ break;
448
+ case 'validation_failed':
449
+ $class = 'invalid';
450
+ break;
451
+ case 'acceptance_missing':
452
+ $class = 'unaccepted';
453
+ break;
454
+ case 'spam':
455
+ $class = 'spam';
456
+ break;
457
+ case 'aborted':
458
+ $class = 'aborted';
459
+ break;
460
+ case 'mail_sent':
461
+ $class = 'sent';
462
+ break;
463
+ case 'mail_failed':
464
+ $class = 'failed';
465
+ break;
466
+ default:
467
+ $class = sprintf(
468
+ 'custom-%s',
469
+ preg_replace( '/[^0-9a-z]+/i', '-', $status )
470
+ );
471
+ }
472
+
473
+ return $class;
474
+ }
475
+
476
  private function form_hidden_fields() {
477
  $hidden_fields = array(
478
  '_wpcf7' => $this->id(),
518
 
519
  $atts = array(
520
  'class' => trim( $class ),
 
521
  'aria-hidden' => 'true',
522
  );
523
 
536
  }
537
 
538
  public function screen_reader_response() {
539
+ $primary_response = '';
540
+ $validation_errors = array();
541
 
542
  if ( $this->is_posted() ) { // Post response output for non-AJAX
543
  $submission = WPCF7_Submission::get_instance();
544
+ $primary_response = $submission->get_response();
 
 
 
545
 
546
  if ( $invalid_fields = $submission->get_invalid_fields() ) {
 
 
547
  foreach ( (array) $invalid_fields as $name => $field ) {
548
+ $list_item = esc_html( $field['reason'] );
549
+
550
  if ( $field['idref'] ) {
551
+ $list_item = sprintf(
552
+ '<a href="#%1$s">%2$s</a>',
553
  esc_attr( $field['idref'] ),
554
+ $list_item
 
 
 
 
555
  );
556
  }
557
 
558
+ $validation_error_id = sprintf(
559
+ '%1$s-ve-%2$s',
560
+ $this->unit_tag(),
561
+ $name
562
+ );
563
+
564
+ $list_item = sprintf(
565
+ '<li id="%1$s">%2$s</li>',
566
+ $validation_error_id,
567
+ $list_item
568
+ );
569
 
570
+ $validation_errors[] = $list_item;
571
+ }
572
  }
573
  }
574
 
575
+ $primary_response = sprintf(
576
+ '<p role="status" aria-live="polite" aria-atomic="true">%s</p>',
577
+ esc_html( $primary_response )
 
578
  );
579
 
580
+ $validation_errors = sprintf(
581
+ '<ul>%s</ul>',
582
+ implode( "\n", $validation_errors )
583
+ );
584
 
585
+ $output = sprintf(
586
+ '<div class="screen-reader-response">%1$s %2$s</div>',
587
+ $primary_response,
588
+ $validation_errors
589
  );
590
 
591
  return $output;
608
 
609
  $atts = array(
610
  'class' => 'wpcf7-not-valid-tip',
 
611
  'aria-hidden' => 'true',
612
  );
613
 
658
 
659
  public function form_scan_shortcode( $cond = null ) {
660
  wpcf7_deprecated_function( __METHOD__, '4.6',
661
+ 'WPCF7_ContactForm::scan_form_tags'
662
+ );
663
 
664
  return $this->scan_form_tags( $cond );
665
  }
666
 
667
  public function form_elements() {
668
  return apply_filters( 'wpcf7_form_elements',
669
+ $this->replace_all_form_tags()
670
+ );
671
  }
672
 
673
  public function collect_mail_tags( $args = '' ) {
722
  $mail = array_filter( $mail );
723
 
724
  foreach ( (array) $this->collect_mail_tags() as $mail_tag ) {
725
+ $pattern = sprintf(
726
+ '/\[(_[a-z]+_)?%s([ \t]+[^]]+)?\]/',
727
+ preg_quote( $mail_tag, '/' )
728
+ );
729
+
730
  $used = preg_grep( $pattern, $mail );
731
 
732
  echo sprintf(
733
  '<span class="%1$s">[%2$s]</span>',
734
  'mailtag code ' . ( $used ? 'used' : 'unused' ),
735
+ esc_html( $mail_tag )
736
+ );
737
  }
738
  }
739
 
752
  'status' => 'error',
753
  'message' => __(
754
  "This contact form is available only for logged in users.",
755
+ 'contact-form-7'
756
+ ),
757
  );
758
 
759
  return $result;
includes/css/styles.css CHANGED
@@ -71,7 +71,7 @@ span.wpcf7-list-item-label::after {
71
  div.wpcf7 .ajax-loader {
72
  visibility: hidden;
73
  display: inline-block;
74
- background-image: url('../../images/ajax-loader.gif');
75
  width: 16px;
76
  height: 16px;
77
  border: none;
71
  div.wpcf7 .ajax-loader {
72
  visibility: hidden;
73
  display: inline-block;
74
+ background-image: url('../../assets/ajax-loader.gif');
75
  width: 16px;
76
  height: 16px;
77
  border: none;
includes/form-tag.php CHANGED
@@ -35,7 +35,7 @@ class WPCF7_FormTag implements ArrayAccess {
35
 
36
  public function get_option( $opt, $pattern = '', $single = false ) {
37
  $preset_patterns = array(
38
- 'date' => '([0-9]{4}-[0-9]{2}-[0-9]{2}|today(.*))',
39
  'int' => '[0-9]+',
40
  'signed_int' => '-?[0-9]+',
41
  'class' => '[-0-9a-zA-Z_]+',
@@ -183,24 +183,33 @@ class WPCF7_FormTag implements ArrayAccess {
183
  }
184
 
185
  public function get_date_option( $opt ) {
186
- $option = $this->get_option( $opt, 'date', true );
187
 
188
- if ( preg_match( '/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/', $option ) ) {
189
- return $option;
190
  }
191
 
192
- if ( preg_match( '/^today(?:([+-][0-9]+)([a-z]*))?/', $option, $matches ) ) {
193
- $today = wp_date( 'Y-m-d' );
194
- $number = isset( $matches[1] ) ? (int) $matches[1] : 0;
195
- $unit = isset( $matches[2] ) ? $matches[2] : '';
196
 
197
- if ( ! preg_match( '/^(day|month|year|week)s?$/', $unit ) ) {
198
- $unit = 'days';
199
- }
200
 
201
- $format = sprintf( '%1$s %2$s %3$s', $today, $number, $unit );
 
 
 
 
 
 
 
 
202
 
203
- return gmdate( 'Y-m-d', strtotime( $format ) );
 
 
204
  }
205
 
206
  return false;
35
 
36
  public function get_option( $opt, $pattern = '', $single = false ) {
37
  $preset_patterns = array(
38
+ 'date' => '[0-9]{4}-[0-9]{2}-[0-9]{2}',
39
  'int' => '[0-9]+',
40
  'signed_int' => '-?[0-9]+',
41
  'class' => '[-0-9a-zA-Z_]+',
183
  }
184
 
185
  public function get_date_option( $opt ) {
186
+ $option_value = $this->get_option( $opt, '', true );
187
 
188
+ if ( empty( $option_value ) ) {
189
+ return false;
190
  }
191
 
192
+ $date = apply_filters( 'wpcf7_form_tag_date_option',
193
+ null,
194
+ array( $opt => $option_value )
195
+ );
196
 
197
+ if ( $date ) {
198
+ $date_pattern = '/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/';
 
199
 
200
+ if ( preg_match( $date_pattern, $date, $matches )
201
+ and checkdate( $matches[2], $matches[3], $matches[1] ) ) {
202
+ return $date;
203
+ }
204
+ } else {
205
+ $datetime_obj = date_create_immutable(
206
+ preg_replace( '/[_]+/', ' ', $option_value ),
207
+ wp_timezone()
208
+ );
209
 
210
+ if ( $datetime_obj ) {
211
+ return $datetime_obj->format( 'Y-m-d' );
212
+ }
213
  }
214
 
215
  return false;
includes/functions.php CHANGED
@@ -40,33 +40,6 @@ function wpcf7_create_nonce( $action = 'wp_rest' ) {
40
  return wp_create_nonce( $action );
41
  }
42
 
43
- function wpcf7_blacklist_check( $target ) {
44
- $mod_keys = trim( get_option( 'blacklist_keys' ) );
45
-
46
- if ( empty( $mod_keys ) ) {
47
- return false;
48
- }
49
-
50
- $words = explode( "\n", $mod_keys );
51
-
52
- foreach ( (array) $words as $word ) {
53
- $word = trim( $word );
54
-
55
- if ( empty( $word )
56
- or 256 < strlen( $word ) ) {
57
- continue;
58
- }
59
-
60
- $pattern = sprintf( '#%s#i', preg_quote( $word, '#' ) );
61
-
62
- if ( preg_match( $pattern, $target ) ) {
63
- return true;
64
- }
65
- }
66
-
67
- return false;
68
- }
69
-
70
  function wpcf7_array_flatten( $input ) {
71
  if ( ! is_array( $input ) ) {
72
  return array( $input );
40
  return wp_create_nonce( $action );
41
  }
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  function wpcf7_array_flatten( $input ) {
44
  if ( ! is_array( $input ) ) {
45
  return array( $input );
includes/js/scripts.js CHANGED
@@ -208,6 +208,10 @@
208
  $( n.into, $form ).each( function() {
209
  wpcf7.notValidTip( this, n.message );
210
  $( '.wpcf7-form-control', this ).addClass( 'wpcf7-not-valid' );
 
 
 
 
211
  $( '[aria-invalid]', this ).attr( 'aria-invalid', 'true' );
212
  } );
213
  } );
@@ -265,11 +269,9 @@
265
 
266
  $( '.screen-reader-response', $form.closest( '.wpcf7' ) ).each( function() {
267
  var $response = $( this );
268
- $response.html( '' ).append( data.message );
269
 
270
  if ( data.invalid_fields ) {
271
- var $invalids = $( '<ul></ul>' );
272
-
273
  $.each( data.invalid_fields, function( i, n ) {
274
  if ( n.idref ) {
275
  var $li = $( '<li></li>' ).append( $( '<a></a>' ).attr( 'href', '#' + n.idref ).append( n.message ) );
@@ -277,13 +279,11 @@
277
  var $li = $( '<li></li>' ).append( n.message );
278
  }
279
 
280
- $invalids.append( $li );
281
- } );
282
 
283
- $response.append( $invalids );
 
284
  }
285
-
286
- $response.focus();
287
  } );
288
 
289
  if ( data.posted_data_hash ) {
@@ -320,10 +320,11 @@
320
 
321
  wpcf7.setStatus = function( form, status ) {
322
  var $form = $( form );
323
- var prevStatus = $form.data( 'status' );
324
 
325
  $form.data( 'status', status );
326
  $form.addClass( status );
 
327
 
328
  if ( prevStatus && prevStatus !== status ) {
329
  $form.removeClass( prevStatus );
@@ -406,7 +407,6 @@
406
 
407
  $( '<span></span>' ).attr( {
408
  'class': 'wpcf7-not-valid-tip',
409
- 'role': 'alert',
410
  'aria-hidden': 'true',
411
  } ).text( message ).appendTo( $target );
412
 
@@ -485,7 +485,11 @@
485
 
486
  wpcf7.clearResponse = function( form ) {
487
  var $form = $( form );
488
- $form.siblings( '.screen-reader-response' ).html( '' );
 
 
 
 
489
 
490
  $( '.wpcf7-not-valid-tip', $form ).remove();
491
  $( '[aria-invalid]', $form ).attr( 'aria-invalid', 'false' );
208
  $( n.into, $form ).each( function() {
209
  wpcf7.notValidTip( this, n.message );
210
  $( '.wpcf7-form-control', this ).addClass( 'wpcf7-not-valid' );
211
+ $( '.wpcf7-form-control', this ).attr(
212
+ 'aria-describedby',
213
+ n.error_id
214
+ );
215
  $( '[aria-invalid]', this ).attr( 'aria-invalid', 'true' );
216
  } );
217
  } );
269
 
270
  $( '.screen-reader-response', $form.closest( '.wpcf7' ) ).each( function() {
271
  var $response = $( this );
272
+ $( '[role="status"]', $response ).html( data.message );
273
 
274
  if ( data.invalid_fields ) {
 
 
275
  $.each( data.invalid_fields, function( i, n ) {
276
  if ( n.idref ) {
277
  var $li = $( '<li></li>' ).append( $( '<a></a>' ).attr( 'href', '#' + n.idref ).append( n.message ) );
279
  var $li = $( '<li></li>' ).append( n.message );
280
  }
281
 
282
+ $li.attr( 'id', n.error_id );
 
283
 
284
+ $( 'ul', $response ).append( $li );
285
+ } );
286
  }
 
 
287
  } );
288
 
289
  if ( data.posted_data_hash ) {
320
 
321
  wpcf7.setStatus = function( form, status ) {
322
  var $form = $( form );
323
+ var prevStatus = $form.attr( 'data-status' );
324
 
325
  $form.data( 'status', status );
326
  $form.addClass( status );
327
+ $form.attr( 'data-status', status );
328
 
329
  if ( prevStatus && prevStatus !== status ) {
330
  $form.removeClass( prevStatus );
407
 
408
  $( '<span></span>' ).attr( {
409
  'class': 'wpcf7-not-valid-tip',
 
410
  'aria-hidden': 'true',
411
  } ).text( message ).appendTo( $target );
412
 
485
 
486
  wpcf7.clearResponse = function( form ) {
487
  var $form = $( form );
488
+
489
+ $form.siblings( '.screen-reader-response' ).each( function() {
490
+ $( '[role="status"]', this ).html( '' );
491
+ $( 'ul', this ).html( '' );
492
+ } );
493
 
494
  $( '.wpcf7-not-valid-tip', $form ).remove();
495
  $( '[aria-invalid]', $form ).attr( 'aria-invalid', 'false' );
includes/l10n.php CHANGED
@@ -56,43 +56,49 @@ function wpcf7_is_rtl( $locale = '' ) {
56
  }
57
 
58
  if ( empty( $locale ) ) {
59
- $locale = get_locale();
60
  }
61
 
62
  return isset( $rtl_locales[$locale] );
63
  }
64
 
65
- function wpcf7_load_textdomain( $locale = null ) {
66
- global $l10n;
67
 
68
- $domain = 'contact-form-7';
 
 
 
 
 
 
 
69
 
70
- if ( ( is_admin() ? get_user_locale() : get_locale() ) === $locale ) {
71
- $locale = null;
72
  }
73
 
74
- if ( empty( $locale ) ) {
75
- if ( is_textdomain_loaded( $domain ) ) {
76
- return true;
77
- } else {
78
- return load_plugin_textdomain( $domain, false, $domain . '/languages' );
79
- }
80
  } else {
81
- $mo_orig = $l10n[$domain];
 
 
 
 
 
82
  unload_textdomain( $domain );
 
83
 
84
- $mofile = $domain . '-' . $locale . '.mo';
85
- $path = WP_PLUGIN_DIR . '/' . $domain . '/languages';
86
 
87
- if ( $loaded = load_textdomain( $domain, $path . '/'. $mofile ) ) {
88
- return $loaded;
89
- } else {
90
- $mofile = WP_LANG_DIR . '/plugins/' . $mofile;
91
- return load_textdomain( $domain, $mofile );
92
- }
93
 
94
- $l10n[$domain] = $mo_orig;
 
 
95
  }
96
 
97
- return false;
98
  }
56
  }
57
 
58
  if ( empty( $locale ) ) {
59
+ $locale = determine_locale();
60
  }
61
 
62
  return isset( $rtl_locales[$locale] );
63
  }
64
 
65
+ function wpcf7_load_textdomain( $locale = '' ) {
66
+ static $locales = array();
67
 
68
+ if ( empty( $locales ) ) {
69
+ $locales = array( determine_locale() );
70
+ }
71
+
72
+ $available_locales = array_merge(
73
+ array( 'en_US' ),
74
+ get_available_languages()
75
+ );
76
 
77
+ if ( ! in_array( $locale, $available_locales ) ) {
78
+ $locale = $locales[0];
79
  }
80
 
81
+ if ( $locale === end( $locales ) ) {
82
+ return false;
 
 
 
 
83
  } else {
84
+ $locales[] = $locale;
85
+ }
86
+
87
+ $domain = WPCF7_TEXT_DOMAIN;
88
+
89
+ if ( is_textdomain_loaded( $domain ) ) {
90
  unload_textdomain( $domain );
91
+ }
92
 
93
+ $mofile = sprintf( '%s-%s.mo', $domain, $locale );
 
94
 
95
+ $domain_path = path_join( WPCF7_PLUGIN_DIR, 'languages' );
96
+ $loaded = load_textdomain( $domain, path_join( $domain_path, $mofile ) );
 
 
 
 
97
 
98
+ if ( ! $loaded ) {
99
+ $domain_path = path_join( WP_LANG_DIR, 'plugins' );
100
+ load_textdomain( $domain, path_join( $domain_path, $mofile ) );
101
  }
102
 
103
+ return true;
104
  }
includes/rest-api.php CHANGED
@@ -338,6 +338,11 @@ function wpcf7_rest_create_feedback( WP_REST_Request $request ) {
338
  . sanitize_html_class( $name ),
339
  'message' => $field['reason'],
340
  'idref' => $field['idref'],
 
 
 
 
 
341
  );
342
  }
343
 
338
  . sanitize_html_class( $name ),
339
  'message' => $field['reason'],
340
  'idref' => $field['idref'],
341
+ 'error_id' => sprintf(
342
+ '%1$s-ve-%2$s',
343
+ $unit_tag,
344
+ $name
345
+ ),
346
  );
347
  }
348
 
includes/submission.php CHANGED
@@ -49,11 +49,13 @@ class WPCF7_Submission {
49
  }
50
 
51
  private function proceed() {
 
 
 
 
52
  $this->setup_meta_data();
53
  $this->setup_posted_data();
54
 
55
- $contact_form = $this->contact_form;
56
-
57
  if ( $this->is( 'init' ) and ! $this->validate() ) {
58
  $this->set_status( 'validation_failed' );
59
  $this->set_response( $contact_form->message( 'validation_error' ) );
@@ -95,6 +97,8 @@ class WPCF7_Submission {
95
  }
96
  }
97
 
 
 
98
  $this->remove_uploaded_files();
99
  }
100
 
@@ -412,16 +416,7 @@ class WPCF7_Submission {
412
  ) );
413
  }
414
 
415
- if ( $this->is_blacklisted() ) {
416
- $spam = true;
417
-
418
- $this->add_spam_log( array(
419
- 'agent' => 'wpcf7',
420
- 'reason' => __( "Blacklisted words are used.", 'contact-form-7' ),
421
- ) );
422
- }
423
-
424
- return apply_filters( 'wpcf7_spam', $spam );
425
  }
426
 
427
  public function add_spam_log( $args = '' ) {
@@ -445,16 +440,6 @@ class WPCF7_Submission {
445
  return wpcf7_verify_nonce( $_POST['_wpnonce'] );
446
  }
447
 
448
- private function is_blacklisted() {
449
- $target = wpcf7_array_flatten( $this->posted_data );
450
- $target[] = $this->get_meta( 'remote_ip' );
451
- $target[] = $this->get_meta( 'user_agent' );
452
- $target = implode( "\n", $target );
453
-
454
- return (bool) apply_filters( 'wpcf7_submission_is_blacklisted',
455
- wpcf7_blacklist_check( $target ), $this );
456
- }
457
-
458
  /* Mail */
459
 
460
  private function before_send_mail() {
49
  }
50
 
51
  private function proceed() {
52
+ $contact_form = $this->contact_form;
53
+
54
+ switch_to_locale( $contact_form->locale() );
55
+
56
  $this->setup_meta_data();
57
  $this->setup_posted_data();
58
 
 
 
59
  if ( $this->is( 'init' ) and ! $this->validate() ) {
60
  $this->set_status( 'validation_failed' );
61
  $this->set_response( $contact_form->message( 'validation_error' ) );
97
  }
98
  }
99
 
100
+ restore_previous_locale();
101
+
102
  $this->remove_uploaded_files();
103
  }
104
 
416
  ) );
417
  }
418
 
419
+ return apply_filters( 'wpcf7_spam', $spam, $this );
 
 
 
 
 
 
 
 
 
420
  }
421
 
422
  public function add_spam_log( $args = '' ) {
440
  return wpcf7_verify_nonce( $_POST['_wpnonce'] );
441
  }
442
 
 
 
 
 
 
 
 
 
 
 
443
  /* Mail */
444
 
445
  private function before_send_mail() {
license.txt CHANGED
@@ -15,6 +15,14 @@ You should have received a copy of the GNU General Public License
15
  along with this program; if not, write to the Free Software
16
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
 
 
 
 
 
 
 
 
 
18
  =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
19
 
20
  GNU GENERAL PUBLIC LICENSE
15
  along with this program; if not, write to the Free Software
16
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
 
18
+
19
+ Contact Form 7 WordPress Plugin bundles the following third-party resources:
20
+
21
+ The official icon designed by Cheung Vong
22
+ https://contactform7.com/2020/04/08/new-official-logo/
23
+
24
+
25
+
26
  =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
27
 
28
  GNU GENERAL PUBLIC LICENSE
settings.php → load.php RENAMED
@@ -18,6 +18,7 @@ require_once WPCF7_PLUGIN_DIR . '/includes/upgrade.php';
18
  require_once WPCF7_PLUGIN_DIR . '/includes/integration.php';
19
  require_once WPCF7_PLUGIN_DIR . '/includes/config-validator.php';
20
  require_once WPCF7_PLUGIN_DIR . '/includes/rest-api.php';
 
21
 
22
  if ( is_admin() ) {
23
  require_once WPCF7_PLUGIN_DIR . '/admin/admin.php';
@@ -34,6 +35,7 @@ class WPCF7 {
34
  self::load_module( 'constant-contact' );
35
  self::load_module( 'count' );
36
  self::load_module( 'date' );
 
37
  self::load_module( 'file' );
38
  self::load_module( 'flamingo' );
39
  self::load_module( 'hidden' );
@@ -96,7 +98,6 @@ class WPCF7 {
96
  add_action( 'plugins_loaded', 'wpcf7', 10, 0 );
97
 
98
  function wpcf7() {
99
- wpcf7_load_textdomain();
100
  WPCF7::load_modules();
101
 
102
  /* Shortcodes */
@@ -137,7 +138,6 @@ function wpcf7_install() {
137
  return;
138
  }
139
 
140
- wpcf7_load_textdomain();
141
  wpcf7_register_post_types();
142
  wpcf7_upgrade();
143
 
18
  require_once WPCF7_PLUGIN_DIR . '/includes/integration.php';
19
  require_once WPCF7_PLUGIN_DIR . '/includes/config-validator.php';
20
  require_once WPCF7_PLUGIN_DIR . '/includes/rest-api.php';
21
+ require_once WPCF7_PLUGIN_DIR . '/includes/block-editor/block-editor.php';
22
 
23
  if ( is_admin() ) {
24
  require_once WPCF7_PLUGIN_DIR . '/admin/admin.php';
35
  self::load_module( 'constant-contact' );
36
  self::load_module( 'count' );
37
  self::load_module( 'date' );
38
+ self::load_module( 'disallowed-list' );
39
  self::load_module( 'file' );
40
  self::load_module( 'flamingo' );
41
  self::load_module( 'hidden' );
98
  add_action( 'plugins_loaded', 'wpcf7', 10, 0 );
99
 
100
  function wpcf7() {
 
101
  WPCF7::load_modules();
102
 
103
  /* Shortcodes */
138
  return;
139
  }
140
 
 
141
  wpcf7_register_post_types();
142
  wpcf7_upgrade();
143
 
modules/acceptance.php CHANGED
@@ -47,7 +47,15 @@ function wpcf7_acceptance_form_tag_handler( $tag ) {
47
  $item_atts['name'] = $tag->name;
48
  $item_atts['value'] = '1';
49
  $item_atts['tabindex'] = $tag->get_option( 'tabindex', 'signed_int', true );
50
- $item_atts['aria-invalid'] = $validation_error ? 'true' : 'false';
 
 
 
 
 
 
 
 
51
 
52
  if ( $tag->has_option( 'default:on' ) ) {
53
  $item_atts['checked'] = 'checked';
47
  $item_atts['name'] = $tag->name;
48
  $item_atts['value'] = '1';
49
  $item_atts['tabindex'] = $tag->get_option( 'tabindex', 'signed_int', true );
50
+
51
+ if ( $validation_error ) {
52
+ $item_atts['aria-invalid'] = 'true';
53
+ $item_atts['aria-describedby'] = wpcf7_get_validation_error_reference(
54
+ $tag->name
55
+ );
56
+ } else {
57
+ $item_atts['aria-invalid'] = 'false';
58
+ }
59
 
60
  if ( $tag->has_option( 'default:on' ) ) {
61
  $item_atts['checked'] = 'checked';
modules/akismet.php CHANGED
@@ -4,9 +4,9 @@
4
  ** Akismet API: http://akismet.com/development/api/
5
  **/
6
 
7
- add_filter( 'wpcf7_spam', 'wpcf7_akismet', 10, 1 );
8
 
9
- function wpcf7_akismet( $spam ) {
10
  if ( $spam ) {
11
  return $spam;
12
  }
@@ -15,9 +15,7 @@ function wpcf7_akismet( $spam ) {
15
  return false;
16
  }
17
 
18
- $submission = WPCF7_Submission::get_instance();
19
-
20
- if ( ! $submission or ! $params = wpcf7_akismet_submitted_params() ) {
21
  return false;
22
  }
23
 
4
  ** Akismet API: http://akismet.com/development/api/
5
  **/
6
 
7
+ add_filter( 'wpcf7_spam', 'wpcf7_akismet', 10, 2 );
8
 
9
+ function wpcf7_akismet( $spam, $submission ) {
10
  if ( $spam ) {
11
  return $spam;
12
  }
15
  return false;
16
  }
17
 
18
+ if ( ! $params = wpcf7_akismet_submitted_params() ) {
 
 
19
  return false;
20
  }
21
 
modules/checkbox.php CHANGED
@@ -52,6 +52,12 @@ function wpcf7_checkbox_form_tag_handler( $tag ) {
52
  $atts['class'] = $tag->get_class_option( $class );
53
  $atts['id'] = $tag->get_id_option();
54
 
 
 
 
 
 
 
55
  $tabindex = $tag->get_option( 'tabindex', 'signed_int', true );
56
 
57
  if ( false !== $tabindex ) {
@@ -261,7 +267,7 @@ function wpcf7_tag_generator_checkbox( $contact_form, $args = '' ) {
261
  <textarea name="values" class="values" id="<?php echo esc_attr( $args['content'] . '-values' ); ?>"></textarea>
262
  <label for="<?php echo esc_attr( $args['content'] . '-values' ); ?>"><span class="description"><?php echo esc_html( __( "One option per line.", 'contact-form-7' ) ); ?></span></label><br />
263
  <label><input type="checkbox" name="label_first" class="option" /> <?php echo esc_html( __( 'Put a label first, a checkbox last', 'contact-form-7' ) ); ?></label><br />
264
- <label><input type="checkbox" name="use_label_element" class="option" /> <?php echo esc_html( __( 'Wrap each item with label element', 'contact-form-7' ) ); ?></label>
265
  <?php if ( 'checkbox' == $type ) : ?>
266
  <br /><label><input type="checkbox" name="exclusive" class="option" /> <?php echo esc_html( __( 'Make checkboxes exclusive', 'contact-form-7' ) ); ?></label>
267
  <?php endif; ?>
52
  $atts['class'] = $tag->get_class_option( $class );
53
  $atts['id'] = $tag->get_id_option();
54
 
55
+ if ( $validation_error ) {
56
+ $atts['aria-describedby'] = wpcf7_get_validation_error_reference(
57
+ $tag->name
58
+ );
59
+ }
60
+
61
  $tabindex = $tag->get_option( 'tabindex', 'signed_int', true );
62
 
63
  if ( false !== $tabindex ) {
267
  <textarea name="values" class="values" id="<?php echo esc_attr( $args['content'] . '-values' ); ?>"></textarea>
268
  <label for="<?php echo esc_attr( $args['content'] . '-values' ); ?>"><span class="description"><?php echo esc_html( __( "One option per line.", 'contact-form-7' ) ); ?></span></label><br />
269
  <label><input type="checkbox" name="label_first" class="option" /> <?php echo esc_html( __( 'Put a label first, a checkbox last', 'contact-form-7' ) ); ?></label><br />
270
+ <label><input type="checkbox" name="use_label_element" class="option" checked="checked" /> <?php echo esc_html( __( 'Wrap each item with label element', 'contact-form-7' ) ); ?></label>
271
  <?php if ( 'checkbox' == $type ) : ?>
272
  <br /><label><input type="checkbox" name="exclusive" class="option" /> <?php echo esc_html( __( 'Make checkboxes exclusive', 'contact-form-7' ) ); ?></label>
273
  <?php endif; ?>
modules/date.php CHANGED
@@ -49,7 +49,14 @@ function wpcf7_date_form_tag_handler( $tag ) {
49
  $atts['aria-required'] = 'true';
50
  }
51
 
52
- $atts['aria-invalid'] = $validation_error ? 'true' : 'false';
 
 
 
 
 
 
 
53
 
54
  $value = (string) reset( $tag->values );
55
 
@@ -61,6 +68,17 @@ function wpcf7_date_form_tag_handler( $tag ) {
61
 
62
  $value = $tag->get_default_option( $value );
63
 
 
 
 
 
 
 
 
 
 
 
 
64
  $value = wpcf7_get_hangover( $tag->name, $value );
65
 
66
  $atts['value'] = $value;
49
  $atts['aria-required'] = 'true';
50
  }
51
 
52
+ if ( $validation_error ) {
53
+ $atts['aria-invalid'] = 'true';
54
+ $atts['aria-describedby'] = wpcf7_get_validation_error_reference(
55
+ $tag->name
56
+ );
57
+ } else {
58
+ $atts['aria-invalid'] = 'false';
59
+ }
60
 
61
  $value = (string) reset( $tag->values );
62
 
68
 
69
  $value = $tag->get_default_option( $value );
70
 
71
+ if ( $value ) {
72
+ $datetime_obj = date_create_immutable(
73
+ preg_replace( '/[_]+/', ' ', $value ),
74
+ wp_timezone()
75
+ );
76
+
77
+ if ( $datetime_obj ) {
78
+ $value = $datetime_obj->format( 'Y-m-d' );
79
+ }
80
+ }
81
+
82
  $value = wpcf7_get_hangover( $tag->name, $value );
83
 
84
  $atts['value'] = $value;
modules/disallowed-list.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ add_filter( 'wpcf7_spam', 'wpcf7_disallowed_list', 10, 2 );
4
+
5
+ function wpcf7_disallowed_list( $spam, $submission ) {
6
+ if ( $spam ) {
7
+ return $spam;
8
+ }
9
+
10
+ $target = wpcf7_array_flatten( $submission->get_posted_data() );
11
+ $target[] = $submission->get_meta( 'remote_ip' );
12
+ $target[] = $submission->get_meta( 'user_agent' );
13
+ $target = implode( "\n", $target );
14
+
15
+ $word = wpcf7_check_disallowed_list( $target );
16
+
17
+ $word = wpcf7_apply_filters_deprecated(
18
+ 'wpcf7_submission_is_blacklisted',
19
+ array( $word, $submission ),
20
+ '5.3',
21
+ 'wpcf7_submission_has_disallowed_words'
22
+ );
23
+
24
+ $word = apply_filters(
25
+ 'wpcf7_submission_has_disallowed_words',
26
+ $word,
27
+ $submission
28
+ );
29
+
30
+ if ( $word ) {
31
+ if ( is_bool( $word ) ) {
32
+ $reason = __( "Disallowed words are used.", 'contact-form-7' );
33
+ } else {
34
+ $reason = sprintf(
35
+ __( "Disallowed words (%s) are used.", 'contact-form-7' ),
36
+ implode( ', ', (array) $word )
37
+ );
38
+ }
39
+
40
+ $submission->add_spam_log( array(
41
+ 'agent' => 'disallowed_list',
42
+ 'reason' => $reason,
43
+ ) );
44
+ }
45
+
46
+ $spam = (bool) $word;
47
+
48
+ return $spam;
49
+ }
50
+
51
+ function wpcf7_check_disallowed_list( $target ) {
52
+ $mod_keys = trim( get_option( 'blacklist_keys' ) );
53
+
54
+ if ( '' === $mod_keys ) {
55
+ return false;
56
+ }
57
+
58
+ foreach ( explode( "\n", $mod_keys ) as $word ) {
59
+ $word = trim( $word );
60
+ $length = strlen( $word );
61
+
62
+ if ( $length < 2 or 256 < $length ) {
63
+ continue;
64
+ }
65
+
66
+ $pattern = sprintf( '#%s#i', preg_quote( $word, '#' ) );
67
+
68
+ if ( preg_match( $pattern, $target ) ) {
69
+ return $word;
70
+ }
71
+ }
72
+
73
+ return false;
74
+ }
75
+
76
+ function wpcf7_blacklist_check( $target ) {
77
+ wpcf7_deprecated_function(
78
+ __FUNCTION__,
79
+ '5.3',
80
+ 'wpcf7_check_disallowed_list'
81
+ );
82
+
83
+ return wpcf7_check_disallowed_list( $target );
84
+ }
modules/file.php CHANGED
@@ -43,7 +43,14 @@ function wpcf7_file_form_tag_handler( $tag ) {
43
  $atts['aria-required'] = 'true';
44
  }
45
 
46
- $atts['aria-invalid'] = $validation_error ? 'true' : 'false';
 
 
 
 
 
 
 
47
 
48
  $atts['type'] = 'file';
49
  $atts['name'] = $tag->name;
43
  $atts['aria-required'] = 'true';
44
  }
45
 
46
+ if ( $validation_error ) {
47
+ $atts['aria-invalid'] = 'true';
48
+ $atts['aria-describedby'] = wpcf7_get_validation_error_reference(
49
+ $tag->name
50
+ );
51
+ } else {
52
+ $atts['aria-invalid'] = 'false';
53
+ }
54
 
55
  $atts['type'] = 'file';
56
  $atts['name'] = $tag->name;
modules/number.php CHANGED
@@ -50,7 +50,14 @@ function wpcf7_number_form_tag_handler( $tag ) {
50
  $atts['aria-required'] = 'true';
51
  }
52
 
53
- $atts['aria-invalid'] = $validation_error ? 'true' : 'false';
 
 
 
 
 
 
 
54
 
55
  $value = (string) reset( $tag->values );
56
 
50
  $atts['aria-required'] = 'true';
51
  }
52
 
53
+ if ( $validation_error ) {
54
+ $atts['aria-invalid'] = 'true';
55
+ $atts['aria-describedby'] = wpcf7_get_validation_error_reference(
56
+ $tag->name
57
+ );
58
+ } else {
59
+ $atts['aria-invalid'] = 'false';
60
+ }
61
 
62
  $value = (string) reset( $tag->values );
63
 
modules/quiz.php CHANGED
@@ -47,7 +47,15 @@ function wpcf7_quiz_form_tag_handler( $tag ) {
47
  $atts['tabindex'] = $tag->get_option( 'tabindex', 'signed_int', true );
48
  $atts['autocomplete'] = 'off';
49
  $atts['aria-required'] = 'true';
50
- $atts['aria-invalid'] = $validation_error ? 'true' : 'false';
 
 
 
 
 
 
 
 
51
 
52
  $pipes = $tag->pipes;
53
 
47
  $atts['tabindex'] = $tag->get_option( 'tabindex', 'signed_int', true );
48
  $atts['autocomplete'] = 'off';
49
  $atts['aria-required'] = 'true';
50
+
51
+ if ( $validation_error ) {
52
+ $atts['aria-invalid'] = 'true';
53
+ $atts['aria-describedby'] = wpcf7_get_validation_error_reference(
54
+ $tag->name
55
+ );
56
+ } else {
57
+ $atts['aria-invalid'] = 'false';
58
+ }
59
 
60
  $pipes = $tag->pipes;
61
 
modules/really-simple-captcha.php CHANGED
@@ -117,7 +117,15 @@ function wpcf7_captchar_form_tag_handler( $tag ) {
117
  $atts['id'] = $tag->get_id_option();
118
  $atts['tabindex'] = $tag->get_option( 'tabindex', 'signed_int', true );
119
  $atts['autocomplete'] = 'off';
120
- $atts['aria-invalid'] = $validation_error ? 'true' : 'false';
 
 
 
 
 
 
 
 
121
 
122
  $value = (string) reset( $tag->values );
123
 
117
  $atts['id'] = $tag->get_id_option();
118
  $atts['tabindex'] = $tag->get_option( 'tabindex', 'signed_int', true );
119
  $atts['autocomplete'] = 'off';
120
+
121
+ if ( $validation_error ) {
122
+ $atts['aria-invalid'] = 'true';
123
+ $atts['aria-describedby'] = wpcf7_get_validation_error_reference(
124
+ $tag->name
125
+ );
126
+ } else {
127
+ $atts['aria-invalid'] = 'false';
128
+ }
129
 
130
  $value = (string) reset( $tag->values );
131
 
modules/recaptcha/recaptcha.php CHANGED
@@ -70,9 +70,9 @@ function wpcf7_recaptcha_add_hidden_fields( $fields ) {
70
  ) );
71
  }
72
 
73
- add_filter( 'wpcf7_spam', 'wpcf7_recaptcha_verify_response', 9, 1 );
74
 
75
- function wpcf7_recaptcha_verify_response( $spam ) {
76
  if ( $spam ) {
77
  return $spam;
78
  }
@@ -83,8 +83,6 @@ function wpcf7_recaptcha_verify_response( $spam ) {
83
  return $spam;
84
  }
85
 
86
- $submission = WPCF7_Submission::get_instance();
87
-
88
  $token = isset( $_POST['_wpcf7_recaptcha_response'] )
89
  ? trim( $_POST['_wpcf7_recaptcha_response'] ) : '';
90
 
70
  ) );
71
  }
72
 
73
+ add_filter( 'wpcf7_spam', 'wpcf7_recaptcha_verify_response', 9, 2 );
74
 
75
+ function wpcf7_recaptcha_verify_response( $spam, $submission ) {
76
  if ( $spam ) {
77
  return $spam;
78
  }
83
  return $spam;
84
  }
85
 
 
 
86
  $token = isset( $_POST['_wpcf7_recaptcha_response'] )
87
  ? trim( $_POST['_wpcf7_recaptcha_response'] ) : '';
88
 
modules/select.php CHANGED
@@ -40,7 +40,14 @@ function wpcf7_select_form_tag_handler( $tag ) {
40
  $atts['aria-required'] = 'true';
41
  }
42
 
43
- $atts['aria-invalid'] = $validation_error ? 'true' : 'false';
 
 
 
 
 
 
 
44
 
45
  $multiple = $tag->has_option( 'multiple' );
46
  $include_blank = $tag->has_option( 'include_blank' );
40
  $atts['aria-required'] = 'true';
41
  }
42
 
43
+ if ( $validation_error ) {
44
+ $atts['aria-invalid'] = 'true';
45
+ $atts['aria-describedby'] = wpcf7_get_validation_error_reference(
46
+ $tag->name
47
+ );
48
+ } else {
49
+ $atts['aria-invalid'] = 'false';
50
+ }
51
 
52
  $multiple = $tag->has_option( 'multiple' );
53
  $include_blank = $tag->has_option( 'include_blank' );
modules/text.php CHANGED
@@ -64,7 +64,14 @@ function wpcf7_text_form_tag_handler( $tag ) {
64
  $atts['aria-required'] = 'true';
65
  }
66
 
67
- $atts['aria-invalid'] = $validation_error ? 'true' : 'false';
 
 
 
 
 
 
 
68
 
69
  $value = (string) reset( $tag->values );
70
 
64
  $atts['aria-required'] = 'true';
65
  }
66
 
67
+ if ( $validation_error ) {
68
+ $atts['aria-invalid'] = 'true';
69
+ $atts['aria-describedby'] = wpcf7_get_validation_error_reference(
70
+ $tag->name
71
+ );
72
+ } else {
73
+ $atts['aria-invalid'] = 'false';
74
+ }
75
 
76
  $value = (string) reset( $tag->values );
77
 
modules/textarea.php CHANGED
@@ -53,7 +53,14 @@ function wpcf7_textarea_form_tag_handler( $tag ) {
53
  $atts['aria-required'] = 'true';
54
  }
55
 
56
- $atts['aria-invalid'] = $validation_error ? 'true' : 'false';
 
 
 
 
 
 
 
57
 
58
  $value = empty( $tag->content )
59
  ? (string) reset( $tag->values )
53
  $atts['aria-required'] = 'true';
54
  }
55
 
56
+ if ( $validation_error ) {
57
+ $atts['aria-invalid'] = 'true';
58
+ $atts['aria-describedby'] = wpcf7_get_validation_error_reference(
59
+ $tag->name
60
+ );
61
+ } else {
62
+ $atts['aria-invalid'] = 'false';
63
+ }
64
 
65
  $value = empty( $tag->content )
66
  ? (string) reset( $tag->values )
readme.txt CHANGED
@@ -2,9 +2,9 @@
2
  Contributors: takayukister
3
  Donate link: https://contactform7.com/donate/
4
  Tags: contact, form, contact form, feedback, email, ajax, captcha, akismet, multilingual
5
- Requires at least: 5.3
6
  Tested up to: 5.5
7
- Stable tag: 5.2.2
8
  License: GPLv2 or later
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -75,6 +75,18 @@ Do you have questions or issues with Contact Form 7? Use these support channels
75
 
76
  For more information, see [Releases](https://contactform7.com/category/releases/).
77
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  = 5.2.2 =
79
 
80
  * Fixed: A REST API call aborted with a PHP fatal error when the `WPCF7_USE_PIPE` constant value was false.
@@ -104,64 +116,4 @@ For more information, see [Releases](https://contactform7.com/category/releases/
104
  * reCAPTCHA: Moves script code to a separate file.
105
  * reCAPTCHA: Changes the name of the field for reCAPTCHA response token from `g-recaptcha-response` to `_wpcf7_recaptcha_response`.
106
 
107
- = 5.1.9 =
108
-
109
- * Special mail-tags: Reflects WP timezone to `[_date]` and `[_time]` mail-tags.
110
- * WPCF7_FormTag: Reflects WP timezone to `get_date_option()` output.
111
- * User input validation: Strictly compares to boolean _false_.
112
-
113
- = 5.1.8 =
114
-
115
- * reCAPTCHA: Shows no warning on upgrading from v2 if the global sitekey is defined.
116
- * reCAPTCHA: Improves the frontend JavaScript coding.
117
- * Accessibility: Improves the response message markup.
118
- * Fixes the regular expression pattern in `wpcf7_is_tel()`.
119
- * Fixed: Character count was not reset after a successful submission.
120
- * Fixed: The fourth parameter of the `wpcf7_special_mail_tags` filter hook was not correctly set.
121
-
122
- = 5.1.7 =
123
-
124
- * CSS: Adds an explicit LTR direction style rule for code inputs.
125
- * Accessibility: Uses _Error_ instead of _ERROR_ in warnings.
126
-
127
- = 5.1.6 =
128
-
129
- * CSS: removes a style rule from the stylesheet that was unnecessary and conflicting with Twenty Twenty’s rules.
130
- * REST API: retrieves the contact form ID explicitly from the route parameters.
131
-
132
- = 5.1.5 =
133
-
134
- * Config Validator: New test item for the unavailable_html_elements error.
135
- * Config Validator: New test item for the attachments_overweight error.
136
-
137
- = 5.1.4 =
138
-
139
- * reCAPTCHA: introduces the WPCF7_RECAPTCHA_SITEKEY and WPCF7_RECAPTCHA_SECRET constants.
140
- * reCAPTCHA: Introduces the wpcf7_recaptcha_sitekey and wpcf7_recaptcha_secret filter hooks.
141
- * Adds $status parameter to the wpcf7_form_response_output filter.
142
- * Creates a nonce only when the submitter is a logged-in user.
143
- * Introduces WPCF7_ContactForm::unit_tag(), a public method that returns a unit tag.
144
- * reCAPTCHA: gives a different spam log message for cases where the response token is empty.
145
- * Acceptance Checkbox: supports the label_first option in an acceptance form-tag.
146
-
147
- = 5.1.3 =
148
-
149
- * Fixes a bug making it unable to unselect an option in the Mail tab panel.
150
-
151
- = 5.1.2 =
152
-
153
- * Constant Contact: Introduces the contact list selector.
154
- * Constant Contact: Introduces the constant_contact additional setting.
155
- * reCAPTCHA: Introduces the wpcf7_recaptcha_actions and wpcf7_recaptcha_threshold filter hooks.
156
-
157
- = 5.1.1 =
158
-
159
- * reCAPTCHA: Modifies the reaction to empty response tokens.
160
-
161
- = 5.1 =
162
-
163
- * Introduces the Constant Contact integration module.
164
- * Updates the reCAPTCHA module to support reCAPTCHA v3.
165
- * Adds Dark Mode style rules.
166
-
167
  == Upgrade Notice ==
2
  Contributors: takayukister
3
  Donate link: https://contactform7.com/donate/
4
  Tags: contact, form, contact form, feedback, email, ajax, captcha, akismet, multilingual
5
+ Requires at least: 5.4
6
  Tested up to: 5.5
7
+ Stable tag: 5.3
8
  License: GPLv2 or later
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
10
 
75
 
76
  For more information, see [Releases](https://contactform7.com/category/releases/).
77
 
78
+ = 5.3 =
79
+
80
+ * Block Editor: Introduces the contact form selector block type.
81
+ * Renames the 'images' directory to 'assets'.
82
+ * New filter hook: `wpcf7_form_tag_date_option`.
83
+ * Date: Makes all DateTime date formats available for `min` and `max` options.
84
+ * Date: Converts the default value to Y-m-d date format string.
85
+ * Disallowed list: Deprecates the `wpcf7_submission_is_blacklisted` filter hook in favor of `wpcf7_submission_has_disallowed_words`.
86
+ * Accessibility: Sets the `aria-describedby` attribute for invalid fields.
87
+ * Default form template: Removes the "(required)" labels from required fields. Adds "(optional)" to optional fields instead.
88
+ * Default mail template: Uses site-related special mail-tags.
89
+
90
  = 5.2.2 =
91
 
92
  * Fixed: A REST API call aborted with a PHP fatal error when the `WPCF7_USE_PIPE` constant value was false.
116
  * reCAPTCHA: Moves script code to a separate file.
117
  * reCAPTCHA: Changes the name of the field for reCAPTCHA response token from `g-recaptcha-response` to `_wpcf7_recaptcha_response`.
118
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  == Upgrade Notice ==
wp-contact-form-7.php CHANGED
@@ -7,12 +7,14 @@ Author: Takayuki Miyoshi
7
  Author URI: https://ideasilo.wordpress.com/
8
  Text Domain: contact-form-7
9
  Domain Path: /languages/
10
- Version: 5.2.2
11
  */
12
 
13
- define( 'WPCF7_VERSION', '5.2.2' );
14
 
15
- define( 'WPCF7_REQUIRED_WP_VERSION', '5.3' );
 
 
16
 
17
  define( 'WPCF7_PLUGIN', __FILE__ );
18
 
@@ -62,6 +64,7 @@ if ( ! defined( 'WPCF7_VALIDATE_CONFIGURATION' ) ) {
62
 
63
  // Deprecated, not used in the plugin core. Use wpcf7_plugin_url() instead.
64
  define( 'WPCF7_PLUGIN_URL',
65
- untrailingslashit( plugins_url( '', WPCF7_PLUGIN ) ) );
 
66
 
67
- require_once WPCF7_PLUGIN_DIR . '/settings.php';
7
  Author URI: https://ideasilo.wordpress.com/
8
  Text Domain: contact-form-7
9
  Domain Path: /languages/
10
+ Version: 5.3
11
  */
12
 
13
+ define( 'WPCF7_VERSION', '5.3' );
14
 
15
+ define( 'WPCF7_REQUIRED_WP_VERSION', '5.4' );
16
+
17
+ define( 'WPCF7_TEXT_DOMAIN', 'contact-form-7' );
18
 
19
  define( 'WPCF7_PLUGIN', __FILE__ );
20
 
64
 
65
  // Deprecated, not used in the plugin core. Use wpcf7_plugin_url() instead.
66
  define( 'WPCF7_PLUGIN_URL',
67
+ untrailingslashit( plugins_url( '', WPCF7_PLUGIN ) )
68
+ );
69
 
70
+ require_once WPCF7_PLUGIN_DIR . '/load.php';