Contact Form 7 - Version 5.1.2

Version Description

  • Constant Contact: Introduces the contact list selector.
  • Constant Contact: Introduces the constant_contact additional setting.
  • reCAPTCHA: Introduces the wpcf7_recaptcha_actions and wpcf7_recaptcha_threshold filter hooks.
Download this release

Release Info

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

Code changes from version 5.1.1 to 5.1.2

admin/admin.php CHANGED
@@ -210,12 +210,10 @@ function wpcf7_load_contact_form_admin() {
210
  ? $_POST['wpcf7-form'] : '';
211
 
212
  $args['mail'] = isset( $_POST['wpcf7-mail'] )
213
- ? wpcf7_sanitize_mail( $_POST['wpcf7-mail'] )
214
- : array();
215
 
216
  $args['mail_2'] = isset( $_POST['wpcf7-mail-2'] )
217
- ? wpcf7_sanitize_mail( $_POST['wpcf7-mail-2'] )
218
- : array();
219
 
220
  $args['messages'] = isset( $_POST['wpcf7-messages'] )
221
  ? $_POST['wpcf7-messages'] : array();
@@ -322,8 +320,6 @@ function wpcf7_load_contact_form_admin() {
322
  exit();
323
  }
324
 
325
- $_GET['post'] = isset( $_GET['post'] ) ? $_GET['post'] : '';
326
-
327
  $post = null;
328
 
329
  if ( 'wpcf7-new' == $plugin_page ) {
@@ -491,6 +487,10 @@ function wpcf7_admin_integration_page() {
491
  add_action( 'wpcf7_admin_notices', 'wpcf7_admin_updated_message', 10, 3 );
492
 
493
  function wpcf7_admin_updated_message( $page, $action, $object ) {
 
 
 
 
494
  if ( empty( $_REQUEST['message'] ) ) {
495
  return;
496
  }
210
  ? $_POST['wpcf7-form'] : '';
211
 
212
  $args['mail'] = isset( $_POST['wpcf7-mail'] )
213
+ ? $_POST['wpcf7-mail'] : array();
 
214
 
215
  $args['mail_2'] = isset( $_POST['wpcf7-mail-2'] )
216
+ ? $_POST['wpcf7-mail-2'] : array();
 
217
 
218
  $args['messages'] = isset( $_POST['wpcf7-messages'] )
219
  ? $_POST['wpcf7-messages'] : array();
320
  exit();
321
  }
322
 
 
 
323
  $post = null;
324
 
325
  if ( 'wpcf7-new' == $plugin_page ) {
487
  add_action( 'wpcf7_admin_notices', 'wpcf7_admin_updated_message', 10, 3 );
488
 
489
  function wpcf7_admin_updated_message( $page, $action, $object ) {
490
+ if ( ! in_array( $page, array( 'wpcf7', 'wpcf7-new' ) ) ) {
491
+ return;
492
+ }
493
+
494
  if ( empty( $_REQUEST['message'] ) ) {
495
  return;
496
  }
admin/css/styles.css CHANGED
@@ -433,3 +433,7 @@ ul.config-error li {
433
  .card .inside .form-table td {
434
  padding: 10px 10px;
435
  }
 
 
 
 
433
  .card .inside .form-table td {
434
  padding: 10px 10px;
435
  }
436
+
437
+ .card .checkboxes li {
438
+ margin: 0;
439
+ }
includes/config-validator.php CHANGED
@@ -175,6 +175,10 @@ class WPCF7_ConfigValidator {
175
  unset( $this->errors[$section][$key] );
176
  }
177
  }
 
 
 
 
178
  }
179
 
180
  public function validate() {
175
  unset( $this->errors[$section][$key] );
176
  }
177
  }
178
+
179
+ if ( empty( $this->errors[$section] ) ) {
180
+ unset( $this->errors[$section] );
181
+ }
182
  }
183
 
184
  public function validate() {
includes/contact-form-functions.php CHANGED
@@ -143,6 +143,8 @@ function wpcf7_save_contact_form( $args = '', $context = 'save' ) {
143
  'additional_settings' => null,
144
  ) );
145
 
 
 
146
  $args['id'] = (int) $args['id'];
147
 
148
  if ( -1 == $args['id'] ) {
143
  'additional_settings' => null,
144
  ) );
145
 
146
+ $args = wp_unslash( $args );
147
+
148
  $args['id'] = (int) $args['id'];
149
 
150
  if ( -1 == $args['id'] ) {
includes/functions.php CHANGED
@@ -380,10 +380,11 @@ function wpcf7_deprecated_function( $function, $version, $replacement ) {
380
 
381
  function wpcf7_log_remote_request( $url, $request, $response ) {
382
  $log = sprintf(
383
- /* translators: 1: response code, 2: response message, 3: URL */
384
- __( 'HTTP Response: %1$s %2$s from %3$s', 'contact-form-7' ),
385
  (int) wp_remote_retrieve_response_code( $response ),
386
  wp_remote_retrieve_response_message( $response ),
 
387
  $url
388
  );
389
 
380
 
381
  function wpcf7_log_remote_request( $url, $request, $response ) {
382
  $log = sprintf(
383
+ /* translators: 1: response code, 2: message, 3: body, 4: URL */
384
+ __( 'HTTP Response: %1$s %2$s %3$s from %4$s', 'contact-form-7' ),
385
  (int) wp_remote_retrieve_response_code( $response ),
386
  wp_remote_retrieve_response_message( $response ),
387
+ wp_remote_retrieve_body( $response ),
388
  $url
389
  );
390
 
includes/integration.php CHANGED
@@ -150,7 +150,7 @@ class WPCF7_Service_OAuth2 extends WPCF7_Service {
150
  }
151
 
152
  public function is_active() {
153
- return ! empty( $this->access_token );
154
  }
155
 
156
  protected function save_data() {
@@ -175,7 +175,19 @@ class WPCF7_Service_OAuth2 extends WPCF7_Service {
175
  $this->request_token( $code );
176
  }
177
 
178
- wp_safe_redirect( $this->menu_page_url( 'action=setup' ) );
 
 
 
 
 
 
 
 
 
 
 
 
179
  exit();
180
  }
181
  }
@@ -227,26 +239,31 @@ class WPCF7_Service_OAuth2 extends WPCF7_Service {
227
  );
228
 
229
  $response = wp_remote_post( esc_url_raw( $endpoint ), $request );
 
 
 
230
 
231
- if ( WP_DEBUG
232
- and 400 <= (int) wp_remote_retrieve_response_code( $response ) ) {
233
  $this->log( $endpoint, $request, $response );
234
  }
235
 
236
- $response_body = wp_remote_retrieve_body( $response );
 
 
 
 
 
 
 
 
237
 
238
- if ( empty( $response_body ) ) {
239
- return $response;
 
 
 
240
  }
241
 
242
- $response_body = json_decode( $response_body, true );
243
-
244
- $this->access_token = isset( $response_body['access_token'] )
245
- ? $response_body['access_token'] : null;
246
-
247
- $this->refresh_token = isset( $response_body['refresh_token'] )
248
- ? $response_body['refresh_token'] : null;
249
-
250
  $this->save_data();
251
 
252
  return $response;
@@ -268,47 +285,54 @@ class WPCF7_Service_OAuth2 extends WPCF7_Service {
268
  );
269
 
270
  $response = wp_remote_post( esc_url_raw( $endpoint ), $request );
 
 
 
271
 
272
- if ( WP_DEBUG
273
- and 400 <= (int) wp_remote_retrieve_response_code( $response ) ) {
274
  $this->log( $endpoint, $request, $response );
275
  }
276
 
277
- $response_body = wp_remote_retrieve_body( $response );
 
 
 
 
 
 
 
 
278
 
279
- if ( empty( $response_body ) ) {
280
- return $response;
 
281
  }
282
 
283
- $response_body = json_decode( $response_body, true );
284
-
285
- $this->access_token = isset( $response_body['access_token'] )
286
- ? $response_body['access_token'] : null;
287
-
288
- $this->refresh_token = isset( $response_body['refresh_token'] )
289
- ? $response_body['refresh_token'] : null;
290
-
291
  $this->save_data();
292
 
293
  return $response;
294
  }
295
 
296
- protected function remote_request( $url, $args = array() ) {
297
- $request = $args = wp_parse_args( $args, array(
298
- 'refresh_token' => true,
299
- ) );
300
 
301
- unset( $request['refresh_token'] );
 
 
 
 
 
 
 
302
 
303
  $response = wp_remote_request( esc_url_raw( $url ), $request );
304
 
305
  if ( 401 === wp_remote_retrieve_response_code( $response )
306
- and $args['refresh_token'] ) {
307
  $this->refresh_token();
 
308
 
309
- $response = $this->remote_request( $url,
310
- array_merge( $args, array( 'refresh_token' => false ) )
311
- );
312
  }
313
 
314
  return $response;
150
  }
151
 
152
  public function is_active() {
153
+ return ! empty( $this->refresh_token );
154
  }
155
 
156
  protected function save_data() {
175
  $this->request_token( $code );
176
  }
177
 
178
+ if ( ! empty( $this->access_token ) ) {
179
+ $message = 'success';
180
+ } else {
181
+ $message = 'failed';
182
+ }
183
+
184
+ wp_safe_redirect( $this->menu_page_url(
185
+ array(
186
+ 'action' => 'setup',
187
+ 'message' => $message,
188
+ )
189
+ ) );
190
+
191
  exit();
192
  }
193
  }
239
  );
