20

I have a plugin I am writing that I want to interact with Contact Form 7. In my plugin I added the following action add_action

add_action("wpcf7_before_send_mail", "wpcf7_do_something_else");

function wpcf7_do_something_else(&$wpcf7_data) {

    // Here is the variable where the data are stored!
    var_dump($wpcf7_data);

    // If you want to skip mailing the data, you can do it...
    $wpcf7_data->skip_mail = true;

}

I submitted the contact form but the add_action I had did nothing. I'm unsure how to make my plugin intercept or do something when Contact Form 7 does something. Any, help on how to do this?

Naterade
  • 2,635
  • 8
  • 34
  • 54

5 Answers5

32

I had to do this to prevent Email from being sent. Hope it helps.

/*
    Prevent the email sending step for specific form
*/
add_action("wpcf7_before_send_mail", "wpcf7_do_something_else");  
function wpcf7_do_something_else($cf7) {
    // get the contact form object
    $wpcf = WPCF7_ContactForm::get_current();

    // if you wanna check the ID of the Form $wpcf->id

    if (/*Perform check here*/) {
        // If you want to skip mailing the data, you can do it...  
        $wpcf->skip_mail = true;    
    }

    return $wpcf;
}

This code assumes that you are running the latest version of CF7 your code above used to work until a couple months ago when they went and did some refactoring of the code. [Apr 28 '15]

Musk
  • 1,477
  • 1
  • 15
  • 25
  • 1
    Thanks Musk, that did it perfectly! That also answered my question on how to manipulate another plugin! – Naterade Apr 28 '15 at 19:04
  • 1
    Make shure that you do not `echo` or `var_dump` anything in your function. – moestly Mar 16 '16 at 10:26
  • @Musk - question: would I add this code in my functions.php? Also how would i be able to "echo" or something to verify that it is running before send? THANKS! – Radmation Jan 12 '17 at 16:55
  • 1
    @Radmation yes and to verify something from the function if you echo it would appear in the Network Tab of Chrome, most likely in the admin-ajax.php. – Musk Jan 12 '17 at 16:59
  • @Musk I am unable to find where it would be in the network tab...there isnt the admin.ajax.php file there...any other ideas why? What else can I do to verify that code block executes? I tried creating a file but that didn't work... – Radmation Jan 12 '17 at 17:26
  • @Radmation i just tested it, the solution still worked, to view the output of echo which should only be used for testing since this function is expected to do a return. You just view your Network Tab in Chrome Dev tools (or equivalent for other Browsers), then proceed to fill the form while the Devtool is open on Network, you should see the current page popup as a request clicking on it you can see the response tab (which will contain whatever you echoed in the function). – Musk Jan 12 '17 at 17:42
  • @Musk thanks for the response. I am unsure where to find this in the network tab..I think I am in the right spot. I am using Chrome. So when I hit send I see a list of requests and I have 2 pages that are the same page I am hitting send from. One page one is a post and the other is a get. The post response is obiviously the page I am on but the GET doesnt have any information - it reads "This request has no response data available." I can see the headers and such..any ideas on what I am screwing up? Here is a link to the page http://kb-demos.com/spbc/about-us/ THANKS – Radmation Jan 12 '17 at 17:56
  • @Radmation I just checked it out, before the complete redirection i saw something like "TEST MESSAGE HERE", but the fact that you don't see it in the Network tab is because of that redirection. Since i was redirected to a PayPal checkout thing. – Musk Jan 12 '17 at 18:01
  • @Musk Great! Will I see that message on an invalid attempt? Or only on a successful form submission? That my be my problem. I was purposely making it invalid. – Radmation Jan 12 '17 at 18:03
  • @Radmation i sort of made it valid when i did mine. But it goes away fast, you should turn off any redirection and test what you gotta test with that form. – Musk Jan 12 '17 at 18:05
  • @Musk Thanks I will disable that plugin for the time being. How did you stop it so fast or catch the message? – Radmation Jan 12 '17 at 18:06
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/133024/discussion-between-musk-and-radmation). – Musk Jan 12 '17 at 18:06
  • 3
    It seems that it doesn't work after version 4.8 There is no official statement from developer about the reason. Related: https://wordpress.org/support/topic/upgrade-to-cf-4-8-seems-to-have-stopped-my-functions-php-to-fire/ I had to downgrade to version 4.7 – xZero Apr 03 '18 at 08:24
  • 1
    upvoted, but after testing it does not work in CF7 5+. – dev101 Jan 08 '19 at 18:23
  • What for is the `$wpcf = WPCF7_ContactForm::get_current();` since you have it as `$cf7` already? – Picard Feb 19 '21 at 13:33
  • @Picard I haven't check the codebase in a while, but at the time the ``get_current()`` actually returned the object to be modified but ``$cf7`` did not. But it could of been an oversight or even the arguments ``$cf7`` itself could of been deprecated as this was the way before one of the major refactor. But i can't fully recall. – Musk Feb 22 '21 at 01:39
  • Another reason it's better to avoid garbage WordPress and it's "magical" plugins.. No official statement. Garbage documentation. Garbage overhead piecing the jigsaw together. – JoeD Apr 19 '23 at 19:26
