• Resolved welfakir

    (@welfakir)


    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-&gt;set_vars(); $this-&gt;hooks(); } public function set_vars() { // Lazy-get options (plugin-specific) if ( class_exists( 'PostmanOptions', false ) ) { $this-&gt;options = PostmanOptions::getInstance(); } else { $this-&gt;options = null; } $this-&gt;Debugoutput = function( $str, $level ) { $this-&gt;transcript .= $str; }; } public function hooks() { add_filter( 'wp_mail', array( $this, 'get_mail_args' ) ); if ( $this-&gt;options &amp;&amp; $this-&gt;options-&gt;getTransportType() == 'smtp' ) { add_action( 'phpmailer_init', array( $this, 'phpmailer_smtp_init' ), 999 ); } } public function get_mail_args( $atts ) { $this-&gt;mail_args = array(); $this-&gt;mail_args[] = isset( $atts['to'] ) ? $atts['to'] : null; $this-&gt;mail_args[] = isset( $atts['subject'] ) ? $atts['subject'] : null; $this-&gt;mail_args[] = isset( $atts['message'] ) ? $atts['message'] : null; $this-&gt;mail_args[] = isset( $atts['headers'] ) ? $atts['headers'] : null; $this-&gt;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-&gt;options ) ) { return; } $mail-&gt;SMTPDebug = 3; if ( method_exists( $mail, 'isSMTP' ) ) { $mail-&gt;isSMTP(); } elseif ( method_exists( $mail, 'isMail' ) ) { $mail-&gt;isMail(); } $mail-&gt;Host = $this-&gt;options-&gt;getHostname(); $mail-&gt;Hostname = $this-&gt;options-&gt;getHostname(); if ( $this-&gt;options-&gt;getAuthenticationType() !== 'none' ) { $mail-&gt;SMTPAuth = true; $mail-&gt;Username = $this-&gt;options-&gt;getUsername(); $mail-&gt;Password = $this-&gt;options-&gt;getPassword(); } if ( $this-&gt;options-&gt;getEncryptionType() !== 'none' ) { $mail-&gt;SMTPSecure = $this-&gt;options-&gt;getEncryptionType(); } $mail-&gt;Port = $this-&gt;options-&gt;getPort(); if ( $this-&gt;options-&gt;isPluginSenderEmailEnforced() ) { if ( method_exists( $mail, 'setFrom' ) ) { $mail-&gt;setFrom( $this-&gt;options-&gt;getMessageSenderEmail(), $this-&gt;options-&gt;getMessageSenderName() ); } else { // attempt to set legacy properties if setFrom is unavailable $mail-&gt;From = $this-&gt;options-&gt;getMessageSenderEmail(); $mail-&gt;FromName = $this-&gt;options-&gt;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-&gt;init(); } list( $to, $subject, $body, $headers, $attachments ) = array_pad( $this-&gt;mail_args, 5, null ); $postmanMessage = $postmanWpMail-&gt;processWpMailCall( $to, $subject, $body, $headers, $attachments ); $log = new PostmanEmailLog(); $log-&gt;originalTo = $to; $log-&gt;originalSubject = $subject; $log-&gt;originalMessage = $body; $log-&gt;originalHeaders = $headers; $transport = PostmanTransportRegistry::getInstance()-&gt;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-&gt;options &amp;&amp; $this-&gt;options-&gt;getTransportType() !== 'smtp' ) { $result = $postmanWpMail-&gt;send( $to, $subject, $body, $headers, $attachments ); if ( $result ) { do_action( 'post_smtp_on_success', $log, $postmanMessage, $this-&gt;transcript, $transport ); } } else { // smtp path $response = $this-&gt;sendSmtp(); if ( $response ) { do_action( 'post_smtp_on_success', $log, $postmanMessage, $this-&gt;transcript, $transport ); $result = true; } else { $result = false; } } } return $result; } catch ( Exception $exc ) { $this-&gt;error = $exc; $this-&gt;mailHeader = ''; $this-&gt;setError( $exc-&gt;getMessage() ); do_action( 'post_smtp_on_failed', $log, $postmanMessage, $this-&gt;transcript, $transport, $exc-&gt;getMessage() ); if ( $this-&gt;exceptions ) { throw $exc; } return false; } } public function sendSmtp() { if ( ! $this-&gt;preSend() ) { return false; } return $this-&gt;postSend(); } public function postman_wp_mail_result() { $result = array( 'time' =&gt; '', 'exception' =&gt; $this-&gt;error, 'transcript' =&gt; $this-&gt;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.’ );
      }
      }
      } );
Viewing 2 replies - 1 through 2 (of 2 total)
  • Plugin Support M Aqib Khan

    (@aqibkhan9)

    Hello @welfakir,

    We hope this message finds you well.

    Thank you for reaching out to our Support team and bringing this to our attention. I’ve forwarded your feedback to our technical team for further review, and the necessary changes are scheduled to be included in the upcoming sprints.

    We truly appreciate your commitment and continued support for the plugin.

    Warm regards,
    Support Team – WP Experts

    Plugin Support M Aqib Khan

    (@aqibkhan9)

    Hello @welfakir ,

    Our team has reviewed the case, fixed the issue, and prepared a beta version of the plugin to address the problems you’ve been experiencing. Kindly download and install the beta plugin on your end.

    Your feedback is extremely valuable to us, so please do share your experience after testing.

    Warm regards,
    Support Team – WP Experts

Viewing 2 replies - 1 through 2 (of 2 total)

The topic ‘phpmailerException’ is closed to new replies.