Completed
Push — master ( 1a7371...4a1bf4 )
by Stephanie
22s
created

FrmFieldCaptcha   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 204
Duplicated Lines 2.45 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
dl 5
loc 204
rs 9.68
c 0
b 0
f 0
wmc 34
lcom 1
cbo 4

15 Methods

Rating   Name   Duplication   Size   Complexity  
A include_form_builder_file() 0 3 1
A field_settings_for_type() 0 8 1
A new_field_settings() 0 7 1
A extra_field_opts() 0 7 1
A before_replace_html_shortcodes() 0 3 1
A front_field_input() 0 18 4
A load_field_scripts() 0 6 1
A api_url() 0 16 3
A class_prefix() 0 9 2
A allow_multiple() 0 5 1
A captcha_size() 0 7 3
B validate() 5 35 9
A should_validate() 0 14 4
A send_api_check() 0 11 1
A sanitize_value() 0 3 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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
	 * @var bool
16
	 * @since 3.0
17
	 */
18
	protected $has_for_label = false;
19
20
	/**
21
	 * @return string
22
	 */
23
	protected function include_form_builder_file() {
24
		return FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/field-captcha.php';
25
	}
26
27
	/**
28
	 * @return array
29
	 */
30
	protected function field_settings_for_type() {
31
		return array(
32
			'required'      => false,
33
			'invalid'       => true,
34
			'captcha_size'  => true,
35
			'default'       => false,
36
		);
37
	}
38
39
	/**
40
	 * @return array
41
	 */
42
	protected function new_field_settings() {
43
		$frm_settings = FrmAppHelper::get_settings();
44
45
		return array(
46
			'invalid' => $frm_settings->re_msg,
47
		);
48
	}
49
50
	/**
51
	 * @return array
52
	 */
53
	protected function extra_field_opts() {
54
		return array(
55
			'label'         => 'none',
56
			'captcha_size'  => 'normal',
57
			'captcha_theme' => 'light',
58
		);
59
	}
60
61
	/**
62
	 * Remove the "for" attribute for captcha
63
	 *
64
	 * @param array $args
65
	 * @param string $html
66
	 *
67
	 * @return string
68
	 */
69
	protected function before_replace_html_shortcodes( $args, $html ) {
70
		return str_replace( ' for="field_[key]"', ' for="g-recaptcha-response"', $html );
71
	}
72
73
	public function front_field_input( $args, $shortcode_atts ) {
74
		$frm_settings = FrmAppHelper::get_settings();
75
		if ( empty( $frm_settings->pubkey ) ) {
76
			return '';
77
		}
78
79
		$class_prefix  = $this->class_prefix();
80
		$captcha_size  = $this->captcha_size();
81
		$allow_mutiple = $frm_settings->re_multi;
82
83
		$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'] ) . '"';
84
		if ( $captcha_size == 'invisible' && ! $allow_mutiple ) {
85
			$html .= ' data-callback="frmAfterRecaptcha"';
86
		}
87
		$html .= '></div>';
88
89
		return $html;
90
	}
91
92
	protected function load_field_scripts( $args ) {
93
		$api_js_url = $this->api_url();
94
95
		wp_register_script( 'recaptcha-api', $api_js_url, array( 'formidable' ), '3', true );
96
		wp_enqueue_script( 'recaptcha-api' );
97
	}
98
99
	protected function api_url() {
100
		$api_js_url = 'https://www.google.com/recaptcha/api.js?';
101
102
		$frm_settings  = FrmAppHelper::get_settings();
103
		$allow_mutiple = $frm_settings->re_multi;
104
		if ( $allow_mutiple ) {
105
			$api_js_url .= '&onload=frmRecaptcha&render=explicit';
106
		}
107
108
		$lang = apply_filters( 'frm_recaptcha_lang', $frm_settings->re_lang, $this->field );
109
		if ( ! empty( $lang ) ) {
110
			$api_js_url .= '&hl=' . $lang;
111
		}
112
113
		return apply_filters( 'frm_recaptcha_js_url', $api_js_url );
114
	}
