automatewoo/includes/Mailer_Abstract.php
fei-source 47d3c9a8b6 Update to v6.2.2
Source: GrootMade/Festinger Vault
2026-03-15 08:31:15 +08:00

417 lines
8 KiB
PHP

<?php
namespace AutomateWoo;
/**
* Abstract class for Mailers.
*
* @since 4.4.0
*/
abstract class Mailer_Abstract {
/**
* The recipient of the email.
*
* @var string
*/
public $email;
/**
* The content of the email body.
*
* @var string
*/
public $content;
/**
* The email subject.
*
* @var string
*/
public $subject;
/**
* The email sender name.
*
* @var string
*/
public $from_name;
/**
* The email sender email.
*
* @var string
*/
public $from_email;
/**
* The email attachments.
*
* @var array
*/
public $attachments = [];
/**
* The reply-to email address.
*
* @var string
*/
public $reply_to;
/**
* The email CC recipients.
*
* @var array
*/
public $cc = [];
/**
* The email BCC recipients.
*
* @var array
*/
public $bcc = [];
/**
* The email type.
*
* @var string (html|plain)
*/
public $email_type = 'html';
/**
* URL to set as the List-Unsubscribe header to support one click
* unsubscribe. Header will not be included if value is false.
*
* @var string|bool
*/
public $one_click_unsubscribe = false;
/**
* Returns email body, can be HTML or plain text.
*
* @since 4.4.0
*
* @return string
*/
abstract public function get_email_body();
/**
* Set email recipient.
*
* @param string $email
*/
public function set_email( $email ) {
$this->email = $email;
}
/**
* Set the email body content.
*
* @param string $content
*/
public function set_content( $content ) {
$this->content = $content;
}
/**
* Set the email subject.
*
* @param string $subject
*/
public function set_subject( $subject ) {
$this->subject = $subject;
}
/**
* Set the URL for the one click unsubscribe header
*
* @param string $url The URL where a POST request will be received to unsubscribe an email address
*
* @return void
*/
public function set_one_click_unsubscribe( $url ) {
$this->one_click_unsubscribe = $url;
}
/**
* Set the reply-to email address.
*
* @param string $reply_to The reply-to email address.
*/
public function set_reply_to( $reply_to ) {
$this->reply_to = $reply_to;
}
/**
* Get email sender email address.
*
* @return string
*/
public function get_from_email() {
if ( ! isset( $this->from_email ) ) {
$this->from_email = Emails::get_from_address();
}
return $this->from_email;
}
/**
* Get email sender name.
*
* @return string
*/
public function get_from_name() {
if ( ! isset( $this->from_name ) ) {
$this->from_name = Emails::get_from_name();
}
return $this->from_name;
}
/**
* Get the reply-to email address.
*
* @return string
*/
public function get_reply_to() {
return $this->reply_to;
}
/**
* Validate the recipient's email address.
*
* @return true|\WP_Error
*/
public function validate_recipient_email() {
if ( ! $this->email ) {
return new \WP_Error( 'email_blank', __( 'Email address is blank.', 'automatewoo' ) );
}
if ( ! is_email( $this->email ) ) {
return new \WP_Error( 'email_invalid', __( 'Email address is not valid.', 'automatewoo' ) );
}
if ( aw_is_email_anonymized( $this->email ) ) {
return new \WP_Error( 'email_anonymized', __( 'Email address appears to be anonymized.', 'automatewoo' ) );
}
/**
* Filter allows blacklisting hosts or email addresses with custom code.
*
* @since 3.6.0
*/
$blacklist = apply_filters( 'automatewoo/mailer/blacklist', [] );
foreach ( $blacklist as $pattern ) {
if ( strstr( $this->email, $pattern ) ) {
return new \WP_Error( 'email_blacklisted', __( 'Email address is blacklisted.', 'automatewoo' ) );
}
}
return true;
}
/**
* Sends the email if validation passes.
*
* @return true|\WP_Error
*/
public function send() {
$validate_email = $this->validate_recipient_email();
if ( is_wp_error( $validate_email ) ) {
return $validate_email;
}
do_action( 'automatewoo/email/before_send', $this );
add_filter( 'wp_mail_from', [ $this, 'get_from_email' ] );
add_filter( 'wp_mail_from_name', [ $this, 'get_from_name' ] );
add_filter( 'wp_mail_content_type', [ $this, 'get_content_type' ] );
add_action( 'wp_mail_failed', [ $this, 'log_wp_mail_errors' ] );
remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
$headers = [
'Content-Type: ' . $this->get_content_type(),
];
if ( $this->reply_to ) {
$headers[] = 'Reply-To: ' . $this->reply_to;
}
if ( ! empty( $this->cc ) ) {
$headers[] = 'Cc: ' . implode( ', ', $this->cc );
}
if ( ! empty( $this->bcc ) ) {
$headers[] = 'Bcc: ' . implode( ', ', $this->bcc );
}
if ( $this->one_click_unsubscribe ) {
$headers[] = 'List-Unsubscribe-Post: List-Unsubscribe=One-Click';
$headers[] = "List-Unsubscribe: <$this->one_click_unsubscribe>";
}
$subject = wp_specialchars_decode( $this->subject, ENT_QUOTES );
$sent = wp_mail(
$this->email,
$subject,
$this->get_email_body(),
$headers,
$this->attachments
);
remove_filter( 'wp_mail_from', [ $this, 'get_from_email' ] );
remove_filter( 'wp_mail_from_name', [ $this, 'get_from_name' ] );
remove_filter( 'wp_mail_content_type', [ $this, 'get_content_type' ] );
remove_action( 'wp_mail_failed', [ $this, 'log_wp_mail_errors' ] );
add_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
if ( $sent === false ) {
$phpmailer_error = $this->get_phpmailer_last_error();
if ( $phpmailer_error ) {
/* translators: PHP Mailer error message. */
return new \WP_Error( 4, sprintf( __( 'PHP Mailer - %s', 'automatewoo' ), $phpmailer_error ) );
}
return new \WP_Error( 5, __( 'The wp_mail() function returned false.', 'automatewoo' ) );
}
return $sent;
}
/**
* Process email variables. Currently only {{ unsubscribe_url }}.
*
* @param string $content
*
* @return string
*/
public function process_email_variables( $content ) {
$replacer = new Replace_Helper( $content, [ $this, 'callback_process_email_variables' ], 'variables' );
return $replacer->process();
}
/**
* Callback function to process email variables
*
* @param string $variable
*
* @return string
*/
public function callback_process_email_variables( $variable ) {
$variable = trim( $variable );
$value = '';
switch ( $variable ) {
case 'unsubscribe_url':
$value = \AW_Mailer_API::unsubscribe_url();
break;
}
return apply_filters( 'automatewoo/mailer/variable_value', $value, $this );
}
/**
* Get the email type.
*
* @return string
*/
public function get_email_type() {
return $this->email_type && class_exists( 'DOMDocument' ) ? $this->email_type : 'plain';
}
/**
* Get the email content type.
*
* @return string
*/
public function get_content_type() {
switch ( $this->get_email_type() ) {
case 'html':
return 'text/html';
case 'multipart':
return 'multipart/alternative';
default:
return 'text/plain';
}
}
/**
* Log a WP_Error.
*
* @param \WP_Error $error
*/
public function log_wp_mail_errors( $error ) {
Logger::error( 'wp-mail', $error->get_error_message() );
}
/**
* Gets the most recent PHPMailer error message.
*
* @since 5.0.3
*
* @return string
*/
protected function get_phpmailer_last_error() {
global $phpmailer;
if ( $phpmailer ) {
// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
return $phpmailer->ErrorInfo;
}
return '';
}
/**
* Set CC recipients for the email.
*
* @since 6.2.1
*
* @param array $cc Array of email addresses.
*/
public function set_cc( array $cc ) {
$this->cc = $cc;
}
/**
* Set BCC recipients for the email.
*
* @since 6.2.1
*
* @param array $bcc Array of email addresses.
*/
public function set_bcc( array $bcc ) {
$this->bcc = $bcc;
}
/**
* Get CC recipients for the email.
*
* @since 6.2.1
*
* @return array
*/
public function get_cc() {
return $this->cc;
}
/**
* Get BCC recipients for the email.
*
* @since 6.2.1
*
* @return array
*/
public function get_bcc() {
return $this->bcc;
}
}