Attaching generated files with Laravel & SwiftMailer

In one of our projects we use Laravel to send emails via the default SwiftMailer implementation. On top of that, we use mPDF to generate a PDF, attach it and then send it to customers. We use mPDF because it allows us to do stuff we can't do in other implementations.

One of the problems we've been facing recently is that mPDF has had to generate the PDF file on a disk before it can attach it to the email.

My first thought was; "oh call, I'll use a Swift_Attachment::newInstance(), attach the string from the PDF output and be done." not quite.

Here is my original code.

$PDF = Model::pdf->Output('', 'I');
$Attachment = Swift_Attachment::newInstance($PDF, 'file.pdf', 'application/pdf');

When I ran the code, I'd get an error that looked like this:

fopen(Content-Type: application/pdf; name=121103-201407151603.pdf Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename=121103-201407151603.pdf JVBERi0xLjQKJeLjz9MKJVBERi0xLjQKJeLjz9MKJVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC9U eXBlIC9QYWdlCi9QYXJlbnQgMSAwIFIKL01lZGlhQm94IFswIDAgNTk1LjI4MCA4NDEuODkwXQov VHJpbUJveCBbMC4wMDAgMC4wMDAgNTk1LjI4MCA4NDEuODkwXQovUmVzb3VyY2VzIDIgMCBSCi9H cm91cCA8PCAvVHlwZSAvR3JvdXAgL1MgL1RyYW5zcGFyZW5jeSAvQ1MgL0RldmljZVJHQiA+PiAK L0NvbnRlbnRzIDQgMCBSPj4KZW5kb2JqCjQgMCBvYmoKPDwvRmlsdGVyIC9GbGF0ZURlY29kZSAv TGVuZ3RoIDMxNTM+PgpzdHJlYW0KYrM3JtovtJOy33W+ipWFRWyc7uoVBdyLUOQjyC8QNrzOVMXD 5a87qaC7gmUa9LcyiFRKxhThZOkbch8V8waOH6/xG04AZZBqnnMPP3XG4ekbljfLoTLCUrcpysPk sAiE+0EBakfjf0eQhmo3vCFqVyGGB3SdcSR/Ow0qeyucvElVYWuMvUbHVRJlA5nE5071tznk0UBr iqOLKcrLfRrMvf+Z463/iT4cwWAPdbkpxtaULglDVNPNyIx3eqnwM9Vgwg6Q/fslMEZD4FszmGHq 9MyGgdtoPqqThqgTHeM1kq//DECRxo7fVMkiN+cgLmgkMhPQyTC/4qHost9VSKmKuNVTFrnebkm6 q3YzH5GP2rM3eXYKdBlogq/5aCdvkfiIVLybaBzUsJDlxQNTRKXL4iVxOmU9LboR6hxGp0rwU9GK  
failed to open stream: Invalid argument (View: /Users/james.brooks/Sites/bloot/app/views/quotes/index.blade.php)  

Not pretty. But what was going on? I spent ages trying to figure this out, thinking that SwiftMailer was at fault.

It turns out that Laravel has a attachData method which won't try and call fopen around the content.

$PDF = Model::pdf->Output('', 'I');
$Message->attachData($PDF, 'file.pdf');

And now Laravel will work out the mimetype for you and ensure everything is dandy.

comments powered by Disqus