WooCommerce自定义产品属性价格开发
本篇文章主要介绍WooCommerce实现如下图的功能,让用户选择自定义属性,并且更新原产品价格。
主要代码如下:
① 添加js、css文件
add_action('wp_enqueue_scripts', function () {
if (is_product()) {
wp_enqueue_script('custom-attribute-js', plugins_url('/js/custom-attribute.js', __FILE__), array('jquery'), '0.0.1', true);
}
wp_register_style('custom-attribute-css', plugin_dir_url(__FILE__) . 'css/custom-attribute.css', false, '0.0.1');
wp_enqueue_style('custom-attribute-css');
});
custom-attribute.css代码
.woocommerce div.product div.images .flex-control-thumbs img {
max-height: 128px;
}
.wc-block-components-product-image img {
max-height: 240px;
}
.custom-attribute-size-field, .custom-attribute-customized-field {
margin-bottom: 20px;
}
.custom-attribute-size-field label, .custom-attribute-customized-field label {
font-weight: bolder;
}
.custom-attribute-size-field .custom-attribute-field-ul, .custom-attribute-customized-field .custom-attribute-field-ul {
list-style: none !important;
padding: 0 !important;
margin: 5px 0 !important;
}
.custom-attribute-size-field .custom-attribute-field-li, .custom-attribute-customized-field .custom-attribute-field-li {
list-style: none !important;
display: inline-block !important;
padding: 5px 15px;
border: 1px solid #E6E6E6;
border-radius: 2px;
margin-right: 5px;
font-size: 14px;
background-color: #ffffff;
color: #000000;
cursor: pointer;
}
.custom-attribute-size-field .custom-attribute-field-li span, .custom-attribute-customized-field .custom-attribute-field-li span {
color: grey;
}
.custom-attribute-size-field .custom-attribute-field-li.active, .custom-attribute-customized-field .custom-attribute-field-li.active {
background-color: #000000 !important;
color: #ffffff !important;
border: 1px solid #000000 !important;
}
.custom-attribute-size-field .custom-attribute-field-li.active span, .custom-attribute-customized-field .custom-attribute-field-li.active span {
color: #ffffff !important;
}
.custom-attribute-customized-field .custom-attribute-customized-text {
width: 100%;
border: 1px solid #E9E9E9;
margin-top: 10px;
outline: none !important;
padding: 10px;
box-sizing: border-box;
display: none;
}
custom-attribute.js代码
jQuery(document).ready(function ($) {
$('.custom-attribute-size-field-ul .custom-attribute-field-li').click(function (){
$('.custom-attribute-size-field-ul .custom-attribute-field-li').removeClass('active');
$(this).addClass('active');
$('#custom-attribute-size').val($(this).attr('data-value'));
});
$('.custom-attribute-customized-field-ul .custom-attribute-field-li').click(function (){
$('.custom-attribute-customized-field-ul .custom-attribute-field-li').removeClass('active');
$(this).addClass('active');
$('#custom-attribute-customized').val($(this).attr('data-value'));
let type = $(this).attr('data-type');
if (type == 'customized'){
$('#custom-attribute-customized-text').show();
} else {
$('#custom-attribute-customized-text').hide();
}
});
});
② 在产品页添加自定义表单
function ca_woocommerce_before_add_to_cart_button()
{
$post_id = ca_get_post_id();
if (empty($post_id)) {
return;
}
$custom_attribute_data = get_custom_attribute_data($post_id);
if (empty($custom_attribute_data)) {
return;
}
$currency_symbol = get_woocommerce_currency_symbol();
// 显示尺寸
if (!empty($custom_attribute_data['size'])) {
$sizes = json_decode($custom_attribute_data['size'], true);
if (!empty($sizes)) {
$first_value = $sizes[0]['name'];
?>
<div class="custom-attribute-size-field">
<input type="hidden" id="custom-attribute-size" name="custom_attribute_size" value="<?php echo esc_attr($first_value);?>">
<label><?php _e('Size:', 'custom-attribute'); ?></label>
<br>
<ul class="custom-attribute-field-ul custom-attribute-size-field-ul">
<?php
foreach ($sizes as $k => $size) {
?>
<li class="custom-attribute-field-li <?php if ($k == 0){echo 'active';}?>" data-value="<?php echo esc_attr($size['name']); ?>">
<?php
echo esc_html($size['name']);
if (!empty($size['price']) && $size['price'] > 0) {
echo '<span>(+ ' . esc_html($currency_symbol) . ' ' . $size['price'] . ')</span>';
}
?>
</li>
<?php
}
?>
</ul>
</div>
<?php
}
}
// 显示自定义属性
if (!empty($custom_attribute_data['customized'])) {
$customizeds = json_decode($custom_attribute_data['customized'], true);
if (!empty($customizeds)) {
$first_value = $customizeds[0]['name'];
?>
<div class="custom-attribute-customized-field">
<input type="hidden" id="custom-attribute-customized" name="custom_attribute_customized" value="<?php echo esc_attr($first_value);?>">
<label><?php _e('Customized:', 'custom-attribute'); ?></label>
<br>
<ul class="custom-attribute-field-ul custom-attribute-customized-field-ul">
<?php
foreach ($customizeds as $k => $customized) {
$type = '';
if (preg_match('/Customized/i', $customized['name'])) {
$type = 'customized';
}
?>
<li class="custom-attribute-field-li <?php if ($k ==0){echo 'active';}?>" data-type="<?php echo esc_attr($type); ?>"
data-value="<?php echo esc_attr($customized['name']); ?>">
<?php
echo esc_html($customized['name']);
if (!empty($customized['price']) && $customized['price'] > 0) {
echo '<span>(+ ' . esc_html($currency_symbol) . ' ' . $customized['price'] . ')</span>';
}
?>
</li>
<?php
}
?>
</ul>
<textarea rows="10" class="custom-attribute-customized-text" id="custom-attribute-customized-text"
name="custom_attribute_customized_text"></textarea>
</div>
<?php
}
}
}
add_action('woocommerce_before_add_to_cart_button', 'ca_woocommerce_before_add_to_cart_button', 60);
③ 保存自定义数据到购物车
function ca_woocommerce_add_cart_item_data($cart_item_data, $product_id, $variation_id)
{
$custom_attribute_size = filter_input(INPUT_POST, 'custom_attribute_size');
if (!empty($custom_attribute_size)) {
$cart_item_data['custom_attribute_size'] = $custom_attribute_size;
}
$custom_attribute_customized = filter_input(INPUT_POST, 'custom_attribute_customized');
if (!empty($custom_attribute_customized)) {
$cart_item_data['custom_attribute_customized'] = $custom_attribute_customized;
$custom_attribute_customized_text = filter_input(INPUT_POST, 'custom_attribute_customized_text');
if (!empty($custom_attribute_customized_text)) {
if (preg_match('/Customized/i', $custom_attribute_customized)) {
$cart_item_data['custom_attribute_customized_text'] = $custom_attribute_customized_text;
} else {
$cart_item_data['custom_attribute_customized_text'] = '';
}
}
}
return $cart_item_data;
}
add_filter('woocommerce_add_cart_item_data', 'ca_woocommerce_add_cart_item_data', 10, 3);
④ 显示自定义数据
function ca_woocommerce_get_item_data($item_data, $cart_item)
{
if (!empty($cart_item['custom_attribute_size'])) {
$item_data[] = array(
'key' => __('Size', 'custom-attribute'),
'value' => wc_clean($cart_item['custom_attribute_size']),
'display' => '',
);
}
if (!empty($cart_item['custom_attribute_customized'])) {
$item_data[] = array(
'key' => __('Customized', 'custom-attribute'),
'value' => wc_clean($cart_item['custom_attribute_customized']),
'display' => '',
);
if (!empty($cart_item['custom_attribute_customized_text'])) {
$item_data[] = array(
'key' => __('Customized Name/Number', 'custom-attribute'),
'value' => wc_clean($cart_item['custom_attribute_customized_text']),
'display' => '',
);
}
}
return $item_data;
}
add_filter('woocommerce_get_item_data', 'ca_woocommerce_get_item_data', 10, 2);
⑤ 保存数据到订单
function ca_woocommerce_checkout_create_order_line_item($item, $cart_item_key, $values, $order)
{
if (!empty($values['custom_attribute_size'])) {
$item->add_meta_data(__('Size', 'custom-attribute'), $values['custom_attribute_size']);
}
if (!empty($values['custom_attribute_customized'])) {
$item->add_meta_data(__('Customized', 'custom-attribute'), $values['custom_attribute_customized']);
if (!empty($values['custom_attribute_customized_text'])) {
$item->add_meta_data(__('Customized Name/Number', 'custom-attribute'), $values['custom_attribute_customized_text']);
}
}
}
add_action('woocommerce_checkout_create_order_line_item', 'ca_woocommerce_checkout_create_order_line_item', 10, 4);
⑥ 修改产品价格
function ca_woocommerce_before_calculate_totals($cart_object)
{
foreach ($cart_object->cart_contents as $key => $value) {
$post_id = $value['product_id'];
$custom_attribute_data = get_custom_attribute_data($post_id);
if (empty($custom_attribute_data)) {
continue;
}
$custom_price = 0;
if (!empty($custom_attribute_data['size']) && !empty($value['custom_attribute_size'])) {
$sizes = json_decode($custom_attribute_data['size'], true);
if (!empty($sizes)) {
foreach ($sizes as $size) {
if (!empty($size['price']) && $size['price'] > 0 && $value['custom_attribute_size'] == $size['name']) {
$custom_price = bcadd($custom_price, $size['price'], 2);
break;
}
}
}
}
if (!empty($custom_attribute_data['customized']) && !empty($value['custom_attribute_customized'])) {
$customizeds = json_decode($custom_attribute_data['customized'], true);
if (!empty($customizeds)) {
foreach ($customizeds as $customized) {
if (!empty($customized['price']) && $customized['price'] > 0 && $value['custom_attribute_customized'] == $customized['name']) {
$custom_price = bcadd($custom_price, $customized['price'], 2);
break;
}
}
}
}
if ($custom_price > 0) {
$item_id = $value['data']->id;
$product = wc_get_product($item_id);
$price = $product->get_price();
// $price = $value['data']->get_price();
$value['data']->set_price(bcadd($price, $custom_price, 2));
}
}
}
add_action('woocommerce_before_calculate_totals', 'ca_woocommerce_before_calculate_totals');
以上就是开发自定义属性插件的核心代码,仅供参考。