16

Since WPCF7 5.2 the wpcf7_before_send_mail hook has changed quite a lot. For reference, here is how to work with this hook in 5.2+

Skip mail

function my_skip_mail() {
    return true; // true skips sending the email
}
add_filter('wpcf7_skip_mail','my_skip_mail');

Or add skip_mail to the Additional Settings tab on your form in the admin area.

Getting the Form ID or Post ID

function wpcf7_before_send_mail_function( $contact_form, $abort, $submission ) {

    $post_id = $submission->get_meta('container_post_id');
    $form_id = $contact_form->id();

    // do something       

    return $contact_form;
    
}
add_filter( 'wpcf7_before_send_mail', 'wpcf7_before_send_mail_function', 10, 3 );

Get user inputted data

function wpcf7_before_send_mail_function( $contact_form, $abort, $submission ) {

    $your_name = $submission->get_posted_data('your-field-name');

    // do something       

    return $contact_form;
    
}
add_filter( 'wpcf7_before_send_mail', 'wpcf7_before_send_mail_function', 10, 3 );

Send the email to a dynamic recipient

function wpcf7_before_send_mail_function( $contact_form, $abort, $submission ) {

    $dynamic_email = 'email@email.com'; // get your email address...

    $properties = $contact_form->get_properties();
    $properties['mail']['recipient'] = $dynamic_email;
    $contact_form->set_properties($properties);

    return $contact_form;
    
}
add_filter( 'wpcf7_before_send_mail', 'wpcf7_before_send_mail_function', 10, 3 );
lukeseager
  • 2,365
  • 11
  • 37
  • 57
  • VERY helpful and detailed answer, thank you @lukeseager! Your skip mail function still works on newest version of Contact Form 7. – Marcin Jan 09 '23 at 18:32
13

I'd like to add that you could just use the wpcf7_skip_mail filter:

add_filter( 'wpcf7_skip_mail', 'maybe_skip_mail', 10, 2 );

function maybe_skip_mail( $skip_mail, $contact_form ) {

    if( /* your condition */ )
        $skip_mail = true;

    return $skip_mail;

}
d79
  • 3,699
  • 1
  • 22
  • 36
2

You can turn Demo Mode on in additional settings and this will prevent emails from being sent. See below from the CF7 Docs.

If you set demo_mode: on in the Additional Settings field, the contact form will be in the demo mode. In this mode, the contact form will skip the process of sending mail and just display “completed successfully” as a response message.

0

If you want to prevent email from being sent, use this code. This code will work if you are using latest version of WPCF7

function wpcf7_before_send_mail_function( $contact_form, &$abort, $submission ) {

  $form_id = $contact_form->id();   
  // Compare the form Id so other form will work as it is.
  if( $form_id == 123 ) {
       // Get field data. For example message field
       $message = $submission->get_posted_data('message');
       $message = trim($message);
       // If messsage field value is empty then set abort to true which will not sent email
       if( empty( $message ) ) {
           $abort = true;
       }
  }
}
add_action( 'wpcf7_before_send_mail', 'wpcf7_before_send_mail_function', 10, 3 );
Kalpesh Prajapati
  • 1,703
  • 1
  • 12
  • 15