Presets::all(), 'guides' => Presets::guides(), ] ); } public function handle_save(): void { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You do not have permission.', 'ago-mail-pilot' ) ); } check_admin_referer( 'agomp_save' ); $current = get_option( self::OPTION_KEY, [] ); $in = wp_unslash( $_POST ); $settings = [ 'preset' => sanitize_key( $in['preset'] ?? '' ), 'host' => sanitize_text_field( $in['host'] ?? '' ), 'port' => (int) ( $in['port'] ?? 587 ), 'encryption' => in_array( $in['encryption'] ?? 'tls', [ 'tls', 'ssl', 'none' ], true ) ? $in['encryption'] : 'tls', 'username' => sanitize_text_field( $in['username'] ?? '' ), 'from_name' => sanitize_text_field( $in['from_name'] ?? '' ), 'from_email' => sanitize_email( $in['from_email'] ?? '' ), 'alerts_enabled' => ! empty( $in['alerts_enabled'] ), 'alerts_threshold' => max( 1, min( 100, (int) ( $in['alerts_threshold'] ?? 30 ) ) ), 'alerts_min_count' => max( 1, (int) ( $in['alerts_min_count'] ?? 5 ) ), 'alerts_email' => sanitize_email( $in['alerts_email'] ?? '' ) ?: get_option( 'admin_email' ), ]; // Password: solo guardar si el campo se rellena (no sobrescribir con vacio). $pwd = (string) ( $in['password'] ?? '' ); if ( '' !== $pwd ) { $settings['password'] = Mailer::store_password( $pwd ); } elseif ( isset( $current['password'] ) ) { $settings['password'] = $current['password']; } if ( $settings['from_email'] && ! is_email( $settings['from_email'] ) ) { $this->redirect_back( 'error', __( 'Invalid From Email address.', 'ago-mail-pilot' ) ); } update_option( self::OPTION_KEY, $settings ); $this->redirect_back( 'success', __( 'Settings saved.', 'ago-mail-pilot' ) ); } public function handle_test(): void { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You do not have permission.', 'ago-mail-pilot' ) ); } check_admin_referer( 'agomp_test' ); $to = wp_get_current_user()->user_email; $subj = sprintf( /* translators: %s: site name */ __( '[%s] aGo Mail Pilot test email', 'ago-mail-pilot' ), get_bloginfo( 'name' ) ); $body = __( 'If you can read this, the SMTP configuration is working. Sent by aGo Mail Pilot.', 'ago-mail-pilot' ); // Capturar errores de PHPMailer y wp_mail_failed. $error_message = ''; $smtp_debug = ''; $listener = function ( $err ) use ( &$error_message, &$smtp_debug ) { $error_message = $err->get_error_message(); $data = $err->get_error_data(); if ( is_array( $data ) && ! empty( $data['phpmailer_exception_code'] ) ) { $smtp_debug = (string) ( $data['phpmailer_exception_code'] ); } }; add_action( 'wp_mail_failed', $listener ); $sent = wp_mail( $to, $subj, $body ); remove_action( 'wp_mail_failed', $listener ); if ( $sent ) { $this->redirect_back( 'success', sprintf( /* translators: %s: email address */ __( 'Test email sent to %s. Check your inbox.', 'ago-mail-pilot' ), $to ) ); } $detail = $error_message ?: __( 'Unknown SMTP error.', 'ago-mail-pilot' ); $hint = $this->error_hint( $error_message ); $this->redirect_back( 'error', sprintf( /* translators: %1$s: error message, %2$s: hint */ __( 'Test email failed: %1$s %2$s', 'ago-mail-pilot' ), '' . esc_html( $detail ) . '', $hint ? '
' . esc_html__( 'Hint:', 'ago-mail-pilot' ) . ' ' . esc_html( $hint ) : '' ) ); } /** * Heuristica simple: matchea errores comunes de PHPMailer a una pista util. */ private function error_hint( string $error ): string { $e = strtolower( $error ); if ( str_contains( $e, '535' ) || str_contains( $e, 'authentication' ) || str_contains( $e, 'no se pudo identificar' ) || str_contains( $e, 'identificar' ) ) { return __( 'Authentication failed. The username or password is wrong, or the provider requires a special user format (e.g. SES uses an AKIA... user, SendGrid uses the literal word "apikey", Mailjet uses API Key as user). Open the credentials guide above.', 'ago-mail-pilot' ); } if ( str_contains( $e, 'connect' ) || str_contains( $e, 'connection refused' ) || str_contains( $e, 'timed out' ) ) { return __( 'Cannot connect to the SMTP host. Check host name, port and firewall. Most providers use 587 (TLS) or 465 (SSL).', 'ago-mail-pilot' ); } if ( str_contains( $e, 'sender' ) || str_contains( $e, 'from' ) || str_contains( $e, 'address' ) ) { return __( 'The From email is not authorized by the provider. Verify the sender or the whole sending domain in the provider dashboard.', 'ago-mail-pilot' ); } if ( str_contains( $e, '550' ) || str_contains( $e, 'rejected' ) ) { return __( 'The provider rejected the message. Usually SPF, DKIM or DMARC is wrong, or the recipient blocks unverified senders.', 'ago-mail-pilot' ); } return ''; } public function handle_clear_log(): void { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You do not have permission.', 'ago-mail-pilot' ) ); } check_admin_referer( 'agomp_clear_log' ); delete_option( self::LOG_KEY ); $this->redirect_back( 'success', __( 'Log cleared.', 'ago-mail-pilot' ) ); } public function handle_dns_audit(): void { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You do not have permission.', 'ago-mail-pilot' ) ); } check_admin_referer( 'agomp_dns_audit' ); $domain = sanitize_text_field( wp_unslash( $_POST['dns_domain'] ?? '' ) ); $selector = sanitize_text_field( wp_unslash( $_POST['dns_selector'] ?? 'default' ) ); if ( '' === $domain ) { $s = get_option( self::OPTION_KEY, [] ); $from = (string) ( $s['from_email'] ?? '' ); $domain = $from && str_contains( $from, '@' ) ? trim( substr( strrchr( $from, '@' ), 1 ) ) : ''; } $result = DnsAuditor::audit( $domain, $selector ?: 'default' ); set_transient( 'agomp_dns_result_' . get_current_user_id(), [ 'domain' => $domain, 'selector' => $selector ?: 'default', 'result' => $result, ], 300 ); wp_safe_redirect( admin_url( 'admin.php?page=ago-mail-pilot#dns' ) ); exit; } private function redirect_back( string $status, string $message ): void { set_transient( 'agomp_notice_' . get_current_user_id(), [ 'status' => $status, 'message' => $message, ], 60 ); wp_safe_redirect( admin_url( 'admin.php?page=ago-mail-pilot' ) ); exit; } /** * Notice global si hay password legacy (pre-1.0.0) que no se puede decodificar. */ public function maybe_legacy_password_notice(): void { $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null; if ( ! $screen || ! str_contains( $screen->id ?? '', 'ago-mail-pilot' ) ) { return; } $s = get_option( self::OPTION_KEY, [] ); if ( ! empty( $s['password'] ) && Mailer::is_legacy_password( (string) $s['password'] ) ) { echo '

' . esc_html__( 'Re-enter the SMTP password: the storage format was upgraded and the old encrypted value cannot be decoded.', 'ago-mail-pilot' ) . '

'; } } }