diff --git a/src/wp-includes/pluggable.php b/src/wp-includes/pluggable.php index 1dbac5e1d707c..6c7c286604c42 100644 --- a/src/wp-includes/pluggable.php +++ b/src/wp-includes/pluggable.php @@ -254,6 +254,17 @@ function wp_mail( $to, $subject, $message, $headers = '', $attachments = array() require_once ABSPATH . WPINC . '/class-wp-phpmailer.php'; $phpmailer = new WP_PHPMailer( true ); + /** + * Filters the PHPMailer object. + * + * Allows plugins to override the PHPMailer class with one of their own if required. + * + * @since 6.9.0 + * + * @param object $phpmailer A PHPMailer (or compatible) class. + */ + $phpmailer = apply_filters( 'wp_phpmailer', $phpmailer ); + $phpmailer::$validator = static function ( $email ) { return (bool) is_email( $email ); }; diff --git a/tests/phpunit/includes/functions.php b/tests/phpunit/includes/functions.php index 516727380c109..fa26df40c40c3 100644 --- a/tests/phpunit/includes/functions.php +++ b/tests/phpunit/includes/functions.php @@ -363,3 +363,14 @@ function _unhook_font_registration() { remove_action( 'init', '_wp_register_default_font_collections' ); } tests_add_filter( 'init', '_unhook_font_registration', 1000 ); + +/** + * Ensure that PHPMailer is always a MockPHPMailer + * + * @param object $phpmailer The PHPMailer object. + * @return object The MockPHPMailer object. + */ +function _wp_phpmailer( $phpmailer ) { + return new MockPHPMailer(); +} +tests_add_filter( 'wp_phpmailer', '_wp_phpmailer' ); diff --git a/tests/phpunit/tests/pluggable/wpMail.php b/tests/phpunit/tests/pluggable/wpMail.php index 7b88d739add22..c500a5f72d3cf 100644 --- a/tests/phpunit/tests/pluggable/wpMail.php +++ b/tests/phpunit/tests/pluggable/wpMail.php @@ -554,4 +554,27 @@ public function test_wp_mail_resets_properties() { $phpmailer = $GLOBALS['phpmailer']; $this->assertNotSame( 'user1', $phpmailer->AltBody ); } + + /** + * If the global $phpmailer is overridden, it should be recreated as a real MockPHPMailer object in tests. + * + * @ticket 28618 + */ + public function test_global_override_can_create_real_phpmailer() { + global $phpmailer; + + $this->assertInstanceOf( 'MockPHPMailer', $phpmailer, 'The global $phpmailer should be a MockPHPMailer.' ); + + $phpmailer = null; + + global $phpmailer; + + $this->assertNull( $phpmailer, 'The global $phpmailer should be null.' ); + + wp_mail( 'test@example.com', 'Test Subject', 'Test Message' ); + + global $phpmailer; + + $this->assertInstanceOf( 'MockPHPMailer', $phpmailer, 'The global $phpmailer should still be a MockPHPMailer.' ); + } }