php - Woocommerce 后端中的多选字段

标签 php wordpress woocommerce backend multi-select

我正在尝试在 Woocommerce 产品变体中创建 4 个多选选项。

例如:我在卖树,想显示树可用的季节。所以我们有 4 个季节(春、夏、秋、冬),有些树有两个或树的季节。

我将此代码添加到我的functions.php,但它不会保存选定的选项。当我保存选项并重新加载页面时,选项再次变为空白。

而且我还想知道如何将单个产品页面(前端)上的选定选项显示为图标。

目前,带有选项的功能适用于产品变体。请参阅此屏幕截图(具有多选选项的产品变体):

image product variation with multi select options

我的代码:

// Add Variation Settings
add_action( 'woocommerce_product_after_variable_attributes', 'variation_settings_fields', 10, 3 );

/**
 * Create custom field type
 *
*/
function woocommerce_wp_select_multiple( $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'];
    $field['value']         = isset( $field['value'] ) ? $field['value'] : ( get_post_meta( $thepostid, $field['id'], true ) ? get_post_meta( $thepostid, $field['id'], true ) : array() );

    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="' . esc_attr( $field['class'] ) . '" multiple="multiple">';

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

        echo '<option value="' . esc_attr( $key ) . '" ' . ( in_array( $key, $field['value'] ) ? 'selected="selected"' : '' ) . '>' . esc_html( $value ) . '</option>';

    }

    echo '</select> ';

    if ( ! empty( $field['description'] ) ) {

        if ( isset( $field['desc_tip'] ) && false !== $field['desc_tip'] ) {
            echo '<img class="help_tip" data-tip="' . esc_attr( $field['description'] ) . '" src="' . esc_url( WC()->plugin_url() ) . '/assets/images/help.png" height="16" width="16" />';
        } else {
            echo '<span class="description">' . wp_kses_post( $field['description'] ) . '</span>';
        }

    }
    echo '</p>';
}


/**
 * Create new fields for variations
 *
*/
function variation_settings_fields( $loop, $variation_data, $variation ) {

    woocommerce_wp_select_multiple( array(
        'id' => 'season_' . $variation->ID,
        'class' => 'season',
        'label' => __('Season', 'woocommerce'),
        'value' => get_post_meta( $variation->ID, '_season', true ),
        'options' => array(
            'spring' => 'Spring',
            'summer' => 'Summer',
            'autumn' => 'Autumn',
            'winter' => 'Winter',
        ))
    );
}

add_action( 'woocommerce_save_product_variation', 'save_variation_settings_fields', 10, 2 );
function save_variation_settings_fields( $post_id ) {

    $select = $_POST["season_$post_id"];
    if( ! empty( $select ) ) {
        update_post_meta( $post_id, '_season', esc_attr( $select ) );
    }
}   

最佳答案

办理多选字段的可变产品是另一回事 并且需要进行一些更改才能使其正常工作。我在以下之后做了2个答案:

  • 第一个产品变体(为您)
  • 另一个适用于所有其他产品类型

  • 因此,在 WooCommerce 后端启用多选字段的主要功能将是:
    function woocommerce_wp_multi_select( $field, $variation_id = 0 ) {
        global $thepostid, $post;
    
        if( $variation_id == 0 )
            $the_id = empty( $thepostid ) ? $post->ID : $thepostid;
        else
            $the_id = $variation_id;
    
        $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'];
    
        $meta_data              = maybe_unserialize( get_post_meta( $the_id, $field['id'], true ) );
        $meta_data              = $meta_data ? $meta_data : array() ;
    
        $field['value'] = isset( $field['value'] ) ? $field['value'] : $meta_data;
    
        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="' . esc_attr( $field['class'] ) . '" multiple="multiple">';
    
        foreach ( $field['options'] as $key => $value ) {
            echo '<option value="' . esc_attr( $key ) . '" ' . ( in_array( $key, $field['value'] ) ? 'selected="selected"' : '' ) . '>' . esc_html( $value ) . '</option>';
        }
        echo '</select> ';
        if ( ! empty( $field['description'] ) ) {
            if ( isset( $field['desc_tip'] ) && false !== $field['desc_tip'] ) {
                echo '<img class="help_tip" data-tip="' . esc_attr( $field['description'] ) . '" src="' . esc_url( WC()->plugin_url() ) . '/assets/images/help.png" height="16" width="16" />';
            } else {
                echo '<span class="description">' . wp_kses_post( $field['description'] ) . '</span>';
            }
        }
    }
    
    代码位于事件子主题(或事件主题)的 function.php 文件中。此功能现在将处理任何类型的产品,包括产品变体。
    相关: Multi checkbox fields in Woocommerce backend

    1)。对于产品变化 (为你):
    // Add custom multi-select fields in variation setting tab
    add_action( 'woocommerce_product_after_variable_attributes', 'add_variation_settings_fields', 20, 3 );
    function add_variation_settings_fields( $loop, $variation_data, $variation_post ) {
    
        woocommerce_wp_multi_select( array(
            'id' => '_season',
            'name' => '_season['.$loop.'][]',
            'class' => '',
            'label' => __('Season', 'woocommerce'),
            'options' => array(
                'spring' => __("Spring", "woocommerce"),
                'summer' => __("Summer", "woocommerce"),
                'autumn' => __("Autumn", "woocommerce"),
                'winter' => __("Winter", "woocommerce"),
            )
        ), $variation_post->ID );
    }
    
    // Save custom multi-select fields for variations
    add_action( 'woocommerce_save_product_variation', 'save_variation_settings_fields', 10, 2 );
    function save_variation_settings_fields( $variation_id, $i ) {
        if( isset( $_POST['_season'][$i] ) ){
            $post_data = $_POST['_season'][$i];
            // 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( $variation_id, '_season', $sanitize_data );
        }
    
    }
    
    代码位于事件子主题(或事件主题)的 function.php 文件中。测试和工作。
    enter image description here

    2)。对于所有其他产品类型 (除了产品变体,我们隐藏了自定义字段):
    // Add custom fields for product general option settings (hidding it for variable products)
    add_action( 'woocommerce_product_options_general_product_data', 'add_custom_settings_fields', 20 );
    function add_custom_settings_fields() {
        global $post;
    
        echo '<div class="options_group hide_if_variable"">'; // Hidding in variable products
    
        woocommerce_wp_multi_select( array(
            'id' => '_season',
            'name' => '_season[]',
            'class' => '',
            'label' => __('Season', 'woocommerce'),
            'options' => array(
                'spring' => __("Spring", "woocommerce"),
                'summer' => __("Summer", "woocommerce"),
                'autumn' => __("Autumn", "woocommerce"),
                'winter' => __("Winter", "woocommerce"),
            )
        ) );
    
        echo '</div>';
    }
    
    // Save custom multi-select fields to database when submitted in Backend (for all other product types)
    add_action( 'woocommerce_process_product_meta', 'save_product_options_custom_fields', 30, 1 );
    function save_product_options_custom_fields( $post_id ){
        if( isset( $_POST['_season'] ) ){
            $post_data = $_POST['_season'];
            // 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, '_season', $sanitize_data );
        }
    }
    
    代码位于事件子主题(或事件主题)的 function.php 文件中。测试和工作。
    enter image description here

    关于php - Woocommerce 后端中的多选字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50132928/

    相关文章:

    php - laravel 4 css 文件 404 未找到

    php - PHP const无法正常工作?

    mysql - WordPress 查询多值列中的单个值,采用序列化字符串格式

    wordpress - 如何删除?使用 htaccess 从 url

    php - WooCommerce 产品简短描述中的自动文本

    php - 使用php查询数据库

    wordpress - 从YouTube API将数据保存到自定义字段

    html - 在 Woocommerce 的数量输入字段中隐藏 "Quantity"标签

    php - 在 Woocommerce 中隐藏特定产品的特定运输方式

    php - Symfony3-在单个sql查询中更新多个实体