@@ -158,9 +158,22 @@ function cache_users( $user_ids ) {
158158 * The default charset is based on the charset used on the blog. The charset can
159159 * be set using the {@see 'wp_mail_charset'} filter.
160160 *
161+ * When using the `$embeds` parameter to embed images for use in HTML emails,
162+ * reference the embedded file in your HTML with a `cid:` URL whose value
163+ * matches the file's Content-ID. By default, the Content-ID (`cid`) used for
164+ * each embedded file is the key in the embeds array, unless modified via the
165+ * {@see 'wp_mail_embed_args'} filter. For example:
166+ *
167+ * `<img src="cid:0" alt="Logo">`
168+ * `<img src="cid:my-image" alt="Image">`
169+ *
170+ * You may also customize the Content-ID for each file by using the
171+ * {@see 'wp_mail_embed_args'} filter and setting the `cid` value.
172+ *
161173 * @since 1.2.1
162174 * @since 5.5.0 is_email() is used for email validation,
163175 * instead of PHPMailer's default validator.
176+ * @since 6.9.0 Added $embeds parameter.
164177 *
165178 * @global PHPMailer\PHPMailer\PHPMailer $phpmailer
166179 *
@@ -169,9 +182,10 @@ function cache_users( $user_ids ) {
169182 * @param string $message Message contents.
170183 * @param string|string[] $headers Optional. Additional headers.
171184 * @param string|string[] $attachments Optional. Paths to files to attach.
185+ * @param string|string[] $embeds Optional. Paths to files to embed.
172186 * @return bool Whether the email was sent successfully.
173187 */
174- function wp_mail ( $ to , $ subject , $ message , $ headers = '' , $ attachments = array () ) {
188+ function wp_mail ( $ to , $ subject , $ message , $ headers = '' , $ attachments = array (), $ embeds = array () ) {
175189 // Compact the input, apply the filters, and extract them back out.
176190
177191 /**
@@ -187,9 +201,10 @@ function wp_mail( $to, $subject, $message, $headers = '', $attachments = array()
187201 * @type string $message Message contents.
188202 * @type string|string[] $headers Additional headers.
189203 * @type string|string[] $attachments Paths to files to attach.
204+ * @type string|string[] $embeds Paths to files to embed.
190205 * }
191206 */
192- $ atts = apply_filters ( 'wp_mail ' , compact ( 'to ' , 'subject ' , 'message ' , 'headers ' , 'attachments ' ) );
207+ $ atts = apply_filters ( 'wp_mail ' , compact ( 'to ' , 'subject ' , 'message ' , 'headers ' , 'attachments ' , ' embeds ' ) );
193208
194209 /**
195210 * Filters whether to preempt sending an email.
@@ -209,6 +224,7 @@ function wp_mail( $to, $subject, $message, $headers = '', $attachments = array()
209224 * @type string $message Message contents.
210225 * @type string|string[] $headers Additional headers.
211226 * @type string|string[] $attachments Paths to files to attach.
227+ * @type string|string[] $embeds Paths to files to embed.
212228 * }
213229 */
214230 $ pre_wp_mail = apply_filters ( 'pre_wp_mail ' , null , $ atts );
@@ -244,6 +260,15 @@ function wp_mail( $to, $subject, $message, $headers = '', $attachments = array()
244260 if ( ! is_array ( $ attachments ) ) {
245261 $ attachments = explode ( "\n" , str_replace ( "\r\n" , "\n" , $ attachments ) );
246262 }
263+
264+ if ( isset ( $ atts ['embeds ' ] ) ) {
265+ $ embeds = $ atts ['embeds ' ];
266+ }
267+
268+ if ( ! is_array ( $ embeds ) ) {
269+ $ embeds = explode ( "\n" , str_replace ( "\r\n" , "\n" , $ embeds ) );
270+ }
271+
247272 global $ phpmailer ;
248273
249274 // (Re)create it, if it's gone missing.
@@ -531,6 +556,50 @@ function wp_mail( $to, $subject, $message, $headers = '', $attachments = array()
531556 }
532557 }
533558
559+ if ( ! empty ( $ embeds ) ) {
560+ foreach ( $ embeds as $ key => $ embed_path ) {
561+ /**
562+ * Filters the arguments for PHPMailer's addEmbeddedImage() method.
563+ *
564+ * @since 6.9.0
565+ *
566+ * @param array $args {
567+ * An array of arguments for `addEmbeddedImage()`.
568+ * @type string $path The path to the file.
569+ * @type string $cid The Content-ID of the image. Default: The key in the embeds array.
570+ * @type string $name The filename of the image.
571+ * @type string $encoding The encoding of the image. Default: 'base64'.
572+ * @type string $type The MIME type of the image. Default: empty string, which lets PHPMailer auto-detect.
573+ * @type string $disposition The disposition of the image. Default: 'inline'.
574+ * }
575+ */
576+ $ embed_args = apply_filters (
577+ 'wp_mail_embed_args ' ,
578+ array (
579+ 'path ' => $ embed_path ,
580+ 'cid ' => (string ) $ key ,
581+ 'name ' => basename ( $ embed_path ),
582+ 'encoding ' => 'base64 ' ,
583+ 'type ' => '' ,
584+ 'disposition ' => 'inline ' ,
585+ )
586+ );
587+
588+ try {
589+ $ phpmailer ->addEmbeddedImage (
590+ $ embed_args ['path ' ],
591+ $ embed_args ['cid ' ],
592+ $ embed_args ['name ' ],
593+ $ embed_args ['encoding ' ],
594+ $ embed_args ['type ' ],
595+ $ embed_args ['disposition ' ]
596+ );
597+ } catch ( PHPMailer \PHPMailer \Exception $ e ) {
598+ continue ;
599+ }
600+ }
601+ }
602+
534603 /**
535604 * Fires after PHPMailer is initialized.
536605 *
@@ -563,6 +632,7 @@ function wp_mail( $to, $subject, $message, $headers = '', $attachments = array()
563632 * @type string $message Message contents.
564633 * @type string[] $headers Additional headers.
565634 * @type string[] $attachments Paths to files to attach.
635+ * @type string[] $embeds Paths to files to embed.
566636 * }
567637 */
568638 do_action ( 'wp_mail_succeeded ' , $ mail_data );
0 commit comments