Search code examples
wordpresswoocommercecontact-form-7

Contact Form 7 + WooCommerce - Save form data in orders


I have following problem: orders page

I have a Contact Form 7 with 2 dropdown options for ordering tickets for an event, no user registration. This works fine but it doesn't save any form data in the "orders" page of woocommerce like the included image, which makes keeping track of orders difficult. In additional settings of the contact form I have following:

on_sent_ok: "switch(document.forms[0].elements["registration_type"].value){case "Normal Registration": location.replace('url/checkout-3/?clear-cart&add-to-cart=325&quantity=1');break;case "Presenter Registration": location.replace('url/checkout-3/?clear-cart&add-to-cart=327&quantity=1');break;};"

Which inserts the order in to Woocommerce but I need customer data like name adress and email too. Unfortunately I am not efficient with this type of code yet, can anyone bump me in the right direction?

Thanks in advance!


Solution

  • First you can save your CF7 data in session, in order to save them later with your order (considering that the order isn't created yet at this point). You can make use of the wpcf7_mail_sent action that is triggered when the mail is sent. Please note that all the following code take place in your theme functions.php.

    function wc_wpcf7_mail_sent_function($contact_form) {
        $submission = WPCF7_Submission::get_instance();
        if($submission) {
            $posted_data = $submission->get_posted_data();
            WC()->session->set('cf7_posted_data', $posted_data);
        }
    }
    add_action('wpcf7_mail_sent', 'wc_wpcf7_mail_sent_function'); 
    

    This use the Woocommerce Session class WC_Session.

    Then save the data in custom fields when the order is processed:

    function wc_save_cf7_data_to_order($order_id) {
        $posted_data = base64_encode(serialize(WC()->session->get('cf7_posted_data')));
        if(!empty($posted_data)) {
            add_post_meta($order_id, 'cf7_posted_data', $posted_data);
            WC()->session->__unset('cf7_posted_data');
        }
    }
    add_action('woocommerce_checkout_order_processed', 'wc_save_cf7_data_to_order', 10, 1);
    

    This will save all the CF7 form data in a serialized string, stored in base64 to avoid any decoding issue.

    Last, you need to add a meta box to show the form data on the order page:

    function wc_add_meta_box() {
        add_meta_box(
            'order_tickets',
            __('Contact form data', 'your-theme'),
            'wc_print_order_cf7_data_callback',
            'shop_order'
        );
    }
    add_action('add_meta_boxes', 'wc_add_meta_box');
    

    Then display the data:

    function print_order_tickets_callback($post) {
        $posted_data = get_post_meta($post->ID, 'cf7_posted_data', true);
        if(!empty($tickets)) {
            $posted_data = unserialiaze(base64_decode($posted_data));
            foreach($posted_data as $key => $data) {
                echo '<b>', $key, ' : </b> ', $data, '<br />';
            }
        }
    }