115
116
	protected function class_prefix() {
117
		if ( $this->allow_multiple() ) {
118
			$class_prefix = 'frm-';
119
		} else {
120
			$class_prefix = '';
121
		}
122
123
		return $class_prefix;
124
	}
125
126
	protected function allow_multiple() {
127
		$frm_settings = FrmAppHelper::get_settings();
128
129
		return $frm_settings->re_multi;
130
	}
131
132
	protected function captcha_size() {
133
		// for reverse compatibility
134
		$frm_settings = FrmAppHelper::get_settings();
135
		$captcha_size = ( $this->field['captcha_size'] == 'default' ) ? 'normal' : $this->field['captcha_size'];
136
137
		return ( $frm_settings->re_type == 'invisible' ) ? 'invisible' : $captcha_size;
138
	}
139
140
	public function validate( $args ) {
141
		$errors = array();
142
143
		if ( ! $this->should_validate() ) {
144
			return $errors;
145
		}
146
147
		if ( ! isset( $_POST['g-recaptcha-response'] ) ) {
148
			// If captcha is missing, check if it was already verified.
149
			$checked = FrmAppHelper::get_param( 'recaptcha_checked', '', 'post', 'sanitize_text_field' );
150
			if ( ! isset( $_POST['recaptcha_checked'] ) || ! wp_verify_nonce( $checked, 'frm_ajax' ) ) {
151
				// There was no captcha submitted.
152
				$errors[ 'field' . $args['id'] ] = __( 'The captcha is missing from this form', 'formidable' );
153
			}
154
155
			return $errors;
156
		}
157
158
		$frm_settings = FrmAppHelper::get_settings();
159
160
		$resp     = $this->send_api_check( $frm_settings );
161
		$response = json_decode( wp_remote_retrieve_body( $resp ), true );
162
163
		if ( isset( $response['success'] ) && ! $response['success'] ) {
164
			// What happens when the CAPTCHA was entered incorrectly
165
			$invalid_message                 = FrmField::get_option( $this->field, 'invalid' );
166
			$errors[ 'field' . $args['id'] ] = ( $invalid_message == '' ? $frm_settings->re_msg : $invalid_message );
167 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...
168
			$error_string                    = $resp->get_error_message();
169
			$errors[ 'field' . $args['id'] ] = __( 'There was a problem verifying your recaptcha', 'formidable' );
170
			$errors[ 'field' . $args['id'] ] .= ' ' . $error_string;
171
		}
172
173
		return $errors;
174
	}
175
176
	protected function should_validate() {
177
		$is_hidden_field = apply_filters( 'frm_is_field_hidden', false, $this->field, wp_unslash( $_POST ) ); // WPCS: CSRF ok.
178
		if ( FrmAppHelper::is_admin() || $is_hidden_field ) {
179
			return false;
180
		}
181
182
		$frm_settings = FrmAppHelper::get_settings();
183
		if ( empty( $frm_settings->pubkey ) ) {
184
			// don't require the captcha if it shouldn't be shown
185
			return false;
186
		}
187
188
		return true;
189
	}
190
191
	protected function send_api_check( $frm_settings ) {
192
		$arg_array = array(
193
			'body' => array(
194
				'secret'   => $frm_settings->privkey,
195
				'response' => FrmAppHelper::get_param( 'g-recaptcha-response', '', 'post', 'sanitize_text_field' ),
196
				'remoteip' => FrmAppHelper::get_ip_address(),
197
			),
198
		);
199
200
		return wp_remote_post( 'https://www.google.com/recaptcha/api/siteverify', $arg_array );
201
	}
202
203
	/**
204
	 * @since 4.0
205
	 */
206
	public function sanitize_value( &$value ) {
207
		FrmAppHelper::sanitize_value( 'sanitize_text_field', $value );
208
	}
209
}
210