How to get current post ID in Contact Form 7 wpcf7_before_send_mail hook action

All we need is an easy explanation of the problem, so here it is.

I’m trying to handle the CF7 data before send and update the current post custom field using ACF function but I’m unable to get the current post ID the form is send from. I’ve also tried getting the ID from global $post variable and get_queried_object_id() but it didn’t work either.

Any idea how can I get the ID of the post the form was send from?

function dv_wpcf7_handle_form_data($wpcf7)
{
    $submission = WPCF7_Submission::get_instance();

    if ($submission) {
        $posted_data = $submission->get_posted_data();
    }

    // Check for ID of specific WPCF7 form
    if ($wpcf7->id() == 128) {
        $number_order = $posted_data['customer-number'];
        $number_current_value = get_field('trip_available_seats', get_the_ID()); // passing the ID to function doesn't work
        $number_new_value = $number_current_value - $number_order;

        if ($number_new_value >= 0) {
            update_field('trip_available_seats', $number_new_value, get_the_ID());
        } else {
            $error = true;
            $err_msg = 'Error message...';
        }
    }

    if (isset($error) && $error === true) {
        $msgs = $wpcf7->prop('messages');
        $msgs['mail_sent_ok'] = $err_msg;
        $wpcf7->set_properties(array('messages' => $msgs));
        add_filter('wpcf7_skip_mail', 'abort_mail_sending');
    }

    return $wpcf7;
}
add_action('wpcf7_before_send_mail', 'dv_wpcf7_handle_form_data');

function abort_mail_sending($contact_form)
{
    return true;
}

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

Due to a backwards-incompatible change in version 5.2, you can no longer retrieve the form’s meta data using get_posted_data().

Instead, you can use the id value in the array returned by get_current():

$contact_form = WPCF7_ContactForm::get_current();
$contact_form_id = $contact_form -> id;

Method 2

You can get the post ID from array variable $posted_data the form was send from

  if ($submission) {
       $posted_data = $submission->get_posted_data();
       print_r($posted_data)
  }

if you do a print_r on it you will get something like this:

Array
(
    [_wpcf7] => 20
    [_wpcf7_version] => 5.1.6
    [_wpcf7_locale] => en_US
    [_wpcf7_unit_tag] => wpcf7-f20-p22-o1
    [_wpcf7_container_post] => 22  **//This is what you want.**
    [your-name] => Jon Doe
    [your-email] => [email protected]
    [your-subject] => subject
    [your-message] => message
)

Edit:

Since CF7 version 5.2 the correct way to get the "post" ID to which the contact form is tied to is:

if ($submission) {
    print_r($_POST);
}

That would return something like this:

Array
(
    [_wpcf7] => 119 **//This is the "contact form" ID. But one should get that using WPCF7_ContactForm::get_current(); method **
    [_wpcf7_version] => 5.2.1
    [_wpcf7_locale] => en_US
    [_wpcf7_unit_tag] => wpcf7-f119-p120-o1
    [_wpcf7_container_post] => 120 **//This is the "post" ID**
    [_wpcf7_posted_data_hash] => 
    [your-name] => Jon
    [your-email] => Doe
    [your-subject] => Test
    [your-message] => Test
)

Method 3

Found out you can get the container post ID with $_POST['_wpcf7_container_post'])

Method 4

if you prefer to retrieve the value from wpcf7 instead of the $_POST array, you can use the following. this is similar to how to retrieve the posted data. just use get_meta instead of get_posted_data:

$submission = WPCF7_Submission :: get_instance();
$submission->get_meta('container_post_id');

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply