从 WooCommerce 后端的 Select2 字段保存值的问题

Issue with saving value from Select2 field in WooCommerce backend

我正在使用代码初始化 WooCommerce 后端中的 select2 字段。选择字段工作正常,但保存产品后出现问题。

我无法从数据库中获取值并被预选。也保存不了。

任何人都可以给点提示吗?数据应该保存为数组吗?

我的代码:

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 class="form-field ' . esc_attr( $field['id'] ) . '_field ' . esc_attr( $field['wrapper_class'] ) . '"><label for="' . esc_attr( $field['id'] ) . '">' . wp_kses_post( $field['label'] ) . '</label><select id="' . esc_attr( $field['id'] ) . '" name="' . esc_attr( $field['name'] ) . '" class="wc-product-search ' . esc_attr( $field['class'] ) . '" 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 class="woocommerce-help-tip" data-tip="' . esc_attr( $field['description'] ) . '"></span>';
        } else {
          echo '<span class="description">' . 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" class="panel woocommerce_options_panel">
        
     <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 ) );
    
}

首先我修改了你正在使用的woocommerce_wp_product_select2()函数:

  • 我已将 $field['placeholder'] 添加到函数中,以便在需要时可以使用占位符
  • data-exclude="<?php echo $thepostid; ?>"已添加,无法选择当前商品
  • $field['value'] = ! empty( $field['value'] ) ? $field['value'] : array(); 也被添加到函数中,以避免在元数据 exist/do 尚不存在
  • 时出现错误消息

在保存时,您犯了一个错误,即 esc_attr() 与数组一起使用,而它需要一个字符串

p.s。要保存字段,您可以使用 woocommerce_admin_process_product_object 挂钩,与过时的 woocommerce_process_product_meta 挂钩

相反

所以你得到:

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 class="form-field ' . esc_attr( $field['id'] ) . '_field ' . esc_attr( $field['wrapper_class'] ) . '"><label for="' . esc_attr( $field['id'] ) . '">' . wp_kses_post( $field['label'] ) . '</label><select id="' . esc_attr( $field['id'] ) . '" name="' . esc_attr( $field['name'] ) . '" class="wc-product-search ' . esc_attr( $field['class'] ) . '" 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 class="woocommerce-help-tip" data-tip="' . esc_attr( $field['description'] ) . '"></span>';
        } else {
          echo '<span class="description">' . 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" class="panel woocommerce_options_panel">';
    
    // 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 );

相关: