Home > Back-end >  Issue with saving value from Select2 field in WooCommerce backend
Issue with saving value from Select2 field in WooCommerce backend

Time:03-29

I'm using a code to initial a select2 field in WooCommerce Backend. The selecting field is working good, but I have problems after saving product.

I cannot get the value from db and be pre-selected. Also can not save it as well.

Can anybody give a tip with this? Should data be saved as an array?

My code:

function woocommerce_wp_product_select2( $field ) {
    global $thepostid, $post, $woocommerce;
    $thepostid              = empty( $thepostid ) ? $post->ID : $thepostid;
    $field['class']         = isset( $field['class'] ) ? $field['class'] : 'select short';
    $field['wrapper_class'] = isset( $field['wrapper_class'] ) ? $field['wrapper_class'] : '';
    $field['name']          = isset( $field['name'] ) ? $field['name'] : $field['id'];
    echo '<p ><label for="' . esc_attr( $field['id'] ) . '">' . wp_kses_post( $field['label'] ) . '</label><select id="' . esc_attr( $field['id'] ) . '" name="' . esc_attr( $field['name'] ) . '"  multiple="multiple" data-maximum-selection-length="1">';
    foreach ( $field['value'][0] as $key => $value ) {
        echo '<option value="'.$value.'" selected="selected">'.wc_get_product( $value )->name.' (#'.$value.')</option>';
    }
    echo '</select> ';
    if ( ! empty( $field['description'] ) ) {
        if ( isset( $field['desc_tip'] ) && false !== $field['desc_tip'] ) {
            echo '<span  data-tip="' . esc_attr( $field['description'] ) . '"></span>';
        } else {
          echo '<span >' . wp_kses_post( $field['description'] ) . '</span>';
        }
    }
    echo '</p>';
}

add_filter( 'woocommerce_product_data_tabs', 'kyatipov_promo_tab', 10, 1 );
function kyatipov_promo_tab($default_tabs) {

    $default_tabs['promo'] = array(
        'label'   =>  __( 'Промоция', 'domain' ),
        'target'  =>  'kyatipov_promo_tab_content',
        'priority' => 60,
        'class'   => array('promo-tab-produkti')
    );
    return $default_tabs;
}

add_action( 'woocommerce_product_data_panels', 'kyatipov_promo_tab_content' );
function kyatipov_promo_tab_content() {
    global $woocommerce, $post;
    ?>
    <div id="kyatipov_promo_tab_content" >
        
     <style>
        #woocommerce-product-data ul li.promo_options.promo_tab.promo-tab-produkti a::before {
            font-family: Dashicons;
            content: "\f198";
        }
         h4#ízbran-produkt, h4#iztrii-izbran-prod {
             margin-left: 12px;
         }
         .iztrii-container {
             display: flex;
         }
         h4#iztrii-izbran-prod::after {
             font-family: Dashicons;
             content: "\f182";
             color: red;
             font-size: 26px;
         }
         h4#iztrii-izbran-prod {
             margin-top: 0;
         }
         h4#iztrii-izbran-prod:hover {
             cursor: -webkit-grabbing; cursor: grabbing;
         }
         select#wc_product_ids   span.select2 {
             width: 350px !IMPORTANT;
         }
    </style>
 
    <?php
    woocommerce_wp_checkbox( array( 
        'id'            => '_enable_promo_for_current_product', 
        //'wrapper_class' => 'show_if_simple', 
        'label'         => __( 'Включи промо', 'woocommerce' ),
        'description'   => __( 'Тази опция е задължителна, ако желаете да ползвате промо фу-ота за този продукт!', 'my_text_domain' ),
        'default'       => '0',
        'desc_tip'      => true,
    ) );    
    
    
    $save_data = get_post_meta( $post->ID, 'wc_product_ids' );
    echo $save_data;
    print_r($save_data);

    woocommerce_wp_product_select2([
        'id'      => 'wc_product_ids',
        'label'   => __( 'Продукт', 'woocommerce' ),
        'class' => '',
        'name' => 'wc_product_ids[]',
        'value'   => $save_data,
        'desc_tip' => true,
        'description' => __( 'Избери продукт за промоция', 'wc' ),
    ]);
    
    echo '</div>';
}

