Diff: STRATO-apps/wordpress_03/app/wp-content/plugins/google-site-kit/includes/Core/Email/Email.php

Keine Baseline-Datei – Diff nur gegen leer.
Zur Liste
1 -
1 + <?php
2 + /**
3 + * Class Google\Site_Kit\Core\Email\Email
4 + *
5 + * @package Google\Site_Kit\Core\Email
6 + * @copyright 2025 Google LLC
7 + * @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
8 + * @link https://sitekit.withgoogle.com
9 + */
10 +
11 + namespace Google\Site_Kit\Core\Email;
12 +
13 + use WP_Error;
14 +
15 + /**
16 + * Class for sending emails with Site Kit branding.
17 + *
18 + * @since 1.168.0
19 + * @access private
20 + * @ignore
21 + */
22 + class Email {
23 +
24 + /**
25 + * Stores the last error from wp_mail.
26 + *
27 + * @since 1.168.0
28 + * @var WP_Error|null
29 + */
30 + protected $last_error = null;
31 +
32 + /**
33 + * Builds email headers with Site Kit branding.
34 + *
35 + * Fetches the filtered From email via wp_mail_from filter,
36 + * overrides the From name to "Site Kit", and merges with
37 + * caller-supplied headers.
38 + *
39 + * @since 1.168.0
40 + *
41 + * @param array $headers Optional. Additional headers to merge. Default empty array.
42 + * @return array Final header array with Site Kit branding.
43 + */
44 + public function build_headers( $headers = array() ) {
45 + $from_email = apply_filters( 'wp_mail_from', '' );
46 +
47 + if ( empty( $from_email ) || ! is_email( $from_email ) ) {
48 + $from_email = get_option( 'admin_email' );
49 + }
50 +
51 + $from_header = sprintf( 'From: Site Kit <%s>', $from_email );
52 +
53 + if ( ! is_array( $headers ) ) {
54 + $headers = array();
55 + }
56 +
57 + // Merge the From header with caller-supplied headers.
58 + // Place the From header first.
59 + $final_headers = array_merge( array( $from_header ), $headers );
60 +
61 + return $final_headers;
62 + }
63 +
64 + /**
65 + * Sends an email using wp_mail with error tracking.
66 + *
67 + * Wraps wp_mail with a scoped listener for wp_mail_failed hook
68 + * to capture any errors during sending. When text_content is provided,
69 + * it will be set as the AltBody for multipart/alternative MIME emails.
70 + *
71 + * @since 1.168.0
72 + * @since 1.170.0 Added $text_content parameter for plain text alternative.
73 + *
74 + * @param string|array $to Array or comma-separated list of email addresses to send message.
75 + * @param string $subject Email subject.
76 + * @param string $content Message contents (HTML).
77 + * @param array $headers Optional. Additional headers. Default empty array.
78 + * @param string $text_content Optional. Plain text alternative content. Default empty string.
79 + * @return bool|WP_Error True if the email was sent successfully, WP_Error on failure.
80 + */
81 + public function send( $to, $subject, $content, $headers = array(), $text_content = '' ) {
82 + $this->last_error = null;
83 +
84 + $result = $this->send_email_and_catch_errors( $to, $subject, $content, $headers, $text_content );
85 +
86 + if ( false === $result || $this->last_error instanceof WP_Error ) {
87 + if ( $this->last_error instanceof WP_Error ) {
88 + return $this->last_error;
89 + }
90 +
91 + $this->set_last_error( new WP_Error( 'wp_mail_failed', __( 'Failed to send email.', 'google-site-kit' ) ) );
92 + return $this->last_error;
93 + }
94 +
95 + return true;
96 + }
97 +
98 + /**
99 + * Sends an email via wp_mail while capturing any errors.
100 + *
101 + * Attaches a temporary listener to the wp_mail_failed hook to capture
102 + * any errors that occur during sending. When text_content is provided,
103 + * uses phpmailer_init hook to set AltBody for multipart MIME emails.
104 + *
105 + * @since 1.168.0
106 + * @since 1.170.0 Added $text_content parameter for plain text alternative.
107 + *
108 + * @param string|array $to Array or comma-separated list of email addresses to send message.
109 + * @param string $subject Email subject.
110 + * @param string $content Message contents (HTML).
111 + * @param array $headers Additional headers.
112 + * @param string $text_content Optional. Plain text alternative content. Default empty string.
113 + * @return bool Whether the email was sent successfully.
114 + */
115 + protected function send_email_and_catch_errors( $to, $subject, $content, $headers, $text_content = '' ) {
116 + add_action( 'wp_mail_failed', array( $this, 'set_last_error' ) );
117 +
118 + // Set up AltBody for multipart MIME email if text content is provided.
119 + $alt_body_callback = null;
120 + if ( ! empty( $text_content ) ) {
121 + $alt_body_callback = function ( $phpmailer ) use ( $text_content ) {
122 + // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- PHPMailer property.
123 + $phpmailer->AltBody = $text_content;
124 + };
125 + add_action( 'phpmailer_init', $alt_body_callback );
126 + }
127 +
128 + $result = wp_mail( $to, $subject, $content, $headers ); // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.wp_mail_wp_mail
129 +
130 + // Clean up hooks.
131 + remove_action( 'wp_mail_failed', array( $this, 'set_last_error' ) );
132 + if ( null !== $alt_body_callback ) {
133 + remove_action( 'phpmailer_init', $alt_body_callback );
134 + }
135 +
136 + return $result;
137 + }
138 +
139 + /**
140 + * Sets the last error from a failed email attempt.
141 + *
142 + * This method is public because it is used as a callback for the
143 + * wp_mail_failed hook which requires public accessibility.
144 + *
145 + * @since 1.168.0
146 + *
147 + * @param WP_Error $error The error from wp_mail_failed hook.
148 + */
149 + public function set_last_error( WP_Error $error ) {
150 + $this->last_error = $error;
151 + }
152 +
153 + /**
154 + * Gets the last error from the most recent send attempt.
155 + *
156 + * @since 1.168.0
157 + *
158 + * @return WP_Error|null The last error if one occurred, null otherwise.
159 + */
160 + public function get_last_error() {
161 + return $this->last_error;
162 + }
163 + }
164 +