• Resolved Damibu

    (@damibu)


    Hi,

    I’m trying to use…

                $phpmailer_init_hook = function( $phpmailer ) use ( $embedded_images, $attachments ) {

                    foreach ( $embedded_images as $image ) {

                        $phpmailer->addEmbeddedImage( $image[‘path’], $image[‘cid’] );

                    }

                };

                add_action( ‘phpmailer_init’, $phpmailer_init_hook );

    Works fine on X-Mail-Queue-Prio: Instant, but not when queued.

    Any ideas?

    Dave

Viewing 4 replies - 1 through 4 (of 4 total)
  • Plugin Author WDM

    (@wdm-team)

    Hi Dave,

    You have a real talent for bringing us the wonderfully tricky edge cases – just when we think we have seen it all. 😉

    We have had a first look, and yes: this one is a proper brain-teaser. We will need to sit down, think it through properly (and possibly fuel up with coffee) and then we will come back to you.

    We will be in touch as soon as we have untangled it.

    best,
    Nicolas

    Thread Starter Damibu

    (@damibu)

    happy to help 🤣

    solution could be your own hook, although I think you’re trying not to do that. Or a hackie way could be a naming convention on an attachment

    cheers

    Dave

    Thread Starter Damibu

    (@damibu)

    Hi,

    I got it working like this….

    • Add a global phpmailer_init that checks if emails have this header and does the $phpmailer->addEmbeddedImage
    • Add an array of cid=>file_paths in a new mail header called X-Embedded-Images
    • Call wp_mail as normal

    Details

    X-Embedded-Images Header Setup

                $dom = new DOMDocument();
    libxml_use_internal_errors(true);
    $dom->loadHTML($email_html);
    libxml_clear_errors();

    $xpath = new DOMXPath($dom);

    // Find all the imgs and prepare them for CID embedding
    $images = $xpath->query('//img');
    $embedded_images = [];
    foreach ($images as $img) {
    $src = $img->getAttribute('src');
    $parsed_url = parse_url($src);
    $path = ABSPATH . substr($parsed_url['path'], strlen('/wordpress/'));
    $cid = basename($path);
    $img->setAttribute('src', 'cid:' . $cid);
    $embedded_images[] = [
    'path' => $path,
    'cid' => $cid
    ];
    }
    $email_html = $dom->saveHTML();

    // Store embedded images data in a custom header that survives the queue
    if ( !empty($embedded_images) ) {
    $embedded_images_data = base64_encode(serialize($embedded_images));
    $headers[] = "X-Embedded-Images: {$embedded_images_data}";
    }

    phpmailer_init action is…

        add_action('phpmailer_init', 'reconstruct_embedded_images', 10);

    static function reconstruct_embedded_images($phpmailer) {
    // Check if this email has embedded images stored in headers
    $custom_headers = $phpmailer->getCustomHeaders();

    foreach ($custom_headers as $header) {
    if (strpos($header[0], 'X-Embedded-Images') === 0) {
    // Decode the embedded images data
    $embedded_data = unserialize(base64_decode($header[1]));

    if (is_array($embedded_data)) {
    foreach ($embedded_data as $image) {
    if (isset($image['path']) && isset($image['cid']) && file_exists($image['path'])) {
    $phpmailer->addEmbeddedImage($image['path'], $image['cid']);
    }
    }
    }

    // Remove the custom header so it doesn't appear in the final email
    $phpmailer->clearCustomHeaders();

    // Re-add all other custom headers except the X-Embedded-Images one
    foreach ($custom_headers as $other_header) {
    if (strpos($other_header[0], 'X-Embedded-Images') !== 0) {
    $phpmailer->addCustomHeader($other_header[0], $other_header[1]);
    }
    }

    break;
    }
    }
    }
    Plugin Author WDM

    (@wdm-team)

    Great solution – thanks for sharing!

Viewing 4 replies - 1 through 4 (of 4 total)

You must be logged in to reply to this topic.