Completed
Push — master ( ce9b57...42e549 )
by Stephanie
29s queued 11s
created

FrmFieldCaptcha::should_show_captcha()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @since 3.0
5
 */
6
class FrmFieldCaptcha extends FrmFieldType {
7
8
	/**
9
	 * @var string
10
	 * @since 3.0
11
	 */
12
	protected $type = 'captcha';
13
14
	/**
15
	 * @return string
16
	 */
17
	protected function include_form_builder_file() {
18
		return FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/field-captcha.php';
19
	}
20
21
	/**
22
	 * @return array
23
	 */
24
	protected function field_settings_for_type() {
25
		return array(
26
			'required'      => false,
27
			'invalid'       => true,
28
			'captcha_size'  => true,
29
			'default'       => false,
30
		);
31
	}
32
33
	/**
34
	 * @return array
35
	 */
36
	protected function new_field_settings() {
37
		$frm_settings = FrmAppHelper::get_settings();
38
39
		return array(
40
			'invalid' => $frm_settings->re_msg,
41
		);
42
	}
43
44
	/**
45
	 * @return array
46
	 */
47
	protected function extra_field_opts() {
48
		return array(
49
			'label'         => 'none',
50
			'captcha_size'  => 'normal',
51
			'captcha_theme' => 'light',
52
		);
53
	}
54
55
	/**
56
	 * Remove the "for" attribute for captcha
57
	 *
58
	 * @param array $args
59
	 * @param string $html
60
	 *
61
	 * @return string
62
	 */
63
	protected function before_replace_html_shortcodes( $args, $html ) {
64
		return str_replace( ' for="field_[key]"', ' for="g-recaptcha-response"', $html );
65
	}
66
67
	public function front_field_input( $args, $shortcode_atts ) {
68
		$frm_settings = FrmAppHelper::get_settings();
69
		if ( empty( $frm_settings->pubkey ) ) {
70
			return '';
71
		}
72
73
		$class_prefix  = $this->class_prefix();
74
		$captcha_size  = $this->captcha_size();
75
		$allow_mutiple = $frm_settings->re_multi;
76
77
		$html = '<div id="' . esc_attr( $args['html_id'] ) . '" class="' . esc_attr( $class_prefix ) . 'g-recaptcha" data-sitekey="' . esc_attr( $frm_settings->pubkey ) . '" data-size="' . esc_attr( $captcha_size ) . '" data-theme="' . esc_attr( $this->field['captcha_theme'] ) . '"';
78
		if ( $captcha_size == 'invisible' && ! $allow_mutiple ) {
79
			$html .= ' data-callback="frmAfterRecaptcha"';
80
		}
81
		$html .= '></div>';
82
83
		return $html;
84
	}
85
86
	protected function load_field_scripts( $args ) {
87
		$api_js_url = $this->api_url();
88
89
		wp_register_script( 'recaptcha-api', $api_js_url, array( 'formidable' ), '3', true );
90
		wp_enqueue_script( 'recaptcha-api' );
91
	}
92
93
	protected function api_url() {
94
		$api_js_url = 'https://www.google.com/recaptcha/api.js?';
95
96
		$frm_settings  = FrmAppHelper::get_settings();
97
		$allow_mutiple = $frm_settings->re_multi;
98
		if ( $allow_mutiple ) {
99
			$api_js_url .= '&onload=frmRecaptcha&render=explicit';
100
		}
101
102
		$lang = apply_filters( 'frm_recaptcha_lang', $frm_settings->re_lang, $this->field );
103
		if ( ! empty( $lang ) ) {
104
			$api_js_url .= '&hl=' . $lang;
105
		}
106
107
		return apply_filters( 'frm_recaptcha_js_url', $api_js_url );
108
	}
109
110
	protected function class_prefix() {
111
		if ( $this->allow_multiple() ) {
112
			$class_prefix = 'frm-';
113
		} else {
114
			$class_prefix = '';
115
		}
116
117
		return $class_prefix;
118
	}
119
120
	protected function allow_multiple() {
121
		$frm_settings = FrmAppHelper::get_settings();
122
123
		return $frm_settings->re_multi;
124
	}
125
126
	protected function captcha_size() {
127
		// for reverse compatibility
128
		$frm_settings = FrmAppHelper::get_settings();
129
		$captcha_size = ( $this->field['captcha_size'] == 'default' ) ? 'normal' : $this->field['captcha_size'];
130
131
		return ( $frm_settings->re_type == 'invisible' ) ? 'invisible' : $captcha_size;
132
	}
133
134
	/**
135
	 * @since 4.07
136
	 * @param array $args
137
	 * @return array
138
	 */
139
	protected function validate_against_api( $args ) {
140
		$errors       = array();
141
		$frm_settings = FrmAppHelper::get_settings();
142
		$resp         = $this->send_api_check( $frm_settings );
143
		$response     = json_decode( wp_remote_retrieve_body( $resp ), true );
144
145
		if ( isset( $response['success'] ) && ! $response['success'] ) {
146
			// What happens when the CAPTCHA was entered incorrectly
147
			$invalid_message                 = FrmField::get_option( $this->field, 'invalid' );
148
			$errors[ 'field' . $args['id'] ] = ( $invalid_message == '' ? $frm_settings->re_msg : $invalid_message );
149 View Code Duplication
		} elseif ( is_wp_error( $resp ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
150
			$error_string                     = $resp->get_error_message();
151
			$errors[ 'field' . $args['id'] ]  = __( 'There was a problem verifying your recaptcha', 'formidable' );
152
			$errors[ 'field' . $args['id'] ] .= ' ' . $error_string;
153
		}
154
155
		return $errors;
156
	}
157
158
	/**
159
	 * @param array $args
160
	 * @return array
161
	 */
162
	public function validate( $args ) {
163
		if ( ! $this->should_validate() ) {
164
			return array();
165
		}
166
167
		if ( ! isset( $_POST['g-recaptcha-response'] ) ) {
168
			// There was no captcha submitted.
169
			return array( 'field' . $args['id'] => __( 'The captcha is missing from this form', 'formidable' ) );
170
		}
171
172
		return $this->validate_against_api( $args );
173
	}
174
175
	/**
176
	 * @since 4.07
177
	 * @return bool
178
	 */
179
	private function should_show_captcha() {
180
		$frm_settings = FrmAppHelper::get_settings();
181
		return ! empty( $frm_settings->pubkey );
182
	}
183
184
	protected function should_validate() {
185
		$is_hidden_field = apply_filters( 'frm_is_field_hidden', false, $this->field, wp_unslash( $_POST ) ); // WPCS: CSRF ok.
186
		if ( FrmAppHelper::is_admin() || $is_hidden_field ) {
187
			return false;
188
		}
189
190
		// don't require the captcha if it shouldn't be shown
191
		return $this->should_show_captcha();
192
	}
193
194
	protected function send_api_check( $frm_settings ) {
195
		$arg_array = array(
196
			'body' => array(
197
				'secret'   => $frm_settings->privkey,
198
				'response' => FrmAppHelper::get_param( 'g-recaptcha-response', '', 'post', 'sanitize_text_field' ),
199
				'remoteip' => FrmAppHelper::get_ip_address(),
200
			),
201
		);
202
203
		return wp_remote_post( 'https://www.google.com/recaptcha/api/siteverify', $arg_array );
204
	}
205
}
206