240
 
241
  $response = wp_remote_post( esc_url_raw( $endpoint ), $request );
242
+ $response_code = (int) wp_remote_retrieve_response_code( $response );
243
+ $response_body = wp_remote_retrieve_body( $response );
244
+ $response_body = json_decode( $response_body, true );
245
 
246
+ if ( WP_DEBUG and 400 <= $response_code ) {
 
247
  $this->log( $endpoint, $request, $response );
248
  }
249
 
250
+ if ( 401 == $response_code ) { // Unauthorized
251
+ $this->access_token = null;
252
+ $this->refresh_token = null;
253
+ } else {
254
+ if ( isset( $response_body['access_token'] ) ) {
255
+ $this->access_token = $response_body['access_token'];
256
+ } else {
257
+ $this->access_token = null;
258
+ }
259
 
260
+ if ( isset( $response_body['refresh_token'] ) ) {
261
+ $this->refresh_token = $response_body['refresh_token'];
262
+ } else {
263
+ $this->refresh_token = null;
264
+ }
265
  }
266
 
 
 
 
 
 
 
 
 
267
  $this->save_data();
268
 
269
  return $response;
285
  );
286
 
287
  $response = wp_remote_post( esc_url_raw( $endpoint ), $request );
288
+ $response_code = (int) wp_remote_retrieve_response_code( $response );
289
+ $response_body = wp_remote_retrieve_body( $response );
290
+ $response_body = json_decode( $response_body, true );
291
 
292
+ if ( WP_DEBUG and 400 <= $response_code ) {
 
293
  $this->log( $endpoint, $request, $response );
294
  }
295
 
