2

I'm using amforms for a client and need to create a user confirmation email that has a pdf attached containing the submitted form data, like a receipt.

After a little google searching, I believe I'd have to hook into amforms' onEmailSubmission method and generate the pdf using the mPDF library, is this correct?

  1. How do I add the mPDF library to Craft?
  2. After creating a nice pdf template design, how can I populate a 2 column table in the pdf with form names/values submission data from all the fields?
  3. And then finally attach that pdf to the user confirmation email?

Does anybody have experience with this whether using amforms or not?

2 Answers 2

4

Note: I've never used amforms nor mPDF, so I'm on a bit thin ice with this answer – hopefully it'll prove semi-useful, though.

How do I add the mPDF library to Craft?

To include any third-party PHP library in Craft, you'll need to build a custom plugin, since that's the only real way to write (or include) PHP inside a Craft CMS app.

Craft plugins are just plain ol' PHP, so to actually include the library, you can use a regular require statement:

public function init()
{
    ...
    require_once('/path/to/mpdf.php');
}

...however, the recommended way to include a third party package is to use Composer (which mPDF supports) and autoload your dependencies from your plugin's main class' init method:

public function init()
{
    ...
    require_once(__DIR__ . '/vendor/autoload.php');
}

One thing to pay attention to when using third party libraries inside a Craft plugin, is that Craft has it's \Craft namespace for the core and all plugins, and your third party library's code won't be found under that namespace. To account for this, you can use the use statement (add it to the top of any file where you want to use the mPDF library:

use \Mpdf\Mpdf as Mpdf;

...
$mpdf = new Mpdf();

...or you can skip the use statement, in which case you'll have to type out the namespace path for the third party library every time you use it:

$mpdf = new \Mpdf\Mpdf();

After creating a nice pdf template design, how can I populate a 2 column table in the pdf with form names/values submission data from all the fields?

In order to generate a PDF based on the fields submitted via amforms, you'll probably need to hook into the onEmailSubmission event (as you mention), and render a Twig template to HTML before using mPDF to generate a PDF from that HTML output.

Here's a very basic example – this would also go into your plugin's main class' init method:

public function init()
{
    // Require your Composer dependencies (mPDF, possibly others)
    require_once(__DIR__ . '/vendor/autoload.php');

    // Hook into amforms' onEmailSubmission event
    craft()->on('amForms_submissions.onEmailSubmission', function (Event $event) {

        $params = $event->params();

        // Use whatever's in $params to generate a PDF via mPDF
        // One way to do it is to compile a Twig template from your site's /templates folder via Craft's [TemplatesService][5], and then feed the HTML output to mPDF:
        $html = craft()->templates->render('/path/to/template', $params);

        // Create a mPDF instance, and generate a PDF file from the HTML
        $mpdf = new Mpdf();
        $mpdf->WriteHTML($html);

        // Have mPDF save the PDF file to some location
        $mpdf->Output('/path/to/your/pdf.pdf');

        // Some code that will attach the PDF to the email amforms will send
        ...
    });
}

Note: As I've never used amforms, I'm not totally sure about the syntax for the actual event listener here – the plugin's documentation is lacking in terms of its custom events; briefly looking at the source code makes me believe that amForms_submissions is the correct prefix for the event, but a minor disclaimer here.

Beyond the simple example above, for details on how to generate the actual PDF, I'll have to refer to the official mPDF documentation: https://mpdf.github.io/.

And then finally attach that pdf to the user confirmation email?

I've no idea how to attach the PDF to the actual confirmation email amforms sends, and the documentation doesn't mention a use case like that – hopefully someone familiar with amforms can help you out with that part.

Finally – this is probably not helpful to your specific use case, but still – here's how you could send the PDF using Craft's EmailService:

$email = new EmailModel();
$email->toEmail = '[email protected]';
$email->subject = 'Your PDF is ready, boss';
$email->body    = 'How you doin, {{ user.name }}?';
$email->attachments = [[
   'path' => '/path/to/your/pdf.pdf',
   'name' => 'An awesome PDF',
   'encoding' => 'UTF-8',
   'type' => 'application/pdf',
]];

craft()->email->sendEmail($email);

(If amforms doesn't offer a way to include the PDF attachment, you might be able to solve it by a) using the onBeforeEmailSubmission event instead and setting $event->performAction to false inside the event handler, to prevent amforms from actually sending the email confirmation; then compile an EmailModel yourself (like in the example above), and sending that instead – just an idea)

3
  • 1
    wowowow, this answer goes above and beyond! Thanks for all the details, I'll try giving it ago sometime this week and getting back to you.
    – Ryan
    Commented Sep 10, 2017 at 22:18
  • The hook works great, but I can't seem to get the actual submission out of the event that is passed... Commented Oct 30, 2017 at 13:33
  • 1
    this should be marked as the solution.
    – Hal
    Commented May 27, 2019 at 11:32
3

Here is a working example using mPDF 6.1. Thanks to Mats Mikkel Rummelhoff for pointing me in the right direction.

Note: the event you need is amForms_submissions.onBeforeEmailConfirmSubmission. This event contains the confirmation email, so you can add your attachment straight to it.

public function init(){
    require_once __DIR__ . '/vendor/autoload.php';
    //If you want to attach to the submission email, use: onBeforeEmailSubmission
    craft()->on('amForms_submissions.onBeforeEmailConfirmSubmission', function (Event $event) {

        //Grab the params out of the event. From this you can get the submission and the associated form.
        $params = $event->params;
        $submission = $params['submission'];
        $form = $submission->getForm();

        //This bit is pretty much straight out of the getSubmissionEmailBody method in the AMForms_SubmissionsServerice
        $variables = array(
                'tabs' => $form->getFieldLayout()->getTabs(),
                'form' => $form,
                'submission' => $submission
            );
        //Get HTML using template. The default amforms email template is a good starting point and can be found in: craft/plugins/amforms/templates/_display/templates/email.twig
        $html = craft()->templates->render('_amforms/attachment', $variables);

        //Create the mPDF object.
        $mpdf = new \mPDF();
        //Feed in the HTML.
        $mpdf->WriteHTML($html);
        //Output the PDF as a string.
        $data = $mpdf->Output('', 'S');
        //Grab the EmailModel from the event params.
        $email = $params['email'];
        //Add the PDF string as an attachment and specify a file name.
        $email->addStringAttachment($data,'Email Attachemnt.pdf');
    });
}

Your Answer

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

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