FileMaster
Search
Toggle Dark Mode
Home
/
.
/
wp-content
/
plugins
/
sureforms
/
inc
/
email
Edit File: email-template.php
<?php /** * Email template loader. * * @package SureForms. */ namespace SRFM\Inc\Email; use SRFM\Inc\Helper; use SRFM\Inc\Traits\Get_Instance; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Email Class * * @since 0.0.1 */ class Email_Template { use Get_Instance; /** * Class Constructor * * @since 0.0.1 * @return void */ public function __construct() { } /** * Get email header. * * @since 0.0.1 * @return string|false */ public function get_header() { ob_start(); ?> <html> <head> <meta charset="utf-8"> <title><?php echo esc_html__( 'New form submission', 'sureforms' ); ?></title> </head> <body style="margin: 0; padding: 0;"> <div id="srfm_wrapper" dir="ltr" style="margin: 0; background-color: #F8F8FC; padding: 40px 0 0 0; width: 100%"> <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tbody> <tr> <td align="center" valign="top"> <table border="0" cellpadding="0" cellspacing="0" width="600" id="srfm_template_container" style="background-color: #ffffff;border: 1px solid #dce0e6;margin-bottom: 25px; "> <tbody> <tr> <td align="center" valign="top"> <table border="0" cellpadding="0" cellspacing="0" width="600" id="srfm_template_body"> <tbody> <tr> <td valign="top" id="srfm_body_content" style="background-color: #ffffff"> <table border="0" cellpadding="20" cellspacing="0" width="100%"> <tbody> <tr> <td valign="top" style="padding:32px"> <div id="srfm_body_content_inner" style="color: #384860;font-family: Roboto-Medium,Roboto,-apple-system,BlinkMacSystemFont,Helvetica Neue,Helvetica,Arial,sans-serif;font-size: 14px;line-height: 20px;text-align: left;"> <?php return ob_get_clean(); } /** * Get email footer. * * @since 0.0.1 * @return string|false footer tags. */ public function get_footer() { ob_start(); ?> </div> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table> </div> </body> </html> <?php return ob_get_clean(); } /** * Render email template. * * @param array<mixed> $fields Submission fields. * @param string $email_body email body. * @since 0.0.1 * @return string */ public function render( $fields, $email_body ) { $message = $this->get_header(); $message .= $this->process_all_data_tag( $fields, $email_body ); return $message . $this->get_footer(); } /** * Render email as raw HTML with no template wrapping. * * Returns the email body exactly as written with only smart tag * processing applied. No wrapper, no container, no layout, no * styles, no footer — true raw HTML output. * * @param array<mixed> $fields Submission fields. * @param string $email_body Email body content. * @since 2.5.2 * @return string The raw email body with smart tags processed. */ public function render_raw( $fields, $email_body ) { return $this->process_all_data_tag( $fields, $email_body ); } /** * Remove border from the last table row in repeater table HTML. * * This method finds the last <tr> element in the provided HTML content * and removes the border-bottom style from all <td> elements within it. * This is used to clean up the visual appearance of repeater tables. * * @param string $content HTML content containing table structure. * * @since 1.11.0 * @return string Modified HTML content with border removed from last row. */ public function remove_border_from_last_tr_td_table( $content ) { // Check if content contains table and tr elements. if ( empty( $content ) || ! preg_match( '/<tr[^>]*>/i', $content ) ) { return $content; } // Find and modify the last tr in one go. $modified_html = preg_replace_callback( '/(.*)(<tr[^>]*>.*?<\/tr>)(?!.*<tr)/is', static function( $matches ) { $before_last_tr = $matches[1]; $last_tr = $matches[2]; // Remove border-bottom from all td elements in this tr. $modified_tr = preg_replace_callback( '/(<td[^>]*style\s*=\s*["\'])([^"\']*?)(["\'][^>]*>)/i', static function( $td_match ) { $start = $td_match[1]; $style = $td_match[2]; // Remove ONLY border-bottom (not border-bottom-width, etc.). $style = preg_replace( '/\s*border-bottom\s*:[^;]*;?/i', '', $style ); $style = is_string( $style ) ? $style : ''; // Clean up multiple semicolons and trim. $style = preg_replace( '/;+/', ';', $style ); $style = is_string( $style ) ? trim( $style, '; ' ) : ''; $end = $td_match[3]; return $start . $style . $end; }, $last_tr ); return $before_last_tr . $modified_tr; }, $content ); return is_string( $modified_html ) ? $modified_html : ''; } /** * Process the {all_data} smart tag in the email body. * * Replaces {all_data} with a formatted HTML table of all submission fields. * * @param array<mixed> $fields Submission fields. * @param string $email_body Email body content. * @since 2.5.2 * @return string Email body with {all_data} replaced. */ private function process_all_data_tag( $fields, $email_body ) { if ( strpos( $email_body, '{all_data}' ) === false ) { return $email_body; } $excluded_fields = [ 'srfm-honeypot-field', 'g-recaptcha-response', 'srfm-sender-email-field' ]; $td_style = 'font-weight: 500;font-size: 14px;line-height: 20px;padding: 12px;text-align:left;word-break: break-word;border-bottom: 1px solid #E5E7EB;'; ob_start(); ?> <table class="srfm_all_data" width="536" cellpadding="0" cellspacing="0" style="border: 1px solid #dce0e6;border-radius: 6px;margin-top: 25px;margin-bottom: 25px;overflow:hidden;"> <style> .srfm_all_data tr:last-child td { border: none !important; } </style> <tbody> <?php foreach ( $fields as $field_name => $value ) { $values_array = []; if ( is_array( $value ) ) { $values_array = $value; } else { $value = Helper::get_string_value( $value ); } if ( in_array( $field_name, $excluded_fields, true ) || false === str_contains( $field_name, '-lbl-' ) ) { continue; } $label = explode( '-lbl-', $field_name )[1]; $label = explode( '-', $label )[0]; $field_label = $label ? Helper::decrypt( $label ) : ''; $field_block_name = Helper::get_block_name_from_field( $field_name ); /** * Fires before rendering a field in the all data section of emails. * * This action allows other packages (like Pro, Business) to process and render fields * with custom data structures that the core plugin cannot handle. Since the core plugin * does not know the structure of data from other packages, this action provides a way * for those packages to properly process and display their field data. * * @since 1.11.0 * * @param array $field_data Field data containing: * 'value' => mixed The field value * 'label' => string The field name/key * 'block_name' => string The block type identifier * 'processed_label' => string The decrypted human readable label */ do_action( 'srfm_before_processing_all_data_field', [ 'value' => $value, 'label' => $field_name, 'block_name' => $field_block_name, 'processed_label' => $field_label, ] ); /** * Filters whether to add a field row in the all data section. * * This filter allows skipping rows for fields that cannot be processed with the * core plugin's structure. Fields from other packages may have complex data structures * that could cause fatal errors if processed normally. Those packages can use the * 'srfm_before_processing_all_data_field' action to render their fields and return false here * to prevent the core plugin from attempting to process them. * * @since 1.11.0 * * @param bool $should_add_field_row Whether to add the field row. Default true. * @param array $field_data Field data containing: * 'value' => mixed The field value * 'field_name' => string The field name/key * 'block_name' => string The block type identifier * * @return bool Whether to add the field row to the table. */ $should_add_field_row = apply_filters( 'srfm_all_data_field_row', true, [ 'value' => $value, 'field_name' => $field_name, 'block_name' => $field_block_name, ] ); if ( true !== $should_add_field_row ) { continue; } $is_array_value = is_array( $value ); if ( $is_array_value ) { $values_array = array_filter( $value, static function( $input_value ) { return ! empty( Helper::get_string_value( $input_value ) ); } ); } else { $value = Helper::get_string_value( $value ); } // Skip if both $value and $values_array are empty. if ( empty( $value ) || ( $is_array_value && empty( $values_array ) ) ) { continue; } ?> <tr class="field-label"> <th style="<?php echo esc_attr( $td_style ); ?>color: #1E293B;background-color: #F1F5F9;"> <strong><?php echo wp_kses_post( html_entity_decode( $field_label ) ); ?>:</strong> </th> </tr> <tr class="field-value"> <td style="<?php echo esc_attr( $td_style ); ?>color: #475569;"> <?php if ( ! empty( $values_array ) && is_array( $values_array ) ) { $clean_values = []; foreach ( $values_array as $value ) { $value = Helper::get_string_value( $value ); if ( ! empty( $value ) && is_string( $value ) ) { $clean_values[] = $value; } } if ( count( $clean_values ) === 1 ) { $value = reset( $clean_values ); $decoded_value = urldecode( $value ); ?> <a target="_blank" rel="noopener noreferrer" href="<?php echo esc_url( $decoded_value ); ?>"> <?php echo esc_html( $decoded_value ); ?> </a> <?php } elseif ( count( $clean_values ) > 1 ) { ?> <ol style="list-style: decimal; padding-left: 20px; margin: 0;"> <?php foreach ( $clean_values as $value ) { ?> <?php $decoded_value = urldecode( $value ); ?> <li style="margin-bottom: 6px;"> <a target="_blank" rel="noopener noreferrer" href="<?php echo esc_url( $decoded_value ); ?>"> <?php echo esc_html( $decoded_value ); ?> </a> </li> <?php } ?> </ol> <?php } } elseif ( is_string( $value ) && filter_var( $value, FILTER_VALIDATE_URL ) ) { ob_start(); ?> <a target="_blank" href="<?php echo esc_url( $value ); ?>"> <?php echo esc_html( esc_url( $value ) ); ?> </a> <?php $template_html = ob_get_clean(); // Apply filter. $render_url = apply_filters( 'srfm_email_template_render_url', $template_html, [ 'block_type' => $field_name, 'submission_item_value' => $value, ] ); // Validate fallback. if ( empty( $render_url ) ) { ob_start(); ?> <a target="_blank" href="<?php echo esc_url( $value ); ?>"> <?php echo esc_html( esc_url( $value ) ); ?> </a> <?php $render_url = ob_get_clean(); } echo wp_kses( Helper::get_string_value( $render_url ), [ 'a' => [ 'href' => [], 'target' => [], ], 'img' => [ 'src' => [], 'alt' => [], 'width' => [], ], ] ); } else { if ( strpos( Helper::get_string_value( $field_name ), 'srfm-input-multi-choice' ) !== false && strpos( Helper::get_string_value( $value ), '|' ) !== false ) { $options = array_map( 'trim', explode( '|', Helper::get_string_value( $value ) ) ); foreach ( $options as $index => $option ) { $border_style = $index < count( $options ) - 1 ? 'border-bottom:1px solid #E5E7EB;padding-bottom:4px;margin-bottom:4px;' : ''; echo '<div style="' . esc_attr( $border_style ) . '">' . esc_html( $option ) . '</div>'; } continue; } if ( is_string( $value ) ) { if ( false !== strpos( $field_name, 'srfm-textarea' ) ) { echo Helper::esc_textarea( html_entity_decode( $value ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- using a custom escaping function. } else { echo false !== strpos( $value, PHP_EOL ) ? wp_kses_post( wpautop( $value ) ) : wp_kses( $value, [ 'a' => [ 'href' => [], 'target' => [], ], ] ); } } } ?> </td> </tr> <?php } ?> </tbody> </table> <?php $table_data = ob_get_clean(); $current_table_data = $table_data ? $table_data : ''; // This is done as str_replace expects array|string but ob_get_clean() returns string|false. $current_table_data = $this->remove_border_from_last_tr_td_table( $current_table_data ); return str_replace( '{all_data}', $current_table_data, $email_body ); } }
Save
Back