Как приплюсовать к цене значения из кастомных полей woocommerce
Я реализую добавление ингредиентов к товару на сайте wordpress+woocommerce.
При добавлении ингредиентов должна изменяться сумма в соответствии с выбранным ингредиентом, но у меня прибавляется только первый и последний ингредиент. Это сводит меня с ума. Благодарю за любую помощь
add_action( 'woocommerce_product_options_general_product_data', 'add_ingredient_fields' );
function add_ingredient_fields() {
global $product, $post;
echo '<div class="options_group">';
woocommerce_wp_text_input( array(
'id' => 'ingredients',
'label' => __( 'Ингредиенты', 'woocommerce' ),
'placeholder' => __( 'Введите ингредиенты через запятую', 'woocommerce' ),
'description' => __( 'Перечислите ингредиенты, доступные для этого товара.', 'woocommerce' ),
'value' => get_post_meta( $post->ID, 'ingredients', true ),
) );
woocommerce_wp_text_input( array(
'id' => 'ingredient_prices',
'label' => __( 'Стоимость ингредиентов', 'woocommerce' ),
'placeholder' => __( 'Введите стоимость ингредиентов через запятую', 'woocommerce' ),
'description' => __( 'Введите стоимость каждого ингредиента в том же порядке, в котором они перечислены в поле "Ингредиенты".', 'woocommerce' ),
'value' => get_post_meta( $post->ID, 'ingredient_prices', true ),
) );
echo '</div>';
}
add_action( 'woocommerce_process_product_meta', 'save_ingredient_fields' );
function save_ingredient_fields( $post_id ) {
update_post_meta( $post_id, 'ingredients', wp_kses_post( $_POST['ingredients'] ) );
update_post_meta( $post_id, 'ingredient_prices', wp_kses_post( $_POST['ingredient_prices'] ) );
}
add_action( 'woocommerce_add_to_cart_handler', 'custom_add_to_cart_handler', 10, 1 );
function custom_add_to_cart_handler( $product_id ) {
$selected_ingredients = isset( $_POST['ingredients'] ) ? (array) $_POST['ingredients'] : array();
$ingredient_prices = array_filter(array_map('trim', explode( ',', get_post_meta( $product_id, 'ingredient_prices', true ))));
$total_ingredient_cost = 0;
foreach ( $selected_ingredients as $ingredient ) {
$index = array_search( $ingredient, $ingredient_prices );
if ( $index !== false ) {
$total_ingredient_cost += (float) $ingredient_prices[$index];
}
}
$product = wc_get_product( $product_id );
if ( $product && $product->is_type( 'simple' ) ) {
$original_price = (float) $product->get_price();
$new_price = number_format( $original_price + $total_ingredient_cost, 2, '.', '' );
$product->set_price( $new_price );
$product->save();
wc_delete_product_transients( $product_id );
WC()->cart->add_to_cart( $product_id );
} else {
wc_add_notice( __( 'Не удалось добавить товар в корзину.', 'woocommerce' ), 'error' );
}
}
add_action( 'woocommerce_single_product_summary', 'view_ingredients', 61 );
function view_ingredients() {
global $product;
$ingredients = explode( ',', get_post_meta( $product->get_id(), 'ingredients', true ) );
$ingredient_prices = explode( ',', get_post_meta( $product->get_id(), 'ingredient_prices', true ) );
?>
<h3>Выберите ингредиенты:</h3>
<form class="cart-ing" method="post" action="<?php echo esc_url( wc_get_cart_url() ); ?>">
<input type="hidden" name="add-to-cart" value="<?php echo absint( $product->get_id() ); ?>">
<?php
// Проверка наличия ингредиентов
if ( !empty( $ingredients ) ) {
foreach ( $ingredients as $key => $ingredient ) {
?>
<div>
<input type="checkbox" name="ingredients[]" value="<?php echo esc_attr( $ingredient ); ?>" id="<?php echo sanitize_title( $ingredient ); ?>">
<label for="<?php echo sanitize_title( $ingredient ); ?>"><?php echo esc_html( $ingredient ); ?></label>
<?php
if ( isset( $ingredient_prices[ $key ] ) ) {
echo ' (';
echo wc_price( $ingredient_prices[ $key ] );
echo ')';
}
?>
</div>
<?php
}
} else {
// Сообщение о том, что ингредиентов нет
echo '<p>' . __( 'Для этого товара нет доступных ингредиентов.', 'woocommerce' ) . '</p>';
}
?>
<button type="submit" class="button"><?php echo __( 'Добавить в корзину', 'woocommerce' ); ?></button>
<span id="price-element"><?php echo wc_price( $product->get_price() ); ?></span>
</form>
<script>
jQuery(document).ready(function ($) {
var input = $('.cart-ing input[type="checkbox"]');
input.change(function (event) {
var productId = $('input[name="add-to-cart"]').val();
var selectedIngredients = [];
var selectedIngredientPrices = [];
$('.cart-ing input[type="checkbox"]:checked').each(function (index) {
var ingredientId = $(this).val();
var ingredientPrice = parseFloat($(this).data('price'));
selectedIngredients.push(ingredientId);
selectedIngredientPrices.push(ingredientPrice);
});
$.ajax({
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'POST',
data: {
action: 'update_product_price',
product_id: productId,
ingredients: selectedIngredients,
ingredient_prices: selectedIngredientPrices
},
success: function (response) {
console.log('Ответ от сервера:', response);
if (response.success) {
console.log('Новая цена:', response.data.data.price);
// Обновляем цену
$('.price').html(response.data.data.price);
} else {
console.error('Ошибка:', response.data);
}
},
error: function (error) {
console.log('Ошибка при обновлении цены: ', error);
}
});
});
});
</script>
<?php
}
add_action('wp_ajax_update_product_price', 'update_product_price');
add_action('wp_ajax_nopriv_update_product_price', 'update_product_price');
function update_product_price() {
if (!isset($_POST['product_id']) || empty($_POST['product_id'])) {
wp_send_json_error('Invalid product ID.', 400);
wp_die();
}
$product_id = intval($_POST['product_id']); // Sanitize as integer
$product = wc_get_product($product_id);
if (!$product) {
wp_send_json_error('Product not found.', 404);
wp_die();
}
$ingredients = isset($_POST['ingredients']) ? array_map('sanitize_text_field', $_POST['ingredients']) : array();
$ingredient_names = explode(',', get_post_meta($product_id, 'ingredients', true));
$ingredient_prices = explode(',', get_post_meta($product_id, 'ingredient_prices', true));
$new_price = calculate_product_price($product, $ingredients, $ingredient_names, $ingredient_prices);
wp_send_json_success(array(
'data' => array(
'price' => wc_price($new_price) // Форматируем цену
)
));
wp_die();
}
function calculate_product_price($product, $selected_ingredients, $all_ingredients, $ingredient_prices) {
$base_price = $product->get_price();
$new_price = $base_price;
foreach ($selected_ingredients as $ingredient) {
if (($index = array_search($ingredient, $all_ingredients)) !== false && isset($ingredient_prices[$index])) {
$new_price += floatval($ingredient_prices[$index]);
}
}
return $new_price;
}