Search code examples
phplaraveldompdf

Attach PDF file to email with DOMPDF in Laravel


I'm using my MyEmail model to attach a PDF file to it. The mail gets sent with all the data I want and a PDF gets attached but it is empty, how can I import my layout and data into the PDF if I attach?

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Course;
use Barryvdh\DomPDF\PDF;

class MyEmail extends Mailable {
    use Queueable, SerializesModels;
    public $data;
    public $course;
    private $pdf;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct($data, Course $course) {
        $this->course = $course;
        $this->data = $data;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build() {
        return $this->subject('Thanks')->view('emails.my_email')->attachData($this->pdf, 'my_pdf.pdf')->with(['data' => $this->data, 'course' => $this->course]);
    }
}

Here's the function to send the email my controller:

public function sendMail(Request $request) {

    $data = array(
        'first_name'        => $request->first_name,
        'last_name'         => $request->last_name,
        'id'                => $request->id,
        'course_id'         => $request->course_id,
    );

    $resultJson = $this->validateRecaptcha($request);

    $course= Course::where('id', $data['course_id'])->first();

    if($resultJson->success != true) :
        return redirect()->back()->with(['success' => 'success']);
    else :
        \Mail::to($request->email)
             ->cc('my@*******')
             ->queue(
            new Mail\MyEmail($data, $course)
        );
        return redirect()->back()->with(['success' => 'Success!']);
    endif;
    
}

Solution

  • The PDF also requires a view, like so:

    // creating the pfd:
    $pdf = PDF::loadView('pdf.multiple_pages', [
                'pages' => $this->pages,
                'title' => $this->options->get('documentName'),
            ]);
    

    Where the view looks like this:

    <?php
    
    $imgPath = public_path('store/assets/images/new_logo.png');
    $img = base64_encode(file_get_contents($imgPath));
    ?>
    <html lang="{{ app()->getLocale() }}">
    <head>
        <title>{{ $title ?? 'document' }}</title>
    
    </head>
    <body>
    <style>
        @php
            include(public_path('/css/pdf/multiple_pages.css'))
        @endphp
    
        div.page {
            background-image: url("data:image/png;base64, {{ $img }}");
        }
    </style>
    @foreach($pages as $page)
        <div class="page">
            {!! html_entity_decode($page) !!}
        </div>
    @endforeach
    </body>
    </html>
    

    So i recommend first creating the PDF, and only then attaching it to the email

    Keep in mind this is very specific to our own use case and you will need to modify this.