Contact Form 7 - Version 5.5.6

Version Description

https://contactform7.com/contact-form-7-556/

Download this release

Release Info

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

Code changes from version 5.5.5 to 5.5.6

includes/integration.php CHANGED
@@ -1,4 +1,9 @@
1
  <?php
 
 
 
 
 
2
 
3
  class WPCF7_Integration {
4
 
@@ -9,6 +14,12 @@ class WPCF7_Integration {
9
 
10
  private function __construct() {}
11
 
 
 
 
 
 
 
12
  public static function get_builtin_categories() {
13
  return array(
14
  'spam_protection' => __( 'Spam protection', 'contact-form-7' ),
@@ -17,6 +28,12 @@ class WPCF7_Integration {
17
  );
18
  }
19
 
 
 
 
 
 
 
20
  public static function get_instance() {
21
  if ( empty( self::$instance ) ) {
22
  self::$instance = new self;
@@ -26,6 +43,10 @@ class WPCF7_Integration {
26
  return self::$instance;
27
  }
28
 
 
 
 
 
29
  public function add_service( $name, WPCF7_Service $service ) {
30
  $name = sanitize_key( $name );
31
 
@@ -37,6 +58,10 @@ class WPCF7_Integration {
37
  $this->services[$name] = $service;
38
  }
39
 
 
 
 
 
40
  public function add_category( $name, $title ) {
41
  $name = sanitize_key( $name );
42
 
@@ -48,6 +73,12 @@ class WPCF7_Integration {
48
  $this->categories[$name] = $title;
49
  }
50
 
 
 
 
 
 
 
51
  public function service_exists( $name = '' ) {
52
  if ( '' == $name ) {
53
  return (bool) count( $this->services );
@@ -56,6 +87,14 @@ class WPCF7_Integration {
56
  }
57
  }
58
 
 
 
 
 
 
 
 
 
59
  public function get_service( $name ) {
60
  if ( $this->service_exists( $name ) ) {
61
  return $this->services[$name];
@@ -64,6 +103,10 @@ class WPCF7_Integration {
64
  }
65
  }
66
 
 
 
 
 
67
  public function list_services( $args = '' ) {
68
  $args = wp_parse_args( $args, array(
69
  'include' => array(),
@@ -117,34 +160,54 @@ class WPCF7_Integration {
117
 
118
  }
119
 
 
 
 
 
 
 
 
120
  abstract class WPCF7_Service {
121
 
122
  abstract public function get_title();
123
  abstract public function is_active();
124
 
 
125
  public function get_categories() {
126
  return array();
127
  }
128
 
 
129
  public function icon() {
130
  return '';
131
  }
132
 
 
133
  public function link() {
134
  return '';
135
  }
136
 
 
137
  public function load( $action = '' ) {
138
  }
139
 
 
140
  public function display( $action = '' ) {
141
  }
142
 
 
143
  public function admin_notice( $message = '' ) {
144
  }
145
 
146
  }
147
 
 
 
 
 
 
 
 
148
  class WPCF7_Service_OAuth2 extends WPCF7_Service {
149
 
150
  protected $client_id = '';
@@ -154,28 +217,35 @@ class WPCF7_Service_OAuth2 extends WPCF7_Service {
154
  protected $authorization_endpoint = 'https://example.com/authorization';
155
  protected $token_endpoint = 'https://example.com/token';
156
 
 
157
  public function get_title() {
158
  return '';
159
  }
160
 
 
161
  public function is_active() {
162
  return ! empty( $this->refresh_token );
163
  }
164
 
 
165
  protected function save_data() {
166
  }
167
 
 
168
  protected function reset_data() {
169
  }
170
 
 
171
  protected function get_redirect_uri() {
172
  return admin_url();
173
  }
174
 
 
175
  protected function menu_page_url( $args = '' ) {
176
  return menu_page_url( 'wpcf7-integration', false );
177
  }
178
 
 
179
  public function load( $action = '' ) {
180
  if ( 'auth_redirect' == $action ) {
181
  $code = isset( $_GET['code'] ) ? $_GET['code'] : '';
@@ -201,6 +271,7 @@ class WPCF7_Service_OAuth2 extends WPCF7_Service {
201
  }
202
  }
203
 
 
204
  protected function authorize( $scope = '' ) {
205
  $endpoint = add_query_arg(
206
  array(
@@ -217,6 +288,7 @@ class WPCF7_Service_OAuth2 extends WPCF7_Service {
217
  }
218
  }
219
 
 
220
  protected function get_http_authorization_header( $scheme = 'basic' ) {
221
  $scheme = strtolower( trim( $scheme ) );
222
 
@@ -231,6 +303,7 @@ class WPCF7_Service_OAuth2 extends WPCF7_Service {
231
  }
232
  }
233
 
 
234
  protected function request_token( $authorization_code ) {
235
  $endpoint = add_query_arg(
236
  array(
@@ -278,6 +351,7 @@ class WPCF7_Service_OAuth2 extends WPCF7_Service {
278
  return $response;
279
  }
280
 
 
281
  protected function refresh_token() {
282
  $endpoint = add_query_arg(
283
  array(
@@ -322,6 +396,7 @@ class WPCF7_Service_OAuth2 extends WPCF7_Service {
322
  return $response;
323
  }
324
 
 
325
  protected function remote_request( $url, $request = array() ) {
326
  static $refreshed = false;
327
 
@@ -347,6 +422,7 @@ class WPCF7_Service_OAuth2 extends WPCF7_Service {
347
  return $response;
348
  }
349
 
 
350
  protected function log( $url, $request, $response ) {
351
  wpcf7_log_remote_request( $url, $request, $response );
352
  }
1
  <?php
2
+ /**
3
+ * Integration API
4
+ *
5
+ * @link https://contactform7.com/integration-with-external-apis/
6
+ */
7
 
8
  class WPCF7_Integration {
9
 
14
 
15
  private function __construct() {}
16
 
17
+
18
+ /**
19
+ * Returns initially supported service categories.
20
+ *
21
+ * @return array Service categories.
22
+ */
23
  public static function get_builtin_categories() {
24
  return array(
25
  'spam_protection' => __( 'Spam protection', 'contact-form-7' ),
28
  );
29
  }
30
 
31
+
32
+ /**
33
+ * Returns the singleton instance of this class.
34
+ *
35
+ * @return WPCF7_Integration The instance.
36
+ */
37
  public static function get_instance() {
38
  if ( empty( self::$instance ) ) {
39
  self::$instance = new self;
43
  return self::$instance;
44
  }
45
 
46
+
47
+ /**
48
+ * Adds a service to the services list.
49
+ */
50
  public function add_service( $name, WPCF7_Service $service ) {
51
  $name = sanitize_key( $name );
52
 
58
  $this->services[$name] = $service;
59
  }
60
 
61
+
62
+ /**
63
+ * Adds a service category to the categories list.
64
+ */
65
  public function add_category( $name, $title ) {
66
  $name = sanitize_key( $name );
67
 
73
  $this->categories[$name] = $title;
74
  }
75
 
76
+
77
+ /**
78
+ * Returns true if a service with the name exists in the services list.
79
+ *
80
+ * @param string $name The name of service to search.
81
+ */
82
  public function service_exists( $name = '' ) {
83
  if ( '' == $name ) {
84
  return (bool) count( $this->services );
87
  }
88
  }
89
 
90
+
91
+ /**
92
+ * Returns a service object with the name.
93
+ *
94
+ * @param string $name The name of service.
95
+ * @return WPCF7_Service|bool The service object if it exists,
96
+ * false otherwise.
97
+ */
98
  public function get_service( $name ) {
99
  if ( $this->service_exists( $name ) ) {
100
  return $this->services[$name];
103
  }
104
  }
105
 
106
+
107
+ /**
108
+ * Prints services list.
109
+ */
110
  public function list_services( $args = '' ) {
111
  $args = wp_parse_args( $args, array(
112
  'include' => array(),
160
 
161
  }
162
 
163
+
164
+ /**
165
+ * Abstract class for services.
166
+ *
167
+ * Only instances of this class's subclasses are allowed to be
168
+ * listed on the Integration page.
169
+ */
170
  abstract class WPCF7_Service {
171
 
172
  abstract public function get_title();
173
  abstract public function is_active();
174
 
175
+
176
  public function get_categories() {
177
  return array();
178
  }
179
 
180
+
181
  public function icon() {
182
  return '';
183
  }
184
 
185
+
186
  public function link() {
187
  return '';
188
  }
189
 
190
+
191
  public function load( $action = '' ) {
192
  }
193
 
194
+
195
  public function display( $action = '' ) {
196
  }
197
 
198
+
199
  public function admin_notice( $message = '' ) {
200
  }
201
 
202
  }
203
 
204
+
205
+ /**
206
+ * Class for services that use OAuth.
207
+ *
208
+ * While this is not an abstract class, subclassing this class for
209
+ * your aim is advised.
210
+ */
211
  class WPCF7_Service_OAuth2 extends WPCF7_Service {
212
 
213
  protected $client_id = '';
217
  protected $authorization_endpoint = 'https://example.com/authorization';
218
  protected $token_endpoint = 'https://example.com/token';
219
 
220
+
221
  public function get_title() {
222
  return '';
223
  }
224
 
225
+
226
  public function is_active() {
227
  return ! empty( $this->refresh_token );
228
  }
229
 
230
+
231
  protected function save_data() {
232
  }
233
 
234
+
235
  protected function reset_data() {
236
  }
237
 
238
+
239
  protected function get_redirect_uri() {
240
  return admin_url();
241
  }
242
 
243
+
244
  protected function menu_page_url( $args = '' ) {
245
  return menu_page_url( 'wpcf7-integration', false );
246
  }
247
 
248
+
249
  public function load( $action = '' ) {
250
  if ( 'auth_redirect' == $action ) {
251
  $code = isset( $_GET['code'] ) ? $_GET['code'] : '';
271
  }
272
  }
273
 
274
+
275
  protected function authorize( $scope = '' ) {
276
  $endpoint = add_query_arg(
277
  array(
288
  }
289
  }
290
 
291
+
292
  protected function get_http_authorization_header( $scheme = 'basic' ) {
293
  $scheme = strtolower( trim( $scheme ) );
294
 
303
  }
304
  }
305
 
306
+
307
  protected function request_token( $authorization_code ) {
308
  $endpoint = add_query_arg(
309
  array(
351
  return $response;
352
  }
353
 
354
+
355
  protected function refresh_token() {
356
  $endpoint = add_query_arg(
357
  array(
396
  return $response;
397
  }
398
 
399
+
400
  protected function remote_request( $url, $request = array() ) {
401
  static $refreshed = false;
402
 
422
  return $response;
423
  }
424
 
425
+
426
  protected function log( $url, $request, $response ) {
427
  wpcf7_log_remote_request( $url, $request, $response );
428
  }
includes/submission.php CHANGED
@@ -598,11 +598,13 @@ class WPCF7_Submission {
598
 
599
 
600
  private function verify_nonce() {
601
- if ( ! $this->contact_form->nonce_is_active() ) {
602
  return true;
603
  }
604
 
605
- return wpcf7_verify_nonce( $_POST['_wpnonce'] );
 
 
606
  }
607
 
608
 
598
 
599
 
600
  private function verify_nonce() {
601
+ if ( ! $this->contact_form->nonce_is_active() or ! is_user_logged_in() ) {
602
  return true;
603
  }
604
 
605
+ $nonce = isset( $_POST['_wpnonce'] ) ? $_POST['_wpnonce'] : '';
606
+
607
+ return wpcf7_verify_nonce( $nonce );
608
  }
609
 
610
 
modules/akismet.php CHANGED
@@ -70,6 +70,10 @@ function wpcf7_akismet( $spam, $submission ) {
70
  return $spam;
71
  }
72
 
 
 
 
 
73
  function wpcf7_akismet_is_available() {
74
  if ( is_callable( array( 'Akismet', 'get_api_key' ) ) ) {
75
  return (bool) Akismet::get_api_key();
@@ -78,7 +82,28 @@ function wpcf7_akismet_is_available() {
78
  return false;
79
  }
80
 
 
 
 
 
 
81
  function wpcf7_akismet_submitted_params() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  $params = array(
83
  'author' => '',
84
  'author_email' => '',
@@ -86,56 +111,83 @@ function wpcf7_akismet_submitted_params() {
86
  'content' => '',
87
  );
88
 
89
- $has_akismet_option = false;
90
-
91
  foreach ( (array) $_POST as $key => $val ) {
92
  if ( '_wpcf7' == substr( $key, 0, 6 )
93
  or '_wpnonce' == $key ) {
94
  continue;
95
  }
96
 
97
- if ( is_array( $val ) ) {
98
- $val = implode( ', ', wpcf7_array_flatten( $val ) );
99
- }
100
-
101
- $val = trim( $val );
 
102
 
103
- if ( 0 == strlen( $val ) ) {
104
  continue;
105
  }
106
 
107
  if ( $tags = wpcf7_scan_form_tags( array( 'name' => $key ) ) ) {
108
  $tag = $tags[0];
109
 
110
- $akismet = $tag->get_option( 'akismet',
111
- '(author|author_email|author_url)', true
 
112
  );
113
 
114
- if ( $akismet ) {
115
- $has_akismet_option = true;
 
 
 
 
116
 
117
- if ( 'author' == $akismet ) {
118
- $params[$akismet] = trim( $params[$akismet] . ' ' . $val );
119
- continue;
120
- } elseif ( '' == $params[$akismet] ) {
121
- $params[$akismet] = $val;
122
- continue;
123
- }
124
  }
125
- }
126
 
127
- $params['content'] .= "\n\n" . $val;
128
- }
 
 
 
129
 
130
- if ( ! $has_akismet_option ) {
131
- return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  }
133
 
134
- $params['content'] = trim( $params['content'] );
135
 
136
  return $params;
137
  }
138
 
 
 
 
 
 
 
 
139
  function wpcf7_akismet_comment_check( $comment ) {
140
  $spam = false;
141
  $query_string = wpcf7_build_query( $comment );
70
  return $spam;
71
  }
72
 
73
+
74
+ /**
75
+ * Returns true if Akismet is active and has a valid API key.
76
+ */
77
  function wpcf7_akismet_is_available() {
78
  if ( is_callable( array( 'Akismet', 'get_api_key' ) ) ) {
79
  return (bool) Akismet::get_api_key();
82
  return false;
83
  }
84
 
85
+
86
+ /**
87
+ * Returns an array of parameters based on the current form submission.
88
+ * Returns false if Akismet is not active on the contact form.
89
+ */
90
  function wpcf7_akismet_submitted_params() {
91
+ $akismet_tags = array_filter(
92
+ wpcf7_scan_form_tags(),
93
+ function ( $tag ) {
94
+ $akismet_option = $tag->get_option( 'akismet',
95
+ '(author|author_email|author_url)',
96
+ true
97
+ );
98
+
99
+ return (bool) $akismet_option;
100
+ }
101
+ );
102
+
103
+ if ( ! $akismet_tags ) { // Akismet is not active on this contact form.
104
+ return false;
105
+ }
106
+
107
  $params = array(
108
  'author' => '',
109
  'author_email' => '',
111
  'content' => '',
112
  );
113
 
 
 
114
  foreach ( (array) $_POST as $key => $val ) {
115
  if ( '_wpcf7' == substr( $key, 0, 6 )
116
  or '_wpnonce' == $key ) {
117
  continue;
118
  }
119
 
120
+ $vals = array_filter(
121
+ wpcf7_array_flatten( $val ),
122
+ function ( $val ) {
123
+ return '' !== trim( $val );
124
+ }
125
+ );
126
 
127
+ if ( empty( $vals ) ) {
128
  continue;
129
  }
130
 
131
  if ( $tags = wpcf7_scan_form_tags( array( 'name' => $key ) ) ) {
132
  $tag = $tags[0];
133
 
134
+ $akismet_option = $tag->get_option( 'akismet',
135
+ '(author|author_email|author_url)',
136
+ true
137
  );
138
 
139
+ if ( 'author' === $akismet_option ) {
140
+ $params['author'] = sprintf(
141
+ '%s %s',
142
+ $params['author'],
143
+ implode( ' ', $vals )
144
+ );
145
 
146
+ continue;
 
 
 
 
 
 
147
  }
 
148
 
149
+ if ( 'author_email' === $akismet_option
150
+ and '' === $params['author_email'] ) {
151
+ $params['author_email'] = $vals[0];
152
+ continue;
153
+ }
154
 
155
+ if ( 'author_url' === $akismet_option
156
+ and '' === $params['author_url'] ) {
157
+ $params['author_url'] = $vals[0];
158
+ continue;
159
+ }
160
+
161
+ $vals = array_filter(
162
+ $vals,
163
+ function ( $val ) use ( $tag ) {
164
+ if ( wpcf7_form_tag_supports( $tag->type, 'selectable-values' )
165
+ and in_array( $val, $tag->labels ) ) {
166
+ return false;
167
+ } else {
168
+ return true;
169
+ }
170
+ }
171
+ );
172
+ }
173
+
174
+ if ( $vals ) {
175
+ $params['content'] .= "\n\n" . implode( ', ', $vals );
176
+ }
177
  }
178
 
179
+ $params = array_map( 'trim', $params );
180
 
181
  return $params;
182
  }
183
 
184
+
185
+ /**
186
+ * Sends data to Akismet.
187
+ *
188
+ * @param array $comment Submission and environment data.
189
+ * @return bool True if Akismet called it spam, or false otherwise.
190
+ */
191
  function wpcf7_akismet_comment_check( $comment ) {
192
  $spam = false;
193
  $query_string = wpcf7_build_query( $comment );
modules/constant-contact/constant-contact.php CHANGED
@@ -1,4 +1,9 @@
1
  <?php
 
 
 
 
 
2
 
3
  wpcf7_include_module_file( 'constant-contact/service.php' );
4
  wpcf7_include_module_file( 'constant-contact/contact-post-request.php' );
1
  <?php
2
+ /**
3
+ * Constant Contact module main file
4
+ *
5
+ * @link https://contactform7.com/constant-contact-integration/
6
+ */
7
 
8
  wpcf7_include_module_file( 'constant-contact/service.php' );
9
  wpcf7_include_module_file( 'constant-contact/contact-post-request.php' );
modules/constant-contact/service.php CHANGED
@@ -7,8 +7,12 @@ if ( ! class_exists( 'WPCF7_Service_OAuth2' ) ) {
7
  class WPCF7_ConstantContact extends WPCF7_Service_OAuth2 {
8
 
9
  const service_name = 'constant_contact';
10
- const authorization_endpoint = 'https://api.cc.email/v3/idfed';
11
- const token_endpoint = 'https://idfed.constantcontact.com/as/token.oauth2';
 
 
 
 
12
 
13
  private static $instance;
14
  protected $contact_lists = array();
@@ -54,15 +58,15 @@ class WPCF7_ConstantContact extends WPCF7_Service_OAuth2 {
54
 
55
  public function auth_redirect() {
56
  $auth = isset( $_GET['auth'] ) ? trim( $_GET['auth'] ) : '';
57
- $code = isset( $_GET['code'] ) ? trim( $_GET['code'] ) : '';
58
 
59
- if ( self::service_name === $auth and $code
60
  and current_user_can( 'wpcf7_manage_integration' ) ) {
61
  $redirect_to = add_query_arg(
62
  array(
63
  'service' => self::service_name,
64
  'action' => 'auth_redirect',
65
- 'code' => $code,
 
66
  ),
67
  menu_page_url( 'wpcf7-integration', false )
68
  );
@@ -125,7 +129,7 @@ class WPCF7_ConstantContact extends WPCF7_Service_OAuth2 {
125
  $url = menu_page_url( 'wpcf7-integration', false );
126
  $url = add_query_arg( array( 'service' => self::service_name ), $url );
127
 
128
- if ( ! empty( $args) ) {
129
  $url = add_query_arg( $args, $url );
130
  }
131
 
@@ -133,7 +137,30 @@ class WPCF7_ConstantContact extends WPCF7_Service_OAuth2 {
133
  }
134
 
135
  public function load( $action = '' ) {
136
- parent::load( $action );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
 
138
  if ( 'setup' == $action and 'POST' == $_SERVER['REQUEST_METHOD'] ) {
139
  check_admin_referer( 'wpcf7-constant-contact-setup' );
@@ -148,7 +175,7 @@ class WPCF7_ConstantContact extends WPCF7_Service_OAuth2 {
148
  ? trim( $_POST['client_secret'] ) : '';
149
 
150
  $this->save_data();
151
- $this->authorize( 'contact_data' );
152
  }
153
 
154
  wp_safe_redirect( $this->menu_page_url( 'action=setup' ) );
@@ -156,6 +183,23 @@ class WPCF7_ConstantContact extends WPCF7_Service_OAuth2 {
156
  }
157
  }
158
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  public function email_exists( $email ) {
160
  $endpoint = add_query_arg(
161
  array(
7
  class WPCF7_ConstantContact extends WPCF7_Service_OAuth2 {
8
 
9
  const service_name = 'constant_contact';
10
+
11
+ const authorization_endpoint
12
+ = 'https://authz.constantcontact.com/oauth2/default/v1/authorize';
13
+
14
+ const token_endpoint
15
+ = 'https://authz.constantcontact.com/oauth2/default/v1/token';
16
 
17
  private static $instance;
18
  protected $contact_lists = array();
58
 
59
  public function auth_redirect() {
60
  $auth = isset( $_GET['auth'] ) ? trim( $_GET['auth'] ) : '';
 
61
 
62
+ if ( self::service_name === $auth
63
  and current_user_can( 'wpcf7_manage_integration' ) ) {
64
  $redirect_to = add_query_arg(
65
  array(
66
  'service' => self::service_name,
67
  'action' => 'auth_redirect',
68
+ 'code' => isset( $_GET['code'] ) ? trim( $_GET['code'] ) : '',
69
+ 'state' => isset( $_GET['state'] ) ? trim( $_GET['state'] ) : '',
70
  ),
71
  menu_page_url( 'wpcf7-integration', false )
72
  );
129
  $url = menu_page_url( 'wpcf7-integration', false );
130
  $url = add_query_arg( array( 'service' => self::service_name ), $url );
131
 
132
+ if ( ! empty( $args ) ) {
133
  $url = add_query_arg( $args, $url );
134
  }
135
 
137
  }
138
 
139
  public function load( $action = '' ) {
140
+ if ( 'auth_redirect' == $action ) {
141
+ $code = isset( $_GET['code'] ) ? urldecode( $_GET['code'] ) : '';
142
+ $state = isset( $_GET['state'] ) ? urldecode( $_GET['state'] ) : '';
143
+
144
+ if ( $code and $state
145
+ and wpcf7_verify_nonce( $state, 'wpcf7_constant_contact_authorize' ) ) {
146
+ $response = $this->request_token( $code );
147
+ }
148
+
149
+ if ( ! empty( $this->access_token ) ) {
150
+ $message = 'success';
151
+ } else {
152
+ $message = 'failed';
153
+ }
154
+
155
+ wp_safe_redirect( $this->menu_page_url(
156
+ array(
157
+ 'action' => 'setup',
158
+ 'message' => $message,
159
+ )
160
+ ) );
161
+
162
+ exit();
163
+ }
164
 
165
  if ( 'setup' == $action and 'POST' == $_SERVER['REQUEST_METHOD'] ) {
166
  check_admin_referer( 'wpcf7-constant-contact-setup' );
175
  ? trim( $_POST['client_secret'] ) : '';
176
 
177
  $this->save_data();
178
+ $this->authorize( 'contact_data offline_access' );
179
  }
180
 
181
  wp_safe_redirect( $this->menu_page_url( 'action=setup' ) );
183
  }
184
  }
185
 
186
+ protected function authorize( $scope = '' ) {
187
+ $endpoint = add_query_arg(
188
+ array_map( 'urlencode', array(
189
+ 'response_type' => 'code',
190
+ 'client_id' => $this->client_id,
191
+ 'redirect_uri' => $this->get_redirect_uri(),
192
+ 'scope' => $scope,
193
+ 'state' => wpcf7_create_nonce( 'wpcf7_constant_contact_authorize' ),
194
+ ) ),
195
+ $this->authorization_endpoint
196
+ );
197
+
198
+ if ( wp_redirect( esc_url_raw( $endpoint ) ) ) {
199
+ exit();
200
+ }
201
+ }
202
+
203
  public function email_exists( $email ) {
204
  $endpoint = add_query_arg(
205
  array(
modules/recaptcha/recaptcha.php CHANGED
@@ -1,7 +1,18 @@
1
  <?php
 
 
 
 
 
 
 
 
2
 
3
  add_action( 'wpcf7_init', 'wpcf7_recaptcha_register_service', 15, 0 );
4
 
 
 
 
5
  function wpcf7_recaptcha_register_service() {
6
  $integration = WPCF7_Integration::get_instance();
7
 
@@ -10,8 +21,16 @@ function wpcf7_recaptcha_register_service() {
10
  );
11
  }
12
 
13
- add_action( 'wp_enqueue_scripts', 'wpcf7_recaptcha_enqueue_scripts', 20, 0 );
14
 
 
 
 
 
 
 
 
 
 
15
  function wpcf7_recaptcha_enqueue_scripts() {
16
  $service = WPCF7_RECAPTCHA::get_instance();
17
 
@@ -76,10 +95,16 @@ function wpcf7_recaptcha_enqueue_scripts() {
76
  );
77
  }
78
 
79
- add_filter( 'wpcf7_form_hidden_fields',
80
- 'wpcf7_recaptcha_add_hidden_fields', 100, 1
 
 
 
81
  );
82
 
 
 
 
83
  function wpcf7_recaptcha_add_hidden_fields( $fields ) {
84
  $service = WPCF7_RECAPTCHA::get_instance();
85
 
@@ -92,8 +117,12 @@ function wpcf7_recaptcha_add_hidden_fields( $fields ) {
92
  ) );
93
  }
94
 
 
95
  add_filter( 'wpcf7_spam', 'wpcf7_recaptcha_verify_response', 9, 2 );
96
 
 
 
 
97
  function wpcf7_recaptcha_verify_response( $spam, $submission ) {
98
  if ( $spam ) {
99
  return $spam;
@@ -116,13 +145,19 @@ function wpcf7_recaptcha_verify_response( $spam, $submission ) {
116
  if ( '' === $token ) {
117
  $submission->add_spam_log( array(
118
  'agent' => 'recaptcha',
119
- 'reason' => __( 'reCAPTCHA response token is empty.', 'contact-form-7' ),
 
 
 
120
  ) );
121
  } else {
122
  $submission->add_spam_log( array(
123
  'agent' => 'recaptcha',
124
  'reason' => sprintf(
125
- __( 'reCAPTCHA score (%1$.2f) is lower than the threshold (%2$.2f).', 'contact-form-7' ),
 
 
 
126
  $service->get_last_score(),
127
  $service->get_threshold()
128
  ),
@@ -133,8 +168,12 @@ function wpcf7_recaptcha_verify_response( $spam, $submission ) {
133
  return $spam;
134
  }
135
 
 
136
  add_action( 'wpcf7_init', 'wpcf7_recaptcha_add_form_tag_recaptcha', 10, 0 );
137
 
 
 
 
138
  function wpcf7_recaptcha_add_form_tag_recaptcha() {
139
  $service = WPCF7_RECAPTCHA::get_instance();
140
 
@@ -148,8 +187,12 @@ function wpcf7_recaptcha_add_form_tag_recaptcha() {
148
  );
149
  }
150
 
 
151
  add_action( 'wpcf7_upgrade', 'wpcf7_upgrade_recaptcha_v2_v3', 10, 2 );
152
 
 
 
 
153
  function wpcf7_upgrade_recaptcha_v2_v3( $new_ver, $old_ver ) {
154
  if ( version_compare( '5.1-dev', $old_ver, '<=' ) ) {
155
  return;
@@ -166,32 +209,53 @@ function wpcf7_upgrade_recaptcha_v2_v3( $new_ver, $old_ver ) {
166
  WPCF7::update_option( 'recaptcha', null );
167
  }
168
 
 
169
  add_action( 'wpcf7_admin_menu', 'wpcf7_admin_init_recaptcha_v2_v3', 10, 0 );
170
 
 
 
 
171
  function wpcf7_admin_init_recaptcha_v2_v3() {
172
  if ( ! WPCF7::get_option( 'recaptcha_v2_v3_warning' ) ) {
173
  return;
174
  }
175
 
176
- add_filter( 'wpcf7_admin_menu_change_notice',
177
- 'wpcf7_admin_menu_change_notice_recaptcha_v2_v3', 10, 1 );
 
 
 
178
 
179
- add_action( 'wpcf7_admin_warnings',
180
- 'wpcf7_admin_warnings_recaptcha_v2_v3', 5, 3 );
 
 
 
181
  }
182
 
 
 
 
 
183
  function wpcf7_admin_menu_change_notice_recaptcha_v2_v3( $counts ) {
184
  $counts['wpcf7-integration'] += 1;
185
  return $counts;
186
  }
187
 
 
 
 
 
188
  function wpcf7_admin_warnings_recaptcha_v2_v3( $page, $action, $object ) {
189
  if ( 'wpcf7-integration' !== $page ) {
190
  return;
191
  }
192
 
193
  $message = sprintf(
194
- esc_html( __( "API keys for reCAPTCHA v3 are different from those for v2; keys for v2 don&#8217;t work with the v3 API. You need to register your sites again to get new keys for v3. For details, see %s.", 'contact-form-7' ) ),
 
 
 
195
  wpcf7_link(
196
  __( 'https://contactform7.com/recaptcha/', 'contact-form-7' ),
197
  __( 'reCAPTCHA (v3)', 'contact-form-7' )
@@ -203,337 +267,3 @@ function wpcf7_admin_warnings_recaptcha_v2_v3( $page, $action, $object ) {
203
  $message
204
  );
205
  }
206
-
207
- if ( ! class_exists( 'WPCF7_Service' ) ) {
208
- return;
209
- }
210
-
211
- class WPCF7_RECAPTCHA extends WPCF7_Service {
212
-
213
- private static $instance;
214
- private $sitekeys;
215
- private $last_score;
216
-
217
- public static function get_instance() {
218
- if ( empty( self::$instance ) ) {
219
- self::$instance = new self;
220
- }
221
-
222
- return self::$instance;
223
- }
224
-
225
- private function __construct() {
226
- $this->sitekeys = WPCF7::get_option( 'recaptcha' );
227
- }
228
-
229
- public function get_title() {
230
- return __( 'reCAPTCHA', 'contact-form-7' );
231
- }
232
-
233
- public function is_active() {
234
- $sitekey = $this->get_sitekey();
235
- $secret = $this->get_secret( $sitekey );
236
- return $sitekey && $secret;
237
- }
238
-
239
- public function get_categories() {
240
- return array( 'spam_protection' );
241
- }
242
-
243
- public function icon() {
244
- }
245
-
246
- public function link() {
247
- echo wpcf7_link(
248
- 'https://www.google.com/recaptcha/intro/index.html',
249
- 'google.com/recaptcha'
250
- );
251
- }
252
-
253
- public function get_global_sitekey() {
254
- static $sitekey = '';
255
-
256
- if ( $sitekey ) {
257
- return $sitekey;
258
- }
259
-
260
- if ( defined( 'WPCF7_RECAPTCHA_SITEKEY' ) ) {
261
- $sitekey = WPCF7_RECAPTCHA_SITEKEY;
262
- }
263
-
264
- $sitekey = apply_filters( 'wpcf7_recaptcha_sitekey', $sitekey );
265
-
266
- return $sitekey;
267
- }
268
-
269
- public function get_global_secret() {
270
- static $secret = '';
271
-
272
- if ( $secret ) {
273
- return $secret;
274
- }
275
-
276
- if ( defined( 'WPCF7_RECAPTCHA_SECRET' ) ) {
277
- $secret = WPCF7_RECAPTCHA_SECRET;
278
- }
279
-
280
- $secret = apply_filters( 'wpcf7_recaptcha_secret', $secret );
281
-
282
- return $secret;
283
- }
284
-
285
- public function get_sitekey() {
286
- if ( $this->get_global_sitekey() && $this->get_global_secret() ) {
287
- return $this->get_global_sitekey();
288
- }
289
-
290
- if ( empty( $this->sitekeys )
291
- or ! is_array( $this->sitekeys ) ) {
292
- return false;
293
- }
294
-
295
- $sitekeys = array_keys( $this->sitekeys );
296
-
297
- return $sitekeys[0];
298
- }
299
-
300
- public function get_secret( $sitekey ) {
301
- if ( $this->get_global_sitekey() && $this->get_global_secret() ) {
302
- return $this->get_global_secret();
303
- }
304
-
305
- $sitekeys = (array) $this->sitekeys;
306
-
307
- if ( isset( $sitekeys[$sitekey] ) ) {
308
- return $sitekeys[$sitekey];
309
- } else {
310
- return false;
311
- }
312
- }
313
-
314
- protected function log( $url, $request, $response ) {
315
- wpcf7_log_remote_request( $url, $request, $response );
316
- }
317
-
318
- public function verify( $token ) {
319
- $is_human = false;
320
-
321
- if ( empty( $token ) or ! $this->is_active() ) {
322
- return $is_human;
323
- }
324
-
325
- $endpoint = 'https://www.google.com/recaptcha/api/siteverify';
326
-
327
- $sitekey = $this->get_sitekey();
328
- $secret = $this->get_secret( $sitekey );
329
-
330
- $request = array(
331
- 'body' => array(
332
- 'secret' => $secret,
333
- 'response' => $token,
334
- ),
335
- );
336
-
337
- $response = wp_remote_post( esc_url_raw( $endpoint ), $request );
338
-
339
- if ( 200 != wp_remote_retrieve_response_code( $response ) ) {
340
- if ( WP_DEBUG ) {
341
- $this->log( $endpoint, $request, $response );
342
- }
343
-
344
- return $is_human;
345
- }
346
-
347
- $response_body = wp_remote_retrieve_body( $response );
348
- $response_body = json_decode( $response_body, true );
349
-
350
- $this->last_score = $score = isset( $response_body['score'] )
351
- ? $response_body['score']
352
- : 0;
353
-
354
- $threshold = $this->get_threshold();
355
- $is_human = $threshold < $score;
356
-
357
- $is_human = apply_filters( 'wpcf7_recaptcha_verify_response',
358
- $is_human, $response_body );
359
-
360
- if ( $submission = WPCF7_Submission::get_instance() ) {
361
- $submission->recaptcha = array(
362
- 'version' => '3.0',
363
- 'threshold' => $threshold,
364
- 'response' => $response_body,
365
- );
366
- }
367
-
368
- return $is_human;
369
- }
370
-
371
- public function get_threshold() {
372
- return apply_filters( 'wpcf7_recaptcha_threshold', 0.50 );
373
- }
374
-
375
- public function get_last_score() {
376
- return $this->last_score;
377
- }
378
-
379
- protected function menu_page_url( $args = '' ) {
380
- $args = wp_parse_args( $args, array() );
381
-
382
- $url = menu_page_url( 'wpcf7-integration', false );
383
- $url = add_query_arg( array( 'service' => 'recaptcha' ), $url );
384
-
385
- if ( ! empty( $args ) ) {
386
- $url = add_query_arg( $args, $url );
387
- }
388
-
389
- return $url;
390
- }
391
-
392
- protected function save_data() {
393
- WPCF7::update_option( 'recaptcha', $this->sitekeys );
394
- }
395
-
396
- protected function reset_data() {
397
- $this->sitekeys = null;
398
- $this->save_data();
399
- }
400
-
401
- public function load( $action = '' ) {
402
- if ( 'setup' == $action and 'POST' == $_SERVER['REQUEST_METHOD'] ) {
403
- check_admin_referer( 'wpcf7-recaptcha-setup' );
404
-
405
- if ( ! empty( $_POST['reset'] ) ) {
406
- $this->reset_data();
407
- $redirect_to = $this->menu_page_url( 'action=setup' );
408
- } else {
409
- $sitekey = isset( $_POST['sitekey'] ) ? trim( $_POST['sitekey'] ) : '';
410
- $secret = isset( $_POST['secret'] ) ? trim( $_POST['secret'] ) : '';
411
-
412
- if ( $sitekey and $secret ) {
413
- $this->sitekeys = array( $sitekey => $secret );
414
- $this->save_data();
415
-
416
- $redirect_to = $this->menu_page_url( array(
417
- 'message' => 'success',
418
- ) );
419
- } else {
420
- $redirect_to = $this->menu_page_url( array(
421
- 'action' => 'setup',
422
- 'message' => 'invalid',
423
- ) );
424
- }
425
- }
426
-
427
- if ( WPCF7::get_option( 'recaptcha_v2_v3_warning' ) ) {
428
- WPCF7::update_option( 'recaptcha_v2_v3_warning', false );
429
- }
430
-
431
- wp_safe_redirect( $redirect_to );
432
- exit();
433
- }
434
- }
435
-
436
- public function admin_notice( $message = '' ) {
437
- if ( 'invalid' == $message ) {
438
- echo sprintf(
439
- '<div class="notice notice-error"><p><strong>%1$s</strong>: %2$s</p></div>',
440
- esc_html( __( "Error", 'contact-form-7' ) ),
441
- esc_html( __( "Invalid key values.", 'contact-form-7' ) ) );
442
- }
443
-
444
- if ( 'success' == $message ) {
445
- echo sprintf( '<div class="notice notice-success"><p>%s</p></div>',
446
- esc_html( __( 'Settings saved.', 'contact-form-7' ) ) );
447
- }
448
- }
449
-
450
- public function display( $action = '' ) {
451
- echo '<p>' . sprintf(
452
- esc_html( __( 'reCAPTCHA protects you against spam and other types of automated abuse. With Contact Form 7&#8217;s reCAPTCHA integration module, you can block abusive form submissions by spam bots. For details, see %s.', 'contact-form-7' ) ),
453
- wpcf7_link(
454
- __( 'https://contactform7.com/recaptcha/', 'contact-form-7' ),
455
- __( 'reCAPTCHA (v3)', 'contact-form-7' )
456
- )
457
- ) . '</p>';
458
-
459
- if ( $this->is_active() ) {
460
- echo sprintf(
461
- '<p class="dashicons-before dashicons-yes">%s</p>',
462
- esc_html( __( "reCAPTCHA is active on this site.", 'contact-form-7' ) )
463
- );
464
- }
465
-
466
- if ( 'setup' == $action ) {
467
- $this->display_setup();
468
- } else {
469
- echo sprintf(
470
- '<p><a href="%1$s" class="button">%2$s</a></p>',
471
- esc_url( $this->menu_page_url( 'action=setup' ) ),
472
- esc_html( __( 'Setup Integration', 'contact-form-7' ) )
473
- );
474
- }
475
- }
476
-
477
- private function display_setup() {
478
- $sitekey = $this->is_active() ? $this->get_sitekey() : '';
479
- $secret = $this->is_active() ? $this->get_secret( $sitekey ) : '';
480
-
481
- ?>
482
- <form method="post" action="<?php echo esc_url( $this->menu_page_url( 'action=setup' ) ); ?>">
483
- <?php wp_nonce_field( 'wpcf7-recaptcha-setup' ); ?>
484
- <table class="form-table">
485
- <tbody>
486
- <tr>
487
- <th scope="row"><label for="sitekey"><?php echo esc_html( __( 'Site Key', 'contact-form-7' ) ); ?></label></th>
488
- <td><?php
489
- if ( $this->is_active() ) {
490
- echo esc_html( $sitekey );
491
- echo sprintf(
492
- '<input type="hidden" value="%1$s" id="sitekey" name="sitekey" />',
493
- esc_attr( $sitekey )
494
- );
495
- } else {
496
- echo sprintf(
497
- '<input type="text" aria-required="true" value="%1$s" id="sitekey" name="sitekey" class="regular-text code" />',
498
- esc_attr( $sitekey )
499
- );
500
- }
501
- ?></td>
502
- </tr>
503
- <tr>
504
- <th scope="row"><label for="secret"><?php echo esc_html( __( 'Secret Key', 'contact-form-7' ) ); ?></label></th>
505
- <td><?php
506
- if ( $this->is_active() ) {
507
- echo esc_html( wpcf7_mask_password( $secret, 4, 4 ) );
508
- echo sprintf(
509
- '<input type="hidden" value="%1$s" id="secret" name="secret" />',
510
- esc_attr( $secret )
511
- );
512
- } else {
513
- echo sprintf(
514
- '<input type="text" aria-required="true" value="%1$s" id="secret" name="secret" class="regular-text code" />',
515
- esc_attr( $secret )
516
- );
517
- }
518
- ?></td>
519
- </tr>
520
- </tbody>
521
- </table>
522
- <?php
523
- if ( $this->is_active() ) {
524
- if ( $this->get_global_sitekey() && $this->get_global_secret() ) {
525
- // nothing
526
- } else {
527
- submit_button(
528
- _x( 'Remove Keys', 'API keys', 'contact-form-7' ),
529
- 'small', 'reset'
530
- );
531
- }
532
- } else {
533
- submit_button( __( 'Save Changes', 'contact-form-7' ) );
534
- }
535
- ?>
536
- </form>
537
- <?php
538
- }
539
- }
1
  <?php
2
+ /**
3
+ * reCAPTCHA module main file
4
+ *
5
+ * @link https://contactform7.com/recaptcha/
6
+ */
7
+
8
+ wpcf7_include_module_file( 'recaptcha/service.php' );
9
+
10
 
11
  add_action( 'wpcf7_init', 'wpcf7_recaptcha_register_service', 15, 0 );
12
 
13
+ /**
14
+ * Registers the reCAPTCHA service.
15
+ */
16
  function wpcf7_recaptcha_register_service() {
17
  $integration = WPCF7_Integration::get_instance();
18
 
21
  );
22
  }
23
 
 
24
 
25
+ add_action(
26
+ 'wp_enqueue_scripts',
27
+ 'wpcf7_recaptcha_enqueue_scripts',
28
+ 20, 0
29
+ );
30
+
31
+ /**
32
+ * Enqueues frontend scripts for reCAPTCHA.
33
+ */
34
  function wpcf7_recaptcha_enqueue_scripts() {
35
  $service = WPCF7_RECAPTCHA::get_instance();
36
 
95
  );
96
  }
97
 
98
+
99
+ add_filter(
100
+ 'wpcf7_form_hidden_fields',
101
+ 'wpcf7_recaptcha_add_hidden_fields',
102
+ 100, 1
103
  );
104
 
105
+ /**
106
+ * Adds hidden form field for reCAPTCHA.
107
+ */
108
  function wpcf7_recaptcha_add_hidden_fields( $fields ) {
109
  $service = WPCF7_RECAPTCHA::get_instance();
110
 
117
  ) );
118
  }
119
 
120
+
121
  add_filter( 'wpcf7_spam', 'wpcf7_recaptcha_verify_response', 9, 2 );
122
 
123
+ /**
124
+ * Verifies reCAPTCHA token on the server side.
125
+ */
126
  function wpcf7_recaptcha_verify_response( $spam, $submission ) {
127
  if ( $spam ) {
128
  return $spam;
145
  if ( '' === $token ) {
146
  $submission->add_spam_log( array(
147
  'agent' => 'recaptcha',
148
+ 'reason' => __(
149
+ 'reCAPTCHA response token is empty.',
150
+ 'contact-form-7'
151
+ ),
152
  ) );
153
  } else {
154
  $submission->add_spam_log( array(
155
  'agent' => 'recaptcha',
156
  'reason' => sprintf(
157
+ __(
158
+ 'reCAPTCHA score (%1$.2f) is lower than the threshold (%2$.2f).',
159
+ 'contact-form-7'
160
+ ),
161
  $service->get_last_score(),
162
  $service->get_threshold()
163
  ),
168
  return $spam;
169
  }
170
 
171
+
172
  add_action( 'wpcf7_init', 'wpcf7_recaptcha_add_form_tag_recaptcha', 10, 0 );
173
 
174
+ /**
175
+ * Registers form-tag types for reCAPTCHA.
176
+ */
177
  function wpcf7_recaptcha_add_form_tag_recaptcha() {
178
  $service = WPCF7_RECAPTCHA::get_instance();
179
 
187
  );
188
  }
189
 
190
+
191
  add_action( 'wpcf7_upgrade', 'wpcf7_upgrade_recaptcha_v2_v3', 10, 2 );
192
 
193
+ /**
194
+ * Adds warnings for users upgrading from reCAPTCHA v2 to v3.
195
+ */
196
  function wpcf7_upgrade_recaptcha_v2_v3( $new_ver, $old_ver ) {
197
  if ( version_compare( '5.1-dev', $old_ver, '<=' ) ) {
198
  return;
209
  WPCF7::update_option( 'recaptcha', null );
210
  }
211
 
212
+
213
  add_action( 'wpcf7_admin_menu', 'wpcf7_admin_init_recaptcha_v2_v3', 10, 0 );
214
 
215
+ /**
216
+ * Adds filters and actions for warnings.
217
+ */
218
  function wpcf7_admin_init_recaptcha_v2_v3() {
219
  if ( ! WPCF7::get_option( 'recaptcha_v2_v3_warning' ) ) {
220
  return;
221
  }
222
 
223
+ add_filter(
224
+ 'wpcf7_admin_menu_change_notice',
225
+ 'wpcf7_admin_menu_change_notice_recaptcha_v2_v3',
226
+ 10, 1
227
+ );
228
 
229
+ add_action(
230
+ 'wpcf7_admin_warnings',
231
+ 'wpcf7_admin_warnings_recaptcha_v2_v3',
232
+ 5, 3
233
+ );
234
  }
235
 
236
+
237
+ /**
238
+ * Increments the admin menu counter for the Integration page.
239
+ */
240
  function wpcf7_admin_menu_change_notice_recaptcha_v2_v3( $counts ) {
241
  $counts['wpcf7-integration'] += 1;
242
  return $counts;
243
  }
244
 
245
+
246
+ /**
247
+ * Prints warnings on the admin screen.
248
+ */
249
  function wpcf7_admin_warnings_recaptcha_v2_v3( $page, $action, $object ) {
250
  if ( 'wpcf7-integration' !== $page ) {
251
  return;
252
  }
253
 
254
  $message = sprintf(
255
+ esc_html( __(
256
+ "API keys for reCAPTCHA v3 are different from those for v2; keys for v2 don&#8217;t work with the v3 API. You need to register your sites again to get new keys for v3. For details, see %s.",
257
+ 'contact-form-7'
258
+ ) ),
259
  wpcf7_link(
260
  __( 'https://contactform7.com/recaptcha/', 'contact-form-7' ),
261
  __( 'reCAPTCHA (v3)', 'contact-form-7' )
267
  $message
268
  );
269
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/recaptcha/service.php ADDED
@@ -0,0 +1,357 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( ! class_exists( 'WPCF7_Service' ) ) {
4
+ return;
5
+ }
6
+
7
+ class WPCF7_RECAPTCHA extends WPCF7_Service {
8
+
9
+ private static $instance;
10
+ private $sitekeys;
11
+ private $last_score;
12
+
13
+
14
+ public static function get_instance() {
15
+ if ( empty( self::$instance ) ) {
16
+ self::$instance = new self;
17
+ }
18
+
19
+ return self::$instance;
20
+ }
21
+
22
+
23
+ private function __construct() {
24
+ $this->sitekeys = WPCF7::get_option( 'recaptcha' );
25
+ }
26
+
27
+
28
+ public function get_title() {
29
+ return __( 'reCAPTCHA', 'contact-form-7' );
30
+ }
31
+
32
+
33
+ public function is_active() {
34
+ $sitekey = $this->get_sitekey();
35
+ $secret = $this->get_secret( $sitekey );
36
+ return $sitekey && $secret;
37
+ }
38
+
39
+
40
+ public function get_categories() {
41
+ return array( 'spam_protection' );
42
+ }
43
+
44
+
45
+ public function icon() {
46
+ }
47
+
48
+
49
+ public function link() {
50
+ echo wpcf7_link(
51
+ 'https://www.google.com/recaptcha/intro/index.html',
52
+ 'google.com/recaptcha'
53
+ );
54
+ }
55
+
56
+
57
+ public function get_global_sitekey() {
58
+ static $sitekey = '';
59
+
60
+ if ( $sitekey ) {
61
+ return $sitekey;
62
+ }
63
+
64
+ if ( defined( 'WPCF7_RECAPTCHA_SITEKEY' ) ) {
65
+ $sitekey = WPCF7_RECAPTCHA_SITEKEY;
66
+ }
67
+
68
+ $sitekey = apply_filters( 'wpcf7_recaptcha_sitekey', $sitekey );
69
+
70
+ return $sitekey;
71
+ }
72
+
73
+
74
+ public function get_global_secret() {
75
+ static $secret = '';
76
+
77
+ if ( $secret ) {
78
+ return $secret;
79
+ }
80
+
81
+ if ( defined( 'WPCF7_RECAPTCHA_SECRET' ) ) {
82
+ $secret = WPCF7_RECAPTCHA_SECRET;
83
+ }
84
+
85
+ $secret = apply_filters( 'wpcf7_recaptcha_secret', $secret );
86
+
87
+ return $secret;
88
+ }
89
+
90
+
91
+ public function get_sitekey() {
92
+ if ( $this->get_global_sitekey() and $this->get_global_secret() ) {
93
+ return $this->get_global_sitekey();
94
+ }
95
+
96
+ if ( empty( $this->sitekeys )
97
+ or ! is_array( $this->sitekeys ) ) {
98
+ return false;
99
+ }
100
+
101
+ $sitekeys = array_keys( $this->sitekeys );
102
+
103
+ return $sitekeys[0];
104
+ }
105
+
106
+
107
+ public function get_secret( $sitekey ) {
108
+ if ( $this->get_global_sitekey() and $this->get_global_secret() ) {
109
+ return $this->get_global_secret();
110
+ }
111
+
112
+ $sitekeys = (array) $this->sitekeys;
113
+
114
+ if ( isset( $sitekeys[$sitekey] ) ) {
115
+ return $sitekeys[$sitekey];
116
+ } else {
117
+ return false;
118
+ }
119
+ }
120
+
121
+
122
+ protected function log( $url, $request, $response ) {
123
+ wpcf7_log_remote_request( $url, $request, $response );
124
+ }
125
+
126
+
127
+ public function verify( $token ) {
128
+ $is_human = false;
129
+
130
+ if ( empty( $token ) or ! $this->is_active() ) {
131
+ return $is_human;
132
+ }
133
+
134
+ $endpoint = 'https://www.google.com/recaptcha/api/siteverify';
135
+
136
+ $sitekey = $this->get_sitekey();
137
+ $secret = $this->get_secret( $sitekey );
138
+
139
+ $request = array(
140
+ 'body' => array(
141
+ 'secret' => $secret,
142
+ 'response' => $token,
143
+ ),
144
+ );
145
+
146
+ $response = wp_remote_post( esc_url_raw( $endpoint ), $request );
147
+
148
+ if ( 200 != wp_remote_retrieve_response_code( $response ) ) {
149
+ if ( WP_DEBUG ) {
150
+ $this->log( $endpoint, $request, $response );
151
+ }
152
+
153
+ return $is_human;
154
+ }
155
+
156
+ $response_body = wp_remote_retrieve_body( $response );
157
+ $response_body = json_decode( $response_body, true );
158
+
159
+ $this->last_score = $score = isset( $response_body['score'] )
160
+ ? $response_body['score']
161
+ : 0;
162
+
163
+ $threshold = $this->get_threshold();
164
+ $is_human = $threshold < $score;
165
+
166
+ $is_human = apply_filters( 'wpcf7_recaptcha_verify_response',
167
+ $is_human, $response_body );
168
+
169
+ if ( $submission = WPCF7_Submission::get_instance() ) {
170
+ $submission->recaptcha = array(
171
+ 'version' => '3.0',
172
+ 'threshold' => $threshold,
173
+ 'response' => $response_body,
174
+ );
175
+ }
176
+
177
+ return $is_human;
178
+ }
179
+
180
+
181
+ public function get_threshold() {
182
+ return apply_filters( 'wpcf7_recaptcha_threshold', 0.50 );
183
+ }
184
+
185
+
186
+ public function get_last_score() {
187
+ return $this->last_score;
188
+ }
189
+
190
+
191
+ protected function menu_page_url( $args = '' ) {
192
+ $args = wp_parse_args( $args, array() );
193
+
194
+ $url = menu_page_url( 'wpcf7-integration', false );
195
+ $url = add_query_arg( array( 'service' => 'recaptcha' ), $url );
196
+
197
+ if ( ! empty( $args ) ) {
198
+ $url = add_query_arg( $args, $url );
199
+ }
200
+
201
+ return $url;
202
+ }
203
+
204
+
205
+ protected function save_data() {
206
+ WPCF7::update_option( 'recaptcha', $this->sitekeys );
207
+ }
208
+
209
+
210
+ protected function reset_data() {
211
+ $this->sitekeys = null;
212
+ $this->save_data();
213
+ }
214
+
215
+
216
+ public function load( $action = '' ) {
217
+ if ( 'setup' == $action and 'POST' == $_SERVER['REQUEST_METHOD'] ) {
218
+ check_admin_referer( 'wpcf7-recaptcha-setup' );
219
+
220
+ if ( ! empty( $_POST['reset'] ) ) {
221
+ $this->reset_data();
222
+ $redirect_to = $this->menu_page_url( 'action=setup' );
223
+ } else {
224
+ $sitekey = isset( $_POST['sitekey'] ) ? trim( $_POST['sitekey'] ) : '';
225
+ $secret = isset( $_POST['secret'] ) ? trim( $_POST['secret'] ) : '';
226
+
227
+ if ( $sitekey and $secret ) {
228
+ $this->sitekeys = array( $sitekey => $secret );
229
+ $this->save_data();
230
+
231
+ $redirect_to = $this->menu_page_url( array(
232
+ 'message' => 'success',
233
+ ) );
234
+ } else {
235
+ $redirect_to = $this->menu_page_url( array(
236
+ 'action' => 'setup',
237
+ 'message' => 'invalid',
238
+ ) );
239
+ }
240
+ }
241
+
242
+ if ( WPCF7::get_option( 'recaptcha_v2_v3_warning' ) ) {
243
+ WPCF7::update_option( 'recaptcha_v2_v3_warning', false );
244
+ }
245
+
246
+ wp_safe_redirect( $redirect_to );
247
+ exit();
248
+ }
249
+ }
250
+
251
+
252
+ public function admin_notice( $message = '' ) {
253
+ if ( 'invalid' == $message ) {
254
+ echo sprintf(
255
+ '<div class="notice notice-error"><p><strong>%1$s</strong>: %2$s</p></div>',
256
+ esc_html( __( "Error", 'contact-form-7' ) ),
257
+ esc_html( __( "Invalid key values.", 'contact-form-7' ) ) );
258
+ }
259
+
260
+ if ( 'success' == $message ) {
261
+ echo sprintf( '<div class="notice notice-success"><p>%s</p></div>',
262
+ esc_html( __( 'Settings saved.', 'contact-form-7' ) ) );
263
+ }
264
+ }
265
+
266
+
267
+ public function display( $action = '' ) {
268
+ echo '<p>' . sprintf(
269
+ esc_html( __( 'reCAPTCHA protects you against spam and other types of automated abuse. With Contact Form 7&#8217;s reCAPTCHA integration module, you can block abusive form submissions by spam bots. For details, see %s.', 'contact-form-7' ) ),
270
+ wpcf7_link(
271
+ __( 'https://contactform7.com/recaptcha/', 'contact-form-7' ),
272
+ __( 'reCAPTCHA (v3)', 'contact-form-7' )
273
+ )
274
+ ) . '</p>';
275
+
276
+ if ( $this->is_active() ) {
277
+ echo sprintf(
278
+ '<p class="dashicons-before dashicons-yes">%s</p>',
279
+ esc_html( __( "reCAPTCHA is active on this site.", 'contact-form-7' ) )
280
+ );
281
+ }
282
+
283
+ if ( 'setup' == $action ) {
284
+ $this->display_setup();
285
+ } else {
286
+ echo sprintf(
287
+ '<p><a href="%1$s" class="button">%2$s</a></p>',
288
+ esc_url( $this->menu_page_url( 'action=setup' ) ),
289
+ esc_html( __( 'Setup Integration', 'contact-form-7' ) )
290
+ );
291
+ }
292
+ }
293
+
294
+
295
+ private function display_setup() {
296
+ $sitekey = $this->is_active() ? $this->get_sitekey() : '';
297
+ $secret = $this->is_active() ? $this->get_secret( $sitekey ) : '';
298
+
299
+ ?>
300
+ <form method="post" action="<?php echo esc_url( $this->menu_page_url( 'action=setup' ) ); ?>">
301
+ <?php wp_nonce_field( 'wpcf7-recaptcha-setup' ); ?>
302
+ <table class="form-table">
303
+ <tbody>
304
+ <tr>
305
+ <th scope="row"><label for="sitekey"><?php echo esc_html( __( 'Site Key', 'contact-form-7' ) ); ?></label></th>
306
+ <td><?php
307
+ if ( $this->is_active() ) {
308
+ echo esc_html( $sitekey );
309
+ echo sprintf(
310
+ '<input type="hidden" value="%1$s" id="sitekey" name="sitekey" />',
311
+ esc_attr( $sitekey )
312
+ );
313
+ } else {
314
+ echo sprintf(
315
+ '<input type="text" aria-required="true" value="%1$s" id="sitekey" name="sitekey" class="regular-text code" />',
316
+ esc_attr( $sitekey )
317
+ );
318
+ }
319
+ ?></td>
320
+ </tr>
321
+ <tr>
322
+ <th scope="row"><label for="secret"><?php echo esc_html( __( 'Secret Key', 'contact-form-7' ) ); ?></label></th>
323
+ <td><?php
324
+ if ( $this->is_active() ) {
325
+ echo esc_html( wpcf7_mask_password( $secret, 4, 4 ) );
326
+ echo sprintf(
327
+ '<input type="hidden" value="%1$s" id="secret" name="secret" />',
328
+ esc_attr( $secret )
329
+ );
330
+ } else {
331
+ echo sprintf(
332
+ '<input type="text" aria-required="true" value="%1$s" id="secret" name="secret" class="regular-text code" />',
333
+ esc_attr( $secret )
334
+ );
335
+ }
336
+ ?></td>
337
+ </tr>
338
+ </tbody>
339
+ </table>
340
+ <?php
341
+ if ( $this->is_active() ) {
342
+ if ( $this->get_global_sitekey() and $this->get_global_secret() ) {
343
+ // nothing
344
+ } else {
345
+ submit_button(
346
+ _x( 'Remove Keys', 'API keys', 'contact-form-7' ),
347
+ 'small', 'reset'
348
+ );
349
+ }
350
+ } else {
351
+ submit_button( __( 'Save Changes', 'contact-form-7' ) );
352
+ }
353
+ ?>
354
+ </form>
355
+ <?php
356
+ }
357
+ }
modules/sendinblue/sendinblue.php CHANGED
@@ -1,4 +1,9 @@
1
  <?php
 
 
 
 
 
2
 
3
  wpcf7_include_module_file( 'sendinblue/service.php' );
4
  wpcf7_include_module_file( 'sendinblue/contact-form-properties.php' );
@@ -7,6 +12,9 @@ wpcf7_include_module_file( 'sendinblue/doi.php' );
7
 
8
  add_action( 'wpcf7_init', 'wpcf7_sendinblue_register_service', 1, 0 );
9
 
 
 
 
10
  function wpcf7_sendinblue_register_service() {
11
  $integration = WPCF7_Integration::get_instance();
12
 
@@ -18,6 +26,10 @@ function wpcf7_sendinblue_register_service() {
18
 
19
  add_action( 'wpcf7_submit', 'wpcf7_sendinblue_submit', 10, 2 );
20
 
 
 
 
 
21
  function wpcf7_sendinblue_submit( $contact_form, $result ) {
22
  if ( $contact_form->in_demo_mode() ) {
23
  return;
@@ -150,6 +162,11 @@ function wpcf7_sendinblue_submit( $contact_form, $result ) {
150
  }
151
 
152
 
 
 
 
 
 
153
  function wpcf7_sendinblue_collect_parameters() {
154
  $params = array();
155
 
1
  <?php
2
+ /**
3
+ * Sendinblue module main file
4
+ *
5
+ * @link https://contactform7.com/sendinblue-integration/
6
+ */
7
 
8
  wpcf7_include_module_file( 'sendinblue/service.php' );
9
  wpcf7_include_module_file( 'sendinblue/contact-form-properties.php' );
12
 
13
  add_action( 'wpcf7_init', 'wpcf7_sendinblue_register_service', 1, 0 );
14
 
15
+ /**
16
+ * Registers the Sendinblue service.
17
+ */
18
  function wpcf7_sendinblue_register_service() {
19
  $integration = WPCF7_Integration::get_instance();
20
 
26
 
27
  add_action( 'wpcf7_submit', 'wpcf7_sendinblue_submit', 10, 2 );
28
 
29
+ /**
30
+ * Callback to the wpcf7_submit action hook. Creates a contact
31
+ * based on the submission.
32
+ */
33
  function wpcf7_sendinblue_submit( $contact_form, $result ) {
34
  if ( $contact_form->in_demo_mode() ) {
35
  return;
162
  }
163
 
164
 
165
+ /**
166
+ * Collects parameters for Sendinblue contact data based on submission.
167
+ *
168
+ * @return array Sendinblue contact parameters.
169
+ */
170
  function wpcf7_sendinblue_collect_parameters() {
171
  $params = array();
172
 
modules/stripe/stripe.php CHANGED
@@ -1,4 +1,9 @@
1
  <?php
 
 
 
 
 
2
 
3
  wpcf7_include_module_file( 'stripe/service.php' );
4
  wpcf7_include_module_file( 'stripe/api.php' );
1
  <?php
2
+ /**
3
+ * Stripe module main file
4
+ *
5
+ * @link https://contactform7.com/stripe-integration/
6
+ */
7
 
8
  wpcf7_include_module_file( 'stripe/service.php' );
9
  wpcf7_include_module_file( 'stripe/api.php' );
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: 5.7
6
  Tested up to: 5.9
7
- Stable tag: 5.5.5
8
  License: GPLv2 or later
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -77,6 +77,10 @@ Do you have questions or issues with Contact Form 7? Use these support channels
77
 
78
  For more information, see [Releases](https://contactform7.com/category/releases/).
79
 
 
 
 
 
80
  = 5.5.5 =
81
 
82
  [https://contactform7.com/contact-form-7-555/](https://contactform7.com/contact-form-7-555/)
4
  Tags: contact, form, contact form, feedback, email, ajax, captcha, akismet, multilingual
5
  Requires at least: 5.7
6
  Tested up to: 5.9
7
+ Stable tag: 5.5.6
8
  License: GPLv2 or later
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
10
 
77
 
78
  For more information, see [Releases](https://contactform7.com/category/releases/).
79
 
80
+ = 5.5.6 =
81
+
82
+ [https://contactform7.com/contact-form-7-556/](https://contactform7.com/contact-form-7-556/)
83
+
84
  = 5.5.5 =
85
 
86
  [https://contactform7.com/contact-form-7-555/](https://contactform7.com/contact-form-7-555/)
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: 5.5.5
11
  */
12
 
13
- define( 'WPCF7_VERSION', '5.5.5' );
14
 
15
  define( 'WPCF7_REQUIRED_WP_VERSION', '5.7' );
16
 
7
  Author URI: https://ideasilo.wordpress.com/
8
  Text Domain: contact-form-7
9
  Domain Path: /languages/
10
+ Version: 5.5.6
11
  */
12
 
13
+ define( 'WPCF7_VERSION', '5.5.6' );
14
 
15
  define( 'WPCF7_REQUIRED_WP_VERSION', '5.7' );
16