Skip to content

Instantly share code, notes, and snippets.

@ianhampton
Last active January 3, 2024 14:50
Show Gist options
  • Save ianhampton/eee8f8ea1a6280db8bbae3944c07a451 to your computer and use it in GitHub Desktop.
Save ianhampton/eee8f8ea1a6280db8bbae3944c07a451 to your computer and use it in GitHub Desktop.
Dynamically add file attachments to Contact Form 7 emails from a custom field
<?php
/* Dynamically add file attachments to Contact Form 7 emails from a Wordpress custom field.
* Custom field is 'case-pdf' in the example.
*/
add_action('wpcf7_before_send_mail', 'wpcf7_add_attachment');
function wpcf7_add_attachment($contact_form) {
global $_POST;
$submission = WPCF7_Submission::get_instance();
if ( $submission && !empty($_POST['case-pdf']) ) {
$mail = $contact_form->prop('mail');
$mail['attachments'] .= $_POST['case-pdf'];
$contact_form->set_properties(array('mail' => $mail));
}
}
@jca0310
Copy link

jca0310 commented May 10, 2017

Hello,

What's custom fiels do you use ? i tried with this input :

[dynamichidden PDF id:PDF "uploads/pdf/Full_lighting_price_list.pdf"]

Not working :-(

Tried this code too :

function send_pdf( $wpcf7 ) {
    $id = $wpcf7->id();
	if ($id==215){
		$uploads = wp_upload_dir();
		define ('MY_FILE_PATH',$uploads['path'].'/pdf/');
		$copy_to_send=MY_FILE_PATH.'Full_lighting_price_list.pdf';	

		$mail = $wpcf7->prop('mail');
		$mail['attachments'] = $copy_to_send;
		
 $wpcf7->set_properties(array(
	    "mail" => $mail
));
	}
}
add_action('wpcf7_before_send_mail','send_pdf', 100);

Can you help me please ?

@elirant3
Copy link

thank you bro!!!!!!!!!!!!!!!! dam god. nothing worked. only your code!!!!!!

@ckurir
Copy link

ckurir commented Jan 11, 2021

It does not really work for me. What about path? Where should path to file be assigned, and what is default?

@robbertvancaem
Copy link

Oof, this was a tricky one. I expected that WPCF7 would allow dynamic fields as mail tags in the attachments field out-of-the-box, but I had to jump through some hoops to make it work. If anyone has any feedback on how to do this more efficiently, I'd gladly hear so. Hope this helps :-)

The form contains a hidden field called whitepaper, as defined in WPCF7.

[hidden whitepaper default:shortcode_attr]

This is then rendered to a shortcode to populate the field with the value, in your template

// components/some-form-block.php
<?php
echo do_shortcode("[contact-form-7 id=123 whitepaper=uploads/2018/09/some-file-name.pdf]")
?>

To make sure the field actually gets populated, you'll need a snippet in your functions.php as well

// functions.php
add_filter('shortcode_atts_wpcf7', 'custom_shortcode_atts_wpcf7_filter', 10, 3);
function custom_shortcode_atts_wpcf7_filter($out, $pairs, $atts)
{
    $shortcodes = ['another-hidden-field', 'whitepaper'];

    foreach ($shortcodes as $shortcode) {
        if (isset($atts[$shortcode])) {
            $out[$shortcode] = $atts[$shortcode];
        }
    }

    return $out;
}

Finally, to add the attachment to the mail, another piece of code is needed in functions.php

// functions.php

/**
 * Custom piece of code to add a 'whitepaper' shortcode value
 * into the attachments of WPCF7. Using a [whitepaper] tag in 
 * the WPCF7 mail field does not work as expected. Perhaps because
 * 'whitepaper' is a hidden field and needs to be provided through shortcodes, like:
 * [contact-form-7 id=123 whitepaper=uploads/2021/12/path-to-file.pdf]
 */
add_action('wpcf7_before_send_mail', 'wpcf7_add_attachment');
function wpcf7_add_attachment($contact_form)
{
    global $_POST;
    $submission = WPCF7_Submission::get_instance();

    if ($submission && !empty($_POST['whitepaper'])) {

        $mail = $contact_form->prop('mail');
        $mail['attachments'] .= "\n{$_POST['whitepaper']}"; // Note the newline character here
        $contact_form->set_properties(array('mail' => $mail));
    }
}

@jsalinas
Copy link

jsalinas commented Feb 25, 2022

For me it only worked this way:

    add_filter( 'wpcf7_mail_components', 'mycustom_wpcf7_mail_components' );

    function mycustom_wpcf7_mail_components( $components ) {

        $coupon_field = get_field('coupon_img', 'options');
        $relative_path = (_wp_get_attachment_relative_path($coupon_field['url']));
        $output = ABSPATH . 'wp-content/uploads/' . $relative_path . '/' . $coupon_field['filename'];

        $components['attachments'][] = $output;

        return $components;
    }

@fsanterva
Copy link

fsanterva commented Sep 13, 2022

It does not really work for me. What about path? Where should path to file be assigned, and what is default?

BRO: I used this for my Path

if($cf7->id == 3990) {
	$mail = $cf7->prop('mail');
	$mail['attachments'] = './wp-content/themes/autocardivi/sample.pdf';
    $cf7->set_properties(array( "mail" => $mail));
}

add_action("wpcf7_before_send_mail", "Pdfdownload_test_func");

@fsanterva
Copy link

Hello,

What's custom fiels do you use ? i tried with this input :

[dynamichidden PDF id:PDF "uploads/pdf/Full_lighting_price_list.pdf"]

Not working :-(

Tried this code too :

function send_pdf( $wpcf7 ) {
    $id = $wpcf7->id();
	if ($id==215){
		$uploads = wp_upload_dir();
		define ('MY_FILE_PATH',$uploads['path'].'/pdf/');
		$copy_to_send=MY_FILE_PATH.'Full_lighting_price_list.pdf';	

		$mail = $wpcf7->prop('mail');
		$mail['attachments'] = $copy_to_send;
		
 $wpcf7->set_properties(array(
	    "mail" => $mail
));
	}
}
add_action('wpcf7_before_send_mail','send_pdf', 100);

Can you help me please ?

BRO: you're a legend, more blessings to you and you're family :D could you explain in details what those "$mail = $wpcf7->prop('mail');" & "$wpcf7->set_properties(array( "mail" => $mail ));" does, where you got this method, my feature worked, this is all I need, you're awesome <3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment