phpmailerException
-
The code is declaring phpmailerException when that class already exists. The plugin should guard class declarations with class_exists checks. file: wp-content/plugins/post-smtp/Postman/Phpmailer/PostsmtpMailer.php
recommended fix
<?php
/**- PostsmtpMailer.php – Postsmtp wrapper around PHPMailer with guarded class loading
* - Changes:
- – Add guards around class includes/aliasing to avoid redeclaring PHPMailer/SMTP/phpmailerException.
- – Introduce an internal BasePostsmtpPHPMailer alias so PostsmtpMailer can reliably extend a single parent
- without risking a duplicate class declaration.
- – Guard creation of global $phpmailer so we don’t clobber an existing instance unexpectedly.
* - Install: replace the existing file at wp-content/plugins/post-smtp/Postman/PostsmtpMailer.php with this file.
- Test: deactivate/activate the plugin or reload plugins and exercise wp_mail/pb_perform_reservation_delete paths.
* - Note: this file intentionally avoids requiring any PHPMailer source if the classes already exist.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit; // Exit if accessed directly
}/*
- Ensure the core WP PHPMailer classes are available without redeclaring classes.
- Use class_exists checks with the second parameter false (don’t trigger autoload).
*/
if ( version_compare( get_bloginfo( ‘version’ ), ‘5.5-alpha’, ‘<‘ ) ) { if ( ! class_exists( ‘\PHPMailer’, false ) && ! class_exists( ‘PHPMailer’, false ) ) { // WP < 5.5 uses non-namespaced class in ABSPATH . WPINC . ‘/class-phpmailer.php’ require_once ABSPATH . WPINC . ‘/class-phpmailer.php’; } } else { // WP >= 5.5 uses namespaced PHPMailer in WP core
if ( ! class_exists( ‘\PHPMailer\PHPMailer\PHPMailer’, false ) ) {
// Only include if not already loaded by another component/autoloader
require_once ABSPATH . WPINC . ‘/PHPMailer/PHPMailer.php’;
}
if ( ! class_exists( ‘\PHPMailer\PHPMailer\Exception’, false ) ) {
require_once ABSPATH . WPINC . ‘/PHPMailer/Exception.php’;
}
if ( ! class_exists( ‘\PHPMailer\PHPMailer\SMTP’, false ) ) {
require_once ABSPATH . WPINC . ‘/PHPMailer/SMTP.php’;
}
}
/*
- Create safe aliases so PostsmtpMailer can extend a stable parent class name without
- causing duplicate declarations of global non-namespaced symbols.
* - Strategy:
- – If namespaced classes exist in core, alias them to BasePostsmtpPHPMailer / BasePostsmtpSMTP / BasePostsmtpException.
- – If legacy non-namespaced PHPMailer exists, alias that to BasePostsmtpPHPMailer.
- – Only create aliases when the target alias does not already exist (avoid redeclare).
*/
// Ensure a single base parent class name exists for extending
if ( ! class_exists( ‘BasePostsmtpPHPMailer’, false ) ) {
if ( class_exists( ‘\PHPMailer\PHPMailer\PHPMailer’, false ) ) {
class_alias( ‘\PHPMailer\PHPMailer\PHPMailer’, ‘BasePostsmtpPHPMailer’ );
} elseif ( class_exists( ‘PHPMailer’, false ) ) {
// older WP core/class-phpmailer defines PHPMailer; alias it
class_alias( ‘PHPMailer’, ‘BasePostsmtpPHPMailer’ );
}
}// Alias SMTP class if needed (non-critical for inheritance, but used below via fully-qualified names)
if ( ! class_exists( ‘BasePostsmtpSMTP’, false ) ) {
if ( class_exists( ‘\PHPMailer\PHPMailer\SMTP’, false ) ) {
class_alias( ‘\PHPMailer\PHPMailer\SMTP’, ‘BasePostsmtpSMTP’ );
} elseif ( class_exists( ‘SMTP’, false ) ) {
class_alias( ‘SMTP’, ‘BasePostsmtpSMTP’ );
}
}// Alias Exception class if not already present
if ( ! class_exists( ‘BasePostsmtpException’, false ) ) {
if ( class_exists( ‘\PHPMailer\PHPMailer\Exception’, false ) ) {
class_alias( ‘\PHPMailer\PHPMailer\Exception’, ‘BasePostsmtpException’ );
} elseif ( class_exists( ‘phpmailerException’, false ) ) {
class_alias( ‘phpmailerException’, ‘BasePostsmtpException’ );
}
}/*
- Only create backward-compatible global short names if they are not already declared.
- This keeps other code that expects PHPMailer, SMTP or phpmailerException working, but avoids redeclare.
*/
if ( class_exists( ‘BasePostsmtpPHPMailer’, false ) && ! class_exists( ‘PHPMailer’, false ) ) {
class_alias( ‘BasePostsmtpPHPMailer’, ‘PHPMailer’ );
}
if ( class_exists( ‘BasePostsmtpSMTP’, false ) && ! class_exists( ‘SMTP’, false ) ) {
class_alias( ‘BasePostsmtpSMTP’, ‘SMTP’ );
}
if ( class_exists( ‘BasePostsmtpException’, false ) && ! class_exists( ‘phpmailerException’, false ) ) {
class_alias( ‘BasePostsmtpException’, ‘phpmailerException’ );
}
/*
- Defer PostsmtpMailer class declaration until a base PHPMailer class is available.
- If no base parent exists, do not declare the PostsmtpMailer class — the plugin environment
- is invalid and a clear error should be surfaced instead of a fatal redeclare.
*/
if ( class_exists( ‘BasePostsmtpPHPMailer’, false ) ) { // Only declare PostsmtpMailer if not already declared
if ( ! class_exists( ‘PostsmtpMailer’, false ) ) {/** * PostsmtpMailer extends a safe aliased PHPMailer parent (BasePostsmtpPHPMailer). */ class PostsmtpMailer extends BasePostsmtpPHPMailer {private $mail_args = array(); private $options; private $error; private $transcript = ''; public function __construct( $exceptions = null ) { parent::__construct( $exceptions ); $this->set_vars(); $this->hooks(); } public function set_vars() { // Lazy-get options (plugin-specific) if ( class_exists( 'PostmanOptions', false ) ) { $this->options = PostmanOptions::getInstance(); } else { $this->options = null; } $this->Debugoutput = function( $str, $level ) { $this->transcript .= $str; }; } public function hooks() { add_filter( 'wp_mail', array( $this, 'get_mail_args' ) ); if ( $this->options && $this->options->getTransportType() == 'smtp' ) { add_action( 'phpmailer_init', array( $this, 'phpmailer_smtp_init' ), 999 ); } } public function get_mail_args( $atts ) { $this->mail_args = array(); $this->mail_args[] = isset( $atts['to'] ) ? $atts['to'] : null; $this->mail_args[] = isset( $atts['subject'] ) ? $atts['subject'] : null; $this->mail_args[] = isset( $atts['message'] ) ? $atts['message'] : null; $this->mail_args[] = isset( $atts['headers'] ) ? $atts['headers'] : null; $this->mail_args[] = isset( $atts['attachments'] ) ? $atts['attachments'] : null; return $atts; } /** * Initialize PHPMailer for SMTP transport. * * @param \PHPMailer\PHPMailer\PHPMailer $mail */ public function phpmailer_smtp_init( $mail ) { if ( ! is_object( $this->options ) ) { return; } $mail->SMTPDebug = 3; if ( method_exists( $mail, 'isSMTP' ) ) { $mail->isSMTP(); } elseif ( method_exists( $mail, 'isMail' ) ) { $mail->isMail(); } $mail->Host = $this->options->getHostname(); $mail->Hostname = $this->options->getHostname(); if ( $this->options->getAuthenticationType() !== 'none' ) { $mail->SMTPAuth = true; $mail->Username = $this->options->getUsername(); $mail->Password = $this->options->getPassword(); } if ( $this->options->getEncryptionType() !== 'none' ) { $mail->SMTPSecure = $this->options->getEncryptionType(); } $mail->Port = $this->options->getPort(); if ( $this->options->isPluginSenderEmailEnforced() ) { if ( method_exists( $mail, 'setFrom' ) ) { $mail->setFrom( $this->options->getMessageSenderEmail(), $this->options->getMessageSenderName() ); } else { // attempt to set legacy properties if setFrom is unavailable $mail->From = $this->options->getMessageSenderEmail(); $mail->FromName = $this->options->getMessageSenderName(); } } } public function send() { // The Postsmtp implementation delegates to PostmanWpMail to process the message. if ( ! class_exists( 'PostmanWpMail', false ) ) { require_once dirname( __DIR__ ) . '/PostmanWpMail.php'; } $postmanWpMail = new PostmanWpMail(); if ( method_exists( $postmanWpMail, 'init' ) ) { $postmanWpMail->init(); } list( $to, $subject, $body, $headers, $attachments ) = array_pad( $this->mail_args, 5, null ); $postmanMessage = $postmanWpMail->processWpMailCall( $to, $subject, $body, $headers, $attachments ); $log = new PostmanEmailLog(); $log->originalTo = $to; $log->originalSubject = $subject; $log->originalMessage = $body; $log->originalHeaders = $headers; $transport = PostmanTransportRegistry::getInstance()->getActiveTransport(); add_filter( 'postman_wp_mail_result', array( $this, 'postman_wp_mail_result' ) ); try { $response = false; $result = false; if ( $send_email = apply_filters( 'post_smtp_do_send_email', true ) ) { if ( $this->options && $this->options->getTransportType() !== 'smtp' ) { $result = $postmanWpMail->send( $to, $subject, $body, $headers, $attachments ); if ( $result ) { do_action( 'post_smtp_on_success', $log, $postmanMessage, $this->transcript, $transport ); } } else { // smtp path $response = $this->sendSmtp(); if ( $response ) { do_action( 'post_smtp_on_success', $log, $postmanMessage, $this->transcript, $transport ); $result = true; } else { $result = false; } } } return $result; } catch ( Exception $exc ) { $this->error = $exc; $this->mailHeader = ''; $this->setError( $exc->getMessage() ); do_action( 'post_smtp_on_failed', $log, $postmanMessage, $this->transcript, $transport, $exc->getMessage() ); if ( $this->exceptions ) { throw $exc; } return false; } } public function sendSmtp() { if ( ! $this->preSend() ) { return false; } return $this->postSend(); } public function postman_wp_mail_result() { $result = array( 'time' => '', 'exception' => $this->error, 'transcript' => $this->transcript, ); return $result; }} // end class PostsmtpMailer} // end if PostsmtpMailer exists
} else {
// If BasePostsmtpPHPMailer isn’t available, log an admin notice and do not attempt to declare PostsmtpMailer.
if ( defined( ‘WP_DEBUG’ ) && WP_DEBUG ) {
error_log( ‘[Post SMTP] Base PHPMailer class not available; PostsmtpMailer not declared.’ );
}
}
/*
- Create the global $phpmailer instance only if PostsmtpMailer class exists and we are not overriding
- an existing PostsmtpMailer instance. This avoids clobbering another plugin’s $phpmailer.
*/
add_action( ‘plugins_loaded’, function() {
global $phpmailer; if ( class_exists( ‘PostsmtpMailer’, false ) ) {
if ( ! isset( $phpmailer ) || ! ( $phpmailer instanceof PostsmtpMailer ) ) {
// instantiate PostsmtpMailer safely
try {
$phpmailer = new PostsmtpMailer( true );
} catch ( Throwable $e ) {
if ( defined( ‘WP_DEBUG’ ) && WP_DEBUG ) {
error_log( ‘[Post SMTP] Failed to instantiate PostsmtpMailer: ‘ . $e->getMessage() );
}
}
}
} else {
if ( defined( ‘WP_DEBUG’ ) && WP_DEBUG ) {
error_log( ‘[Post SMTP] PostsmtpMailer class not available on plugins_loaded.’ );
}
}
} );
- PostsmtpMailer.php – Postsmtp wrapper around PHPMailer with guarded class loading
The topic ‘phpmailerException’ is closed to new replies.