1

I added successfully a Metabox with a multi checkbox field that is displayed on admin single order pages and works perfectly.

I am using Multi checkbox fields in Woocommerce backend answer code for that multi checkbox.

 // Adding Meta container admin shop_order pages
add_action( 'add_meta_boxes', 'em_add_meta_boxes' );
if ( ! function_exists( 'em_add_meta_boxes' ) )
{
    function em_add_meta_boxes()
    {
        add_meta_box( 'em_other_fields', __('Employee Extra Actions','woocommerce'), 'em_add_other_fields_for_order_empl', 'shop_order', 'side', 'core' );
    }
}

// Adding Meta field in the meta container admin shop_order pages
if ( ! function_exists( 'em_add_other_fields_for_order_empl' ) )
{
    function em_add_other_fields_for_order_empl()
    {
        global $post;

    echo '<div class="options_group">';

        
        woocommerce_wp_multi_checkbox( array(
        'id'    => 'employee_actions12',
        'name'  => 'employee_actions12[]',
        'label' => __('Levels', 'woocommerce'),
        'options' => array(
            'tee'   => __( 'MBO', 'woocommerce' ),
            'saa'   => __( 'HBO', 'woocommerce' ),
            'tee1'    => __( 'WO', 'woocommerce' ),
        )
    ) );
            

    echo '</div>';

    }
}

Final part of code is to save at database, Here is it:

    add_action( 'save_post', 'save_product_options_custom_fields32', 30, 1 );
    function save_product_options_custom_fields32( $post_id ){
        if( isset( $_POST['employee_actions12'] ) ){
            $post_data = $_POST['employee_actions12'];
            // Multi data sanitization 
            $sanitize_data = array();
            if( is_array($post_data) && sizeof($post_data) > 0 ){
                foreach( $post_data as $value ){
                    $sanitize_data[] = esc_attr( $value );
                }
            }
            update_post_meta( $post_id, 'employee_actions12', $sanitize_data );
        }
    }

I know code works for product pages with action: 'woocommerce_product_process_meta'

So, i need help for saving at db, an fixing error notice for array (i think this can happen if we select default value).

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • How can i save field to db if thia meta is on shop_order page? – Vladimir Kyatipov Jan 25 '21 at 08:57
  • Thank you @LoicTheAztec, I updated code I use this article for metabox - https://stackoverflow.com/questions/37772912/woocommerce-add-custom-metabox-to-admin-order-page – Vladimir Kyatipov Jan 25 '21 at 10:46
  • 1
    I have finally answered your question… The `woocommerce_wp_multi_checkbox()` function was not working properly on custom metaboxes (I have update that function again)… – LoicTheAztec Jan 25 '21 at 12:03

1 Answers1

1

There was another issue with the function woocommerce_wp_multi_checkbox() that I have updated again (when used in a custom metabox).

I have also revisited all your code, specially the last function that saves the multi-checkboxes selected values.

The complete code:

// WooCommerce admin custom multi checkbox field function
function woocommerce_wp_multi_checkbox( $field ) {
    global $thepostid, $post;

    if( ! $thepostid ) {
        $thepostid = $post->ID;
    }    

    $field['value'] = get_post_meta( $thepostid, $field['id'], true );

    $thepostid              = empty( $thepostid ) ? $post->ID : $thepostid;
    $field['class']         = isset( $field['class'] ) ? $field['class'] : 'select short';
    $field['style']         = isset( $field['style'] ) ? $field['style'] : '';
    $field['wrapper_class'] = isset( $field['wrapper_class'] ) ? $field['wrapper_class'] : '';
    $field['value']         = isset( $field['value'] ) ? $field['value'] : array();
    $field['name']          = isset( $field['name'] ) ? $field['name'] : $field['id'];
    $field['desc_tip']      = isset( $field['desc_tip'] ) ? $field['desc_tip'] : false;

    echo '<fieldset class="form-field ' . esc_attr( $field['id'] ) . '_field ' . esc_attr( $field['wrapper_class'] ) . '">
    <legend>' . wp_kses_post( $field['label'] ) . '</legend>';

    if ( ! empty( $field['description'] ) && false !== $field['desc_tip'] ) {
        echo wc_help_tip( $field['description'] );
    }

    echo '<ul class="wc-radios">';

    foreach ( $field['options'] as $key => $value ) {

        echo '<li><label><input
                name="' . esc_attr( $field['name'] ) . '"
                value="' . esc_attr( $key ) . '"
                type="checkbox"
                class="' . esc_attr( $field['class'] ) . '"
                style="' . esc_attr( $field['style'] ) . '"
                ' . ( is_array( $field['value'] ) && in_array( $key, $field['value'] ) ? 'checked="checked"' : '' ) . ' /> ' . esc_html( $value ) . '</label>
        </li>';
    }
    echo '</ul>';

    if ( ! empty( $field['description'] ) && false === $field['desc_tip'] ) {
        echo '<span class="description">' . wp_kses_post( $field['description'] ) . '</span>';
    }

    echo '</fieldset>';
}

// Adding a custom Metabox on WooCommerce single orders
add_action( 'add_meta_boxes', 'add_custom_shop_order_metabox' );
function add_custom_shop_order_metabox(){
    add_meta_box(
        'custom_shop_order_metabox',
        __('Employee Extra Actions', 'woocommerce'),
        'content_custom_shop_order_metabox',
        'shop_order',
        'side',
        'core'
    );
}


// Custom Metabox content on WooCommerce single orders
function content_custom_shop_order_metabox() {
    global $thepostid, $post;

    echo '<div class="options_group">';

    woocommerce_wp_multi_checkbox( array(
        'id'      => 'employee_actions12',
        'name'    => 'employee_actions12[]',
        'label'   => __('Levels', 'woocommerce'),
        'options' => array(
            'tee'  => __( 'MBO', 'woocommerce' ),
            'saa'  => __( 'HBO', 'woocommerce' ),
            'tee1' => __( 'WO', 'woocommerce' ),
        ),
    ) );


    echo '</div>';
}

// Save WooCommerce single orders Custom Metabox field values
add_action( 'save_post_shop_order', 'save_custom_shop_order_metabox_field_values' );
function save_custom_shop_order_metabox_field_values( $post_id ){
    if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
    || ! current_user_can( 'edit_shop_order', $post_id ) ) {
        return;
    }

    if( isset( $_POST['employee_actions12'] ) ){
        update_post_meta( $post_id,  'employee_actions12', wc_clean($_POST['employee_actions12']) );
    }
}

Code goes in functions.php file of the active child theme (or active theme). Tested and works.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • Thank you very very much. Working like a charm!!! As a beginner like me, can you give some recommendation for courses in woocommerce, php or jQuery. I rode almost all posts on this topic on forum. Thank you! – Vladimir Kyatipov Jan 25 '21 at 12:05
  • 1
    @ВладимирКятипов Learning is a long process that never ends… Here on StackOverFlow, you can learn trying to answer other questions on your side (even if you don't publish an answer) and looking to other answers. Internet is full of tutorial, documentation… Also for WooCommerce, Always try to go [in the source code](https://github.com/woocommerce/woocommerce), searching for functions methods or hooks, that you are using... – LoicTheAztec Jan 25 '21 at 12:13
  • Thank you one more time sir, i will start looking at source code for future and will remember your tip! Have a good day! – Vladimir Kyatipov Jan 25 '21 at 12:17