modules = $modules; $this->logs = $logs; } /** * Register hooks. * * @return void */ public function register() { add_action( 'phpmailer_init', array( $this, 'configure_phpmailer' ) ); add_action( 'wp_mail_succeeded', array( $this, 'log_success' ) ); add_action( 'wp_mail_failed', array( $this, 'log_failure' ) ); add_action( 'noorsmtp_prune_logs', array( $this, 'prune_logs' ) ); } /** * Configure PHPMailer using the active module's settings. * * @param \PHPMailer\PHPMailer\PHPMailer $phpmailer PHPMailer instance. * @return void */ public function configure_phpmailer( $phpmailer ) { $slug = $this->modules->active_mailer_slug(); $settings = get_option( 'noorsmtp_settings', array() ); $from_email = ! empty( $settings['from_email'] ) ? sanitize_email( $settings['from_email'] ) : get_option( 'admin_email' ); $from_name = ! empty( $settings['from_name'] ) ? sanitize_text_field( $settings['from_name'] ) : get_bloginfo( 'name' ); // Enforce or default From header if ( ! empty( $settings['force_from'] ) || empty( $phpmailer->From ) || 'wordpress@' === substr( (string) $phpmailer->From, 0, 10 ) ) { if ( ! empty( $from_email ) ) { $phpmailer->setFrom( $from_email, $from_name, false ); } } // Ensure envelope Sender (Return-Path) is set so mail servers don't drop unauthenticated envelope headers if ( ! empty( $from_email ) && empty( $phpmailer->Sender ) ) { $phpmailer->Sender = $from_email; } if ( empty( $slug ) || 'default' === $slug || 'mail' === $slug ) { $phpmailer->isMail(); return; } $module = $this->modules->get( $slug ); if ( ! $module ) { // Fallback to PHP mail() if the configured mailer is unavailable or deactivated. $phpmailer->isMail(); return; } $module->configure_phpmailer( $phpmailer, $settings ); } /** * Log a successful send. * * `wp_mail_succeeded` fires with a plain array from WordPress core * (the internal $mail_data array: to/subject/message/headers/attachments) * but some provider modules in this plugin fire it with a stdClass for * convenience — accept either shape. * * @param array|object $mail_data Result data from wp_mail_succeeded. * @return void */ public function log_success( $mail_data ) { $to_raw = is_array( $mail_data ) ? ( isset( $mail_data['to'] ) ? $mail_data['to'] : '' ) : ( isset( $mail_data->to ) ? $mail_data->to : '' ); $subject = is_array( $mail_data ) ? ( isset( $mail_data['subject'] ) ? $mail_data['subject'] : '' ) : ( isset( $mail_data->subject ) ? $mail_data->subject : '' ); $to = is_array( $to_raw ) ? implode( ', ', $to_raw ) : (string) $to_raw; $this->logs->insert( array( 'to_address' => $to, 'subject' => $subject, 'mailer' => $this->modules->active_mailer_slug(), 'status' => 'sent', ) ); } /** * Log a failed send. * * @param \WP_Error $error Error object from wp_mail_failed. * @return void */ public function log_failure( $error ) { $data = $error->get_error_data(); $to = isset( $data['to'] ) ? ( is_array( $data['to'] ) ? implode( ', ', $data['to'] ) : $data['to'] ) : ''; $subject = isset( $data['subject'] ) ? $data['subject'] : ''; $this->logs->insert( array( 'to_address' => $to, 'subject' => $subject, 'mailer' => $this->modules->active_mailer_slug(), 'status' => 'failed', 'error_message' => $error->get_error_message(), ) ); } /** * Prune old log entries (cron callback). * * @return void */ public function prune_logs() { $this->logs->prune( 30 ); } }