/** * Primary class constructor. * * @since 1.0.0 */ public function __construct() { // Load form if found $form_id = isset($_GET['form_id']) ? absint($_GET['form_id']) : false; $this->form = wpforms()->form->get($form_id); $this->form_data = $this->form ? wpforms_decode($this->form->post_content) : false; // Bootstrap $this->init(); // Load panel specific enqueus add_action('admin_enqueue_scripts', array($this, 'enqueues'), 15); // Primary panel button add_action('wpforms_builder_panel_buttons', array($this, 'button'), $this->order, 2); // Output add_action('wpforms_builder_panels', array($this, 'panel_output'), $this->order, 2); }
/** * Retrieve actual fields from a form. * * Non-posting elements such as section divider, page break, and HTML are * automatically excluded. Optionally a white list can be provided. * * @since 1.0.0 * @param mixed $form * @return mixed boolean or array */ function wpforms_get_form_fields($form = false, $whitelist = array()) { // Accept form (post) object or form ID if (is_object($form)) { $form = wpforms_decode($form->post_content); } elseif (is_numeric($form)) { $form = wpforms()->form->get($form, array('content_only' => true)); } if (!is_array($form) || empty($form['fields'])) { return false; } // White list of field types to allow $allowed_form_fields = array('text', 'textarea', 'select', 'radio', 'checkbox', 'email', 'address', 'url', 'name', 'hidden', 'date-time', 'phone', 'number', 'file-upload', 'payment-single', 'payment-multiple', 'payment-total'); $allowed_form_fields = apply_filters('wpforms_get_form_fields_allowed', $allowed_form_fields); $whitelist = !empty($whitelist) ? $whitelist : $allowed_form_fields; $form_fields = $form['fields']; foreach ($form_fields as $id => $form_field) { if (!in_array($form_field['type'], $whitelist)) { unset($form_fields[$id]); } } return $form_fields; }
/** * Primary function to render a form on the frontend. * * @since 1.0.0 * @param int $id * @param boolean $title * @param boolean $description */ public function output($id, $title = false, $description = false) { // Grab the form data, if not found then we bail $form = wpforms()->form->get((int) $id); if (!$form) { return; } // Basic information $form_data = wpforms_decode($form->post_content, true); $form_id = absint($form->ID); $settings = $form_data['settings']; $action = esc_url_raw(remove_query_arg('wpforms')); $class[] = wpforms_setting('disable-css', '1') == '1' ? 'wpforms-container-full' : ''; $errors = empty(wpforms()->process->errors[$form->ID]) ? array() : wpforms()->process->errors[$form->ID]; $success = false; // If the form does not contain any fields do not proceed if (empty($form_data['fields'])) { echo '<!-- WPForms: no fields, form hidden -->'; return; } // Before output hook do_action('wpforms_frontend_output_before', $form_data, $form); // Check for return hash OR error free completed form and confirmation before we continue if (!empty($_GET['wpforms_return'])) { $success = wpforms()->process->validate_return_hash($_GET['wpforms_return']); if ($success) { $form_data = wpforms()->form->get($success, array('content_only' => true)); } } elseif (!empty($_POST['wpforms']['id']) && $form->ID == $_POST['wpforms']['id'] && empty($errors)) { $success = true; } if ($success && !empty($form_data)) { do_action('wpforms_frontend_output_success', $form_data); // Debug wpforms_debug_data($_POST); return; } // Allow filter to return early if some condition is not met. if (!apply_filters('wpforms_frontend_load', true, $form_data, $form)) { return; } // Prep the form action URL, allow filter if (!empty($settings['confirmation_type']) && 'message' == $settings['confirmation_type'] && !empty($settings['confirmation_message_scroll'])) { $action .= '#wpforms-' . $form_id; } $action = apply_filters('wpforms_frontend_form_action', $action, $form_data, $form); // Allow form container classes to be filtered $class = array_map('sanitize_html_class', apply_filters('wpforms_frontend_container_class', $class, $form_data)); if (!empty($form_data['settings']['form_class'])) { $class = array_merge($class, array_map('sanitize_html_class', explode(' ', $form_data['settings']['form_class']))); } // Begin to build the output echo '<div class="wpforms-container ' . implode(' ', $class) . '" id="wpforms-' . $form_id . '">'; echo '<form method="post" enctype="multipart/form-data" id="wpforms-form-' . $form_id . '" action="' . $action . '" class="wpforms-validate wpforms-form" data-formid="' . $form_id . '">'; do_action('wpforms_frontend_output', $form_data, $form, $title, $description, $errors); echo '</form>'; echo '</div>'; // After output hook do_action('wpforms_frontend_output_after', $form_data, $form); $this->forms[$form_id] = $form_data; // Debug wpforms_debug_data($form_data); }
/** * Duplicate forms. * * @since 1.1.4 * @param array $ids * @return boolean */ public function duplicate($ids = array()) { // Check for permissions if (!current_user_can(apply_filters('wpforms_manage_cap', 'manage_options'))) { return false; } if (!is_array($ids)) { $ids = array($ids); } $ids = array_map('absint', $ids); foreach ($ids as $id) { // Get original entry $form = get_post($id); // Confirm form exists if (!$form || empty($form)) { return false; } // Get the form data $new_form_data = wpforms_decode($form->post_content); // Remove form ID from title if present $new_form_data['settings']['form_title'] = str_replace('(ID #' . absint($id) . ')', '', $new_form_data['settings']['form_title']); // Create the duplicate form $new_form = array('post_author' => $form->post_author, 'post_content' => wp_slash(json_encode($new_form_data)), 'post_excerpt' => $form->post_excerpt, 'post_status' => $form->post_status, 'post_title' => $new_form_data['settings']['form_title'], 'post_type' => $form->post_type); $new_form_id = wp_insert_post($new_form); if (!$new_form_id || is_wp_error($new_form_id)) { return false; } // Set new form title $new_form_data['settings']['form_title'] .= ' (ID #' . absint($new_form_id) . ')'; // Set new form ID $new_form_data['id'] = absint($new_form_id); // Update new duplicate form $new_form_id = $this->update($new_form_id, $new_form_data); if (!$new_form_id || is_wp_error($new_form_id)) { return false; } } return true; }
/** * Load the appropriate files to build the page. * * @since 1.0.0 */ public function output() { $form_id = $this->form ? absint($this->form->ID) : ''; $form_data = $this->form ? wpforms_decode($this->form->post_content) : false; ?> <div id="wpforms-builder"> <div id="wpforms-builder-overlay"> <div class="wpforms-builder-overlay-content"> <i class="fa fa-cog fa-spin"></i> <span class="msg"><?php _e('Loading', 'wpforms'); ?> </span> </div> </div> <form name="wpforms-builder" id="wpforms-builder-form" method="post" data-id="<?php echo $form_id; ?> "> <input type="hidden" name="id" value="<?php echo $form_id; ?> "> <input type="hidden" value="<?php echo absint($form_data['field_id']); ?> " name="field_id" id="wpforms-field-id"> <!-- Toolbar --> <div class="wpforms-toolbar"> <div class="wpforms-left"> <img src="<?php echo WPFORMS_PLUGIN_URL; ?> /assets/images/logo-builder.png" alt="Sullie WPForms mascot"> </div> <div class="wpforms-center"> <?php if ($this->form) { ?> <?php _e('Now editing', 'wpforms'); ?> <span class="wpforms-center-form-name wpforms-form-name"><?php echo esc_html($this->form->post_title); ?> </span> <?php } ?> </div> <div class="wpforms-right"> <?php if ($this->form) { ?> <!--<a href="<?php echo esc_url(wpforms()->preview->form_preview_url($form_id)); ?> " id="wpforms-preview" title="<?php _e('Preview Form', 'wpforms'); ?> "> <i class="fa fa-eye"></i> <span class="text"><?php _e('Preview', 'wpforms'); ?> </span> </a>--> <a href="#" id="wpforms-embed" title="<?php _e('Embed Form', 'wpforms'); ?> "> <i class="fa fa-code"></i> <span class="text"><?php _e('Embed', 'wpforms'); ?> </span> </a> <a href="#" id="wpforms-save" title="<?php _e('Save Form', 'wpforms'); ?> "> <i class="fa fa-check"></i> <span class="text"><?php _e('Save', 'wpforms'); ?> </span> </a> <?php } ?> <a href="#" id="wpforms-exit" title="<?php _e('Exit', 'wpforms'); ?> "> <i class="fa fa-times"></i> </a> </div> </div> <!-- Panel toggle buttons --> <div class="wpforms-panels-toggle" id="wpforms-panels-toggle"> <?php do_action('wpforms_builder_panel_buttons', $this->form, $this->view); ?> </div> <div class="wpforms-panels"> <?php do_action('wpforms_builder_panels', $this->form, $this->view); ?> </div> </form> </div> <?php }
/** * Process the form entry. * * @since 1.0.0 * @param array $form $_POST object */ public function process($entry) { $this->errors = array(); $this->fields = array(); $form_id = absint($entry['id']); $form = wpforms()->form->get($form_id); $honeypot = false; // Validate form is real and active (published) if (!$form || 'publish' != $form->post_status) { $this->errors[$form_id]['header'] = __('Invalid form.', 'wpforms'); return; } // Formatted form data for hooks $form_data = wpforms_decode($form->post_content); // Pre-process/validate hooks and filter. Data is not validated or // cleaned yet so use with caution. $entry = apply_filters('wpforms_process_before_filter', $entry, $form_data); do_action('wpforms_process_before', $entry, $form_data); do_action("wpforms_process_before_{$form_id}", $entry, $form_data); // Validate fields foreach ($form_data['fields'] as $field) { $field_id = $field['id']; $field_type = $field['type']; $field_submit = isset($entry['fields'][$field_id]) ? $entry['fields'][$field_id] : ''; do_action("wpforms_process_validate_{$field_type}", $field_id, $field_submit, $form_data); } // reCAPTCHA check $site_key = wpforms_setting('recaptcha-site-key', ''); $secret_key = wpforms_setting('recaptcha-secret-key', ''); if (!empty($site_key) || !empty($secret_key)) { if (isset($form_data['settings']['recaptcha']) && '1' == $form_data['settings']['recaptcha']) { // We should have a reCAPTCHA so let's process $response = $_POST['g-recaptcha-response']; $secret = wpforms_setting('recaptcha-secret-key'); $data = wp_remote_get('https://www.google.com/recaptcha/api/siteverify?secret=' . $secret . '&response=' . $response); $data = json_decode(wp_remote_retrieve_body($data)); if (empty($data->success)) { $this->errors[$form_id]['recaptcha'] = __('Incorrect reCAPTCHA, please try again.', 'wpforms'); } } } // One last error check - don't proceed if there are any errors if (!empty($this->errors[$form_id])) { $this->errors[$form_id]['header'] = __('Form has not been submitted, please see the errors below.', 'wpforms'); return; } // Validate honeypot if (!empty($form_data['settings']['honeypot']) && '1' == $form_data['settings']['honeypot']) { if (isset($entry['hp']) && !empty($entry['hp'])) { $honeypot = __('WPForms honeypot field triggered.', 'wpforms'); } } $honeypot = apply_filters('wpforms_process_honeypot', $honeypot, $this->fields, $entry, $form_data); // Only trigger the processing (saving/sending entries, etc) if the entry // is not spam. if (!$honeypot) { // Pass the form created date into the form data $form_data['created'] = $form->post_date; // Format fields foreach ($form_data['fields'] as $field) { $field_id = $field['id']; $field_type = $field['type']; $field_submit = isset($entry['fields'][$field_id]) ? $entry['fields'][$field_id] : ''; do_action("wpforms_process_format_{$field_type}", $field_id, $field_submit, $form_data); } // Process hooks/filter - this is where most add-ons should hook // because at this point we have completed all field validation and // formatted the data. $this->fields = apply_filters('wpforms_process_filter', $this->fields, $entry, $form_data); do_action('wpforms_process', $this->fields, $entry, $form_data); do_action("wpforms_process_{$form_id}", $this->fields, $entry, $form_data); $this->fields = apply_filters('wpforms_process_after_filter', $this->fields, $entry, $form_data); // One last error check - don't proceed if there are any errors if (!empty($this->errors[$form_id])) { if (empty($this->errors[$form_id]['header'])) { $this->errors[$form_id]['header'] = __('Form has not been submitted, please see the errors below.', 'wpforms'); } return; } // Success - add entry to database $entry_id = $this->entry_save($this->fields, $entry, $form_data['id'], $form_data); // Success - send email notification $this->entry_email($this->fields, $entry, $form_data, $entry_id); // Pass completed and formatted fields in POST $_POST['wpforms']['complete'] = $this->fields; // Pass entry ID in POST $_POST['wpforms']['entry_id'] = $entry_id; // Logs entry depending on log levels set wpforms_log('Entry', $this->fields, array('type' => array('entry'), 'parent' => $entry_id, 'form_id' => $form_data['id'])); // Post-process hooks do_action('wpforms_process_complete', $this->fields, $entry, $form_data, $entry_id); do_action("wpforms_process_complete_{$form_id}", $this->fields, $entry, $form_data, $entry_id); } else { // Logs spam entry depending on log levels set wpforms_log('Spam Entry', array($honeypot, $entry), array('type' => array('spam'), 'form_id' => $form_data['id'])); } $this->entry_confirmation_redirect($form_data); }
/** * Print Preview. * * @since 1.1.5 */ public function print_preview() { // Load entry details $entry = wpforms()->entry->get(absint($_GET['entry_id'])); // Double check that we found a real entry if (!$entry || empty($entry)) { return; } // Get form details $form_data = wpforms()->form->get($entry->form_id, array('content_only' => true)); // Double check that we found a valid entry if (!$form_data || empty($form_data)) { return; } ?> <!doctype html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>WPForms Print Preview - <?php echo ucfirst(sanitize_text_field($form_data['settings']['form_title'])); ?> </title> <meta name="description" content=""> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="robots" content="noindex,nofollow,noarchive"> <link rel="stylesheet" href="<?php echo includes_url('css/buttons.min.css'); ?> " type="text/css"> <link rel="stylesheet" href="<?php echo WPFORMS_PLUGIN_URL; ?> assets/css/wpforms-preview.css" type="text/css"> <script type="text/javascript" src="<?php echo includes_url('js/jquery/jquery.js'); ?> "></script> <script type="text/javascript" src="<?php echo WPFORMS_PLUGIN_URL; ?> assets/js/wpforms-preview.js"></script> </head> <body class="wp-core-ui"> <div class="wpforms-preview" id="print"> <h1> <?php echo sanitize_text_field($form_data['settings']['form_title']); ?> <span> - <?php printf(__('Entry #%d', 'wpforms'), absint($entry->entry_id)); ?> </span> <div class="buttons"> <a href="" class="button button-secondary close-window">Close</a> <a href="" class="button button-primary print">Print</a> </div> </h1> <?php $fields = apply_filters('wpforms_entry_single_data', wpforms_decode($entry->fields), $entry, $form_data); if (empty($fields)) { // Whoops, no fields! This shouldn't happen under normal use cases. echo '<p class="no-fields">' . __('This entry does not have any fields', 'wpforms') . '</p>'; } else { echo '<div class="fields">'; // Display the fields and their values foreach ($fields as $key => $field) { $field_value = apply_filters('wpforms_html_field_value', wp_strip_all_tags($field['value']), $field, $form_data); $field_class = sanitize_html_class('wpforms-field-' . $field['type']); $field_class .= empty($field_value) ? ' empty' : ''; echo '<div class="wpforms-entry-field ' . $field_class . '">'; // Field name echo '<p class="wpforms-entry-field-name">'; echo !empty($field['name']) ? wp_strip_all_tags($field['name']) : sprintf(__('Field ID #%d', 'wpforms'), absint($field['id'])); echo '</p>'; // Field value echo '<p class="wpforms-entry-field-value">'; echo !empty($field_value) ? nl2br(make_clickable($field_value)) : __('Empty', 'wpforms'); echo '</p>'; echo '</div>'; } echo '</div>'; } ?> </div><!-- .wrap --> <p class="site"><a href="<?php echo home_url(); ?> "><?php echo get_bloginfo('name'); ?> </a></p> </body> <?php exit; }
/** * Pass information about the active template back to the builder. * * @since 1.0.0 * @param array $details * @param object $form * @return array */ function template_active($details, $form) { if (empty($form)) { return; } $form_data = wpforms_decode($form->post_content); if (empty($this->modal) || $this->slug != $form_data['meta']['template']) { return $details; } else { $display = $this->template_modal_conditional($form_data); } $template = array('name' => $this->name, 'slug' => $this->slug, 'description' => $this->description, 'includes' => $this->includes, 'icon' => $this->icon, 'modal' => $this->modal, 'modal_display' => $display); return $template; }