Woocommerce后端中的多选字段

时间:2018-05-02 10:54:50

标签: 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 ) );
    }
}   

1 个答案:

答案 0 :(得分:2)

为多选字段处理变量产品是另一回事,需要进行一些更改才能使其正常工作。我有下面的女佣2个答案:

  1. 第一个产品变体(适合您)
  2. 所有其他产品类型的另一个
  3. 因此,在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文件中。此功能现在可以处理任何类型的产品,包括产品变化。

    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