PluginProbe ʕ •ᴥ•ʔ
WPForms – Easy Form Builder for WordPress – Contact Forms, Payment Forms, Surveys, & More / 1.3.1.1
WPForms – Easy Form Builder for WordPress – Contact Forms, Payment Forms, Surveys, & More v1.3.1.1
1.10.1.1 1.10.1 1.10.0.5 trunk 1.1.4 1.1.4.2 1.1.5 1.1.5.1 1.1.6 1.1.6.1 1.1.7 1.1.7.1 1.1.7.2 1.1.8 1.1.8.1 1.1.8.2 1.1.8.3 1.1.8.4 1.10.0.1 1.10.0.2 1.10.0.3 1.10.0.4 1.2.0 1.2.0.1 1.2.1 1.2.2 1.2.2.1 1.2.2.2 1.2.3 1.2.3.1 1.2.3.2 1.2.4 1.2.4.1 1.2.5 1.2.5.1 1.2.6 1.2.7 1.2.8 1.2.8.1 1.2.9 1.3.0 1.3.1 1.3.1.1 1.3.1.2 1.3.2 1.3.3 1.3.5 1.3.6 1.3.6.1 1.3.6.2 1.3.7.2 1.3.7.3 1.3.7.4 1.3.8 1.3.9.1 1.4.0.1 1.4.1.1 1.4.2 1.4.2.1 1.4.2.2 1.4.3 1.4.4 1.4.4.1 1.4.5 1.4.5.1 1.4.5.2 1.4.5.3 1.4.6 1.4.7.1 1.4.7.2 1.4.8.1 1.4.9 1.5.0.1 1.5.0.3 1.5.0.4 1.5.1 1.5.1.1 1.5.1.3 1.5.2.1 1.5.2.2 1.5.2.3 1.5.3 1.5.3.1 1.5.4.1 1.5.4.2 1.5.5 1.5.5.1 1.5.6 1.5.6.2 1.5.7 1.5.8.2 1.5.9.1 1.5.9.4 1.5.9.5 1.6.0.1 1.6.0.2 1.6.1 1.6.2.2 1.6.2.3 1.6.3.1 1.6.4 1.6.4.1 1.6.5 1.6.6 1.6.7 1.6.7.1 1.6.7.2 1.6.7.3 1.6.8 1.6.8.1 1.6.9 1.7.0 1.7.1.1 1.7.1.2 1.7.2 1.7.2.1 1.7.3 1.7.4 1.7.4.1 1.7.4.2 1.7.5.1 1.7.5.2 1.7.5.3 1.7.5.5 1.7.6 1.7.7 1.7.7.1 1.7.7.2 1.7.8 1.7.9 1.7.9.1 1.8.0.1 1.8.0.2 1.8.1.1 1.8.1.2 1.8.1.3 1.8.2.1 1.8.2.2 1.8.2.3 1.8.3 1.8.3.1 1.8.4 1.8.4.1 1.8.5.2 1.8.5.3 1.8.5.4 1.8.6.2 1.8.6.3 1.8.6.4 1.8.7.2 1.8.8.2 1.8.8.3 1.8.9.1 1.8.9.2 1.8.9.4 1.8.9.5 1.8.9.6 1.9.0.1 1.9.0.2 1.9.0.3 1.9.0.4 1.9.1.1 1.9.1.2 1.9.1.3 1.9.1.4 1.9.1.5 1.9.1.6 1.9.2.1 1.9.2.2 1.9.2.3 1.9.3.1 1.9.3.2 1.9.4.1 1.9.4.2 1.9.5 1.9.5.1 1.9.5.2 1.9.6 1.9.6.1 1.9.6.2 1.9.7.1 1.9.7.2 1.9.7.3 1.9.8.1 1.9.8.2 1.9.8.4 1.9.8.7 1.9.9.2 1.9.9.3 1.9.9.4
wpforms-lite / includes / class-process.php
wpforms-lite / includes Last commit date
admin 9 years ago emails 9 years ago fields 9 years ago templates 9 years ago class-fields.php 9 years ago class-form.php 9 years ago class-frontend.php 9 years ago class-install.php 9 years ago class-logging.php 9 years ago class-preview.php 9 years ago class-process.php 9 years ago class-smart-tags.php 9 years ago class-templates.php 9 years ago class-widget.php 10 years ago functions.php 9 years ago integrations.php 9 years ago
class-process.php
382 lines
1 <?php
2 /**
3 * Process and vaidate form entries.
4 *
5 * @package WPForms
6 * @author WPForms
7 * @since 1.0.0
8 * @license GPL-2.0+
9 * @copyright Copyright (c) 2016, WPForms LLC
10 */
11 class WPForms_Process {
12
13 /**
14 * Holds errors.
15 *
16 * @since 1.0.0
17 * @var array
18 */
19 public $errors;
20
21 /**
22 * Holds formatted fields.
23 *
24 * @since 1.0.0
25 * @var array
26 */
27 public $fields;
28
29 /**
30 * Holds the ID of a successful entry.
31 *
32 * @since 1.2.3
33 * @var int
34 */
35 public $entry_id = 0;
36
37 /**
38 * Primary class constructor.
39 *
40 * @since 1.0.0
41 */
42 public function __construct() {
43
44 add_action( 'wp', array( $this, 'listen' ) );
45 }
46
47 /**
48 * Listen to see if this is a return callback or a posted form entry.
49 *
50 * @since 1.0.0
51 */
52 public function listen() {
53
54 if ( !empty( $_GET['wpforms_return'] ) ) {
55 $this->entry_confirmation_redirect( '', $_GET['wpforms_return'] );
56 }
57
58 if ( !empty( $_POST['wpforms']['id'] ) ) {
59 $this->process( stripslashes_deep( $_POST['wpforms'] ) );
60 }
61 }
62
63 /**
64 * Process the form entry.
65 *
66 * @since 1.0.0
67 * @param array $form $_POST object
68 */
69 public function process( $entry ) {
70
71 $this->errors = array();
72 $this->fields = array();
73 $form_id = absint( $entry['id'] );
74 $form = wpforms()->form->get( $form_id );
75 $honeypot = false;
76
77 // Validate form is real and active (published)
78 if ( !$form || 'publish' != $form->post_status ) {
79 $this->errors[$form_id]['header'] = __( 'Invalid form.', 'wpforms' );
80 return;
81 }
82
83 // Formatted form data for hooks
84 $form_data = apply_filters( 'wpforms_process_before_form_data', wpforms_decode( $form->post_content ), $entry );
85
86 // Pre-process/validate hooks and filter. Data is not validated or
87 // cleaned yet so use with caution.
88 $entry = apply_filters( 'wpforms_process_before_filter', $entry, $form_data );
89
90 do_action( 'wpforms_process_before', $entry, $form_data );
91 do_action( "wpforms_process_before_{$form_id}", $entry, $form_data );
92
93 // Validate fields
94 foreach ( $form_data['fields'] as $field ) {
95
96 $field_id = $field['id'];
97 $field_type = $field['type'];
98 $field_submit = isset( $entry['fields'][$field_id] ) ? $entry['fields'][$field_id] : '';
99
100 do_action( "wpforms_process_validate_{$field_type}", $field_id, $field_submit, $form_data );
101 }
102
103 // reCAPTCHA check
104 $site_key = wpforms_setting( 'recaptcha-site-key', '' );
105 $secret_key = wpforms_setting( 'recaptcha-secret-key', '' );
106 if ( !empty( $site_key ) && !empty( $secret_key ) && isset( $form_data['settings']['recaptcha'] ) && '1' == $form_data['settings']['recaptcha'] ) {
107 if ( !empty( $_POST['g-recaptcha-response'] ) ) {
108 $data = wp_remote_get( 'https://www.google.com/recaptcha/api/siteverify?secret=' . $secret_key . '&response=' . $_POST['g-recaptcha-response'] );
109 $data = json_decode( wp_remote_retrieve_body( $data ) );
110 if ( empty( $data->success ) ) {
111 $this->errors[$form_id]['recaptcha'] = __( 'Incorrect reCAPTCHA, please try again.', 'wpforms' );
112 }
113 } else {
114 $this->errors[$form_id]['recaptcha'] = __( 'reCAPTCHA is required.', 'wpforms' );
115 }
116 }
117
118 // One last error check - don't proceed if there are any errors
119 if ( !empty( $this->errors[$form_id] ) ) {
120 $this->errors[$form_id]['header'] = __( 'Form has not been submitted, please see the errors below.', 'wpforms' );
121 return;
122 }
123
124 // Validate honeypot
125 if ( !empty( $form_data['settings']['honeypot'] ) && '1' == $form_data['settings']['honeypot'] ) {
126 if ( isset( $entry['hp'] ) && !empty( $entry['hp'] ) ) {
127 $honeypot = __( 'WPForms honeypot field triggered.', 'wpforms' );
128 }
129 }
130
131 $honeypot = apply_filters( 'wpforms_process_honeypot', $honeypot, $this->fields, $entry, $form_data );
132
133 // Only trigger the processing (saving/sending entries, etc) if the entry
134 // is not spam.
135 if ( !$honeypot ) {
136
137 // Pass the form created date into the form data
138 $form_data['created'] = $form->post_date;
139
140 // Format fields
141 foreach ( $form_data['fields'] as $field ) {
142
143 $field_id = $field['id'];
144 $field_type = $field['type'];
145 $field_submit = isset( $entry['fields'][$field_id] ) ? $entry['fields'][$field_id] : '';
146
147 do_action( "wpforms_process_format_{$field_type}", $field_id, $field_submit, $form_data );
148 }
149
150 // Process hooks/filter - this is where most add-ons should hook
151 // because at this point we have completed all field validation and
152 // formatted the data.
153 $this->fields = apply_filters( 'wpforms_process_filter', $this->fields, $entry, $form_data );
154
155 do_action( 'wpforms_process', $this->fields, $entry, $form_data );
156 do_action( "wpforms_process_{$form_id}", $this->fields, $entry, $form_data );
157
158 $this->fields = apply_filters( 'wpforms_process_after_filter', $this->fields, $entry, $form_data );
159
160 // One last error check - don't proceed if there are any errors
161 if ( ! empty( $this->errors[$form_id] ) ) {
162 if ( empty( $this->errors[$form_id]['header'] ) ) {
163 $this->errors[$form_id]['header'] = __( 'Form has not been submitted, please see the errors below.', 'wpforms' );
164 }
165 return;
166 }
167
168 // Success - add entry to database
169 $entry_id = $this->entry_save( $this->fields, $entry, $form_data['id'], $form_data );
170
171 // Success - send email notification
172 $this->entry_email( $this->fields, $entry, $form_data, $entry_id );
173
174 // Pass completed and formatted fields in POST
175 $_POST['wpforms']['complete'] = $this->fields;
176
177 // Pass entry ID in POST
178 $_POST['wpforms']['entry_id'] = $entry_id;
179
180 // Logs entry depending on log levels set
181 wpforms_log(
182 'Entry',
183 $this->fields,
184 array(
185 'type' => array( 'entry' ),
186 'parent' => $entry_id,
187 'form_id' => $form_data['id'],
188 )
189 );
190
191 // Post-process hooks
192 do_action( 'wpforms_process_complete', $this->fields, $entry, $form_data, $entry_id );
193 do_action( "wpforms_process_complete_{$form_id}", $this->fields, $entry, $form_data, $entry_id );
194
195 } else {
196
197 // Logs spam entry depending on log levels set
198 wpforms_log(
199 'Spam Entry',
200 array( $honeypot, $entry ),
201 array(
202 'type' => array( 'spam' ),
203 'form_id' => $form_data['id'],
204 )
205 );
206 }
207
208 $this->entry_confirmation_redirect( $form_data );
209 }
210
211 /**
212 * Validate the form return hash.
213 *
214 * @since 1.0.0
215 * @param string $hash
216 * @return mixed false for invalid or form id
217 */
218 public function validate_return_hash( $hash = '' ) {
219
220 $query_args = base64_decode( $hash );
221 parse_str( $query_args );
222
223 // Verify hash matches
224 if ( $hash != wp_hash( $form_id . ',' . $entry_id ) ) {
225 return false;
226 }
227
228 // Get lead and verify it is attached to the form we received with it
229 $entry = wpforms()->entry->get( $entry_id );
230 if ( $form_id != $entry->form_id ) {
231 return false;
232 }
233
234 return $form_id;
235 }
236
237 /**
238 * Redirects user to a page or URL specified in the form confirmation settings.
239 *
240 * @since 1.0.0
241 * @param array $form_data
242 * @param string $hash
243 */
244 public function entry_confirmation_redirect( $form_data = '', $hash = '' ) {
245
246 $url = '';
247
248 if ( !empty( $hash ) ) {
249
250 $form_id = $this->validate_return_hash( $hash );
251
252 if ( !$form_id )
253 return;
254
255 // Get form
256 $form_data = wpforms()->form->get( $form_id, array( 'content_only' => true ) );
257 }
258
259 // Redirect if needed, to either a page or URL, after form processing
260 if ( !empty( $form_data['settings']['confirmation_type'] ) && $form_data['settings']['confirmation_type'] != 'message' ) {
261
262 if ( $form_data['settings']['confirmation_type'] == 'redirect' ) {
263 $url = apply_filters( 'wpforms_process_smart_tags', $form_data['settings']['confirmation_redirect'], $form_data, $this->fields, $this->entry_id );
264 }
265
266 if ( $form_data['settings']['confirmation_type'] == 'page' ) {
267 $url = get_permalink( (int) $form_data['settings']['confirmation_page'] );
268 }
269 }
270
271 if ( !empty( $form_data['id'] ) ) {
272 $form_id = $form_data['id'];
273 } else {
274 return;
275 }
276
277 if ( !empty( $url ) ) {
278 $url = apply_filters( 'wpforms_process_redirect_url', $url, $form_id, $this->fields );
279 wp_redirect( esc_url_raw( $url ) );
280 do_action( 'wpforms_process_redirect', $form_id );
281 do_action( "wpforms_process_redirect_{$form_id}", $form_id );
282 exit;
283 }
284 }
285
286 /**
287 * Sends entry email notifications.
288 *
289 * @since 1.0.0
290 * @param array $fields
291 * @param array $entry
292 * @param array $form_data
293 */
294 public function entry_email( $fields, $entry, $form_data ) {
295
296 // Check that the form was configured for email notifcations
297 if ( empty( $form_data['settings']['notification_enable'] ) || '1' != $form_data['settings']['notification_enable'] ) {
298 return;
299 }
300
301 // Provide the opportunity to override via a filter
302 if ( ! apply_filters( 'wpforms_entry_email', true, $fields, $entry, $form_data ) ) {
303 return;
304 }
305
306 $fields = apply_filters( 'wpforms_entry_email_data', $fields, $entry, $form_data );
307
308 // Backwards compatibility for notifications before v1.2.3
309 if ( empty( $form_data['settings']['notifications'] ) ) {
310 $notifications[1] = array(
311 'email' => $form_data['settings']['notification_email'],
312 'subject' => $form_data['settings']['notification_subject'],
313 'sender_name' => $form_data['settings']['notification_fromname'],
314 'sender_address' => $form_data['settings']['notification_fromaddress'],
315 'replyto' => $form_data['settings']['notification_replyto'],
316 'message' => '{all_fields}',
317 );
318 } else {
319 $notifications = $form_data['settings']['notifications'];
320 }
321
322 foreach( $notifications as $notification_id => $notification ) {
323
324 if ( empty( $notification['email'] ) ) {
325 continue;
326 }
327
328 $process_email = apply_filters( 'wpforms_entry_email_process', true, $fields, $form_data, $notification_id );
329
330 if ( ! $process_email ) {
331 continue;
332 }
333
334 $email = array();
335
336 // Setup email properties
337 $email['address'] = explode( ',', apply_filters( 'wpforms_process_smart_tags', $notification['email'], $form_data, $fields, $this->entry_id ) );
338 $email['address'] = array_map( 'sanitize_email', $email['address'] );
339 $email['subject'] = !empty( $notification['subject'] ) ? $notification['subject'] : sprintf( __( 'New %s Entry', 'wpforms ' ), $form_data['settings']['form_title'] );
340 $email['sender_address'] = !empty( $notification['sender_address'] ) ? $notification['sender_address'] : get_option( 'admin_email' );
341 $email['sender_name'] = !empty( $notification['sender_name'] ) ? $notification['sender_name'] : get_bloginfo( 'name' );
342 $email['replyto'] = !empty( $notification['replyto'] ) ? $notification['replyto'] : false;
343 $email['message'] = !empty( $notification['message'] ) ? $notification['message'] : '{all_fields}';
344 $email = apply_filters( 'wpforms_entry_email_atts', $email, $fields, $entry, $form_data, $notification_id );
345
346 // Create new email
347 $emails = new WPForms_WP_Emails;
348 $emails->__set( 'form_data', $form_data );
349 $emails->__set( 'fields', $fields );
350 $emails->__set( 'entry_id', $this->entry_id );
351 $emails->__set( 'from_name', $email['sender_name'] );
352 $emails->__set( 'from_address', $email['sender_address'] );
353 $emails->__set( 'reply_to', $email['replyto'] );
354
355 // Maybe include CC
356 if ( !empty( $notification['carboncopy'] ) && wpforms_setting( 'email-carbon-copy', false ) ) {
357 $emails->__set( 'cc', $notification['carboncopy'] );
358 }
359
360 // Go
361 foreach( $email['address'] as $address ) {
362 $emails->send( trim( $address ), $email['subject'], $email['message'] );
363 }
364 }
365 }
366
367 /**
368 * Saves entry to database.
369 *
370 * @since 1.0.0
371 * @param array $fields
372 * @param array $entry
373 * @param array $form_data
374 */
375 public function entry_save( $fields, $entry, $form_id, $form_data = '' ) {
376
377 do_action( 'wpforms_process_entry_save', $fields, $entry, $form_id, $form_data );
378
379 return $this->entry_id;
380 }
381 }
382