3
votes

I'm working in WordPress with Contact Form 7. I'm dynamically creating a Word Document based on the users submitted data, and I want to attach that file to the e-mail that the user is sent from Contact Form 7.

To confirm, the file is created and saved in the correct location. My issue is definitely with attaching it to the e-mail from CF7.

I have the following code at the moment:

add_action('wpcf7_before_send_mail', 'cv_word_doc');  
    function cv_word_doc($WPCF7_ContactForm) {

        // Check we're on the CV Writer (212)
        if ( $WPCF7_ContactForm->id() === 212 ) {

            //Get current form
            $wpcf7 = WPCF7_ContactForm::get_current();

            // get current SUBMISSION instance
            $submission = WPCF7_Submission::get_instance();

            if ($submission) {

                // get submission data
                $data = $submission->get_posted_data();

                // nothing's here... do nothing...
                if (empty($data))
                   return;


               // collect info to add to word doc, removed for brevity...


               // setup upload directory and name the file
               $upload_dir = wp_upload_dir();
               $upload_dir = $upload_dir['basedir'] . '/cv/';
               $fileName = 'cv-' . str_replace(' ', '-', strtolower($firstName)) . '-' . str_replace(' ', '-', strtolower($lastName)) .'-'. time() .'.docx';


              // PHPWord stuff, removed for brevity...


              // save the doc 
              $objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
              $objWriter->save($upload_dir . $fileName);

              // add upload to e-mail
              $submission->add_uploaded_file('docx', $upload_dir . $fileName);

              // carry on with cf7
              return $wpcf7;

           }
        }
    }

Everything works up until $submission->add_uploaded_file('docx', $upload_dir . $fileName);.

There's not much documentation about, but I have read that I need to include something similar to:

add_filter( 'wpcf7_mail_components', 'mycustom_wpcf7_mail_components' );

function mycustom_wpcf7_mail_components( $components ) {
    $components['attachments'][] = 'full path of your PDF file';

    return $components;
}

(source: https://wordpress.stackexchange.com/questions/239579/attaching-a-pdf-to-contact-form-7-e-mail-via-functions-php)

In order to get the attachment to show. However, I don't know how I can get the specific file that I need, as the file is unique to each submission and all of the variables will be in a separate function.

3

3 Answers

2
votes

Fixed this issue.

I added:

// make file variable global
  global $CV_file;
  $CV_file = $upload_dir . $fileName;

after $submission->add_uploaded_file('docx', $upload_dir . $fileName);

Then seperate to the add_action, I used the filter and referenced the global var:

add_filter( 'wpcf7_mail_components', 'mycustom_wpcf7_mail_components' );
    function mycustom_wpcf7_mail_components( $components ) {
        global $CV_file;
        $components['attachments'][] = $CV_file;
        return $components;
    }
1
votes

Here is the working solution:

add_filter('wpcf7_mail_components', 'custom_wpcf7_mail_components');
    function custom_wpcf7_mail_components($components)
    {
        //Get current form
        $wpcf7 = WPCF7_ContactForm::get_current();
        $attachment_file_path = '';
        //check the relevant form id
        if ($wpcf7->id == '30830') {
            // get current SUBMISSION instance
            $submission = WPCF7_Submission::get_instance();
            if ($submission) {
                // get submission data
                $data = $submission->get_posted_data();
                // setup upload directory
                $upload_dir = wp_upload_dir();
                if (isset($data['file_name']) && !empty($data['file_name'])) {
                    /*
                    * Form hidden attachment file name Ex: 'ProRail_NA_Gen5.pdf'
                    * You can hard-code the file name or set file name to hidden form field using JavaScript
                    */
                    $file_name = $data['file_name'];
                    //get upload base dir path Ex: {path}/html/app/uploads
                    $base_dir = $upload_dir['basedir'];
                    //file uploaded folder
                    $file_dir = 'download';
                    //set attachment full path
                    $attachment_file_path = $base_dir .'/'.$file_dir.'/'.$file_name;
                    //append new file to mail attachments
                    $components['attachments'][] = $attachment_file_path;
                }
            }
        }
        return $components;
    }
0
votes

I'll leave a full example using wpcf7_before_send_mail to create and store the PDF and wpcf7_mail_components to attach it to the email.
PDF created with FPDF.

<?php
/**
 * Plugin Name: Create and attach PDF to CF7 email
 * Author: brasofilo
 * Plugin URL: https://stackoverflow.com/q/48189010/
 */

!defined('ABSPATH') && exit;

require_once('fpdf/fpdf.php');

add_action('plugins_loaded', array(SendFormAttachment::get_instance(), 'plugin_setup'));

class SendFormAttachment {
    protected static $instance = NULL;
    public $formID = 5067; # YOUR ID
    public $theFile = false;

    public function __construct() { }

    public static function get_instance() {
        NULL === self::$instance and self::$instance = new self;
        return self::$instance;
    }

    public function plugin_setup() {
        add_action('wpcf7_before_send_mail', function ( $contact_form, $abort, $submission ) {
            if ($contact_form->id() == $this->formID) {
                $posted_data = $submission->get_posted_data();
                $uploads = wp_upload_dir();
                $the_path = $uploads['basedir'] . '/cf7_pdf/';
                $fname = $this->createPDF($posted_data, $the_path);
                $this->theFile = $the_path . $fname;
            }
        }, 10, 3);

        add_filter( 'wpcf7_mail_components', function( $components ) {
            if( $this->theFile )
                $components['attachments'][] = $this->theFile;
            return $components;
        });
    }

    public function createPDF($posted_data, $savepath) {
        $pdf = new FPDF();
        $pdf->AliasNbPages();
        $pdf->AddPage();
        $pdf->SetFont('Times','',12);
        $pdf->SetCreator('example.com');
        $pdf->SetAuthor('Author name', true);
        $pdf->SetTitle('The title', true);
        $pdf->SetSubject('The subject', true);
        for($i=1;$i<=40;$i++)
            $pdf->Cell(0,10,'Printing line number '.$i,0,1);

        $filename = rand() . '_' . time() . '.pdf';
        $pdf->Output('F', $savepath . $filename);
        return $filename;
    }
}