/** * Process the contact form's POST submission * Stores feedback. Sends email. */ function process_submission() { global $post; $plugin = Grunion_Contact_Form_Plugin::init(); $id = $this->get_attribute('id'); $to = $this->get_attribute('to'); $widget = $this->get_attribute('widget'); $contact_form_subject = $this->get_attribute('subject'); $to = str_replace(' ', '', $to); $emails = explode(',', $to); $valid_emails = array(); foreach ((array) $emails as $email) { if (!is_email($email)) { continue; } if (function_exists('is_email_address_unsafe') && is_email_address_unsafe($email)) { continue; } $valid_emails[] = $email; } // No one to send it to :( if (!$valid_emails) { return false; } $to = $valid_emails; // Make sure we're processing the form we think we're processing... probably a redundant check. if ($widget) { if ('widget-' . $widget != $_POST['contact-form-id']) { return false; } } else { if ($post->ID != $_POST['contact-form-id']) { return false; } } $field_ids = $this->get_field_ids(); // Initialize all these "standard" fields to null $comment_author_email = $comment_author_email_label = $comment_author = $comment_author_label = $comment_author_url = $comment_author_url_label = $comment_content = $comment_content_label = null; // For each of the "standard" fields, grab their field label and value. if (isset($field_ids['name'])) { $field = $this->fields[$field_ids['name']]; $comment_author = Grunion_Contact_Form_Plugin::strip_tags(stripslashes(apply_filters('pre_comment_author_name', addslashes($field->value)))); $comment_author_label = Grunion_Contact_Form_Plugin::strip_tags($field->get_attribute('label')); } if (isset($field_ids['email'])) { $field = $this->fields[$field_ids['email']]; $comment_author_email = Grunion_Contact_Form_Plugin::strip_tags(stripslashes(apply_filters('pre_comment_author_email', addslashes($field->value)))); $comment_author_email_label = Grunion_Contact_Form_Plugin::strip_tags($field->get_attribute('label')); } if (isset($field_ids['url'])) { $field = $this->fields[$field_ids['url']]; $comment_author_url = Grunion_Contact_Form_Plugin::strip_tags(stripslashes(apply_filters('pre_comment_author_url', addslashes($field->value)))); if ('http://' == $comment_author_url) { $comment_author_url = ''; } $comment_author_url_label = Grunion_Contact_Form_Plugin::strip_tags($field->get_attribute('label')); } if (isset($field_ids['textarea'])) { $field = $this->fields[$field_ids['textarea']]; $comment_content = trim(Grunion_Contact_Form_Plugin::strip_tags($field->value)); $comment_content_label = Grunion_Contact_Form_Plugin::strip_tags($field->get_attribute('label')); } if (isset($field_ids['subject'])) { $field = $this->fields[$field_ids['subject']]; if ($field->value) { $contact_form_subject = Grunion_Contact_Form_Plugin::strip_tags($field->value); } } $all_values = $extra_values = array(); // For all fields, grab label and value foreach ($field_ids['all'] as $field_id) { $field = $this->fields[$field_id]; $label = $field->get_attribute('label'); $value = $field->value; $all_values[$label] = $value; } // For the "non-standard" fields, grab label and value foreach ($field_ids['extra'] as $field_id) { $field = $this->fields[$field_id]; $label = $field->get_attribute('label'); $value = $field->value; $extra_values[$label] = $value; } $contact_form_subject = trim($contact_form_subject); $comment_author_IP = Grunion_Contact_Form_Plugin::strip_tags($_SERVER['REMOTE_ADDR']); $vars = array('comment_author', 'comment_author_email', 'comment_author_url', 'contact_form_subject', 'comment_author_IP'); foreach ($vars as $var) { ${$var} = str_replace(array("\n", "\r"), '', ${$var}); } $vars[] = 'comment_content'; $spam = ''; $akismet_values = $plugin->prepare_for_akismet(compact($vars)); // Is it spam? $is_spam = apply_filters('contact_form_is_spam', $akismet_values); if (is_wp_error($is_spam)) { // WP_Error to abort return $is_spam; } else { if ($is_spam === TRUE) { // TRUE to flag a spam $spam = '***SPAM*** '; } } if (!$comment_author) { $comment_author = $comment_author_email; } $to = (array) apply_filters('contact_form_to', $to); foreach ($to as $to_key => $to_value) { $to[$to_key] = Grunion_Contact_Form_Plugin::strip_tags($to_value); } $blog_url = parse_url(site_url()); $from_email_addr = 'wordpress@' . $blog_url['host']; $reply_to_addr = $to[0]; if (!empty($comment_author_email)) { $reply_to_addr = $comment_author_email; } $headers = 'From: ' . $comment_author . ' <' . $from_email_addr . ">\r\n" . 'Reply-To: ' . $comment_author . ' <' . $reply_to_addr . ">\r\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\""; $subject = apply_filters('contact_form_subject', $contact_form_subject); $time = date_i18n(__('l F j, Y \\a\\t g:i a', 'jetpack'), current_time('timestamp')); $extra_content = ''; foreach ($extra_values as $label => $value) { $extra_content .= $label . ': ' . trim($value) . "\n"; } $message = "{$comment_author_label}: {$comment_author}\n"; if (!empty($comment_author_email)) { $message .= "{$comment_author_email_label}: {$comment_author_email}\n"; } if (!empty($comment_author_url)) { $message .= "{$comment_author_url_label}: {$comment_author_url}\n"; } if (!empty($comment_content_label)) { $message .= "{$comment_content_label}: {$comment_content}\n"; } $message .= $extra_content . "\n"; $message .= __('Time:', 'jetpack') . ' ' . $time . "\n"; $message .= __('IP Address:', 'jetpack') . ' ' . $comment_author_IP . "\n"; if ($widget) { $url = home_url('/'); } else { $url = get_permalink($post->ID); } $message .= __('Contact Form URL:', 'jetpack') . " {$url}\n"; if (is_user_logged_in()) { $message .= "\n"; $message .= sprintf(__('Sent by a verified %s user.', 'jetpack'), isset($GLOBALS['current_site']->site_name) && $GLOBALS['current_site']->site_name ? $GLOBALS['current_site']->site_name : '"' . get_option('blogname') . '"'); } else { $message .= __('Sent by an unverified visitor to your site.', 'jetpack'); } $message = apply_filters('contact_form_message', $message); $message = Grunion_Contact_Form_Plugin::strip_tags($message); // keep a copy of the feedback as a custom post type $feedback_mysql_time = current_time('mysql'); $feedback_title = "{$comment_author} - {$feedback_mysql_time}"; $feedback_status = 'publish'; if ($is_spam === TRUE) { $feedback_status = 'spam'; } foreach ((array) $akismet_values as $av_key => $av_value) { $akismet_values[$av_key] = Grunion_Contact_Form_Plugin::strip_tags($av_value); } foreach ((array) $all_values as $all_key => $all_value) { $all_values[$all_key] = Grunion_Contact_Form_Plugin::strip_tags($all_value); } foreach ((array) $extra_values as $ev_key => $ev_value) { $extra_values[$ev_key] = Grunion_Contact_Form_Plugin::strip_tags($ev_value); } /* We need to make sure that the post author is always zero for contact * form submissions. This prevents export/import from trying to create * new users based on form submissions from people who were logged in * at the time. * * Unfortunately wp_insert_post() tries very hard to make sure the post * author gets the currently logged in user id. That is how we ended up * with this work around. */ add_filter('wp_insert_post_data', array($plugin, 'insert_feedback_filter'), 10, 2); $post_id = wp_insert_post(array('post_date' => addslashes($feedback_mysql_time), 'post_type' => 'feedback', 'post_status' => addslashes($feedback_status), 'post_parent' => (int) $post->ID, 'post_title' => addslashes(wp_kses($feedback_title, array())), 'post_content' => addslashes(wp_kses($comment_content . "\n<!--more-->\n" . "AUTHOR: {$comment_author}\nAUTHOR EMAIL: {$comment_author_email}\nAUTHOR URL: {$comment_author_url}\nSUBJECT: {$contact_form_subject}\nIP: {$comment_author_IP}\n" . print_r($all_values, TRUE), array())), 'post_name' => md5($feedback_title))); // once insert has finished we don't need this filter any more remove_filter('wp_insert_post_data', array($plugin, 'insert_feedback_filter'), 10, 2); update_post_meta($post_id, '_feedback_author', addslashes($comment_author)); update_post_meta($post_id, '_feedback_author_email', addslashes($comment_author_email)); update_post_meta($post_id, '_feedback_author_url', addslashes($comment_author_url)); update_post_meta($post_id, '_feedback_subject', addslashes($contact_form_subject)); update_post_meta($post_id, '_feedback_ip', addslashes($comment_author_IP)); update_post_meta($post_id, '_feedback_contact_form_url', addslashes(get_permalink($post->ID))); update_post_meta($post_id, '_feedback_all_fields', $this->addslashes_deep($all_values)); update_post_meta($post_id, '_feedback_extra_fields', $this->addslashes_deep($extra_values)); update_post_meta($post_id, '_feedback_akismet_values', $this->addslashes_deep($akismet_values)); update_post_meta($post_id, '_feedback_email', $this->addslashes_deep(array('to' => $to, 'subject' => $subject, 'message' => $message, 'headers' => $headers))); do_action('grunion_pre_message_sent', $post_id, $all_values, $extra_values); // schedule deletes of old spam feedbacks if (!wp_next_scheduled('grunion_scheduled_delete')) { wp_schedule_event(time() + 250, 'daily', 'grunion_scheduled_delete'); } if ($is_spam !== TRUE) { wp_mail($to, "{$spam}{$subject}", $message, $headers); } elseif (apply_filters('grunion_still_email_spam', FALSE) == TRUE) { // don't send spam by default. Filterable. wp_mail($to, "{$spam}{$subject}", $message, $headers); } if (defined('DOING_AJAX') && DOING_AJAX) { return self::success_message($post_id, $this); } $redirect = wp_get_referer(); if (!$redirect) { // wp_get_referer() returns false if the referer is the same as the current page $redirect = $_SERVER['REQUEST_URI']; } $redirect = add_query_arg(urlencode_deep(array('contact-form-id' => $id, 'contact-form-sent' => $post_id, '_wpnonce' => wp_create_nonce("contact-form-sent-{$post_id}"))), $redirect); $redirect = apply_filters('grunion_contact_form_redirect_url', $redirect, $id, $post_id); wp_safe_redirect($redirect); exit; }
/** * Process the contact form's POST submission * Stores feedback. Sends email. */ function process_submission() { global $post; $plugin = Grunion_Contact_Form_Plugin::init(); $id = $this->get_attribute('id'); $to = $this->get_attribute('to'); $widget = $this->get_attribute('widget'); $contact_form_subject = $this->get_attribute('subject'); $to = str_replace(' ', '', $to); $emails = explode(',', $to); $valid_emails = array(); foreach ((array) $emails as $email) { if (!is_email($email)) { continue; } if (function_exists('is_email_address_unsafe') && is_email_address_unsafe($email)) { continue; } $valid_emails[] = $email; } // No one to send it to, which means none of the "to" attributes are valid emails. // Use default email instead. if (!$valid_emails) { $valid_emails = $this->defaults['to']; } $to = $valid_emails; // Last ditch effort to set a recipient if somehow none have been set. if (empty($to)) { $to = get_option('admin_email'); } // Make sure we're processing the form we think we're processing... probably a redundant check. if ($widget) { if ('widget-' . $widget != $_POST['contact-form-id']) { return false; } } else { if ($post->ID != $_POST['contact-form-id']) { return false; } } $field_ids = $this->get_field_ids(); // Initialize all these "standard" fields to null $comment_author_email = $comment_author_email_label = $comment_author = $comment_author_label = $comment_author_url = $comment_author_url_label = $comment_content = $comment_content_label = null; // For each of the "standard" fields, grab their field label and value. if (isset($field_ids['name'])) { $field = $this->fields[$field_ids['name']]; $comment_author = Grunion_Contact_Form_Plugin::strip_tags(stripslashes(apply_filters('pre_comment_author_name', addslashes($field->value)))); $comment_author_label = Grunion_Contact_Form_Plugin::strip_tags($field->get_attribute('label')); } if (isset($field_ids['email'])) { $field = $this->fields[$field_ids['email']]; $comment_author_email = Grunion_Contact_Form_Plugin::strip_tags(stripslashes(apply_filters('pre_comment_author_email', addslashes($field->value)))); $comment_author_email_label = Grunion_Contact_Form_Plugin::strip_tags($field->get_attribute('label')); } if (isset($field_ids['url'])) { $field = $this->fields[$field_ids['url']]; $comment_author_url = Grunion_Contact_Form_Plugin::strip_tags(stripslashes(apply_filters('pre_comment_author_url', addslashes($field->value)))); if ('http://' == $comment_author_url) { $comment_author_url = ''; } $comment_author_url_label = Grunion_Contact_Form_Plugin::strip_tags($field->get_attribute('label')); } if (isset($field_ids['textarea'])) { $field = $this->fields[$field_ids['textarea']]; $comment_content = trim(Grunion_Contact_Form_Plugin::strip_tags($field->value)); $comment_content_label = Grunion_Contact_Form_Plugin::strip_tags($field->get_attribute('label')); } if (isset($field_ids['subject'])) { $field = $this->fields[$field_ids['subject']]; if ($field->value) { $contact_form_subject = Grunion_Contact_Form_Plugin::strip_tags($field->value); } } $all_values = $extra_values = array(); $i = 1; // Prefix counter for stored metadata // For all fields, grab label and value foreach ($field_ids['all'] as $field_id) { $field = $this->fields[$field_id]; $label = $i . '_' . $field->get_attribute('label'); $value = $field->value; $all_values[$label] = $value; $i++; // Increment prefix counter for the next field } // For the "non-standard" fields, grab label and value // Extra fields have their prefix starting from count( $all_values ) + 1 foreach ($field_ids['extra'] as $field_id) { $field = $this->fields[$field_id]; $label = $i . '_' . $field->get_attribute('label'); $value = $field->value; if (is_array($value)) { $value = implode(', ', $value); } $extra_values[$label] = $value; $i++; // Increment prefix counter for the next extra field } $contact_form_subject = trim($contact_form_subject); $comment_author_IP = Grunion_Contact_Form_Plugin::get_ip_address(); $vars = array('comment_author', 'comment_author_email', 'comment_author_url', 'contact_form_subject', 'comment_author_IP'); foreach ($vars as $var) { ${$var} = str_replace(array("\n", "\r"), '', ${$var}); } // Ensure that Akismet gets all of the relevant information from the contact form, // not just the textarea field and predetermined subject. $akismet_vars = compact($vars); $akismet_vars['comment_content'] = $comment_content; foreach (array_merge($field_ids['all'], $field_ids['extra']) as $field_id) { $field = $this->fields[$field_id]; // Skip any fields that are just a choice from a pre-defined list. They wouldn't have any value // from a spam-filtering point of view. if (in_array($field->get_attribute('type'), array('select', 'checkbox', 'checkbox-multiple', 'radio'))) { continue; } // Normalize the label into a slug. $field_slug = trim(preg_replace('/[^a-z0-9_]+/', '-', strtolower($field->get_attribute('label'))), '-'); $field_value = is_array($field->value) ? trim(implode(', ', $field->value)) : trim($field->value); // Skip any values that are already in the array we're sending. if ($field_value && in_array($field_value, $akismet_vars)) { continue; } $akismet_vars['contact_form_field_' . $field_slug] = $field_value; } $spam = ''; $akismet_values = $plugin->prepare_for_akismet($akismet_vars); // Is it spam? /** This filter is already documented in modules/contact-form/admin.php */ $is_spam = apply_filters('jetpack_contact_form_is_spam', false, $akismet_values); if (is_wp_error($is_spam)) { // WP_Error to abort return $is_spam; } elseif ($is_spam === TRUE) { // TRUE to flag a spam $spam = '***SPAM*** '; } if (!$comment_author) { $comment_author = $comment_author_email; } /** * Filter the email where a submitted feedback is sent. * * @module contact-form * * @since 1.3.1 * * @param string|array $to Array of valid email addresses, or single email address. */ $to = (array) apply_filters('contact_form_to', $to); foreach ($to as $to_key => $to_value) { $to[$to_key] = Grunion_Contact_Form_Plugin::strip_tags($to_value); } $blog_url = parse_url(site_url()); $from_email_addr = 'wordpress@' . $blog_url['host']; $reply_to_addr = $to[0]; if (!empty($comment_author_email)) { $reply_to_addr = $comment_author_email; } $headers = 'From: "' . $comment_author . '" <' . $from_email_addr . ">\r\n" . 'Reply-To: "' . $comment_author . '" <' . $reply_to_addr . ">\r\n" . "Content-Type: text/html; charset=\"" . get_option('blog_charset') . "\""; // Build feedback reference $feedback_time = current_time('mysql'); $feedback_title = "{$comment_author} - {$feedback_time}"; $feedback_id = md5($feedback_title); $all_values = array_merge($all_values, array('entry_title' => the_title_attribute('echo=0'), 'entry_permalink' => esc_url(get_permalink(get_the_ID())), 'feedback_id' => $feedback_id)); /** This filter is already documented in modules/contact-form/admin.php */ $subject = apply_filters('contact_form_subject', $contact_form_subject, $all_values); $url = $widget ? home_url('/') : get_permalink($post->ID); $date_time_format = _x('%1$s \\a\\t %2$s', '{$date_format} \\a\\t {$time_format}', 'jetpack'); $date_time_format = sprintf($date_time_format, get_option('date_format'), get_option('time_format')); $time = date_i18n($date_time_format, current_time('timestamp')); // keep a copy of the feedback as a custom post type $feedback_status = $is_spam === TRUE ? 'spam' : 'publish'; foreach ((array) $akismet_values as $av_key => $av_value) { $akismet_values[$av_key] = Grunion_Contact_Form_Plugin::strip_tags($av_value); } foreach ((array) $all_values as $all_key => $all_value) { $all_values[$all_key] = Grunion_Contact_Form_Plugin::strip_tags($all_value); } foreach ((array) $extra_values as $ev_key => $ev_value) { $extra_values[$ev_key] = Grunion_Contact_Form_Plugin::strip_tags($ev_value); } /* We need to make sure that the post author is always zero for contact * form submissions. This prevents export/import from trying to create * new users based on form submissions from people who were logged in * at the time. * * Unfortunately wp_insert_post() tries very hard to make sure the post * author gets the currently logged in user id. That is how we ended up * with this work around. */ add_filter('wp_insert_post_data', array($plugin, 'insert_feedback_filter'), 10, 2); $post_id = wp_insert_post(array('post_date' => addslashes($feedback_time), 'post_type' => 'feedback', 'post_status' => addslashes($feedback_status), 'post_parent' => (int) $post->ID, 'post_title' => addslashes(wp_kses($feedback_title, array())), 'post_content' => addslashes(wp_kses($comment_content . "\n<!--more-->\n" . "AUTHOR: {$comment_author}\nAUTHOR EMAIL: {$comment_author_email}\nAUTHOR URL: {$comment_author_url}\nSUBJECT: {$subject}\nIP: {$comment_author_IP}\n" . print_r($all_values, TRUE), array())), 'post_name' => $feedback_id)); // once insert has finished we don't need this filter any more remove_filter('wp_insert_post_data', array($plugin, 'insert_feedback_filter'), 10); update_post_meta($post_id, '_feedback_extra_fields', $this->addslashes_deep($extra_values)); if ('publish' == $feedback_status) { // Increase count of unread feedback. $unread = get_option('feedback_unread_count', 0) + 1; update_option('feedback_unread_count', $unread); } if (defined('AKISMET_VERSION')) { update_post_meta($post_id, '_feedback_akismet_values', $this->addslashes_deep($akismet_values)); } $message = self::get_compiled_form($post_id, $this); array_push($message, "", '<hr />', __('Time:', 'jetpack') . ' ' . $time . '<br />', __('IP Address:', 'jetpack') . ' ' . $comment_author_IP . '<br />', __('Contact Form URL:', 'jetpack') . " " . $url . '<br />'); if (is_user_logged_in()) { array_push($message, "", sprintf(__('Sent by a verified %s user.', 'jetpack'), isset($GLOBALS['current_site']->site_name) && $GLOBALS['current_site']->site_name ? $GLOBALS['current_site']->site_name : '"' . get_option('blogname') . '"')); } else { array_push($message, __('Sent by an unverified visitor to your site.', 'jetpack')); } $message = join($message, "\n"); /** * Filters the message sent via email after a successfull form submission. * * @module contact-form * * @since 1.3.1 * * @param string $message Feedback email message. */ $message = apply_filters('contact_form_message', $message); update_post_meta($post_id, '_feedback_email', $this->addslashes_deep(compact('to', 'message'))); /** * Fires right before the contact form message is sent via email to * the recipient specified in the contact form. * * @module contact-form * * @since 1.3.1 * * @param integer $post_id Post contact form lives on * @param array $all_values Contact form fields * @param array $extra_values Contact form fields not included in $all_values */ do_action('grunion_pre_message_sent', $post_id, $all_values, $extra_values); // schedule deletes of old spam feedbacks if (!wp_next_scheduled('grunion_scheduled_delete')) { wp_schedule_event(time() + 250, 'daily', 'grunion_scheduled_delete'); } if ($is_spam !== TRUE && true === apply_filters('grunion_should_send_email', true, $post_id)) { wp_mail($to, "{$spam}{$subject}", $message, $headers); } elseif (true === $is_spam && apply_filters('grunion_still_email_spam', FALSE) == TRUE) { // don't send spam by default. Filterable. wp_mail($to, "{$spam}{$subject}", $message, $headers); } if (defined('DOING_AJAX') && DOING_AJAX) { return self::success_message($post_id, $this); } $redirect = wp_get_referer(); if (!$redirect) { // wp_get_referer() returns false if the referer is the same as the current page $redirect = $_SERVER['REQUEST_URI']; } $redirect = add_query_arg(urlencode_deep(array('contact-form-id' => $id, 'contact-form-sent' => $post_id, '_wpnonce' => wp_create_nonce("contact-form-sent-{$post_id}"))), $redirect); /** * Filter the URL where the reader is redirected after submitting a form. * * @module contact-form * * @since 1.9.0 * * @param string $redirect Post submission URL. * @param int $id Contact Form ID. * @param int $post_id Post ID. */ $redirect = apply_filters('grunion_contact_form_redirect_url', $redirect, $id, $post_id); wp_safe_redirect($redirect); exit; }
function test_remove_contact_form_shortcode_from_filtered_content() { require_once JETPACK__PLUGIN_DIR . 'modules/contact-form/grunion-contact-form.php'; $this->post->post_content = '<p>This post has a contact form:[contact-form][contact-field label=\'Name\' type=\'name\' required=\'1\'/][/contact-form]</p>'; Grunion_Contact_Form_Plugin::init(); wp_update_post($this->post); $this->assertContains('<form action=', apply_filters('the_content', $this->post->post_content)); $this->sender->do_sync(); $synced_post = $this->server_replica_storage->get_post($this->post->ID); $this->assertEquals("<p>This post has a contact form:</p>\n", $synced_post->post_content_filtered); }