296
+ if ( 401 == $response_code ) { // Unauthorized
297
+ $this->access_token = null;
298
+ $this->refresh_token = null;
299
+ } else {
300
+ if ( isset( $response_body['access_token'] ) ) {
301
+ $this->access_token = $response_body['access_token'];
302
+ } else {
303
+ $this->access_token = null;
304
+ }
305
 
306
+ if ( isset( $response_body['refresh_token'] ) ) {
307
+ $this->refresh_token = $response_body['refresh_token'];
308
+ }
309
  }
310
 
 
 
 
 
 
 
 
 
311
  $this->save_data();
312
 
313
  return $response;
314
  }
315
 
316
+ protected function remote_request( $url, $request = array() ) {
317
+ static $refreshed = false;
 
 
318
 
319
+ $request = wp_parse_args( $request, array() );
320
+
321
+ $request['headers'] = array_merge(
322
+ $request['headers'],
323
+ array(
324
+ 'Authorization' => $this->get_http_authorization_header( 'bearer' ),
325
+ )
326
+ );
327
 
328
  $response = wp_remote_request( esc_url_raw( $url ), $request );
329
 
330
  if ( 401 === wp_remote_retrieve_response_code( $response )
331
+ and ! $refreshed ) {
332
  $this->refresh_token();
333
+ $refreshed = true;
334
 
335
+ $response = $this->remote_request( $url, $request );
 
 
336
  }
337
 
338
  return $response;
includes/mail.php CHANGED
@@ -213,7 +213,7 @@ function wpcf7_mail_replace_tags( $content, $args = '' ) {
213
  $replaced_tags = $line->get_replaced_tags();
214
 
215
  if ( empty( $replaced_tags )
216
- or array_filter( $replaced_tags ) ) {
217
  $content[$num] = $replaced;
218
  } else {
219
  unset( $content[$num] ); // Remove a line.
213
  $replaced_tags = $line->get_replaced_tags();
214
 
215
  if ( empty( $replaced_tags )
216
+ or array_filter( $replaced_tags, 'strlen' ) ) {
217
  $content[$num] = $replaced;
218
  } else {
219
  unset( $content[$num] ); // Remove a line.
includes/submission.php CHANGED
@@ -13,6 +13,7 @@ class WPCF7_Submission {
13
  private $invalid_fields = array();
14
  private $meta = array();
15
  private $consent = array();
 
16
 
17
  private function __construct() {}
18
 
@@ -301,19 +302,47 @@ class WPCF7_Submission {
301
 
302
  if ( strlen( $user_agent ) < 2 ) {
303
  $spam = true;
 
 
 
 
 
304
  }
305
 
306
  if ( ! $this->verify_nonce() ) {
307
  $spam = true;
 
 
 
 
 
308
  }
309
 
310
  if ( $this->is_blacklisted() ) {
311
  $spam = true;
 
 
 
 
 
312
  }
313
 
314
  return apply_filters( 'wpcf7_spam', $spam );
315
  }
316
 
 
 
 
 
 
 
 
 
 
 
 
 
 
317
  private function verify_nonce() {
318
  if ( ! $this->contact_form->nonce_is_active() ) {
319
  return true;
13
  private $invalid_fields = array();
14
  private $meta = array();
15
  private $consent = array();
16
+ private $spam_log = array();
17
 
18
  private function __construct() {}
19
 
302
 
303
  if ( strlen( $user_agent ) < 2 ) {
304
  $spam = true;
305
+
306
+ $this->add_spam_log( array(
307
+ 'agent' => 'wpcf7',
308
+ 'reason' => __( "User-Agent string is unnaturally short.", 'contact-form-7' ),
309
+ ) );
310
  }
311
 
312
  if ( ! $this->verify_nonce() ) {
313
  $spam = true;
314
+
315
+ $this->add_spam_log( array(
316
+ 'agent' => 'wpcf7',
317
+ 'reason' => __( "Submitted nonce is invalid.", 'contact-form-7' ),
318
+ ) );
319
  }
320
 
321
  if ( $this->is_blacklisted() ) {
322
  $spam = true;
323
+
324
+ $this->add_spam_log( array(
325
+ 'agent' => 'wpcf7',
326
+ 'reason' => __( "Blacklisted words are used.", 'contact-form-7' ),
327
+ ) );
328
  }
329
 
330
  return apply_filters( 'wpcf7_spam', $spam );
331
  }
332
 
333
+ public function add_spam_log( $args = '' ) {
334
+ $args = wp_parse_args( $args, array(
335
+ 'agent' => '',
336
+ 'reason' => '',
337
+ ) );
338
+
339
+ $this->spam_log[] = $args;
340
+ }
341
+
342
+ public function get_spam_log() {
343
+ return $this->spam_log;
344
+ }
345
+
346
  private function verify_nonce() {
347
  if ( ! $this->contact_form->nonce_is_active() ) {
348
  return true;
license.txt CHANGED
@@ -1,4 +1,4 @@
1
- Contact Form 7 WordPress Plugin, 2007-2018 Takayuki Miyoshi
2
  Contact Form 7 is distributed under the terms of the GNU GPL
3
 
4
  This program is free software; you can redistribute it and/or modify
1
+ Contact Form 7 WordPress Plugin, 2007-2019 Takayuki Miyoshi
2
  Contact Form 7 is distributed under the terms of the GNU GPL
3
 
4
  This program is free software; you can redistribute it and/or modify
modules/akismet.php CHANGED
@@ -48,7 +48,20 @@ function wpcf7_akismet( $spam ) {
48
  }
49
  }
50
 
51
- return wpcf7_akismet_comment_check( $c );
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  }
53
 
54
  function wpcf7_akismet_is_available() {
48
  }
49
  }
50
 
51
+ if ( wpcf7_akismet_comment_check( $c ) ) {
52
+ $spam = true;
53
+
54
+ $submission = WPCF7_Submission::get_instance();
55
+
56
+ $submission->add_spam_log( array(
57
+ 'agent' => 'akismet',
58
+ 'reason' => __( "Akismet returns a spam response.", 'contact-form-7' ),
59
+ ) );
60
+ } else {
61
+ $spam = false;
62
+ }
63
+
64
+ return $spam;
65
  }
66
 
67
  function wpcf7_akismet_is_available() {
modules/constant-contact.php CHANGED
@@ -12,6 +12,50 @@ function wpcf7_constant_contact_register_service() {
12
  $integration->add_service( 'constant_contact', $service );
13
  }
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  add_action( 'wpcf7_submit', 'wpcf7_constant_contact_submit', 10, 2 );
16
 
17
  function wpcf7_constant_contact_submit( $contact_form, $result ) {
@@ -32,6 +76,18 @@ function wpcf7_constant_contact_submit( $contact_form, $result ) {
32
  $do_submit = false;
33
  }
34
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  $do_submit = apply_filters( 'wpcf7_constant_contact_submit',
36
  $do_submit, $contact_form, $result );
37
 
@@ -90,6 +146,7 @@ class WPCF7_ConstantContact extends WPCF7_Service_OAuth2 {
90
  const token_endpoint = 'https://idfed.constantcontact.com/as/token.oauth2';
91
 
92
  private static $instance;
 
93
 
94
  public static function get_instance() {
95
  if ( empty( self::$instance ) ) {
@@ -121,6 +178,12 @@ class WPCF7_ConstantContact extends WPCF7_Service_OAuth2 {
121
  $this->refresh_token = $option['refresh_token'];
122
  }
123
 
 
 
 
 
 
 
124
  add_action( 'wpcf7_admin_init', array( $this, 'auth_redirect' ) );
125
  }
126
 
@@ -152,6 +215,7 @@ class WPCF7_ConstantContact extends WPCF7_Service_OAuth2 {
152
  'client_secret' => $this->client_secret,
153
  'access_token' => $this->access_token,
154
  'refresh_token' => $this->refresh_token,
 
155
  )
156
  );
157
 
@@ -163,6 +227,7 @@ class WPCF7_ConstantContact extends WPCF7_Service_OAuth2 {
163
  $this->client_secret = '';
164
  $this->access_token = '';
165
  $this->refresh_token = '';
 
166
 
167
  $this->save_data();
168
  }
@@ -224,6 +289,29 @@ class WPCF7_ConstantContact extends WPCF7_Service_OAuth2 {
224
  wp_safe_redirect( $this->menu_page_url( 'action=setup' ) );
225
  exit();
226
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
  }
228
 
229
  public function email_exists( $email ) {
@@ -237,15 +325,17 @@ class WPCF7_ConstantContact extends WPCF7_Service_OAuth2 {
237
  'headers' => array(
238
  'Accept' => 'application/json',
239
  'Content-Type' => 'application/json; charset=utf-8',
240
- 'Authorization' => $this->get_http_authorization_header( 'bearer' ),
241
  ),
242
  );
243
 
244
- $response = $this->remote_request( esc_url_raw( $endpoint ), $request );
 
 
 
 
 
245
 
246
- if ( WP_DEBUG
247
- and 400 <= (int) wp_remote_retrieve_response_code( $response ) ) {
248
- $this->log( $endpoint, $request, $response );
249
  }
250
 
251
  $response_body = wp_remote_retrieve_body( $response );
@@ -267,16 +357,122 @@ class WPCF7_ConstantContact extends WPCF7_Service_OAuth2 {
267
  'headers' => array(
268
  'Accept' => 'application/json',
269
  'Content-Type' => 'application/json; charset=utf-8',
270
- 'Authorization' => $this->get_http_authorization_header( 'bearer' ),
271
  ),
272
  'body' => json_encode( $properties ),
273
  );
274
 
275
- $response = $this->remote_request( esc_url_raw( $endpoint ), $request );
 
 
 
 
 
276
 
277
- if ( WP_DEBUG
278
- and 400 <= (int) wp_remote_retrieve_response_code( $response ) ) {
279
- $this->log( $endpoint, $request, $response );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280
  }
281
  }
282
 
@@ -292,7 +488,14 @@ class WPCF7_ConstantContact extends WPCF7_Service_OAuth2 {
292
  )
293
  ) . '</p>';
294
 
295
- if ( $this->is_active() or 'setup' == $action ) {
 
 
 
 
 
 
 
296
  $this->display_setup();
297
  } else {
298
  echo sprintf(
@@ -359,11 +562,55 @@ class WPCF7_ConstantContact extends WPCF7_Service_OAuth2 {
359
  <?php
360
  if ( $this->is_active() ) {
361
  submit_button(
362
- _x( 'Remove Keys', 'API keys', 'contact-form-7' ),
363
  'small', 'reset'
364
  );
365
  } else {
366
- submit_button( __( 'Connect to the Constant Contact API', 'contact-form-7' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
367
  }
368
  ?>
369
  </form>
@@ -457,6 +704,25 @@ class WPCF7_ConstantContact_ContactPostRequest {
457
  isset( $posted_data['your-address-country'] )
458
  ? $posted_data['your-address-country'] : ''
459
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
460
  }
461
 
462
  public function is_valid() {
12
  $integration->add_service( 'constant_contact', $service );
13
  }
14
 
15
+ add_action( 'wpcf7_save_contact_form',
16
+ 'wpcf7_constant_contact_save_contact_form', 10, 1 );
17
+
18
+ function wpcf7_constant_contact_save_contact_form( $contact_form ) {
19
+ $service = WPCF7_ConstantContact::get_instance();
20
+
21
+ if ( ! $service->is_active() ) {
22
+ return;
23
+ }
24
+
25
+ $additional_settings = $contact_form->additional_setting(
26
+ 'constant_contact',
27
+ false
28
+ );
29
+
30
+ $list_names = array();
31
+
32
+ $pattern = '/[\t ]*('
33
+ . "'[^']*'"
34
+ . '|'
35
+ . '"[^"]*"'
36
+ . '|'
37
+ . '[^,]*?'
38
+ . ')[\t ]*(?:[,]+|$)/';
39
+
40
+ foreach ( $additional_settings as $setting ) {
41
+ if ( preg_match_all( $pattern, $setting, $matches ) ) {
42
+ foreach ( $matches[1] as $match ) {
43
+ $name = trim( wpcf7_strip_quote( $match ) );
44
+
45
+ if ( '' !== $name ) {
46
+ $list_names[] = $name;
47
+ }
48
+ }
49
+ }
50
+ }
51
+
52
+ $list_names = array_unique( $list_names );
53
+
54
+ $key = sprintf( 'wpcf7_contact_form:%d', $contact_form->id() );
55
+
56
+ $service->update_contact_lists( array( $key => $list_names ) );
57
+ }
58
+
59
  add_action( 'wpcf7_submit', 'wpcf7_constant_contact_submit', 10, 2 );
60
 
61
  function wpcf7_constant_contact_submit( $contact_form, $result ) {
76
  $do_submit = false;
77
  }
78
 
79
+ $additional_settings = $contact_form->additional_setting(
80
+ 'constant_contact',
81
+ false
82
+ );
83
+
84
+ foreach ( $additional_settings as $setting ) {
85
+ if ( in_array( $setting, array( 'off', 'false', '0' ), true ) ) {
86
+ $do_submit = false;
87
+ break;
88
+ }
89
+ }
90
+
91
  $do_submit = apply_filters( 'wpcf7_constant_contact_submit',
92
  $do_submit, $contact_form, $result );
93
 
146
  const token_endpoint = 'https://idfed.constantcontact.com/as/token.oauth2';
147
 
148
  private static $instance;
149
+ protected $contact_lists = array();
150
 
151
  public static function get_instance() {
152
  if ( empty( self::$instance ) ) {
178
  $this->refresh_token = $option['refresh_token'];
179
  }
180
 
181
+ if ( $this->is_active() ) {
182
+ if ( isset( $option['contact_lists'] ) ) {
183
+ $this->contact_lists = $option['contact_lists'];
184
+ }
185
+ }
186
+
187
  add_action( 'wpcf7_admin_init', array( $this, 'auth_redirect' ) );
188
  }
189
 
215
  'client_secret' => $this->client_secret,
216
  'access_token' => $this->access_token,
217
  'refresh_token' => $this->refresh_token,
218
+ 'contact_lists' => $this->contact_lists,
219
  )
220
  );
221
 
227
  $this->client_secret = '';
228
  $this->access_token = '';
229
  $this->refresh_token = '';
230
+ $this->contact_lists = array();
231
 
232
  $this->save_data();
233
  }
289
  wp_safe_redirect( $this->menu_page_url( 'action=setup' ) );
290
  exit();
291
  }
292
+
293
+ if ( 'edit' == $action and 'POST' == $_SERVER['REQUEST_METHOD'] ) {
294
+ check_admin_referer( 'wpcf7-constant-contact-edit' );
295
+
296
+ $list_ids = isset( $_POST['contact_lists'] )
297
+ ? (array) $_POST['contact_lists']
298
+ : array();
299
+
300
+ $this->update_contact_lists( array( 'default' => $list_ids ) );
301
+
302
+ wp_safe_redirect( $this->menu_page_url(
303
+ array(
304
+ 'action' => 'setup',
305
+ 'message' => 'updated',
306
+ )
307
+ ) );
308
+
309
+ exit();
310
+ }
311
+
312
+ if ( $this->is_active() ) {
313
+ $this->update_contact_lists();
314
+ }
315
  }
316
 
317
  public function email_exists( $email ) {
325
  'headers' => array(
326
  'Accept' => 'application/json',
327
  'Content-Type' => 'application/json; charset=utf-8',
 
328
  ),
329
  );
330
 
331
+ $response = $this->remote_request( $endpoint, $request );
332
+
333
+ if ( 400 <= (int) wp_remote_retrieve_response_code( $response ) ) {
334
+ if ( WP_DEBUG ) {
335
+ $this->log( $endpoint, $request, $response );
336
+ }
337
 
338
+ return false;
 
 
339
  }
340
 
341
  $response_body = wp_remote_retrieve_body( $response );
357
  'headers' => array(
358
  'Accept' => 'application/json',
359
  'Content-Type' => 'application/json; charset=utf-8',
 
360
  ),
361
  'body' => json_encode( $properties ),
362
  );
363
 
364
+ $response = $this->remote_request( $endpoint, $request );
365
+
366
+ if ( 400 <= (int) wp_remote_retrieve_response_code( $response ) ) {
367
+ if ( WP_DEBUG ) {
368
+ $this->log( $endpoint, $request, $response );
369
+ }
370
 
371
+ return false;
372
+ }
373
+ }
374
+
375
+ public function get_contact_lists() {
376
+ $endpoint = 'https://api.cc.email/v3/contact_lists';
377
+
378
+ $request = array(
379
+ 'method' => 'GET',
380
+ 'headers' => array(
381
+ 'Accept' => 'application/json',
382
+ 'Content-Type' => 'application/json; charset=utf-8',
383
+ ),
384
+ );
385
+
386
+ $response = $this->remote_request( $endpoint, $request );
387
+
388
+ if ( 400 <= (int) wp_remote_retrieve_response_code( $response ) ) {
389
+ if ( WP_DEBUG ) {
390
+ $this->log( $endpoint, $request, $response );
391
+ }
392
+
393
+ return false;
394
+ }
395
+
396
+ $response_body = wp_remote_retrieve_body( $response );
397
+
398
+ if ( empty( $response_body ) ) {
399
+ return false;
400
+ }
401
+
402
+ $response_body = json_decode( $response_body, true );
403
+
404
+ if ( ! empty( $response_body['lists'] ) ) {
405
+ return (array) $response_body['lists'];
406
+ } else {
407
+ return array();
408
+ }
409
+ }
410
+
411
+ public function update_contact_lists( $selection = array() ) {
412
+ $contact_lists = array();
413
+ $contact_lists_on_api = $this->get_contact_lists();
414
+
415
+ if ( false !== $contact_lists_on_api ) {
416
+ foreach ( (array) $contact_lists_on_api as $list ) {
417
+ if ( isset( $list['list_id'] ) ) {
418
+ $list_id = trim( $list['list_id'] );
419
+ } else {
420
+ continue;
421
+ }
422
+
423
+ if ( isset( $this->contact_lists[$list_id]['selected'] ) ) {
424
+ $list['selected'] = $this->contact_lists[$list_id]['selected'];
425
+ } else {
426
+ $list['selected'] = array();
427
+ }
428
+
429
+ $contact_lists[$list_id] = $list;
430
+ }
431
+ } else {
432
+ $contact_lists = $this->contact_lists;
433
+ }
434
+
435
+ foreach ( (array) $selection as $key => $ids_or_names ) {
436
+ foreach( $contact_lists as $list_id => $list ) {
437
+ if ( in_array( $list['list_id'], (array) $ids_or_names, true )
438
+ or in_array( $list['name'], (array) $ids_or_names, true ) ) {
439
+ $contact_lists[$list_id]['selected'][$key] = true;
440
+ } else {
441
+ unset( $contact_lists[$list_id]['selected'][$key] );
442
+ }
443
+ }
444
+ }
445
+
446
+ $this->contact_lists = $contact_lists;
447
+
448
+ if ( $selection ) {
449
+ $this->save_data();
450
+ }
451
+
452
+ return $this->contact_lists;
453
+ }
454
+
455
+ public function admin_notice( $message = '' ) {
456
+ switch ( $message ) {
457
+ case 'success':
458
+ echo sprintf(
459
+ '<div class="updated notice notice-success is-dismissible"><p>%s</p></div>',
460
+ esc_html( __( "Connection established.", 'contact-form-7' ) )
461
+ );
462
+ break;
463
+ case 'failed':
464
+ echo sprintf(
465
+ '<div class="error notice notice-error is-dismissible"><p><strong>%1$s</strong>: %2$s</p></div>',
466
+ esc_html( __( "ERROR", 'contact-form-7' ) ),
467
+ esc_html( __( "Failed to establish connection. Please double-check your configuration.", 'contact-form-7' ) )
468
+ );
469
+ break;
470
+ case 'updated':
471
+ echo sprintf(
472
+ '<div class="updated notice notice-success is-dismissible"><p>%s</p></div>',
473
+ esc_html( __( "Configuration updated.", 'contact-form-7' ) )
474
+ );
475
+ break;
476
  }
477
  }
478
 
488
  )
489
  ) . '</p>';
490
 
491
+ if ( $this->is_active() ) {
492
+ echo sprintf(
493
+ '<p class="dashicons-before dashicons-yes">%s</p>',
494
+ esc_html( __( "This site is connected to the Constant Contact API.", 'contact-form-7' ) )
495
+ );
496
+ }
497
+
498
+ if ( 'setup' == $action ) {
499
  $this->display_setup();
500
  } else {
501
  echo sprintf(
562
  <?php
563
  if ( $this->is_active() ) {
564
  submit_button(
565
+ _x( 'Reset Keys', 'API keys', 'contact-form-7' ),
566
  'small', 'reset'
567
  );
568
  } else {
569
+ submit_button(
570
+ __( 'Connect to the Constant Contact API', 'contact-form-7' )
571
+ );
572
+ }
573
+ ?>
574
+ </form>
575
+
576
+ <?php
577
+ if ( $this->is_active() and ! empty( $this->contact_lists ) ) {
578
+ ?>
579
+ <form method="post" action="<?php echo esc_url( $this->menu_page_url( 'action=edit' ) ); ?>">
580
+ <?php wp_nonce_field( 'wpcf7-constant-contact-edit' ); ?>
581
+ <table class="form-table">
582
+ <tbody>
583
+ <tr>
584
+ <th scope="row"><?php echo esc_html( _x( 'Contact Lists', 'Constant Contact', 'contact-form-7' ) ); ?></th>
585
+ <td>
586
+ <fieldset>
587
+ <legend class="screen-reader-text"><span><?php echo esc_html( _x( "Contact Lists: Select lists to which newly added contacts are to belong.", 'Constant Contact', 'contact-form-7' ) ); ?></span></legend>
588
+ <p class="description"><?php echo esc_html( __( "Select lists to which newly added contacts are to belong.", 'contact-form-7' ) ); ?></p>
589
+ <ul class="checkboxes"><?php
590
+ foreach ( $this->contact_lists as $list ) {
591
+ echo sprintf(
592
+ '<li><input %1$s /> <label for="%2$s">%3$s</label></li>',
593
+ wpcf7_format_atts( array(
594
+ 'type' => 'checkbox',
595
+ 'name' => 'contact_lists[]',
596
+ 'value' => $list['list_id'],
597
+ 'id' => 'contact_list_' . $list['list_id'],
598
+ 'checked' => empty( $list['selected']['default'] )
599
+ ? ''
600
+ : 'checked',
601
+ ) ),
602
+ esc_attr( 'contact_list_' . $list['list_id'] ),
603
+ esc_html( $list['name'] )
604
+ );
605
+ }
606
+ ?></ul>
607
+ </fieldset>
608
+ </td>
609
+ </tr>
610
+ </tbody>
611
+ </table>
612
+ <?php
613
+ submit_button();
614
  }
615
  ?>
616
  </form>
704
  isset( $posted_data['your-address-country'] )
705
  ? $posted_data['your-address-country'] : ''
706
  );
707
+
708
+ $service_option = (array) WPCF7::get_option( 'constant_contact' );
709
+
710
+ $contact_lists = isset( $service_option['contact_lists'] )
711
+ ? $service_option['contact_lists'] : array();
712
+
713
+ $contact_form = $submission->get_contact_form();
714
+
715
+ if ( $contact_form->additional_setting( 'constant_contact' ) ) {
716
+ $key = sprintf( 'wpcf7_contact_form:%d', $contact_form->id() );
717
+ } else {
718
+ $key = 'default';
719
+ }
720
+
721
+ foreach ( (array) $contact_lists as $list ) {
722
+ if ( ! empty( $list['selected'][$key] ) ) {
723
+ $this->add_list_membership( $list['list_id'] );
724
+ }
725
+ }
726
  }
727
 
728
  public function is_valid() {
modules/flamingo.php CHANGED
@@ -123,6 +123,14 @@ function wpcf7_flamingo_submit( $contact_form, $result ) {
123
  'consent' => $submission->collect_consent(),
124
  );
125
 
 
 
 
 
 
 
 
 
126
  $flamingo_inbound = Flamingo_Inbound_Message::add( $args );
127
 
128
  $result += array(
123
  'consent' => $submission->collect_consent(),
124
  );
125
 
126
+ if ( $args['spam'] ) {
127
+ $args['spam_log'] = $submission->get_spam_log();
128
+ }
129
+
130
+ if ( isset( $submission->recaptcha ) ) {
131
+ $args['recaptcha'] = $submission->recaptcha;
132
+ }
133
+
134
  $flamingo_inbound = Flamingo_Inbound_Message::add( $args );
135
 
136
  $result += array(
modules/recaptcha.php CHANGED
@@ -37,6 +37,12 @@ add_filter( 'wpcf7_form_hidden_fields',
37
  'wpcf7_recaptcha_add_hidden_fields', 100, 1 );
38
 
39
  function wpcf7_recaptcha_add_hidden_fields( $fields ) {
 
 
 
 
 
 
40
  return array_merge( $fields, array(
41
  'g-recaptcha-response' => '',
42
  ) );
@@ -55,15 +61,23 @@ function wpcf7_recaptcha_onload_script() {
55
  return;
56
  }
57
 
 
 
 
 
 
 
 
58
  ?>
59
  <script type="text/javascript">
60
- ( function( grecaptcha, sitekey ) {
61
 
62
  var wpcf7recaptcha = {
63
- execute: function() {
 
64
  grecaptcha.execute(
65
  sitekey,
66
- { action: 'homepage' }
67
  ).then( function( token ) {
68
  var forms = document.getElementsByTagName( 'form' );
69
 
@@ -80,14 +94,35 @@ function wpcf7_recaptcha_onload_script() {
80
  }
81
  }
82
  } );
83
- }
 
 
 
 
 
 
 
 
 
84
  };
85
 
86
- grecaptcha.ready( wpcf7recaptcha.execute );
 
 
 
 
 
 
87
 
88
- document.addEventListener( 'wpcf7submit', wpcf7recaptcha.execute, false );
 
 
89
 
90
- } )( grecaptcha, '<?php echo esc_js( $service->get_sitekey() ); ?>' );
 
 
 
 
91
  </script>
92
  <?php
93
  }
@@ -105,10 +140,27 @@ function wpcf7_recaptcha_verify_response( $spam ) {
105
  return $spam;
106
  }
107
 
 
 
108
  $token = isset( $_POST['g-recaptcha-response'] )
109
  ? trim( $_POST['g-recaptcha-response'] ) : '';
110
 
111
- return ! $service->verify( $token );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  }
113
 
114
  add_action( 'wpcf7_init', 'wpcf7_recaptcha_add_form_tag_recaptcha', 10, 0 );
@@ -190,6 +242,7 @@ class WPCF7_RECAPTCHA extends WPCF7_Service {
190
 
191
  private static $instance;
192
  private $sitekeys;
 
193
 
194
  public static function get_instance() {
195
  if ( empty( self::$instance ) ) {
@@ -284,16 +337,35 @@ class WPCF7_RECAPTCHA extends WPCF7_Service {
284
  $response_body = wp_remote_retrieve_body( $response );
285
  $response_body = json_decode( $response_body, true );
286
 
287
- $score = isset( $response_body['score'] ) ? $response_body['score'] : 0;
288
- $threshold = 0.5;
 
 
 
289
  $is_human = $threshold < $score;
290
 
291
  $is_human = apply_filters( 'wpcf7_recaptcha_verify_response',
292
  $is_human, $response_body );
293
 
 
 
 
 
 
 
 
 
294
  return $is_human;
295
  }
296
 
 
 
 
 
 
 
 
 
297
  protected function menu_page_url( $args = '' ) {
298
  $args = wp_parse_args( $args, array() );
299
 
37
  'wpcf7_recaptcha_add_hidden_fields', 100, 1 );
38
 
39
  function wpcf7_recaptcha_add_hidden_fields( $fields ) {
40
+ $service = WPCF7_RECAPTCHA::get_instance();
41
+
42
+ if ( ! $service->is_active() ) {
43
+ return $fields;
44
+ }
45
+
46
  return array_merge( $fields, array(
47
  'g-recaptcha-response' => '',
48
  ) );
61
  return;
62
  }
63
 
64
+ $actions = apply_filters( 'wpcf7_recaptcha_actions',
65
+ array(
66
+ 'homepage' => 'homepage',
67
+ 'contactform' => 'contactform',
68
+ )
69
+ );
70
+
71
  ?>
72
  <script type="text/javascript">
73
+ ( function( grecaptcha, sitekey, actions ) {
74
 
75
  var wpcf7recaptcha = {
76
+
77
+ execute: function( action ) {
78
  grecaptcha.execute(
79
  sitekey,
80
+ { action: action }
81
  ).then( function( token ) {
82
  var forms = document.getElementsByTagName( 'form' );
83
 
94
  }
95
  }
96
  } );
97
+ },
98
+
99
+ executeOnHomepage: function() {
100
+ wpcf7recaptcha.execute( actions[ 'homepage' ] );
101
+ },
102
+
103
+ executeOnContactform: function() {
104
+ wpcf7recaptcha.execute( actions[ 'contactform' ] );
105
+ },
106
+
107
  };
108
 
109
+ grecaptcha.ready(
110
+ wpcf7recaptcha.executeOnHomepage
111
+ );
112
+
113
+ document.addEventListener( 'change',
114
+ wpcf7recaptcha.executeOnContactform, false
115
+ );
116
 
117
+ document.addEventListener( 'wpcf7submit',
118
+ wpcf7recaptcha.executeOnHomepage, false
119
+ );
120
 
121
+ } )(
122
+ grecaptcha,
123
+ '<?php echo esc_js( $service->get_sitekey() ); ?>',
124
+ <?php echo json_encode( $actions ), "\n"; ?>
125
+ );
126
  </script>
127
  <?php
128
  }
140
  return $spam;
141
  }
142
 
143
+ $submission = WPCF7_Submission::get_instance();
144
+
145
  $token = isset( $_POST['g-recaptcha-response'] )
146
  ? trim( $_POST['g-recaptcha-response'] ) : '';
147
 
148
+ if ( $service->verify( $token ) ) { // Human
149
+ $spam = false;
150
+ } else { // Bot
151
+ $spam = true;
152
+
153
+ $submission->add_spam_log( array(
154
+ 'agent' => 'recaptcha',
155
+ 'reason' => sprintf(
156
+ __( 'reCAPTCHA score (%1$.2f) is lower than the threshold (%2$.2f).', 'contact-form-7' ),
157
+ $service->get_last_score(),
158
+ $service->get_threshold()
159
+ ),
160
+ ) );
161
+ }
162
+
163
+ return $spam;
164
  }
