'How to add custom fields to WooCommerce product data panel

I have created a custom product type for events in WooCommerce. Now I want to add some custom fields to it.

This can be achieved with functions like woocommerce_wp_select(), woocommerce_wp_text_input() etc. However, as far as I know, whith these function you can only add text input fields, textarea's, select boxes and select dropdowns.

I want to add a date picker field, a file upload field and an url input field.

I have created these fields and they do render on the admin panel as they should, but the values are not saved (although I'm using the action hook 'woocommerce_process_product_meta'). Only the first 2 fields (event_type and event_location), which are created with the WooCommerce function, are stored properly.

What am I doing wrong here?

My code:

add_action('woocommerce_product_data_panels', 'okappi_add_custom_fields');

function okappi_add_custom_fields()
{ ?>
<div id="event_details" class="panel woocommerce_options_panel hidden">

    <div class="options_group" class="show_if_event">
        <? woocommerce_wp_select([
            'id' => 'event_type',
            'label' => __('Event type', 'custom'),
            'wrapper_class' => 'show_if_event',
            'value' => get_post_meta(get_the_ID(), 'event_type', true),
            'options' => array('online' => 'Online', 'international' => 'International', 'internal' => 'Internal'),

        ]); ?>

        <? woocommerce_wp_text_input([
            'id' => 'event_location',
            'label' => __('Event location', 'custom'),
            'wrapper_class' => 'show_if_event',
            'value' => get_post_meta(get_the_ID(), 'event_location', true),
        ]); ?>

        <p class="show_if_event form-field event_start_date_field">
            <label for="event_start_date">Start date</label>
            <input type="date" id="event_start_date" name="event_start_date" class="date short">
        </p>

        <p class="show_if_event form-field event_end_date_field">
            <label for="event_end_date">End date</label>
            <input type="date" id="event_end_date" name="event_end_date" class="date short">
        </p>

        <p class="show_if_event form-field event_pdf_field">
            <label for="event_pdf">PDF upload</label>
            <input type="file" id="event_pdf" name="event_pdf" class="date short">
        </p>

        <p class="show_if_event form-field event_link_field">
            <label for="event_link">Event link</label>
            <input type="url" id="event_link" name="event_link" class="date short" placeholder="https://www.my-event.com/">
        </p>
    </div>

</div>'
<? }

add_action('woocommerce_process_product_meta', 'save_custom_fields');

function save_custom_fields($post_id)
{
    $product = wc_get_product($post_id);

    $event_type = isset($_POST['event_type']) ? $_POST['event_type'] : '';
    $product->update_meta_data('event_type', sanitize_text_field($event_type));

    $event_location = isset($_POST['event_location']) ? $_POST['event_location'] : '';
    $product->update_meta_data('event_location', sanitize_text_field($event_location));

    $event_start_date = isset($_POST['event_start_date']) ? $_POST['event_start_date'] : '';
    $product->update_meta_data('event_start_date', sanitize_text_field($event_start_date));

    $event_end_date = isset($_POST['event_end_date']) ? $_POST['event_end_date'] : '';
    $product->update_meta_data('event_end_date', sanitize_text_field($event_end_date));

    $event_pdf = isset($_POST['event_pdf']) ? $_POST['event_pdf'] : '';
    $product->update_meta_data('event_pdf', sanitize_text_field($event_pdf));

    $event_link = isset($_POST['event_link']) ? $_POST['event_link'] : '';
    $product->update_meta_data('event_link', sanitize_text_field($event_link));

    $product->save();
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source