Search code examples
wordpresspluginscontact-form-7

Contact Form 7: Call function only on submit of specific form


I am coding my very first plugin. It is something like an addon for a theme, adding useful things to it. One of these is, that I collect data of food and this is why I allow users to add different food via a contact form. The form itself is pretty standard, and I am using save_posted_data hook to create the food post (as custom post type).

Looks like that:

function save_posted_data( $posted_data ) {

$form_id = $contact_form->id();
if( $form_id == 1903 ) {

    $args = array(
        'post_type' => 'np-food',
        'post_status'=>'draft',
        'post_title'=>$posted_data['food-name'],
        'post_content'=>$posted_data['food-desc'],
    );
    $post_id = wp_insert_post($args);

    if(!is_wp_error($post_id)){
        if( isset($posted_data['food-name']) ){
            update_post_meta($post_id, 'food-name', $posted_data['food-name']);
        }
        // and so on
    }
}
return $posted_data;
}
add_filter( 'wpcf7_posted_data', 'save_posted_data' );

My problem is: The part when checking the form, should only create a post when the chosen form is the one the user uses. But this does not work here, cause every other CF 7 form ends up in a infinite loop when clicking submit. Only the form 1903 does something (creates a post with desired meta fields). All other don´t work.

Does somebody know what I am missing here?


Solution

  • You can grab the submission on before_send_mail and check for your field name to bail out.

    add_action( 'wpcf7_before_send_mail', 'save_posted_data' );
    function save_posted_data( $contact_form ) {
    
        $submission = WPCF7_Submission::get_instance();
            if ( $submission ) {
                $posted_data = $submission->get_posted_data();    
        }
        // This checks for the form tag [food-name]
        if (empty($posted_data['food-name']) || !isset($posted_data['food-name'])) return;
    
        // Or use this to check for form by ID (remove previous if)
        // if ($posted_data['_wpcf7'] !== '{your_form_id}') return;
    
        $args = array(
            'post_type' => 'np-food',
            'post_status'=>'draft',
            'post_title'=>$posted_data['food-name'],
            'post_content'=>$posted_data['food-desc'],
        );
        $post_id = wp_insert_post($args);
    
        if(!is_wp_error($post_id)){
            if( isset($posted_data['food-name']) ){
                update_post_meta($post_id, 'food-name', $posted_data['food-name']);
            }
            // and so on
        }
    }
    

    You can also use the field _wpcf7 which contains the form ID $posted_data['_wpcf7']

    So your "IF" would be this:

    if ($posted_data['_wpcf7'] !== '1903') return;
    

    For Multiple Form Submissions and functions you could do this:

    if ($posted_data['_wpcf7'] == '{your_form_id}') {
        // do stuff when form id = first
    } else if ($posted_data['_wpcf7'] == 'second_form_id') {
       // do more stuff
    }