// Save Meta
add_action('woocommerce_process_product_meta', 'kyatipov_custom_field_save');
function kyatipov_custom_field_save( $post_id ){
        
    // Select
    $izbran_promo_prod = $_POST['wc_product_ids'];
    if( !empty( $izbran_promo_prod ) )
        update_post_meta( $post_id, 'wc_product_ids', esc_attr( $izbran_promo_prod ) );
    
    $izbran_promo_prod2 = $_POST['save_data'];
    if( !empty( $izbran_promo_prod2 ) )
        update_post_meta( $post_id, 'save_data', esc_attr( $izbran_promo_prod2 ) );
    
}

CodePudding user response:

First of all I modified the woocommerce_wp_product_select2() function you are using:

  • I've added $field['placeholder'] to the function, so that a placeholder can be used if desired
  • data-exclude="<?php echo $thepostid; ?>" has been added so that the current product cannot be selected
  • $field['value'] = ! empty( $field['value'] ) ? $field['value'] : array(); was also added to the function, to avoid an error message when the metadata does not exist/do not yet exist

When it comes to saving, you're making the mistake that esc_attr() is used with an array, while it expects a string

p.s. to save fields you can use the woocommerce_admin_process_product_object hook, opposite the outdated woocommerce_process_product_meta hook

So you get:

function woocommerce_wp_product_select2( $field ) {
    global $thepostid, $post;

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

    echo '<p ><label for="' . esc_attr( $field['id'] ) . '">' . wp_kses_post( $field['label'] ) . '</label><select id="' . esc_attr( $field['id'] ) . '" name="' . esc_attr( $field['name'] ) . '"  multiple="multiple" style="width: 50%;" data-maximum-selection-length="1" data-placeholder="' . esc_attr( $field['placeholder'] ) . '" data-exclude="<?php echo $thepostid; ?>" >';

    foreach ( $field['value'] as $key => $value ) {
        $product = wc_get_product( $value );
        if ( is_object( $product ) ) {
            echo '<option value="' . esc_attr( $value ) . '"' . selected( true, true, false ) . '>' . esc_html( wp_strip_all_tags( $product->get_formatted_name() ) ) . '</option>';
        }
    }

    echo '</select> ';

    if ( ! empty( $field['description'] ) ) {
        if ( isset( $field['desc_tip'] ) && false !== $field['desc_tip'] ) {
            echo '<span  data-tip="' . esc_attr( $field['description'] ) . '"></span>';
        } else {
          echo '<span >' . wp_kses_post( $field['description'] ) . '</span>';
        }
    }

    echo '</p>';
}

function filter_woocommerce_product_data_tabs( $default_tabs ) {
    $default_tabs['promo'] = array(
        'label'     =>  __( 'Промоция', 'domain' ),
        'target'    =>  'kyatipov_promo_tab_content',
        'priority'  => 60,
        'class'     => array( 'promo-tab-produkti' )
    );

    return $default_tabs;
}
add_filter( 'woocommerce_product_data_tabs', 'filter_woocommerce_product_data_tabs', 10, 1 );

function action_woocommerce_product_data_panels() {
    global $post;

    echo '<div id="kyatipov_promo_tab_content" >';
    
    // Get data
    $data = get_post_meta( $post->ID, '_wc_product_ids', true );

    // Add field via custom function
    woocommerce_wp_product_select2(
        array(
            'id'            => 'wc_product_ids',
            'label'         => __( 'Продукт', 'woocommerce' ),
            'placeholder'   => __( 'My placeholder', 'woocommerce' ),
            'class'         => '',
            'name'          => 'wc_product_ids[]',
            'value'         => $data,
            'desc_tip'      => true,
            'description'   => __( 'Избери продукт за промоция', 'woocommerce' ),
        )
    );
    
    echo '</div>';
}
add_action( 'woocommerce_product_data_panels', 'action_woocommerce_product_data_panels' );

// Save
function action_woocommerce_admin_process_product_object( $product ) {
    // Good idea to make sure things are set before using them
    $data = isset( $_POST['wc_product_ids'] ) ? (array) $_POST['wc_product_ids'] : array();

    // Update
    $product->update_meta_data( '_wc_product_ids', array_map( 'esc_attr', $data ) );
}
add_action( 'woocommerce_admin_process_product_object', 'action_woocommerce_admin_process_product_object', 10, 1 );

Related: Add custom select2 search field into WooCommerce product data metabox

  • Related