PluginProbe
Happyforms – Form Builder for WordPress: Drag & Drop Contact Forms, Surveys, Payments & Multipurpose Forms / delete
Happyforms – Form Builder for WordPress: Drag & Drop Contact Forms, Surveys, Payments & Multipurpose Forms vdelete
1.26.15 trunk 1.0 1.10.0 1.11.0 1.11.1 1.12.0 1.12.1 1.12.10 1.12.11 1.12.12 1.12.2 1.12.3 1.12.4 1.12.5 1.12.6 1.12.7 1.12.8 1.12.9 1.13.0 1.13.1 1.13.10 1.13.11 1.13.12 1.13.2 All 194 releases
happyforms / inc / classes / class-message-controller.php

class-message-controller.php in Happyforms – Form Builder for WordPress: Drag & Drop Contact Forms, Surveys, Payments & Multipurpose Forms delete, at inc/classes/class-message-controller.php

683 lines 18.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class HappyForms_Message_Controller {
4
5 /**
6 * The singleton instance.
7 *
8 * @since 1.0
9 *
10 * @var HappyForms_Message_Controller
11 */
12 private static $instance;
13
14 /**
15 * The message post type slug.
16 *
17 * @since 1.0
18 *
19 * @var string
20 */
21 public $post_type = 'happyforms-message';
22
23 /**
24 * The dummy post type slug.
25 *
26 * @since 1.13.0
27 *
28 * @var string
29 */
30 public $dummy_type = 'happyforms-activity';
31
32 /**
33 * The parameter name used to identify a
34 * submission form
35 *
36 * @since 1.0
37 *
38 * @var string
39 */
40 public $form_parameter = 'happyforms_form_id';
41
42 /**
43 * The parameter name used to identify a
44 * submission form
45 *
46 * @var string
47 */
48 public $form_step_parameter = 'happyforms_step';
49
50 /**
51 * The action name used to identify a
52 * message submission request.
53 *
54 * @since 1.0
55 *
56 * @var string
57 */
58 public $submit_action = 'happyforms_message';
59
60 /**
61 * The singleton constructor.
62 *
63 * @since 1.0
64 *
65 * @return HappyForms_Message_Controller
66 */
67 public static function instance() {
68 if ( is_null( self::$instance ) ) {
69 self::$instance = new self();
70 }
71
72 self::$instance->hook();
73
74 return self::$instance;
75 }
76
77 /**
78 * Register hooks.
79 *
80 * @since 1.0
81 *
82 * @return void
83 */
84 public function hook() {
85 add_action( 'init', array( $this, 'register_dummy_post_type' ) );
86 add_filter( 'happyforms_responses_page_url', array( $this, 'dummy_page_url' ) );
87
88 add_action( 'parse_request', array( $this, 'admin_post' ) );
89 add_action( 'admin_init', array( $this, 'admin_post' ) );
90 add_filter( 'happyforms_email_part_visible', array( $this, 'email_part_visible' ), 10, 4 );
91
92 // Core multi-step hooks
93 add_action( 'happyforms_step', array( $this, 'default_submission_step' ) );
94 }
95
96 public function get_meta_fields() {
97 $fields = array(
98 'form_id' => 0,
99 'read' => false,
100 'tracking_id' => '',
101 );
102 return $fields;
103 }
104
105 public function to_array( $message ) {
106 $message_array = $message->to_array();
107 $message_meta = happyforms_unprefix_meta( get_post_meta( $message->ID ) );
108 $form_id = $message_meta['form_id'];
109 $form = happyforms_get_form_controller()->get( $form_id );
110 $meta_defaults = $this->get_meta_fields();
111 $message_array = array_merge( $message_array, wp_parse_args( $message_meta, $meta_defaults ) );
112 $message_array['parts'] = array();
113
114 if ( $form ) {
115 foreach ( $form['parts'] as $part_data ) {
116 $part = happyforms_get_part_library()->get_part( $part_data['type'] );
117
118 if ( $part ) {
119 $part_id = $part_data['id'];
120 $part_value = $part->get_default_value( $part_data );
121
122 if ( isset( $message_meta[$part_id] ) ) {
123 $part_value = $message_meta[$part_id];
124 }
125
126 $message_array['parts'][$part_id] = $part_value;
127 unset( $message_array[$part_id] );
128 }
129 }
130 }
131
132 return $message_array;
133 }
134
135 /**
136 * Action: handle a form submission.
137 *
138 * @hooked action parse_request
139 *
140 * @since 1.0
141 *
142 * @return void
143 */
144 public function admin_post() {
145 // Exit early if we're not submitting any form
146 if ( ! isset ( $_REQUEST['action'] ) || $this->submit_action != $_REQUEST['action'] ) {
147 return;
148 }
149
150 // Check form_id parameter
151 if ( ! isset ( $_REQUEST[$this->form_parameter] ) ) {
152 wp_send_json_error();
153 }
154
155 $form_id = intval( $_REQUEST[$this->form_parameter] );
156
157 $form_controller = happyforms_get_form_controller();
158 $form = $form_controller->get( $form_id );
159
160 // Check if form found
161 if ( ! $form || is_wp_error( $form ) ) {
162 wp_send_json_error();
163 }
164
165 // Set form step
166 $step = isset( $_REQUEST[$this->form_step_parameter] ) ?
167 $_REQUEST[$this->form_step_parameter] : '';
168
169 happyforms_get_session()->set_step( $step );
170
171 // Validate honeypot
172 if ( happyforms_get_form_controller()->has_honeypot_protection( $form ) ) {
173 if ( ! happyforms_validate_honeypot( $form ) && ! defined( 'HAPPYFORMS_IS_SPAMBOT' ) ) {
174 define( 'HAPPYFORMS_IS_SPAMBOT', true );
175 }
176 }
177
178 // Validate hash
179 if ( happyforms_get_form_controller()->has_hash_protection( $form ) ) {
180 if ( ! happyforms_validate_hash( $form ) && ! defined( 'HAPPYFORMS_IS_SPAMBOT' ) ) {
181 define( 'HAPPYFORMS_IS_SPAMBOT', true );
182 }
183 }
184
185 // Validate browser
186 if ( happyforms_get_form_controller()->has_browser_protection( $form ) ) {
187 if ( ! happyforms_validate_browser( $form ) && ! defined( 'HAPPYFORMS_IS_SPAMBOT' ) ) {
188 define( 'HAPPYFORMS_IS_SPAMBOT', true );
189 }
190 }
191
192 define( 'HAPPYFORMS_STEPPING', true );
193 do_action( 'happyforms_step', $form );
194 }
195
196 public function default_submission_step( $form ) {
197 if ( 'submit' !== happyforms_get_current_step( $form ) ) {
198 return;
199 }
200
201 $form_id = $form['ID'];
202 $form_controller = happyforms_get_form_controller();
203 $session = happyforms_get_session();
204 $submission = $this->validate_submission( $form, $_REQUEST );
205 $response = array();
206
207 if ( false === $submission ) {
208 // Add a general error notice at the top
209 $session->add_error( $form_id, wp_kses (
210 html_entity_decode( $form['error_message'] ),
211 array(
212 'a' => array(
213 'href' => array(),
214 'title' => array(),
215 ),
216 'p' => array(),
217 'em' => array(),
218 'strong' => array(),
219 ))
220 );
221
222 // Reset to start step
223 $session->reset_step();
224
225 // Render the form
226 $response['html'] = $form_controller->render( $form );
227
228 /**
229 * This action fires upon an invalid submission.
230 *
231 * @since 1.4
232 *
233 * @param WP_Error $submission Error data.
234 * @param array $form Current form data.
235 *
236 * @return void
237 */
238 do_action( 'happyforms_submission_error', $submission, $form );
239
240 // Send error response
241 wp_send_json_error( $response );
242 } else {
243 // Add a general success notice at the top
244 $session->add_notice( $form_id, wp_kses (
245 html_entity_decode($form['confirmation_message'] ) ,
246 array(
247 'a' => array(
248 'href' => array(),
249 'title' => array(),
250 ),
251 'p' => array(),
252 'em' => array(),
253 'strong' => array(),
254 ))
255 );
256
257 // Reset to start step
258 $session->reset_step();
259
260 // Empty submitted values
261 $session->clear_values();
262
263 if ( ! happyforms_is_spambot() ) {
264 if ( 1 === intval( $form['receive_email_alerts'] ) ) {
265 $this->email_owner_confirmation( $form, $submission );
266 }
267
268 if ( 1 === intval( $form['send_confirmation_email'] ) ) {
269 $this->email_user_confirmation( $form, $submission );
270 }
271
272 /**
273 * This action fires once a message is succesfully submitted.
274 *
275 * @since 1.4
276 *
277 * @param array $submission Submission data.
278 * @param array $form Current form data.
279 *
280 * @return void
281 */
282 do_action( 'happyforms_submission_success', $submission, $form, array() );
283 }
284
285 // Render the form
286 $response['html'] = $form_controller->render( $form );
287
288 // Send success response
289 $this->send_json_success( $response, $submission, $form );
290 }
291 }
292
293 public function send_json_success( $response = array(), $submission = array(), $form = array() ) {
294 $response = apply_filters( 'happyforms_json_response', $response, $submission, $form );
295
296 wp_send_json_success( $response );
297 }
298
299 public function validate_part( $form, $part, $request ) {
300 $part_class = happyforms_get_part_library()->get_part( $part['type'] );
301
302 if ( false !== $part_class ) {
303 $part_id = $part['id'];
304 $part_name = happyforms_get_part_name( $part, $form );
305 $sanitized_value = $part_class->sanitize_value( $part, $form, $request );
306 $validated_value = $part_class->validate_value( $sanitized_value, $part, $form );
307 $validated_value = apply_filters( 'happyforms_validate_part_submission', $validated_value, $part, $form, $request );
308
309 $session = happyforms_get_session();
310 $session->add_value( $part_name, $sanitized_value );
311
312 if ( ! is_wp_error( $validated_value ) ) {
313 return $validated_value;
314 } else {
315 do_action( 'happyforms_validation_error', $form, $part );
316
317 $part_field = $part_name;
318 $error_data = $validated_value->get_error_data();
319
320 if ( ! empty( $error_data ) && isset( $error_data['components'] ) ) {
321 foreach ( $error_data['components'] as $component ) {
322 $session->add_error( $part_field, $validated_value->get_error_message(), $component );
323 }
324 } else {
325 $session->add_error( $part_field, $validated_value->get_error_message() );
326 }
327 }
328 }
329
330 return false;
331 }
332
333 public function validate_submission( $form, $request = array() ) {
334 $submission = array();
335 $is_valid = true;
336
337 if ('trash' === get_post_status( $form['ID'] )) {
338 $is_valid = false;
339 } else {
340 foreach( $form['parts'] as $part ) {
341 $part_id = $part['id'];
342 $validated_value = $this->validate_part( $form, $part, $request );
343
344 if ( false !== $validated_value ) {
345 $string_value = happyforms_stringify_part_value( $validated_value, $part, $form );
346 $submission[$part_id] = $string_value;
347 } else {
348 $is_valid = false;
349 }
350 }
351 }
352
353 $is_valid = apply_filters( 'happyforms_validate_submission', $is_valid, $request, $form );
354
355 return $is_valid ? $submission : false;
356 }
357
358 public function email_part_visible( $visible, $part, $form, $response ) {
359 $required = happyforms_is_truthy( $part['required'] );
360 $value = happyforms_get_email_part_value( $response, $part, $form );
361
362 if ( false === $required && empty( $value ) ) {
363 $visible = false;
364 }
365
366 if ( isset( $part['use_as_subject'] ) && $part['use_as_subject'] ) {
367 $visible = false;
368 }
369
370 return $visible;
371 }
372
373 public function get_email_owner_confirmation_subject( $form, $message ) {
374 $subject = $form['alert_email_subject'];
375
376 $subject_parts = array_filter( $form['parts'], function( $part ) {
377 $use_as_subject = (
378 isset( $part['use_as_subject'] )
379 && intval( $part['use_as_subject'] )
380 );
381
382 return $use_as_subject;
383 } );
384 $subject_parts = array_values( $subject_parts );
385
386 if ( count( $subject_parts ) > 0 ) {
387 $part = $subject_parts[count( $subject_parts ) - 1];
388 $message = array( 'parts' => $message );
389 $subject = happyforms_get_email_part_value( $message, $part, $form );
390 }
391
392 return $subject;
393 }
394
395 /**
396 * Send a confirmation email to the site owner.
397 *
398 * @since 1.0
399 *
400 * @param array $form The message form data.
401 * @param string $message The message contents.
402 *
403 * @return void
404 */
405 private function email_owner_confirmation( $form, $message ) {
406 $subject = $this->get_email_owner_confirmation_subject( $form, $message );
407
408 if ( ! empty( $form['email_recipient'] ) && ! empty( $subject ) ) {
409 // Compose an email message
410 $email_message = new HappyForms_Email_Message( $message );
411 $name = $form['alert_email_from_name'];
412 $to = explode( ',', $form['email_recipient'] );
413
414 $from_address = happyforms_get_form_property( $form, 'alert_email_from_address' );
415 $from_address = explode( ',', $from_address );
416
417 $email_message->set_from( $from_address[0] );
418 $email_message->set_from_name( $name );
419 $email_message->set_to( $to[0] );
420
421 if ( count( $to ) > 1 ) {
422 $email_message->set_ccs( array_slice( $to, 1 ) );
423 }
424
425 $bccs = explode( ',', $form['email_bccs'] );
426
427 if ( count( $bccs ) > 0 ) {
428 $email_message->set_bccs( $bccs );
429 }
430
431 $email_message->set_subject( $subject );
432
433 $email_reply_to_id = happyforms_get_form_property( $form, 'alert_email_reply_to' );
434 $email_reply_parts = array();
435
436 if ( 'all' === $email_reply_to_id ) {
437 $email_reply_parts = happyforms_get_form_controller()->get_parts_by_type( $form, 'email' );
438 } else {
439 $email_part = happyforms_get_form_controller()->get_part_by_id( $form, $email_reply_to_id );
440
441 if ( ! $email_part ) {
442 $email_part = happyforms_get_form_controller()->get_first_part_by_type( $form, 'email' );
443 }
444
445 if ( $email_part ) {
446 $email_reply_parts[] = $email_part;
447 }
448 }
449
450 if ( ! empty( $email_reply_parts ) ) {
451 $reply_to = array_map( function( $email_part ) use( $message ) {
452 $part_id = $email_part['id'];
453 $part_value = happyforms_get_message_part_value( $message[$part_id], $email_part );
454
455 return $part_value;
456 }, $email_reply_parts );
457
458 $reply_to = array_values( array_filter( array_map( 'trim', $reply_to ) ) );
459
460 $email_message->set_reply_to( $reply_to );
461 }
462
463 $ip_address = happyforms_get_client_ip();
464 $client_referer = (
465 isset( $_REQUEST['happyforms_client_referer'] ) ?
466 $_REQUEST['happyforms_client_referer'] : ''
467 );
468
469 ob_start();
470 $response = $message;
471 require_once( happyforms_owner_email_template_path() );
472 $content = ob_get_clean();
473
474 $email_message->set_content( $content );
475 $email_message = apply_filters( 'happyforms_email_alert', $email_message );
476 $email_message->send();
477 }
478 }
479
480 /**
481 * Send a confirmation email to the user submitting the form.
482 *
483 * @since 1.0
484 *
485 * @param array $form The message form data.
486 * @param string $message The message contents.
487 *
488 * @return void
489 */
490 private function email_user_confirmation( $form, $message ) {
491 $email_part = happyforms_get_form_controller()->get_first_part_by_type( $form, 'email' );
492
493 if ( false !== $email_part
494 && ! empty( $form['confirmation_email_subject'] )
495 && ! empty( $form['confirmation_email_content'] )
496 && ! empty( $form['confirmation_email_sender_address'] ) ) {
497
498 // Compose an email message
499 $email_message = new HappyForms_Email_Message( $message );
500 $senders = happyforms_get_form_property( $form, 'confirmation_email_sender_address' );
501 $senders = explode( ',', $senders );
502 $name = happyforms_get_form_property( $form, 'confirmation_email_from_name' );
503 $from = $senders[0];
504 $reply_to = happyforms_get_form_property( $form, 'confirmation_email_reply_to' );
505 $reply_to = empty( $reply_to ) ? $from : $reply_to;
506
507 $email_message->set_from( $from );
508 $email_message->set_from_name( $name );
509 $email_message->set_reply_to( $reply_to );
510 $email_message->set_subject( $form['confirmation_email_subject'] );
511 $part_id = $email_part['id'];
512 $to = happyforms_get_message_part_value( $message[$part_id], $email_part );
513 $email_message->set_to( $to );
514 $ip_address = happyforms_get_client_ip();
515 $client_referer = (
516 isset( $_REQUEST['happyforms_client_referer'] ) ?
517 $_REQUEST['happyforms_client_referer'] : ''
518 );
519
520 ob_start();
521 $response = $message;
522 require_once( happyforms_user_email_template_path() );
523 $content = ob_get_clean();
524
525 $email_message->set_content( $content );
526 $email_message = apply_filters( 'happyforms_email_confirmation', $email_message );
527 $email_message->send();
528 }
529 }
530
531 public function get_archivable_forms() {
532 global $wpdb;
533
534 $query = "
535 SELECT p.ID, p.post_title FROM $wpdb->posts p
536 JOIN $wpdb->postmeta m
537 ON p.ID = m.meta_value AND m.meta_key = '_happyforms_form_id'
538 GROUP BY p.ID;
539 ";
540
541 $forms = $wpdb->get_results( $query );
542
543 return $forms;
544 }
545
546 public function export_archive( $form ) {
547 $form_id = $form['ID'];
548 $parts = wp_list_pluck( $form['parts'], 'id' );
549 $parts = array_combine( $parts, $form['parts'] );
550
551 $messages = get_posts( array(
552 'post_type' => $this->post_type,
553 'post_status' => array( 'publish', 'draft', 'trash' ),
554 'posts_per_page' => -1,
555 'meta_query' => array( array(
556 'field' => '_happyforms_form_id',
557 'value' => $form_id,
558 ) )
559 ) );
560
561 $messages = array_map( array( $this, 'to_array'), $messages );
562 $headers = array();
563 $rows = array();
564
565 foreach ( $parts as $part_id => $part ) {
566 $headers[$part_id] = happyforms_get_csv_header( $part );
567 }
568
569 $headers = apply_filters( 'happyforms_csv_headers', $headers, $form );
570
571 foreach( $messages as $message ) {
572 $row = array();
573 foreach( $headers as $part_id => $header ) {
574 $value = $message['parts'][$part_id];
575 $part = $parts[$part_id];
576 $row[] = happyforms_get_csv_value( $value, $message, $part, $form );
577 }
578 $rows[] = $row;
579 }
580
581 $filename = 'messages.csv';
582 $output = fopen( 'php://output', 'w' );
583
584 header( 'Content-Description: File Transfer' );
585 header( 'Content-Disposition: attachment; filename=' . $filename );
586 header( 'Content-Type: text/csv; charset=' . get_option( 'blog_charset' ), true );
587 fputcsv( $output, array_values( $headers ) );
588
589 foreach( $rows as $row ) {
590 fputcsv( $output, array_values( $row ) );
591 }
592
593 exit();
594 }
595
596 public function register_dummy_post_type() {
597 $labels = array(
598 'name' => __( 'Submissions', 'happyforms' ),
599 'singular_name' => __( 'Submission', 'happyforms' ),
600 'all_items' => __( 'All Submissions', 'happyforms' ),
601 'menu_name' => __( 'All Submissions', 'happyforms' ),
602 'not_found' => __( 'No submissions found.', 'happyforms' ),
603 );
604
605 $args = array(
606 'labels' => $labels,
607 'public' => false,
608 'publicly_queryable' => false,
609 'exclude_from_search' => true,
610 'show_ui' => true,
611 'show_in_menu' => false,
612 'show_in_admin_bar' => false,
613 'query_var' => true,
614 'capability_type' => 'page',
615 'has_archive' => false,
616 'hierarchical' => false,
617 'can_export' => false,
618 'supports' => array( '' ),
619 );
620
621 register_post_type( $this->dummy_type, $args );
622 }
623
624 public function dummy_page_url( $url ) {
625 $url = "edit.php?post_type={$this->dummy_type}";
626
627 return $url;
628 }
629
630 public function get_by_form( $form_id, $ids_only = false, $count = -1 ) {
631 if ( $ids_only ) {
632 global $wpdb;
633
634 $query = $wpdb->prepare( "
635 SELECT p.ID FROM $wpdb->posts p
636 JOIN $wpdb->postmeta m ON p.ID = m.post_id
637 WHERE p.post_type = 'happyforms-message'
638 AND m.meta_key = '_happyforms_form_id'
639 AND m.meta_value = %d;
640 ", $form_id );
641
642 $results = $wpdb->get_col( $query );
643
644 return $results;
645 }
646
647 $query_params = array(
648 'post_type' => $this->post_type,
649 'post_status' => 'any',
650 'posts_per_page' => $count,
651 'meta_query' => array( array(
652 'key' => '_happyforms_form_id',
653 'value' => $form_id,
654 ) )
655 );
656
657 $messages = get_posts( $query_params );
658 $message_entries = array_map( array( $this, 'to_array'), $messages );
659
660 return $message_entries;
661 }
662
663 }
664
665 if ( ! function_exists( 'happyforms_get_message_controller' ) ):
666 /**
667 * Get the HappyForms_Message_Controller class instance.
668 *
669 * @since 1.0
670 *
671 * @return HappyForms_Message_Controller
672 */
673 function happyforms_get_message_controller() {
674 return HappyForms_Message_Controller::instance();
675 }
676
677 endif;
678
679 /**
680 * Initialize the HappyForms_Message_Controller class immediately.
681 */
682 happyforms_get_message_controller();
683