9

Goal: I need to send an email with a pdf attachment in Drupal 8.

Progress

I am able to send an email with subject and message but have never been able to get the attachment. When I turn on the logic to attach the file to the email, the email never gets sent but the mail service returns True as if the email was sent anyway. There are no errors and the logs say nothing.

I have the following modules installed:

  • SMTP
  • MailSystem
  • MimeMail

What I've tried

  • Tried using $message['params']['files'][] = $params['attachments'] instead of $message['params']['attachments'][] = $params['attachments'] like some examples have recommended
  • Tried changing $file->uri to $file->filepath
  • Tried attaching the file like so:

    $params['attachments']['filecontent'] = $this->generatePDF($foa_list);
    $params['attachments']['filename'] = 'MyFormsOfAssistance.pdf';
    $params['attachments']['filemime'] = 'application/pdf';
    
  • Tried attaching the file by path alone with an array:

    $attachment = array(
        'filepath'=>'sites/default/files/MyFormsOfAssistance.pdf',
    );
    
    $params['attachments'] = $attachment;
    
  • Tried attaching the file a different way:

    $attachment = array(
        'filepath' => 'sites/default/files/MyFormsOfAssistance.pdf',
        'filename' => 'MyFormsOfAssistance.pdf',
        'filemime' => 'application/pdf'
    );
    
    $params['attachments'][] = $attachment;
    

Setup

  1. There is email landing page in which a user enters the recipient's email address, subject for the email, and message for the email.
  2. When user clicks Send button, that data is routed to my Email Controller
  3. Email controller creates the pdf file, attempts to attach the pdf to the email, and then sends the email.
  4. I have the hook_mail() function defined in my module file.

Here is the code for my Email Controller:

public function submit_email($foa_list = null) {
    $lang = "en";
    $email_to = "[email protected]";
    $params['subject'] = "Test subject";
    $params['body'] = "Test body";

    // -------------------- Attachment Logic -----------------------
    // Create pdf file and store file
    file_put_contents('sites/default/files/MyFormsOfAssistance.pdf', $this->generatePDF($foa_list));


    // Attach pdf file to email params
    $file = new \stdClass();
    $file->uri = 'sites/default/files/MyFormsOfAssistance.pdf';
    $file->filename = 'MyFormsOfAssistance.pdf';
    $file->filemime = 'application/pdf';
    $params['attachments'][] = $file;

    // Send email
    \Drupal::service('plugin.manager.mail')->mail('email', 'email', $email_to, $lang, $params);

    $response = new Response();
    $response->setContent("true");

    return $response;
}

Here is the hook_mail() code in my Email module file:

// Note that print_and_email is what my module is called.
function print_and_email_mail($key, &$message, $params) {
    switch($key) {
        case 'email':
            $message['subject'] = $params['subject'];
            $message['body'][] = $params['body'];
            $message['headers'] = [
              'MIME-Version' => '1.0',
              'Content-Type' => 'text/html; charset=UTF-8; format=flowed; delsp=yes',
              'Content-Transfer-Encoding' => '8Bit',
              'X-Mailer' => 'Drupal',
            ];
            // $message['params']['files'][] = $params['attachments']; // Note: I have seen other examples implement attachments this way
            $message['params']['attachments'][] = $params['attachments'];
            break;
    } 
}

The Drupal 8 documentation isn't really helpful and I would like to be able to figure this out without installing SwiftMailer, like some sources have recommended. Really not sure why this isn't working as it has worked for others. What am I missing?

0

3 Answers 3

3

FINALLY! 4 weeks later...

So the following code ended up working for me:

    $attachment = array(
        'filepath' => 'sites/default/files/MyFormsOfAssistance.pdf',
        'filename' => 'MyFormsOfAssistance.pdf',
        'filemime' => 'application/pdf'
    );

BUT, the key was that in the MailSystem Configuration I had to set the Formatter and Sender to "SMTP Mailer". MimeMail's config automatically pulled it's values from my SMTP's configuration.

4
  • I tried your solution, and no luck. How did you figure out that "MimeMail's config automatically pulled it's values from my SMTP's configuration. " ?
    – lordZ3d
    Oct 31, 2018 at 9:38
  • 1
    @Cadre could you update your full working code so it would be help full.
    – Srikanth
    Nov 1, 2018 at 7:32
  • @Srikanth this tutorial helped me when i had the same problem. Aug 29, 2019 at 14:56
  • One important note - the filepath should be without '/' symbol at the beginning.
    – rsych
    Aug 17, 2022 at 12:06
1

Try the Email Attachment Helper module.

This is a module for developers who want to attach files programmatically to emails send from Drupal 8. This module doesn't send emails but rather intercepts emails from other modules.

If an 'attachment' or an 'attachments' key is present in the $params array, it will be converted into an actual MIME attachment. Otherwise, this module doesn't touch the mail.

This module has no configuration options.

$params['context']['attachments'] = [
  'filecontent' => file_get_contents('sites/default/files/sample.pdf'),
  'filename' => 'Invoice.pdf',
  'filemime' => 'application/pdf',     
];

Hook_mail()

$context = $params['context'];
$message['params']['attachments'][] = $context['attachments'];
-1
$invoice_pdf = File::load($fid); // the file id
$invoice_file = (object) [
  'filename' => 'invoice.pdf',
  'uri' => $invoice_pdf->getFileUri(),
  'filemime' => $invoice_pdf->getMimeType(),
];
$message['params']['files'][] = $invoice_file;

'files' must be an array, that's were I had the most difficulties with. Full code here: Send e-mail with managed file attachment in drupal 8

1
  • This answer seems to be for Swift Mailer, not for Mime Mail. Different mail modules have different ways to add attachments. Some don't allow attachments. The original poster said "I would like to be able to figure this out without installing SwiftMailer"
    – anonymous
    Sep 12, 2020 at 19:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.