Contents
A large problem we have come across with CF7 is the use of dynamic attachments using only a single form. The problem is CF7 is limited to fairly static variables which are tricky to interchange. If you want different attachments you generally need to create multiple contact forms. This short tutorial will explain how to create a custom upload field for posts/pages/custom post types which works with a single contact 7 form when sending email. Commonly this would be used to send a resource such as an eBook or possibly offers which are unique to a single WordPress page/post and you wanted a button in that email to link to a PDF or other resource.
Implementation time: 15 minutes
Prerequisites
- Contact Form 7 Plugin installed
- Just Custom Fields Plugin installed
CF7 Dynamic attachments implementation
For this we will be using Just Custom Fields plugin, Contact form 7 and a little bit of custom code added to the functions.php file through some easy to follow steps.
Create the custom field
We’re going to start off by creating the custom upload field in which your attachment will be stored
- Open the setting page for Just Custom Fields
- Select the Post/Page/Custom post type which you will be using to embed your CF7 Form.
- Add a new Simple Media field with the slug for the field as _acf_uploadfield
Update the functions.php file
For those who don’t know how to update the functions.php file, check out the article here.
Open and append the follow code to your functions.php file. This piece of code will execute on successful submission of a Contact 7 Form before the email is sent.
It will create the shortcode _dynamic_attachments which can be used anywhere in the CF7 mail output. This shortcode will generate a full link to the media file of the custom upload field from the previous step. Output will look something like this http://example.net/wp-content/uploads/filename.pdf
- OPTION 1: Full URL to attachment | Output (http://example.net/wp-content/uploads/filename.pdf) | Shortcode [_dynamic_attachments]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
add_filter( 'wpcf7_special_mail_tags', 'dynamic_attachments', 20, 3 ); function dynamic_attachments( $output, $name, $html ) { $name = preg_replace( '/^wpcf7\./', '_', $name ); if ( '_dynamic_attachments' == $name ) { $submission = WPCF7_Submission::get_instance(); $url = $submission->get_meta( 'url' ); $ID = url_to_postid($url); $attachment_id = get_post_meta( $ID, '_acf_uploadfield', true ); $output = wp_get_attachment_url( $attachment_id ); } return $output; } |
- OPTION 2: Attachment relative root path | Output (Attached file to email) | Shortcode [_acf_uploadfield]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
function dynamic_attachments( $cf7 ) { $submission = WPCF7_Submission::get_instance(); $post_id = null; if ( $submission ) { $unit_tag = $submission->get_meta( 'unit_tag' ); preg_match('/^wpcf7-f\d+-p(?P<post_id>\d+)-o\d+$/', $unit_tag, $matches); if ( array_key_exists( "post_id", $matches ) && is_numeric( $matches["post_id"] ) ) { $post_id = $matches["post_id"]; } } if ( !$post_id ) { return false; } $field = get_post_custom( $post_id ); if ( !$field ) { return false; } foreach ( $field as $key => $id ) { if ( strpos( $key, "_acf_uploadfield", 0 ) === 0 ) { $file = get_attached_file( $id[0], false ); if ( !$file ) { continue; } $name = basename( $file ); $temp = sys_get_temp_dir() . "/" . $name; if ( copy( $file, $temp ) ) { $submission->add_uploaded_file($key, $temp ); } } } return true; } add_action( 'wpcf7_before_send_mail', 'dynamic_attachments' ); |
Update your CF7 mail output
The final step is to now update your output mail tags on Contact form 7 by adding the shortcode _dynamic_attachments anywhere in the mail output form.
Concluding
This is a great solution if you have multiple pages such as offers or ebooks where the landing page/post might change, but you want to use the same contact form + mail template.
If you want you can tweak the code to get other custom fields, text strings, numbers, offer codes… etc.
It is important to note that this contact from will now look for an attachment each time it sends – if no attachment has been uploaded to the post it is sending from, the mail output for that form submission will show blank field values.
I’m not a PHP developer, so i’m sure someone out there reading this post can offer a better improvement 🙂
Dear Moo Master,
I’ve being trying your method but does not seems to be working.
I only get the [_dynamic_attachments] shortcode in return of the email..
Hi Jasmin,
Just noticed there was an error in my original code – Please try using [_attachment_url] or update the code and try using [_dynamic_attachments] again.
Best,
MooMaster
thanks for the code,
But it does not work for me, I’ve done it step by step and it does not work.
I am using:
[_attachment_url]
[_dynamic_attachments]
[Dynamic_attachments]
and it does not work.
Hi Marcos,
Do you receive any error when testing either [_attachment_url] or [_dynamic_attachments] ?
It does not show any error, the message that arrives by email does not have the link of the complete file. Only displays the [_dynamic_attachments] tag without the link.
Here’s what I’m using:
Plugin configured: Just Custom Fields
Functions.php:
Add_filter (‘wpcf7_special_mail_tags’, ‘dynamic_attachments’, 20, 3);
Function dynamic_attachments ($ output, $ name, $ html)
{
$ Name = preg_replace (‘/^wpcf7\./’, ‘_’, $ name);
If (‘_dynamic_attachments’ == $ name) {
$ Url = explode (‘?’, ‘Http: //’.$_SERVER [“HTTP_HOST”]. $ _SERVER [“REQUEST_URI”]);
$ ID = url_to_postid ($ url [0]);
$ Attachment_id = get_post_meta ($ ID, ‘_acf_uploadfield’, true);
$ Output = wp_get_attachment_url ($ attachment_id);
}
Return $ output;
}
——————————————–
Form
Append purchase invoice (required)
[File * UploadResume limit: 10000000 filetypes: jpg | pdf | word | png | gif | jpeg]
E-mail:
From: [your-name]
Subject: [cf7-counter-rma]
Message body:
[Your-message]
Serial number: [serie-755]
Purchase Invoice: [UploadResume]
[_dynamic_attachments]
Hi Marcos,
Sorry for my very late reply on this one – I’ve noticed since the latest version of CF7 there was a change.
Please update to the new version of my code and it should work now.
In particular, the following lines changed
$submission = WPCF7_Submission::get_instance();
$url = $submission->get_meta( ‘url’ );
$ID = url_to_postid($url);
Best regards,
MooMaster
Dear Moo Master,
Still cant get it to work.
I have the same output even after updating the code
And when I use the second option i just get this: “/” without quotes.
Kind Regards
Hi Jasmin,
I’ve updated to a new version of the code. Please update the code and try again. It should now be compatible with CF7 version 4.9.
Best regards,
MooMaster
Thank you so much Moo Master !!
That did the trick.
Regards
Is there any way to get the uploaded file to be included as an attachement to the email instead of just a link to the file?
I want the physical file to go out with the email not just a link
any help on this would be greatly appreciated.
Hi Jacques,
Please try the code in the second example
“OPTION 2: Attachment relative root path”
And then place the shortcode into the attachment field (Make sure you’re using HTML as the content type for the CF7 Email)
Best regards,
MooMaster
Thanks for the quick response but this does not appear to be working
I think it may have to do with the fact that contact form 7 docs here state the following
https://contactform7.com/file-uploading-and-attachment/
When the path is not an absolute path, it will be treated as a relative path to wp-content directory.
So it’s expecting
uploads/test-attachement.pdf
but this function is outputting
/wp-content/uploads/test-attachement.pdf
I think to get this to work the /wp-content/ needs to be removed from the output
Can you make a suggestion on how to modify that happy to send beer money in exchange for your assistance with this.
Ok I figured out how to modify the output string like so
$output = ‘uploads/’ . rawurlencode( basename( $parsed[ ‘path’ ] ) );
so now the short code is outputting
uploads/test-attachement.pdf
I put [_dynamic_attachments] in the File Attachements field and have use HTML content type checked but it’s still not working.
If I had code
uploads/test-attachement.pdf in the Files attachement box it works. It seems like the short code is not running in the file attachement area.
Hi Jacques,
Modified version of some similar code i’m using. Please try out the below.
https://pastebin.com/R7swidHD
If it works, feel free to send beer to 1FfLqTnYABc6K3Cy75eKD5PCEbyqU7pK3d 🙂
Best regards,
MooMaster
Thanks but still not working
I tried both [moometric_dynamic_attachments] and [moometric_dynamic_attachments] in the file attachements dialog box of the but no luck.
Also not sure how to send funds to 1FfLqTnYABc6K3Cy75eKD5PCEbyqU7pK3d what is that reference number?
Jacques Choquette
[email protected]
Hi Jacques,
Please try using the shortcode of your ACF field name [_acf_uploadfield]
Still no go but thank you for your assistance. Do you have a pay pal account I would like to send you something for your troubles regardless.
Thank You so very much for your code and assistance. I have been trying for days to get a dynamic attachment (woocommerce product thumbnail image) to attach to a CF7 form email submission and nothing I have tried to date worked.
You are a genious!! 🙂
Hi,
I have setup woocommerce and have displayed the product enquiry button on the cart page (the products i have got here are from “add to cart” button). The problem i am having is to get the dynamic product name in to the ContactForm7 form.
can you please guide me if there is a way for having the dynamically included product name in the contact form 7.
Thanks.
Hi Iffi,
You might be better off using something like the Dynamic Text Extension if you only need to insert a field from the existing post.
Best,
MooMaster
Hi MooMaster,
Thanks for the reply, actually i am already using it on the products pages and it is working Great (y).
But, currently i am working on the CART page, this page has for e.g. 3 products. i have setup a popup form(ContactForm7) with everything in it, but the only thing i need is, all the products in the cart page into the Product Enquiry form.
Can you please help me out with this.
Iffi
Thank you ! Both options work very well, even with the ACF plugin! Thank you very much !