PluginProbe ʕ •ᴥ•ʔ
Contact Form 7 / 5.0.2
Contact Form 7 v5.0.2
6.1.6 5.0.2 5.0.3 5.0.4 5.0.5 5.1 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.1.8 5.1.9 5.2 5.2.1 5.2.2 5.3 5.3.1 5.3.2 5.4 5.4.1 5.4.2 5.5 5.5.1 5.5.2 5.5.3 5.5.4 5.5.5 5.5.6 5.5.6.1 5.6 5.6.1 5.6.2 5.6.3 5.6.4 5.7 5.7.1 5.7.2 5.7.3 5.7.4 5.7.5 5.7.5.1 5.7.6 5.7.7 5.8 5.8.1 5.8.2 5.8.3 5.8.4 5.8.5 5.8.6 5.8.7 5.9 5.9.2 5.9.3 5.9.4 5.9.5 5.9.6 5.9.7 5.9.8 6.0 6.0.1 6.0.2 6.0.3 6.0.4 6.0.5 6.0.6 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 trunk 1.1 1.10 1.10.0.1 1.10.1 1.2 1.3 1.3.1 1.3.2 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.5 1.6 1.6.1 1.7 1.7.1 1.7.2 1.7.4 1.7.5 1.7.6 1.7.6.1 1.7.7 1.7.7.1 1.7.8 1.8 1.8.0.1 1.8.0.2 1.8.0.3 1.8.0.4 1.8.1 1.8.1.1 1.9 1.9.1 1.9.2 1.9.2.1 1.9.2.2 1.9.3 1.9.4 1.9.5 1.9.5.1 2.0 2.0-beta 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1 2.1.1 2.1.2 2.2 2.2.1 2.3 2.3.1 2.4 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 3.0 3.0-beta 3.0.1 3.0.2 3.0.2.1 3.1 3.1.1 3.1.2 3.2 3.2.1 3.3 3.3.1 3.3.2 3.3.3 3.4 3.4.1 3.4.2 3.5 3.5.1 3.5.2 3.5.3 3.5.4 3.6 3.7 3.7.1 3.7.2 3.8 3.8.1 3.9 3.9-beta 3.9.1 3.9.2 3.9.3 4.0 4.0.1 4.0.2 4.0.3 4.1 4.1-beta 4.1.1 4.1.2 4.2 4.2-beta 4.2.1 4.2.2 4.3 4.3.1 4.4 4.4.1 4.4.2 4.5 4.5.1 4.6 4.6.1 4.7 4.8 4.8.1 4.9 4.9.1 4.9.2 5.0 5.0.1
contact-form-7 / modules / recaptcha.php
contact-form-7 / modules Last commit date
acceptance.php 8 years ago akismet.php 8 years ago checkbox.php 8 years ago count.php 8 years ago date.php 8 years ago file.php 8 years ago flamingo.php 8 years ago hidden.php 9 years ago listo.php 9 years ago number.php 8 years ago quiz.php 8 years ago really-simple-captcha.php 8 years ago recaptcha.php 8 years ago response.php 9 years ago select.php 8 years ago submit.php 8 years ago text.php 8 years ago textarea.php 8 years ago
recaptcha.php
516 lines
1 <?php
2
3 class WPCF7_RECAPTCHA extends WPCF7_Service {
4
5 const VERIFY_URL = 'https://www.google.com/recaptcha/api/siteverify';
6
7 private static $instance;
8 private $sitekeys;
9
10 public static function get_instance() {
11 if ( empty( self::$instance ) ) {
12 self::$instance = new self;
13 }
14
15 return self::$instance;
16 }
17
18 private function __construct() {
19 $this->sitekeys = WPCF7::get_option( 'recaptcha' );
20 }
21
22 public function get_title() {
23 return __( 'reCAPTCHA', 'contact-form-7' );
24 }
25
26 public function is_active() {
27 $sitekey = $this->get_sitekey();
28 $secret = $this->get_secret( $sitekey );
29 return $sitekey && $secret;
30 }
31
32 public function get_categories() {
33 return array( 'captcha' );
34 }
35
36 public function icon() {
37 }
38
39 public function link() {
40 echo sprintf( '<a href="%1$s">%2$s</a>',
41 'https://www.google.com/recaptcha/intro/index.html',
42 'google.com/recaptcha' );
43 }
44
45 public function get_sitekey() {
46 if ( empty( $this->sitekeys ) || ! is_array( $this->sitekeys ) ) {
47 return false;
48 }
49
50 $sitekeys = array_keys( $this->sitekeys );
51
52 return $sitekeys[0];
53 }
54
55 public function get_secret( $sitekey ) {
56 $sitekeys = (array) $this->sitekeys;
57
58 if ( isset( $sitekeys[$sitekey] ) ) {
59 return $sitekeys[$sitekey];
60 } else {
61 return false;
62 }
63 }
64
65 public function verify( $response_token ) {
66 $is_human = false;
67
68 if ( empty( $response_token ) ) {
69 return $is_human;
70 }
71
72 $url = self::VERIFY_URL;
73 $sitekey = $this->get_sitekey();
74 $secret = $this->get_secret( $sitekey );
75
76 $response = wp_safe_remote_post( $url, array(
77 'body' => array(
78 'secret' => $secret,
79 'response' => $response_token,
80 'remoteip' => $_SERVER['REMOTE_ADDR'],
81 ),
82 ) );
83
84 if ( 200 != wp_remote_retrieve_response_code( $response ) ) {
85 return $is_human;
86 }
87
88 $response = wp_remote_retrieve_body( $response );
89 $response = json_decode( $response, true );
90
91 $is_human = isset( $response['success'] ) && true == $response['success'];
92 return $is_human;
93 }
94
95 private function menu_page_url( $args = '' ) {
96 $args = wp_parse_args( $args, array() );
97
98 $url = menu_page_url( 'wpcf7-integration', false );
99 $url = add_query_arg( array( 'service' => 'recaptcha' ), $url );
100
101 if ( ! empty( $args) ) {
102 $url = add_query_arg( $args, $url );
103 }
104
105 return $url;
106 }
107
108 public function load( $action = '' ) {
109 if ( 'setup' == $action ) {
110 if ( 'POST' == $_SERVER['REQUEST_METHOD'] ) {
111 check_admin_referer( 'wpcf7-recaptcha-setup' );
112
113 $sitekey = isset( $_POST['sitekey'] ) ? trim( $_POST['sitekey'] ) : '';
114 $secret = isset( $_POST['secret'] ) ? trim( $_POST['secret'] ) : '';
115
116 if ( $sitekey && $secret ) {
117 WPCF7::update_option( 'recaptcha', array( $sitekey => $secret ) );
118 $redirect_to = $this->menu_page_url( array(
119 'message' => 'success',
120 ) );
121 } elseif ( '' === $sitekey && '' === $secret ) {
122 WPCF7::update_option( 'recaptcha', null );
123 $redirect_to = $this->menu_page_url( array(
124 'message' => 'success',
125 ) );
126 } else {
127 $redirect_to = $this->menu_page_url( array(
128 'action' => 'setup',
129 'message' => 'invalid',
130 ) );
131 }
132
133 wp_safe_redirect( $redirect_to );
134 exit();
135 }
136 }
137 }
138
139 public function admin_notice( $message = '' ) {
140 if ( 'invalid' == $message ) {
141 echo sprintf(
142 '<div class="error notice notice-error is-dismissible"><p><strong>%1$s</strong>: %2$s</p></div>',
143 esc_html( __( "ERROR", 'contact-form-7' ) ),
144 esc_html( __( "Invalid key values.", 'contact-form-7' ) ) );
145 }
146
147 if ( 'success' == $message ) {
148 echo sprintf( '<div class="updated notice notice-success is-dismissible"><p>%s</p></div>',
149 esc_html( __( 'Settings saved.', 'contact-form-7' ) ) );
150 }
151 }
152
153 public function display( $action = '' ) {
154 ?>
155 <p><?php echo esc_html( __( "reCAPTCHA is a free service to protect your website from spam and abuse.", 'contact-form-7' ) ); ?></p>
156
157 <?php
158 if ( 'setup' == $action ) {
159 $this->display_setup();
160 return;
161 }
162
163 if ( $this->is_active() ) {
164 $sitekey = $this->get_sitekey();
165 $secret = $this->get_secret( $sitekey );
166 ?>
167 <table class="form-table">
168 <tbody>
169 <tr>
170 <th scope="row"><?php echo esc_html( __( 'Site Key', 'contact-form-7' ) ); ?></th>
171 <td class="code"><?php echo esc_html( $sitekey ); ?></td>
172 </tr>
173 <tr>
174 <th scope="row"><?php echo esc_html( __( 'Secret Key', 'contact-form-7' ) ); ?></th>
175 <td class="code"><?php echo esc_html( wpcf7_mask_password( $secret ) ); ?></td>
176 </tr>
177 </tbody>
178 </table>
179
180 <p><a href="<?php echo esc_url( $this->menu_page_url( 'action=setup' ) ); ?>" class="button"><?php echo esc_html( __( "Reset Keys", 'contact-form-7' ) ); ?></a></p>
181
182 <?php
183 } else {
184 ?>
185 <p><?php echo esc_html( __( "To use reCAPTCHA, you need to install an API key pair.", 'contact-form-7' ) ); ?></p>
186
187 <p><a href="<?php echo esc_url( $this->menu_page_url( 'action=setup' ) ); ?>" class="button"><?php echo esc_html( __( "Configure Keys", 'contact-form-7' ) ); ?></a></p>
188
189 <p><?php echo sprintf( esc_html( __( "For more details, see %s.", 'contact-form-7' ) ), wpcf7_link( __( 'https://contactform7.com/recaptcha/', 'contact-form-7' ), __( 'reCAPTCHA', 'contact-form-7' ) ) ); ?></p>
190 <?php
191 }
192 }
193
194 public function display_setup() {
195 ?>
196 <form method="post" action="<?php echo esc_url( $this->menu_page_url( 'action=setup' ) ); ?>">
197 <?php wp_nonce_field( 'wpcf7-recaptcha-setup' ); ?>
198 <table class="form-table">
199 <tbody>
200 <tr>
201 <th scope="row"><label for="sitekey"><?php echo esc_html( __( 'Site Key', 'contact-form-7' ) ); ?></label></th>
202 <td><input type="text" aria-required="true" value="" id="sitekey" name="sitekey" class="regular-text code" /></td>
203 </tr>
204 <tr>
205 <th scope="row"><label for="secret"><?php echo esc_html( __( 'Secret Key', 'contact-form-7' ) ); ?></label></th>
206 <td><input type="text" aria-required="true" value="" id="secret" name="secret" class="regular-text code" /></td>
207 </tr>
208 </tbody>
209 </table>
210
211 <p class="submit"><input type="submit" class="button button-primary" value="<?php echo esc_attr( __( 'Save', 'contact-form-7' ) ); ?>" name="submit" /></p>
212 </form>
213 <?php
214 }
215 }
216
217 add_action( 'wpcf7_init', 'wpcf7_recaptcha_register_service' );
218
219 function wpcf7_recaptcha_register_service() {
220 $integration = WPCF7_Integration::get_instance();
221
222 $categories = array(
223 'captcha' => __( 'CAPTCHA', 'contact-form-7' ),
224 );
225
226 foreach ( $categories as $name => $category ) {
227 $integration->add_category( $name, $category );
228 }
229
230 $services = array(
231 'recaptcha' => WPCF7_RECAPTCHA::get_instance(),
232 );
233
234 foreach ( $services as $name => $service ) {
235 $integration->add_service( $name, $service );
236 }
237 }
238
239 add_action( 'wpcf7_enqueue_scripts', 'wpcf7_recaptcha_enqueue_scripts' );
240
241 function wpcf7_recaptcha_enqueue_scripts() {
242 $url = 'https://www.google.com/recaptcha/api.js';
243 $url = add_query_arg( array(
244 'onload' => 'recaptchaCallback',
245 'render' => 'explicit',
246 ), $url );
247
248 wp_register_script( 'google-recaptcha', $url, array(), '2.0', true );
249 }
250
251 add_action( 'wp_footer', 'wpcf7_recaptcha_callback_script' );
252
253 function wpcf7_recaptcha_callback_script() {
254 if ( ! wp_script_is( 'google-recaptcha', 'enqueued' ) ) {
255 return;
256 }
257
258 ?>
259 <script type="text/javascript">
260 var recaptchaWidgets = [];
261 var recaptchaCallback = function() {
262 var forms = document.getElementsByTagName( 'form' );
263 var pattern = /(^|\s)g-recaptcha(\s|$)/;
264
265 for ( var i = 0; i < forms.length; i++ ) {
266 var divs = forms[ i ].getElementsByTagName( 'div' );
267
268 for ( var j = 0; j < divs.length; j++ ) {
269 var sitekey = divs[ j ].getAttribute( 'data-sitekey' );
270
271 if ( divs[ j ].className && divs[ j ].className.match( pattern ) && sitekey ) {
272 var params = {
273 'sitekey': sitekey,
274 'type': divs[ j ].getAttribute( 'data-type' ),
275 'size': divs[ j ].getAttribute( 'data-size' ),
276 'theme': divs[ j ].getAttribute( 'data-theme' ),
277 'badge': divs[ j ].getAttribute( 'data-badge' ),
278 'tabindex': divs[ j ].getAttribute( 'data-tabindex' )
279 };
280
281 var callback = divs[ j ].getAttribute( 'data-callback' );
282
283 if ( callback && 'function' == typeof window[ callback ] ) {
284 params[ 'callback' ] = window[ callback ];
285 }
286
287 var expired_callback = divs[ j ].getAttribute( 'data-expired-callback' );
288
289 if ( expired_callback && 'function' == typeof window[ expired_callback ] ) {
290 params[ 'expired-callback' ] = window[ expired_callback ];
291 }
292
293 var widget_id = grecaptcha.render( divs[ j ], params );
294 recaptchaWidgets.push( widget_id );
295 break;
296 }
297 }
298 }
299 };
300
301 document.addEventListener( 'wpcf7submit', function( event ) {
302 switch ( event.detail.status ) {
303 case 'spam':
304 case 'mail_sent':
305 case 'mail_failed':
306 for ( var i = 0; i < recaptchaWidgets.length; i++ ) {
307 grecaptcha.reset( recaptchaWidgets[ i ] );
308 }
309 }
310 }, false );
311 </script>
312 <?php
313 }
314
315 add_action( 'wpcf7_init', 'wpcf7_recaptcha_add_form_tag_recaptcha' );
316
317 function wpcf7_recaptcha_add_form_tag_recaptcha() {
318 $recaptcha = WPCF7_RECAPTCHA::get_instance();
319
320 if ( $recaptcha->is_active() ) {
321 wpcf7_add_form_tag( 'recaptcha', 'wpcf7_recaptcha_form_tag_handler',
322 array( 'display-block' => true ) );
323 }
324 }
325
326 function wpcf7_recaptcha_form_tag_handler( $tag ) {
327 if ( ! wp_script_is( 'google-recaptcha', 'registered' ) ) {
328 wpcf7_recaptcha_enqueue_scripts();
329 }
330
331 wp_enqueue_script( 'google-recaptcha' );
332
333 $atts = array();
334
335 $recaptcha = WPCF7_RECAPTCHA::get_instance();
336 $atts['data-sitekey'] = $recaptcha->get_sitekey();
337 $atts['data-type'] = $tag->get_option( 'type', '(audio|image)', true );
338 $atts['data-size'] = $tag->get_option(
339 'size', '(compact|normal|invisible)', true );
340 $atts['data-theme'] = $tag->get_option( 'theme', '(dark|light)', true );
341 $atts['data-badge'] = $tag->get_option(
342 'badge', '(bottomright|bottomleft|inline)', true );
343 $atts['data-tabindex'] = $tag->get_option( 'tabindex', 'signed_int', true );
344 $atts['data-callback'] = $tag->get_option( 'callback', '', true );
345 $atts['data-expired-callback'] =
346 $tag->get_option( 'expired_callback', '', true );
347
348 $atts['class'] = $tag->get_class_option(
349 wpcf7_form_controls_class( $tag->type, 'g-recaptcha' ) );
350 $atts['id'] = $tag->get_id_option();
351
352 $html = sprintf( '<div %1$s></div>', wpcf7_format_atts( $atts ) );
353 $html .= wpcf7_recaptcha_noscript(
354 array( 'sitekey' => $atts['data-sitekey'] ) );
355 $html = sprintf( '<div class="wpcf7-form-control-wrap">%s</div>', $html );
356
357 return $html;
358 }
359
360 function wpcf7_recaptcha_noscript( $args = '' ) {
361 $args = wp_parse_args( $args, array(
362 'sitekey' => '',
363 ) );
364
365 if ( empty( $args['sitekey'] ) ) {
366 return;
367 }
368
369 $url = add_query_arg( 'k', $args['sitekey'],
370 'https://www.google.com/recaptcha/api/fallback' );
371
372 ob_start();
373 ?>
374
375 <noscript>
376 <div style="width: 302px; height: 422px;">
377 <div style="width: 302px; height: 422px; position: relative;">
378 <div style="width: 302px; height: 422px; position: absolute;">
379 <iframe src="<?php echo esc_url( $url ); ?>" frameborder="0" scrolling="no" style="width: 302px; height:422px; border-style: none;">
380 </iframe>
381 </div>
382 <div style="width: 300px; height: 60px; border-style: none; bottom: 12px; left: 25px; margin: 0px; padding: 0px; right: 25px; background: #f9f9f9; border: 1px solid #c1c1c1; border-radius: 3px;">
383 <textarea id="g-recaptcha-response" name="g-recaptcha-response" class="g-recaptcha-response" style="width: 250px; height: 40px; border: 1px solid #c1c1c1; margin: 10px 25px; padding: 0px; resize: none;">
384 </textarea>
385 </div>
386 </div>
387 </div>
388 </noscript>
389 <?php
390 return ob_get_clean();
391 }
392
393 add_filter( 'wpcf7_spam', 'wpcf7_recaptcha_check_with_google', 9 );
394
395 function wpcf7_recaptcha_check_with_google( $spam ) {
396 if ( $spam ) {
397 return $spam;
398 }
399
400 $contact_form = wpcf7_get_current_contact_form();
401
402 if ( ! $contact_form ) {
403 return $spam;
404 }
405
406 $tags = $contact_form->scan_form_tags( array( 'type' => 'recaptcha' ) );
407
408 if ( empty( $tags ) ) {
409 return $spam;
410 }
411
412 $recaptcha = WPCF7_RECAPTCHA::get_instance();
413
414 if ( ! $recaptcha->is_active() ) {
415 return $spam;
416 }
417
418 $response_token = wpcf7_recaptcha_response();
419 $spam = ! $recaptcha->verify( $response_token );
420
421 return $spam;
422 }
423
424 add_action( 'wpcf7_admin_init', 'wpcf7_add_tag_generator_recaptcha', 45 );
425
426 function wpcf7_add_tag_generator_recaptcha() {
427 $tag_generator = WPCF7_TagGenerator::get_instance();
428 $tag_generator->add( 'recaptcha', __( 'reCAPTCHA', 'contact-form-7' ),
429 'wpcf7_tag_generator_recaptcha', array( 'nameless' => 1 ) );
430 }
431
432 function wpcf7_tag_generator_recaptcha( $contact_form, $args = '' ) {
433 $args = wp_parse_args( $args, array() );
434
435 $recaptcha = WPCF7_RECAPTCHA::get_instance();
436
437 if ( ! $recaptcha->is_active() ) {
438 ?>
439 <div class="control-box">
440 <fieldset>
441 <legend><?php echo sprintf( esc_html( __( "To use reCAPTCHA, first you need to install an API key pair. For more details, see %s.", 'contact-form-7' ) ), wpcf7_link( __( 'https://contactform7.com/recaptcha/', 'contact-form-7' ), __( 'reCAPTCHA', 'contact-form-7' ) ) ); ?></legend>
442 </fieldset>
443 </div>
444 <?php
445
446 return;
447 }
448
449 $description = __( "Generate a form-tag for a reCAPTCHA widget. For more details, see %s.", 'contact-form-7' );
450
451 $desc_link = wpcf7_link( __( 'https://contactform7.com/recaptcha/', 'contact-form-7' ), __( 'reCAPTCHA', 'contact-form-7' ) );
452
453 ?>
454 <div class="control-box">
455 <fieldset>
456 <legend><?php echo sprintf( esc_html( $description ), $desc_link ); ?></legend>
457
458 <table class="form-table">
459 <tbody>
460 <tr>
461 <th scope="row"><?php echo esc_html( __( 'Size', 'contact-form-7' ) ); ?></th>
462 <td>
463 <fieldset>
464 <legend class="screen-reader-text"><?php echo esc_html( __( 'Size', 'contact-form-7' ) ); ?></legend>
465 <label for="<?php echo esc_attr( $args['content'] . '-size-normal' ); ?>"><input type="radio" name="size" class="option default" id="<?php echo esc_attr( $args['content'] . '-size-normal' ); ?>" value="normal" checked="checked" /> <?php echo esc_html( __( 'Normal', 'contact-form-7' ) ); ?></label>
466 <br />
467 <label for="<?php echo esc_attr( $args['content'] . '-size-compact' ); ?>"><input type="radio" name="size" class="option" id="<?php echo esc_attr( $args['content'] . '-size-compact' ); ?>" value="compact" /> <?php echo esc_html( __( 'Compact', 'contact-form-7' ) ); ?></label>
468 </fieldset>
469 </td>
470 </tr>
471
472 <tr>
473 <th scope="row"><?php echo esc_html( __( 'Theme', 'contact-form-7' ) ); ?></th>
474 <td>
475 <fieldset>
476 <legend class="screen-reader-text"><?php echo esc_html( __( 'Theme', 'contact-form-7' ) ); ?></legend>
477 <label for="<?php echo esc_attr( $args['content'] . '-theme-light' ); ?>"><input type="radio" name="theme" class="option default" id="<?php echo esc_attr( $args['content'] . '-theme-light' ); ?>" value="light" checked="checked" /> <?php echo esc_html( __( 'Light', 'contact-form-7' ) ); ?></label>
478 <br />
479 <label for="<?php echo esc_attr( $args['content'] . '-theme-dark' ); ?>"><input type="radio" name="theme" class="option" id="<?php echo esc_attr( $args['content'] . '-theme-dark' ); ?>" value="dark" /> <?php echo esc_html( __( 'Dark', 'contact-form-7' ) ); ?></label>
480 </fieldset>
481 </td>
482 </tr>
483
484 <tr>
485 <th scope="row"><label for="<?php echo esc_attr( $args['content'] . '-id' ); ?>"><?php echo esc_html( __( 'Id attribute', 'contact-form-7' ) ); ?></label></th>
486 <td><input type="text" name="id" class="idvalue oneline option" id="<?php echo esc_attr( $args['content'] . '-id' ); ?>" /></td>
487 </tr>
488
489 <tr>
490 <th scope="row"><label for="<?php echo esc_attr( $args['content'] . '-class' ); ?>"><?php echo esc_html( __( 'Class attribute', 'contact-form-7' ) ); ?></label></th>
491 <td><input type="text" name="class" class="classvalue oneline option" id="<?php echo esc_attr( $args['content'] . '-class' ); ?>" /></td>
492 </tr>
493
494 </tbody>
495 </table>
496 </fieldset>
497 </div>
498
499 <div class="insert-box">
500 <input type="text" name="recaptcha" class="tag code" readonly="readonly" onfocus="this.select()" />
501
502 <div class="submitbox">
503 <input type="button" class="button button-primary insert-tag" value="<?php echo esc_attr( __( 'Insert Tag', 'contact-form-7' ) ); ?>" />
504 </div>
505 </div>
506 <?php
507 }
508
509 function wpcf7_recaptcha_response() {
510 if ( isset( $_POST['g-recaptcha-response'] ) ) {
511 return $_POST['g-recaptcha-response'];
512 }
513
514 return false;
515 }
516