将所选产品选项和成本保存并显示为WooCommerce中的购物车项目数据

时间:2019-05-10 作者:Edward S Bernstein

我的woocommerce商店里有500多种简单的产品。我将“颜色”选项的成本存储为每个产品中的自定义字段(avp ral paint price),并具有30多个颜色选项的颜色属性。我不想创建可变产品。对于特定产品,所有颜色的成本都相同。

以下代码(挂钩和函数)创建了一个带有颜色选项的下拉菜单,如果未选择任何选项,则会出现错误,并将颜色作为行项目放入购物车中,与点击“添加到购物车”功能时添加的产品相关联。它还在“添加到购物车”按钮上方显示颜色选项的成本。

我搞不清楚的是,如何给带有颜色选项的行项目一个价格,将其添加到购物车中,从而更改购物车总数。我希望在购物车中显示产品的基价,然后显示颜色价格,但我可以接受先将价格添加到产品价格中的价格。我也不知道怎么做。

似乎我只需要cart\\u item\\u数据的正确数组键,但我尝试过的都没有成功。

// Display Select field before add to cart button
add_action( \'woocommerce_before_add_to_cart_button\', \'colors_before_add_to_cart_button\', 0 );
function colors_before_add_to_cart_button() {
    global $product;

    // Only on simple products
    if( ! $product->is_type(\'simple\') ) return;

    // When product colors are available
    if ( $colors = $product->get_attribute( \'color\' ) ) :
    $colors = explode(", ",$colors);

    $required = \'&nbsp;<abbr class="required" title="required">*</abbr></label>\';
    echo \'Standard Powder Coat: $\'. get_post_meta(get_the_ID(), \'avp-ral-paint-price\', true) .\'.00<br>\';
    echo \'<p class="form-row form-row-wide" id="product-color-field">
    <label for="product-color">\' . __(\'Standard Colors:\') . $required . \'</label>
    <select class="product-color" name="product-color" id="product-color">
        <option value="">\' . __("Choose your color") . \'</option>\';

    foreach( $colors as $color ){
        echo \'<option value="\' . $color . \'">\' . $color . \'</option>\';
    }

    echo \'</select>
    </p><br>\';


    endif;
}

add_filter( \'woocommerce_add_to_cart_validation\', \'filter_add_to_cart_validation\', 10, 4 );
function filter_add_to_cart_validation( $passed, $product_id, $quantity, $variation_id = 0 ) {
    $product = wc_get_product($product_id);

    // Only on simple products and When product colors are available
    if( ! $product->is_type(\'simple\') && ! $product->get_attribute( \'color\' ) )
        return $passed;

    if( isset( $_POST[\'product-color\'] ) && empty( $_POST[\'product-color\'] ) ) {
        wc_add_notice( __("Choose A Color (Mill for No Paint)", "woocommerce" ), \'error\' );
        $passed = false;
    }
    return $passed;
}


add_filter( \'woocommerce_add_cart_item_data\', \'add_color_to_cart_item_data\', 10, 3 );
function add_color_to_cart_item_data($cart_item_data, $product_id, $variation_id )
{
    global $product;
    if( isset( $_POST[\'product-color\'] ) )
    {   
        $cart_item_data[\'product-color\'] = esc_attr( $_POST[\'product-color\'] );
    }
    return $cart_item_data;
}

add_filter( \'woocommerce_get_item_data\', \'display_color_on_cart_item\', 10, 2 );
function display_color_on_cart_item( $cart_item_data, $cart_item ) {
    if ( isset( $cart_item[\'product-color\'] ) ){
        $cart_item_data[] = array(
            \'name\' => __(\'Color\'),
            \'value\' => $cart_item[\'product-color\'],
        );
    }
    return $cart_item_data;
}

1 个回复
最合适的回答,由SO网友:LoicTheAztec 整理而成

以下重新访问的代码将购物车项目小计更改为产品+颜色选项的计算总和,并将此更改反映到购物车总计。下单时,它会将选项另存为订单项元数据。

代码:

// Display Select field before add to cart button
add_action( \'woocommerce_before_add_to_cart_button\', \'colors_options_before_add_to_cart_button\' );
function colors_options_before_add_to_cart_button() {
    global $product;

    // Only on simple products
    if( ! $product->is_type(\'simple\') ) return;

    $colors = $product->get_attribute( \'color\' );

    // When product colors are available
    if ( ! empty($colors) && $color_price = $product->get_meta(\'avp-ral-paint-price\') ) :

    $options  = array( \'\' => __("Choose your color") );

    foreach ( (array) explode( \',\', $colors ) as $color ) {
        $options[$color] = $color;
    }

    echo \'<p><strong>\' . __("Standard Powder Coat") . \':</strong> \' . wc_price( $color_price ) .\'</p>\';

    woocommerce_form_field( \'color\', array(
        \'type\'     => \'select\',
        \'class\'    => array(\'form-row-wide product-color\'),
        \'label\'    => __(\'Standard Colors\'),
        \'options\'  => $options,
        \'required\' => true,
    ), \'\' );

    echo \'<br>\';
    endif;
}

// Color option validation
add_filter( \'woocommerce_add_to_cart_validation\', \'filter_add_to_cart_validation\', 10, 2 );
function filter_add_to_cart_validation( $passed, $product_id ) {
    $product = wc_get_product($product_id);

    if( $product->is_type(\'simple\') && $product->get_attribute(\'color\') &&
    $product->get_meta(\'avp-ral-paint-price\') && isset($_POST[\'pa-color\']) && empty($_POST[\'pa-color\']) ) {
        wc_add_notice( __("Choose a Color (Mill for No Paint)", "woocommerce" ), \'error\' );
        $passed = false;
    }
    return $passed;
}

// Add color option as custom cart item data (+ prices)
add_filter( \'woocommerce_add_cart_item_data\', \'add_color_option_as_cart_item_data\', 10, 2 );
function add_color_option_as_cart_item_data( $cart_item_data, $product_id ) {
    if( isset($_POST[\'color\']) && ! empty($_POST[\'color\']) ) {
        $product = wc_get_product($product_id);

        if( $color_price = $product->get_meta(\'avp-ral-paint-price\') ) {
            $cart_item_data[\'color\']         = esc_attr($_POST[\'color\']);
            $cart_item_data[\'color-price\']   = $color_price;
            $cart_item_data[\'default-price\'] = wc_get_price_to_display($product);
            $cart_item_data[\'new-price\']     = $product->get_price() + $color_price;
        }
    }
    return $cart_item_data;
}

// Display select color option on cart item
add_filter( \'woocommerce_get_item_data\', \'display_color_option_on_cart_item\', 10, 2 );
function display_color_option_on_cart_item( $cart_item_data, $cart_item ) {
    if ( isset($cart_item[\'color\']) && isset($cart_item[\'color-price\']) ){
        $cart_item_data[] = array(
            \'name\' => __(\'Color\'),
            \'value\' => $cart_item[\'color\'] . \' (\' . wc_price($cart_item[\'color-price\']) . \')\',
        );
    }
    return $cart_item_data;
}

// Display the default product price (instead of the calculated one)
add_filter( \'woocommerce_cart_item_price\', \'filter_cart_item_price\', 10, 2 );
function filter_cart_item_price( $price, $cart_item ) {
    if ( isset($cart_item[\'color\']) && isset($cart_item[\'default-price\']) ){
        $price = wc_price($cart_item[\'default-price\']);
    }
    return $price;
}

// Customizing cart item price subtotal
add_action( \'woocommerce_before_calculate_totals\', \'set_cart_item_calculated_price\', 10, 1 );
function set_cart_item_calculated_price( $cart ) {
    if ( is_admin() && ! defined( \'DOING_AJAX\' ) )
        return;

    // Required since Woocommerce version 3.2 for cart items properties changes
    if ( did_action( \'woocommerce_before_calculate_totals\' ) >= 2 )
        return;

    // Loop through cart items
    foreach ( $cart->get_cart() as $cart_item ) {
        // Set the new calculated price
        if( isset($cart_item[\'color\']) && isset($cart_item[\'new-price\']) ) {
            $cart_item[\'data\']->set_price( $cart_item[\'new-price\'] );
        }
    }
}

// Save save color option as order item meta data (and display it everywhere)
add_filter( \'woocommerce_checkout_create_order_line_item\', \'save_color_option_as_order_item_meta_data\', 10, 4 );
function save_color_option_as_order_item_meta_data( $item, $cart_item_key, $cart_item, $order ) {
    if( isset($cart_item[\'color\']) && isset($cart_item[\'color-price\']) ) {
        $item->update_meta_data( \'pa_color\', $cart_item[\'color\'] . \' (\' . wc_price($cart_item[\'color-price\']) . \')\' );
    }
    return $item;
}
代码进入函数。活动子主题(或活动主题)的php文件。已测试并正常工作。

<小时>On single Product page:

enter image description here

<人力资源>On cart page (and checkout):

enter image description here

<人力资源>On Orders pages (and email notifications):

enter image description here

相关推荐