AltBody = $text; }; add_action( 'phpmailer_init', $alternative ); wp_mail( $to, $subject, $html, $headers ); remove_action( 'phpmailer_init', $alternative ); } /** * The message headers. * * @param array $values The cleaned fields. * @param array $settings The form settings. * @param bool $as_html Whether the body is HTML. * * @return array */ private static function headers( $values, $settings, $as_html = false ) { $headers = array( 'Content-Type: ' . ( $as_html ? 'text/html' : 'text/plain' ) . '; charset=UTF-8' ); $from_email = is_email( $settings['from_email'] ) ? sanitize_email( $settings['from_email'] ) : ''; $from_name = '' !== $settings['from_name'] ? self::one_line( $settings['from_name'] ) : ''; if ( $from_email ) { $headers[] = $from_name ? 'From: ' . $from_name . ' <' . $from_email . '>' : 'From: ' . $from_email; } if ( 'none' === $settings['reply_to'] ) { return $headers; } $reply = self::find_email( $values ); if ( $reply ) { $headers[] = 'Reply-To: ' . $reply; } return $headers; } /** * Takes the line breaks out of a string that goes into a header. * * A break in a header is not a cosmetic matter. Everything after it is read as * a new header, so one break in a subject is enough to add a recipient nobody * asked for. * * @param string $value The text. * * @return string */ private static function one_line( $value ) { return trim( preg_replace( '/[\r\n\t]+/', ' ', (string) $value ) ); } /** * Looks for an email address among the answers, so a reply takes one click. * * @param array $values The cleaned fields. * * @return string */ private static function find_email( $values ) { foreach ( $values as $value ) { if ( is_scalar( $value ) && is_email( (string) $value ) ) { return sanitize_email( (string) $value ); } } return ''; } /** * The answers, as label and value pairs. * * Both shapes of the message are built out of this one list, so the card and * the plain text can never say different things. * * @param int $form_id The form id. * @param array $values The cleaned fields. * * @return array */ private static function rows( $form_id, $values ) { $rows = array(); foreach ( Ranq_Forms_Fields::get_form_fields( $form_id ) as $field ) { $key = isset( $field['id'] ) ? $field['id'] : ''; $object = isset( $field['type'] ) ? Ranq_Forms_Fields::get( $field['type'] ) : null; if ( '' === $key || ! $object instanceof Ranq_Forms_Field || ! $object->is_input() ) { continue; } $rows[] = array( 'label' => isset( $field['label'] ) && '' !== $field['label'] ? $field['label'] : $key, 'value' => isset( $values[ $key ] ) ? (string) $object->format_value( $values[ $key ], $field ) : '', ); } return $rows; } /** * The address of this one entry in the dashboard. * * The link leads to the entry itself, not to the list, so the owner lands on * the message they were told about. Attached files are opened from there and * only from there: a file link carries a nonce tied to the person opening it, * so a link made at sending time would be dead for the reader. * * @param int $form_id The form id. * @param int $entry_id The entry id. * * @return string */ private static function entry_url( $form_id, $entry_id ) { return admin_url( 'admin.php?page=' . Ranq_Forms_Admin::PAGE_ENTRIES . '&form_id=' . absint( $form_id ) . '&entry_id=' . absint( $entry_id ) ); } /** * The card, as HTML. * * @param int $entry_id The entry id. * @param int $form_id The form id. * @param array $rows The answers. * @param array $values The cleaned fields. * @param array $settings The form settings. * @param string $title The form name. * @param string $site The site name. * * @return string */ private static function html( $entry_id, $form_id, $rows, $values, $settings, $title, $site ) { $html = Ranq_Forms_Notification_Template::render( array( 'color' => isset( $settings['notify_color'] ) ? $settings['notify_color'] : '', 'title' => $title, 'site' => $site, 'date' => wp_date( get_option( 'date_format' ) . ', ' . get_option( 'time_format' ) ), 'rows' => $rows, 'url' => self::entry_url( $form_id, $entry_id ), 'entry_id' => $entry_id, 'reply' => 'none' === $settings['reply_to'] ? '' : self::find_email( $values ), ) ); /** * The card, as HTML. * * @param string $html The message. * @param int $form_id The form id. * @param array $rows The answers, as label and value pairs. */ return apply_filters( 'ranq_forms_notify_html', $html, $form_id, $rows ); } /** * The body of the message, as plain text. * * @param int $entry_id The entry id. * @param int $form_id The form id. * @param array $values The cleaned fields. * @param array $rows The answers. Built here when not handed in. * * @return string */ private static function body( $entry_id, $form_id, $values, $rows = null ) { $rows = is_array( $rows ) ? $rows : self::rows( $form_id, $values ); $lines = array(); foreach ( $rows as $row ) { $lines[] = $row['label']; $lines[] = '' === trim( $row['value'] ) ? '—' : $row['value']; $lines[] = ''; } $lines[] = str_repeat( '-', 40 ); $lines[] = sprintf( /* translators: %s: form name. */ __( 'Form: %s', '2ranq-forms' ), get_the_title( $form_id ) ); $lines[] = sprintf( /* translators: %s: link to this entry in the dashboard. */ __( 'Open this entry: %s', '2ranq-forms' ), self::entry_url( $form_id, $entry_id ) ); $lines[] = sprintf( /* translators: %d: entry number. */ __( 'Entry number: %d', '2ranq-forms' ), absint( $entry_id ) ); /** * The body of the message. * * @param string $body The text. * @param int $form_id The form id. * @param array $values The cleaned fields. */ return apply_filters( 'ranq_forms_notify_body', implode( "\n", $lines ), $form_id, $values ); } }