whoami7 - Manager
:
/
home
/
dataiclx
/
vielorbe.com
/
wp-content
/
plugins
/
suremails
/
inc
/
emails
/
handler
/
Upload File:
files >> //home/dataiclx/vielorbe.com/wp-content/plugins/suremails/inc/emails/handler/process-email-data.php
<?php /** * ProcessEmailData.php * * Handles processing of email data components such as recipients, headers, attachments, message, and subject. * * @package SureEmails\Inc\Emails\Handler */ namespace SureMails\Inc\Emails\Handler; use PHPMailer\PHPMailer\Exception; use SureMails\Inc\ConnectionManager; use SureMails\Inc\Traits\Instance; use SureMails\Inc\Utils\LogError; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Class ProcessEmailData * * Provides methods to process different components of an email. */ class ProcessEmailData { use Instance; /** * Array of primary recipients with 'name' and 'email'. * * @var array */ private $to = []; /** * Associative array containing 'name' and 'email' for the sender. * * @var array */ private $from = [ 'name' => '', 'email' => '', ]; /** * Array of CC recipients with 'name' and 'email'. * * @var array */ private $cc = []; /** * Array of BCC recipients with 'name' and 'email'. * * @var array */ private $bcc = []; /** * Array of Reply-To addresses with 'name' and 'email'. * * @var array */ private $reply_to = []; /** * Content type of the email (e.g., 'text/plain' or 'text/html'). * * @var string */ private $content_type = 'text/plain'; /** * Character set of the email (e.g., 'UTF-8'). * * @var string */ private $charset = 'UTF-8'; /** * Boundary string used in multipart emails. * * @var string */ private $boundary = ''; /** * Mailer used to send the email. * * @var string */ private $x_mailer; /** * Associative array for any additional headers. * * @var array */ private $extra_headers = []; /** * The email body content. * * @var string */ private $message = ''; /** * Array of file paths to be attached. * * @var array */ private $attachments = []; /** * The email subject. * * @var string */ private $subject = ''; /** * Indicates if the email is a resend. * * @var bool */ private $is_resend = false; /** * ProcessEmailData constructor. * * Initializes default values for properties. */ public function __construct() { $this->x_mailer = 'WordPress/' . get_bloginfo( 'version' ); $this->is_resend = ConnectionManager::instance()->get_is_resend(); } /** * Process the recipients ($to). * * @param string|array $to Recipients as a comma-separated string or an array. * @return array Array of recipients with 'name' and 'email'. */ public function process_to( $to ) { $recipients = []; // If $to is a string, split it by commas. if ( ! is_array( $to ) ) { $to = explode( ',', $to ); } foreach ( (array) $to as $recipient ) { $recipient = trim( $recipient ); if ( empty( $recipient ) ) { continue; } // Check if recipient is in the format "Name <email@example.com>". if ( preg_match( '/^(.*)<(.+)>$/', $recipient, $matches ) ) { $name = trim( $matches[1], " \t\n\r\0\x0B\"" ); // Remove surrounding quotes and whitespace. $email = sanitize_email( trim( $matches[2] ) ); } else { $name = ''; $email = sanitize_email( $recipient ); } if ( is_email( $email ) ) { $recipients[] = [ 'name' => $name, 'email' => $email, ]; } } $this->set_to( $recipients ); return $recipients; } /** * Process the headers ($headers). * * @param string|array $headers Headers as a string or an array. * @return array Associative array of processed headers. */ public function process_headers( $headers ) { $processed_headers = [ 'bcc' => [], 'cc' => [], 'reply_to' => [], 'content_type' => 'text/plain', 'charset' => get_bloginfo( 'charset' ), 'boundary' => '', 'x_mailer' => $this->x_mailer, 'extra_headers' => [], 'from' => [ 'name' => '', 'email' => '', ], ]; // If headers are a string, split them by newlines. if ( ! is_array( $headers ) ) { $headers = explode( "\n", str_replace( "\r\n", "\n", $headers ) ); } foreach ( (array) $headers as $header ) { $header = trim( $header ); if ( empty( $header ) ) { continue; } // Ensure the header contains a colon. if ( strpos( $header, ':' ) === false ) { // Handle headers like "boundary=..." without a colon. if ( stripos( $header, 'boundary=' ) !== false ) { $boundary_parts = preg_split( '/boundary=/i', $header ); if ( isset( $boundary_parts[1] ) ) { $processed_headers['boundary'] = trim( str_replace( [ '"', "'" ], '', $boundary_parts[1] ) ); } } continue; } [$name, $content] = explode( ':', $header, 2 ); $name = strtolower( trim( $name ) ); $content = trim( $content ); switch ( $name ) { case 'bcc': $processed_headers['bcc'] = array_merge( $processed_headers['bcc'], $this->parse_emails( $content ) ); break; case 'cc': $processed_headers['cc'] = array_merge( $processed_headers['cc'], $this->parse_emails( $content ) ); break; case 'reply-to': $processed_headers['reply_to'] = array_merge( $processed_headers['reply_to'], $this->parse_emails( $content ) ); break; case 'content-type': // Split content-type and charset if available. if ( strpos( $content, ';' ) !== false ) { [$type, $params] = explode( ';', $content, 2 ); $processed_headers['content_type'] = trim( $type ); // Parse parameters. foreach ( explode( ';', $params ) as $param ) { if ( stripos( $param, 'charset=' ) !== false ) { $charset = trim( str_replace( [ 'charset=', '"' ], '', $param ) ); $processed_headers['charset'] = sanitize_text_field( $charset ); } elseif ( stripos( $param, 'boundary=' ) !== false ) { $boundary = trim( str_replace( [ 'boundary=', '"' ], '', $param ) ); $processed_headers['boundary'] = sanitize_text_field( $boundary ); } } } else { $processed_headers['content_type'] = sanitize_text_field( $content ); } break; case 'x-mailer': $processed_headers['x_mailer'] = sanitize_text_field( $content ); break; case 'from': // Parse "From" header. if ( preg_match( '/^(.*)<(.+)>$/', $content, $matches ) ) { $name = trim( $matches[1], " \t\n\r\0\x0B\"" ); // Remove surrounding quotes and whitespace. $email = sanitize_email( trim( $matches[2] ) ); if ( is_email( $email ) ) { $processed_headers['from'] = [ 'name' => $name, 'email' => $email, ]; } } else { $email = sanitize_email( trim( $content ) ); if ( is_email( $email ) ) { $processed_headers['from'] = [ 'name' => '', 'email' => $email, ]; } } break; default: // Any other headers. $processed_headers['extra_headers'][ $name ] = sanitize_text_field( $content ); break; } } // Apply WordPress filters if 'from' is not set via headers. if ( empty( $processed_headers['from']['email'] ) ) { $from_email = apply_filters( 'wp_mail_from', '' ); $from_name = apply_filters( 'wp_mail_from_name', '' ); if ( is_email( $from_email ) ) { $processed_headers['from'] = [ 'name' => sanitize_text_field( $from_name ), 'email' => $from_email, ]; } } // Apply WordPress filters for content type and charset. $processed_headers['content_type'] = apply_filters( 'wp_mail_content_type', $processed_headers['content_type'] ); $processed_headers['charset'] = apply_filters( 'wp_mail_charset', $processed_headers['charset'] ); // Set the processed headers to class properties. $this->set_from( $processed_headers['from'] ); $this->set_cc( $processed_headers['cc'] ); $this->set_bcc( $processed_headers['bcc'] ); $this->set_reply_to( $processed_headers['reply_to'] ); $this->set_content_type( $processed_headers['content_type'] ); $this->set_charset( $processed_headers['charset'] ); $this->set_boundary( $processed_headers['boundary'] ); $this->set_x_mailer( $processed_headers['x_mailer'] ); $this->set_extra_headers( $processed_headers['extra_headers'] ); return $processed_headers; } /** * Process the attachments ($attachments). * * @param string|array $attachments Attachments as a string or an array. * @return array Array of sanitized attachment file paths. */ public function process_attachments( $attachments ) { $processed_attachments = []; $processed_uploaded_attachments = []; // If attachments are a string, split them by newlines. if ( ! is_array( $attachments ) ) { $attachments = explode( "\n", str_replace( "\r\n", "\n", $attachments ) ); } $upload = Uploads::instance(); // Process each attachment. $uploaded_attachments = $upload->handle_attachments( $attachments ); foreach ( (array) $attachments as $attachment ) { $attachment = trim( $attachment ); if ( empty( $attachment ) ) { continue; } if ( $this->is_resend === true ) { $path = Uploads::get_suremails_base_dir(); if ( ! is_wp_error( $path ) && isset( $path['path'] ) ) { $attachment = $path['path'] . '/attachments/' . $attachment; } } // Validate the attachment path. $attachment = sanitize_text_field( $attachment ); if ( is_readable( $attachment ) ) { $processed_attachments[] = $attachment; } } foreach ( (array) $uploaded_attachments as $attachment ) { $attachment = trim( $attachment ); if ( empty( $attachment ) ) { continue; } // Validate the attachment path. $attachment = sanitize_text_field( $attachment ); if ( file_exists( $attachment ) && is_readable( $attachment ) ) { $processed_uploaded_attachments[] = $attachment; } } $this->set_attachments( $processed_attachments ); return $processed_uploaded_attachments; } /** * Process the message ($message). * * @param string $message The email message. * @param bool $is_html Whether the message is HTML. * @return string The sanitized message. */ public function process_message( string $message, bool $is_html = false ) { $this->set_message( $message ); return $message; } /** * Sanitize and process the subject ($subject). * * @param string $subject The email subject. * @return string The sanitized subject. */ public function process_subject( string $subject ) { $this->set_subject( $subject ); return $subject; } /** * Formats the processed headers into a suitable format for sending. * * @param array $headers Processed headers. * @return array Formatted headers. */ public function format_processed_headers( array $headers ) { $formatted_headers = []; // From. if ( ! empty( $headers['from']['email'] ) ) { $from = $headers['from']['email']; if ( ! empty( $headers['from']['name'] ) ) { $from = $headers['from']['name'] . ' <' . $headers['from']['email'] . '>'; } $formatted_headers[] = 'From: ' . $from; } // CC. if ( ! empty( $headers['cc'] ) ) { $cc_emails = array_map( static function ( $cc ) { return ! empty( $cc['name'] ) ? "{$cc['name']} <{$cc['email']}>" : $cc['email']; }, $headers['cc'] ); $formatted_headers[] = 'Cc: ' . implode( ', ', $cc_emails ); } // BCC. if ( ! empty( $headers['bcc'] ) ) { $bcc_emails = array_map( static function ( $bcc ) { return ! empty( $bcc['name'] ) ? "{$bcc['name']} <{$bcc['email']}>" : $bcc['email']; }, $headers['bcc'] ); $formatted_headers[] = 'Bcc: ' . implode( ', ', $bcc_emails ); } // Reply-To. if ( ! empty( $headers['reply_to'] ) ) { $reply_to_emails = array_map( static function ( $reply_to ) { return ! empty( $reply_to['name'] ) ? "{$reply_to['name']} <{$reply_to['email']}>" : $reply_to['email']; }, $headers['reply_to'] ); $formatted_headers[] = 'Reply-To: ' . implode( ', ', $reply_to_emails ); } // Content-Type. if ( ! empty( $headers['content_type'] ) ) { $content_type_header = 'Content-Type: ' . $headers['content_type']; if ( ! empty( $headers['charset'] ) ) { $content_type_header .= '; charset=' . $headers['charset']; } if ( ! empty( $headers['boundary'] ) ) { $content_type_header .= '; boundary="' . $headers['boundary'] . '"'; } $formatted_headers[] = $content_type_header; } // X-Mailer. if ( ! empty( $headers['x_mailer'] ) ) { $formatted_headers[] = 'X-Mailer: ' . $headers['x_mailer']; } // Extra Headers. if ( ! empty( $headers['extra_headers'] ) && is_array( $headers['extra_headers'] ) ) { foreach ( $headers['extra_headers'] as $name => $content ) { $formatted_headers[] = "{$name}: {$content}"; } } // Return as array for consistency. return $formatted_headers; } /** * Formats email recipients for logging. * * @param array|string $recipients The email recipients. * @return string Formatted recipients. */ public function format_email_recipients( $recipients ) { $formatted = []; if ( ! is_array( $recipients ) ) { $recipients = array_map( 'trim', explode( ',', $recipients ) ); } foreach ( $recipients as $recipient ) { if ( ! empty( $recipient['name'] ) ) { $formatted[] = "{$recipient['name']} <{$recipient['email']}>"; } elseif ( ! empty( $recipient['email'] ) ) { $formatted[] = $recipient['email']; } } return implode( ', ', $formatted ); } /** * Comprehensive processing of all email components. * * @param string|array $to Recipients as a comma-separated string or an array. * @param string|array $headers Headers as a string or an array. * @param string $message The email message. * @param string|array $attachments Attachments as a string or an array. * @param string $subject The email subject. * @return array Processed email data. */ public function process_all( $to, $headers, $message, $attachments, $subject ) { // Process each component. $processed_to = $this->process_to( $to ); $processed_headers = $this->process_headers( $headers ); $processed_message = $this->process_message( $message, true ); $processed_attachments = $this->process_attachments( $attachments ); $processed_subject = $this->process_subject( $subject ); $mail_data = compact( 'to', 'headers', 'message', 'attachments', 'subject', ); // Structure the processed data. $processed_data = [ 'to' => $this->get_to(), 'headers' => [ 'from' => $this->get_from(), // Array of name and email. 'cc' => $this->get_cc(), // Array of name and email. 'bcc' => $this->get_bcc(), // Array of name and email. 'reply_to' => $this->get_reply_to(), // Array of name and email. 'content_type' => $this->get_content_type(), 'charset' => $this->get_charset(), 'boundary' => $this->get_boundary(), 'x_mailer' => $this->get_x_mailer(), 'extra_headers' => $this->get_extra_headers(), // Associative array. ], 'message' => $this->get_message(), 'attachments' => $this->get_attachments(), 'subject' => $this->get_subject(), 'uploaded_attachments' => $processed_attachments, ]; $phpmailer = ConnectionManager::instance()->get_phpmailer(); //phpcs:disable $phpmailer->clearAllRecipients(); $phpmailer->clearAttachments(); $phpmailer->clearCustomHeaders(); $phpmailer->clearReplyTos(); $phpmailer->Body = ''; $phpmailer->AltBody = ''; // Populate PHPMailer with processed data. try { // Set From. $from = $processed_data['headers']['from']; $from_email = $from['email']; $from_name = $from['name']; if( ! empty( $from_email ) ) { $phpmailer->setFrom( $from_email, $from_name ); } // Add To recipients. foreach ( $processed_data['to'] as $recipient ) { $phpmailer->addAddress( $recipient['email'], $recipient['name'] ); } // Add CC recipients. if ( ! empty( $processed_data['headers']['cc'] ) ) { foreach ( $processed_data['headers']['cc'] as $cc ) { $phpmailer->addCC( $cc['email'], $cc['name'] ); } } // Add BCC recipients. if ( ! empty( $processed_data['headers']['bcc'] ) ) { foreach ( $processed_data['headers']['bcc'] as $bcc ) { $phpmailer->addBCC( $bcc['email'], $bcc['name'] ); } } // Add Reply-To addresses. if ( ! empty( $processed_data['headers']['reply_to'] ) ) { foreach ( $processed_data['headers']['reply_to'] as $reply_to ) { $phpmailer->addReplyTo( $reply_to['email'], $reply_to['name'] ); } } // Set Subject. $phpmailer->Subject = $processed_data['subject']; // Set Body. if( strtolower( $processed_data['headers']['content_type'] ) === 'text/html' ) { $phpmailer->Body = $processed_data['message']; $phpmailer->AltBody = wp_strip_all_tags($processed_data['message']); } else { $phpmailer->Body = wp_strip_all_tags($processed_data['message']); } // Add Attachments. if ( ! empty( $processed_data['attachments'] ) ) { foreach ( $processed_data['attachments'] as $attachment ) { $file_name = $this->get_attachment_name( $attachment ); $phpmailer->addAttachment($attachment, $file_name); } } // Set Content-Type and Charset. $phpmailer->isHTML( strtolower( $processed_data['headers']['content_type'] ) === 'text/html' ); $phpmailer->CharSet = $processed_data['headers']['charset']; //phpcs:enable } catch ( Exception $e ) { // Handle exceptions during PHPMailer setup. LogError::instance()->log_error( 'PHPMailer Exception: ' . $e->getMessage() ); do_action( 'wp_mail_failed', new \WP_Error( 'phpmailer_exception', $e->getMessage(), $mail_data ) ); } return $processed_data; } /** * Get the attachment name. * * @param string $attachment The attachment path. * @return string The attachment name. */ public function get_attachment_name( $attachment ) { if ( $this->is_resend === false ) { return basename( $attachment ); } $base_name = basename( $attachment ); return substr( $base_name, strpos( $base_name, '-' ) + 1 ); } /** * Get HTML headers. * * @return string */ public static function get_html_headers() { return 'Content-Type: text/html; charset=UTF-8.'; } /** * Get plain text headers. * * @return string */ public static function get_text_headers() { return 'Content-Type: text/plain; charset=UTF-8.'; } /* ==================== Getter and Setter Methods ==================== */ /** * Get the primary recipients. * * @return array Array of recipients with 'name' and 'email'. */ public function get_to() { return $this->to; } /** * Set the primary recipients. * * @param array $to Array of recipients with 'name' and 'email'. * @return void */ public function set_to( array $to ) { $this->to = $to; } /** * Get the 'from' details. * * @return array Associative array with 'name' and 'email'. */ public function get_from() { return $this->from; } /** * Set the 'from' details. * * @param array $from Associative array with 'name' and 'email'. * @return void */ public function set_from( array $from ) { $this->from = $from; } /** * Get the CC recipients. * * @return array Array of CC recipients with 'name' and 'email'. */ public function get_cc() { return $this->cc; } /** * Set the CC recipients. * * @param array $cc Array of CC recipients with 'name' and 'email'. * @return void */ public function set_cc( array $cc ) { $this->cc = $cc; } /** * Get the BCC recipients. * * @return array Array of BCC recipients with 'name' and 'email'. */ public function get_bcc() { return $this->bcc; } /** * Set the BCC recipients. * * @param array $bcc Array of BCC recipients with 'name' and 'email'. * @return void */ public function set_bcc( array $bcc ) { $this->bcc = $bcc; } /** * Get the Reply-To addresses. * * @return array Array of Reply-To addresses with 'name' and 'email'. */ public function get_reply_to() { return $this->reply_to; } /** * Set the Reply-To addresses. * * @param array $reply_to Array of Reply-To addresses with 'name' and 'email'. * @return void */ public function set_reply_to( array $reply_to ) { $this->reply_to = $reply_to; } /** * Get the content type. * * @return string Content type of the email. */ public function get_content_type() { return $this->content_type; } /** * Set the content type. * * @param string $content_type Content type of the email. * @return void */ public function set_content_type( string $content_type ) { $this->content_type = $content_type; } /** * Get the charset. * * @return string Character set of the email. */ public function get_charset() { return $this->charset; } /** * Set the charset. * * @param string $charset Character set of the email. * @return void */ public function set_charset( string $charset ) { $this->charset = $charset; } /** * Get the boundary. * * @return string Boundary string used in multipart emails. */ public function get_boundary() { return $this->boundary; } /** * Set the boundary. * * @param string $boundary Boundary string used in multipart emails. * @return void */ public function set_boundary( string $boundary ) { $this->boundary = $boundary; } /** * Get the X-Mailer. * * @return string Mailer used to send the email. */ public function get_x_mailer() { return $this->x_mailer; } /** * Set the X-Mailer. * * @param string $x_mailer Mailer used to send the email. * @return void */ public function set_x_mailer( string $x_mailer ) { $this->x_mailer = $x_mailer; } /** * Get the extra headers. * * @return array Associative array of extra headers. */ public function get_extra_headers() { return $this->extra_headers; } /** * Set the extra headers. * * @param array $extra_headers Associative array of extra headers. * @return void */ public function set_extra_headers( array $extra_headers ) { $this->extra_headers = $extra_headers; } /** * Get the message. * * @return string The email body content. */ public function get_message() { return $this->message; } /** * Set the message. * * @param string $message The email body content. * @return void */ public function set_message( string $message ) { $this->message = $message; } /** * Get the attachments. * * @return array Array of attachment file paths. */ public function get_attachments() { return $this->attachments; } /** * Set the attachments. * * @param array $attachments Array of attachment file paths. * @return void */ public function set_attachments( array $attachments ) { $this->attachments = $attachments; } /** * Get the subject. * * @return string The email subject. */ public function get_subject() { return $this->subject; } /** * Set the subject. * * @param string $subject The email subject. * @return void */ public function set_subject( string $subject ) { $this->subject = $subject; } /** * Parse a string of email addresses into an array. * * @param string $emails Comma-separated email addresses. * @return array Array of sanitized email addresses. */ private function parse_emails( string $emails ) { $parsed_emails = []; $emails = explode( ',', $emails ); foreach ( $emails as $email ) { $email = trim( $email ); if ( empty( $email ) ) { continue; } // Check if email is in "Name <email@example.com>" format. if ( preg_match( '/^(.*)<(.+)>$/', $email, $matches ) ) { $name = trim( $matches[1], " \t\n\r\0\x0B\"" ); $email = sanitize_email( trim( $matches[2] ) ); } else { $name = ''; $email = sanitize_email( $email ); } if ( is_email( $email ) ) { $parsed_emails[] = [ 'name' => $name, 'email' => $email, ]; } } return $parsed_emails; } }
Copyright ©2021 || Defacer Indonesia