165
 
166
  add_action( 'wpcf7_init', 'wpcf7_recaptcha_add_form_tag_recaptcha', 10, 0 );
242
 
243
  private static $instance;
244
  private $sitekeys;
245
+ private $last_score;
246
 
247
  public static function get_instance() {
248
  if ( empty( self::$instance ) ) {
337
  $response_body = wp_remote_retrieve_body( $response );
338
  $response_body = json_decode( $response_body, true );
339
 
340
+ $this->last_score = $score = isset( $response_body['score'] )
341
+ ? $response_body['score']
342
+ : 0;
343
+
344
+ $threshold = $this->get_threshold();
345
  $is_human = $threshold < $score;
346
 
347
  $is_human = apply_filters( 'wpcf7_recaptcha_verify_response',
348
  $is_human, $response_body );
349
 
350
+ if ( $submission = WPCF7_Submission::get_instance() ) {
351
+ $submission->recaptcha = array(
352
+ 'version' => '3.0',
353
+ 'threshold' => $threshold,
354
+ 'response' => $response_body,
355
+ );
356
+ }
357
+
358
  return $is_human;
359
  }
360
 
361
+ public function get_threshold() {
362
+ return apply_filters( 'wpcf7_recaptcha_threshold', 0.50 );
363
+ }
364
+
365
+ public function get_last_score() {
366
+ return $this->last_score;
367
+ }
368
+
369
  protected function menu_page_url( $args = '' ) {
370
  $args = wp_parse_args( $args, array() );
371
 
readme.txt CHANGED
@@ -3,8 +3,8 @@ 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: 4.9
6
- Tested up to: 5.0
7
- Stable tag: 5.1.1
8
  License: GPLv2 or later
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -75,6 +75,12 @@ 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.1.1 =
79
 
80
  * reCAPTCHA: Modifies the reaction to empty response tokens.
3
  Donate link: https://contactform7.com/donate/
4
  Tags: contact, form, contact form, feedback, email, ajax, captcha, akismet, multilingual
5
  Requires at least: 4.9
6
+ Tested up to: 5.2
7
+ Stable tag: 5.1.2
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.1.2 =
79
+
80
+ * Constant Contact: Introduces the contact list selector.
81
+ * Constant Contact: Introduces the constant_contact additional setting.
82
+ * reCAPTCHA: Introduces the wpcf7_recaptcha_actions and wpcf7_recaptcha_threshold filter hooks.
83
+
84
  = 5.1.1 =
85
 
86
  * reCAPTCHA: Modifies the reaction to empty response tokens.
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.1.1
11
  */
12
 
13
- define( 'WPCF7_VERSION', '5.1.1' );
14
 
15
  define( 'WPCF7_REQUIRED_WP_VERSION', '4.9' );
16
 
7
  Author URI: https://ideasilo.wordpress.com/
8
  Text Domain: contact-form-7
9
  Domain Path: /languages/
10
+ Version: 5.1.2
11
  */
12
 
13
+ define( 'WPCF7_VERSION', '5.1.2' );
14
 
15
  define( 'WPCF7_REQUIRED_WP_VERSION', '4.9' );
16