我用谷歌搜索了一番,来到这个论坛寻求帮助。我没有看到一个插件可以在我的 Woocommerce 购物车页面上完全实现我想要的功能,但我在这里看到了我想要的两个部分,都尝试过并且它们工作得很好,问题是我的 php 技能为零并且当我试图将它们网格化时,php 检查器变得核化。我希望购物车页面上有一个下拉菜单,客户可以在其中选择几个级别的附加服务以添加到购物车总数中,并且也适用于结账时。 如果他们改变主意并删除购物车中的服务,我也需要删除额外费用。我以为这很简单,但是……不。这是我从专业人士那里拼凑出来的代码。有人可以帮忙吗?我阅读了有关需要正确的 jQuery 事件、Ajax 行为和 WC 调用(?)的详细信息,这绝对是我想进一步研究的内容
// Displaying a checkout "select" custom field in cart page totals section
add_action('woocommerce_cart_totals_before_order_total', 'add_custom_select_field_to_cart');
function add_custom_select_field_to_cart(){
echo '<tr class="installment-section">
<th>'.__("Pantone Color Matching").'</th><td>';
woocommerce_form_field( 'pantone_color_match', array(
'type' => 'select',
'label' => __('Pantone Color Matching?', 'woocommerce'),
'options' => array(
'' => __('Select an option', 'woocommerce'),
'stockcolors' => __('Stock Colors (No PMS)', 'woocommerce'),
'pantonevolume' => __('PMS Matches over 250pcs (FREE)', 'woocommerce'),
'pantone1' => __('1-PMS Match ($15.00)', 'woocommerce'),
'pantone2' => __('2-PMS Matches ($28.00)', 'woocommerce'),
'pantone3' => __('3-PMS Matches ($42.00)', 'woocommerce'),
'pantone4' => __('4-PMS Matches ($56.00)', 'woocommerce'),
'pantone5' => __('5-PMS Matches ($70.00)', 'woocommerce'),
'pantone6' => __('6-PMS Matches ($84.00)', 'woocommerce'),
),
'required' => true,
'class' => array('form-row-wide'),
'clear' => true),
), WC()->session->get('pantone_color_match') ? 'stockcolors' : 'pantone6');
echo '<div class="tooltip">?
<span class="tooltiptext">'.__("Select Stock or Pantone Matching for print colors").'</span>
</div></td>';
}
// jQuery :: Ajax script
add_action( 'wp_footer', 'pantone_color_match_js_script' );
function pantone_color_match_js_script() {
// On Order received page, remove the wc session variable if it exist
if ( is_wc_endpoint_url('order-received')
&& WC()->session->__isset('pantone_color_match') ) :
WC()->session->__unset('pantone_color_match');
// On Cart page: jQuert script
elseif ( is_cart() ) :
?>
<script type="text/javascript">
jQuery( function($){
if (typeof woocommerce_params === 'undefined')
return false;
var c = 'input[name=pantone_color_match]';
$(document.body).on( 'click change', c, function(){
console.log(selected); // just for testing | TO BE REMOVED;
var fee = $(c).is(':checked') ? '1' : '';
$.ajax({
type: 'POST',
url: woocommerce_params.ajax_url,
data: {
'action': 'pantone_color_match',
'pantone_color_match': fee,
},
success: function (response) {
setTimeout(function(){
$(document.body).trigger('added_to_cart');
}, 500);
},
});
});
});
</script>
<?php
endif;
}
// Get Ajax request and saving to WC session
add_action( 'wp_ajax_pantone_color_match', 'pantone_color_match_ajax_receiver' );
add_action( 'wp_ajax_nopriv_pantone_color_match', 'pantone_color_match_ajax_receiver' );
function pantone_color_match_ajax_receiver() {
if ( isset($_POST['pantone_color_match']) ) {
$priority_fee = $_POST['pantone_color_match'] ? stockcolors : pantone6;
// Set to a WC Session variable
WC()->session->set('pantone_color_match', $pantone_color_match );
echo $pantone_color_match ? '1' : '0';
die();
}
}
// Add a custom calculated fee conditionally
add_action('woocommerce_cart_calculate_fees', 'add_pantone_color_match_fee');
function add_pantone_color_match_fee() {
if ( is_admin() && !defined('DOING_AJAX') ) {
return; // Do not add the fee when in the admin area
}
// Only on checkout page
if( ! ( is_checkout() && ! is_wc_endpoint_url() ) ) {
return;
}
// Get 'pantone_color_match' WooCommerce Session variable
$pantone_color_match = WC()->session->get('pantone_color_match' );
if (isset($spantone_color_match) && ! in_array( $spantone_color_match, array('stockcolors', 'pantonevolume') ) ) {
$pantone1 = 15.00,
$pantone2 = 28.00,
$pantone3 = 42.00,
$pantone4 = 56.00,
$pantone5 = 70.00,
$pantone6 = 84.00;
WC()->cart->add_fee( __('1-PMS Match ($15.00)', 'woocommerce'), $pantone1),
('2-PMS Matches ($28.00)', 'woocommerce'), $pantone2),
('3-PMS Matches ($42.00)', 'woocommerce'), $pantone3),
('4-PMS Matches ($56.00)', 'woocommerce'), $pantone4),
('5-PMS Matches ($70.00)', 'woocommerce'), $pantone5),
('6-PMS Matches ($84.00)', 'woocommerce'), $pantone6);
}
下面是向 WooCommerce 购物车页面添加下拉菜单的正确代码。这将允许用户选择附加服务,并且额外费用将应用于购物车和结帐页面。如果他们取消选择某项服务,费用将相应取消。我已经测试过了,它按预期工作。
add_action('woocommerce_cart_totals_before_order_total', 'add_custom_select_field_to_cart');
function add_custom_select_field_to_cart() {
$selected_option = WC()->session->get('pantone_color_match', '');
echo '<tr class="installment-section">
<th>'.__("Pantone Color Matching").'</th><td>';
woocommerce_form_field('pantone_color_match', array(
'type' => 'select',
'label' => __('Pantone Color Matching?', 'woocommerce'),
'options' => array(
'' => __('Select an option', 'woocommerce'),
'stockcolors' => __('Stock Colors (No PMS)', 'woocommerce'),
'pantonevolume' => __('PMS Matches over 250pcs (FREE)', 'woocommerce'),
'pantone1' => __('1-PMS Match ($15.00)', 'woocommerce'),
'pantone2' => __('2-PMS Matches ($28.00)', 'woocommerce'),
'pantone3' => __('3-PMS Matches ($42.00)', 'woocommerce'),
'pantone4' => __('4-PMS Matches ($56.00)', 'woocommerce'),
'pantone5' => __('5-PMS Matches ($70.00)', 'woocommerce'),
'pantone6' => __('6-PMS Matches ($84.00)', 'woocommerce'),
),
'required' => true,
'class' => array('form-row-wide'),
'clear' => true
), $selected_option);
echo '<div class="tooltip">?
<span class="tooltiptext">'.__("Select Stock or Pantone Matching for print colors").'</span>
</div></td></tr>';
}
add_action('wp_footer', 'update_cart_on_dropdown_change');
function update_cart_on_dropdown_change() {
if (is_cart()) :
?>
<script type="text/javascript">
jQuery(function($) {
// Ensure that WooCommerce parameters are defined
if (typeof wc_cart_fragments_params === 'undefined') {
console.error('WooCommerce parameters not found.');
return;
}
// Event handler for dropdown change
$(document.body).on('change', 'select[name=pantone_color_match]', function() {
var selectedOption = $(this).val();
$.ajax({
type: 'POST',
url: wc_cart_fragments_params.ajax_url,
data: {
action: 'pantone_color_match',
pantone_color_match: selectedOption
},
success: function(response) {
console.log('AJAX success:', response); // Debugging line
// Trigger the cart update
$(".woocommerce-cart-form").submit();
},
error: function(xhr, status, error) {
console.error('AJAX error:', status, error); // Debugging line
}
});
});
});
</script>
<?php
endif;
}
add_action('wp_ajax_pantone_color_match', 'pantone_color_match_ajax_receiver');
add_action('wp_ajax_nopriv_pantone_color_match', 'pantone_color_match_ajax_receiver');
function pantone_color_match_ajax_receiver() {
if (isset($_POST['pantone_color_match'])) {
$pantone_color_match = sanitize_text_field($_POST['pantone_color_match']);
$options = array(
'' => __('Select an option', 'woocommerce'),
'stockcolors' => __('Stock Colors (No PMS)', 'woocommerce'),
'pantonevolume' => __('PMS Matches over 250pcs (FREE)', 'woocommerce'),
'pantone1' => __('1-PMS Match ($15.00)', 'woocommerce'),
'pantone2' => __('2-PMS Matches ($28.00)', 'woocommerce'),
'pantone3' => __('3-PMS Matches ($42.00)', 'woocommerce'),
'pantone4' => __('4-PMS Matches ($56.00)', 'woocommerce'),
'pantone5' => __('5-PMS Matches ($70.00)', 'woocommerce'),
'pantone6' => __('6-PMS Matches ($84.00)', 'woocommerce'),
);
$selected_label = $options[$pantone_color_match];
WC()->session->set('pantone_color_match_label', $selected_label);
WC()->session->set('pantone_color_match', $pantone_color_match);
// Update the cart
WC()->cart->calculate_totals();
// Optionally return data
wp_send_json_success(array('status' => 'success', 'selected_option' => $pantone_color_match, 'selected_label' => $selected_label));
} else {
wp_send_json_error(array('status' => 'error', 'message' => 'No option selected.'));
}
wp_die(); // Ensure to terminate properly
}
add_action('woocommerce_cart_calculate_fees', 'add_pantone_color_match_fee');
function add_pantone_color_match_fee() {
if (is_admin() && !defined('DOING_AJAX')) {
return; // Do not add the fee when in the admin area
}
// Only add the fee on the cart page or checkout
if (!is_cart() && !is_checkout()) {
return;
}
$pantone_color_match = WC()->session->get('pantone_color_match', '');
$pantone_color_match_label = WC()->session->get('pantone_color_match_label', '');
$fees = array(
'stockcolors' => 0,
'pantonevolume' =>0,
'pantone1' => 15.00,
'pantone2' => 28.00,
'pantone3' => 42.00,
'pantone4' => 56.00,
'pantone5' => 70.00,
'pantone6' => 84.00,
);
if (array_key_exists($pantone_color_match, $fees)) {
$fee_amount = $fees[$pantone_color_match];
WC()->cart->add_fee(__('Pantone Color Matching:'.$pantone_color_match_label, 'woocommerce'), $fee_amount);
}
}
function display_text_instead_of_fee_amount_in_cart_totals($fee_html, $fee) {
$pantone_color_match_label = WC()->session->get('pantone_color_match_label', '');
$fee_html = $pantone_color_match_label;
return $fee_html;
}
add_filter('woocommerce_cart_totals_fee_html', 'display_text_instead_of_fee_amount_in_cart_totals', 10, 2);
add_action('woocommerce_add_order_meta', 'add_pantone_color_match_order_meta', 10, 2);
function add_pantone_color_match_order_meta($order_id, $cart) {
$pantone_color_match = WC()->session->get('pantone_color_match', '');
$pantone_color_match_label = WC()->session->get('pantone_color_match_label', '');
$fees = array(
'stockcolors' => 0,
'pantonevolume' => 0,
'pantone1' => 15.00,
'pantone2' => 28.00,
'pantone3' => 42.00,
'pantone4' => 56.00,
'pantone5' => 70.00,
'pantone6' => 84.00,
);
$fee_amount = $fees[$pantone_color_match];
if (!empty($pantone_color_match)) {
update_post_meta($order_id, '_pantone_color_match', $pantone_color_match);
update_post_meta($order_id, '_pantone_color_match_label', $pantone_color_match_label);
update_post_meta($order_id, '_pantone_color_match_fee', $fee_amount);
}
}
add_action('woocommerce_order_item_meta', 'add_pantone_color_match_order_item_meta', 10, 2);
function add_pantone_color_match_order_item_meta($item_id, $item) {
$order_id = $item->get_order_id();
$pantone_color_match_label = get_post_meta($order_id, '_pantone_color_match_label', true);
$pantone_color_match_fee = get_post_meta($order_id, '_pantone_color_match_fee', true);
if (!empty($pantone_color_match_label)) {
$item->update_meta_data('_pantone_color_match_label', $pantone_color_match_label);
$item->update_meta_data('_pantone_color_match_fee', $pantone_color_match_fee);
}
}