This script reads the cart, sees if the two products are present and adds another one different from the others. The addition of the quantity of the new product depends on the quantities of the others.
This script seems to work but the page loading suffers a display problem, as the scrollbar disappears and it is therefore not possible to navigate well, if the free product is added by the add_to_cart script
add_action( 'template_redirect', 'pro_gift', 9);
function pro_gift() {
if (is_cart()) {
if ( sizeof( WC()->cart->get_cart() ) > 0) {
$items_gift = WC()->cart->get_cart();
$product_id = 33103;
$product_ids = 33093;
$product_id_gift = 34462;
$product_id_size = 0;
$product_ids_size = 0;
$product_id_gift_size = 0;
$product_id_gift_item = '';
foreach($items_gift as $item_gift_k => $item_gift_v) {
if ($item_gift_v['product_id'] == $product_id ) {
$product_id_size = $item_gift_v['quantity'];
}
if ($item_gift_v['product_id'] == $product_ids ) {
$product_ids_size = $item_gift_v['quantity'];
}
if ($item_gift_v['product_id'] == $product_id_gift ) {
$product_id_gift_size = $item_gift_v['quantity'];
$product_id_gift_item = $item_gift_k;
}
}
//echo '<!-- addo= p' .$product_gift. ' i' .$product_id_size. ' ids' .$product_ids_size. ' ig' .$product_id_gift_size. ' -->';
if ($product_id_size > 0 && $product_ids_size > 0) {
$product_gift = min($product_id_size, $product_ids_size);
if ($product_gift > 0 && $product_id_gift_size == 0) {
WC()->cart->add_to_cart( $product_id_gift, $product_gift);
}
elseif ($product_gift > 0 && $product_id_gift_size > 0 && $product_id_gift_size < $product_gift) {
WC()->cart->set_quantity($product_id_gift_item, $product_gift);
}
}
}
}
}
In addition to the script above I then go to make the new products added free based on the quantity of those requested
add_action( 'woocommerce_cart_calculate_fees', 'pro_gift_d', 10 );
function pro_gift_d() {
if (is_cart() || is_checkout()) {
if ( sizeof( WC()->cart->get_cart() ) > 0) {
$items_gift = WC()->cart->get_cart();
$product_id = 33103;
$product_ids = 33093;
$product_id_gift = 34462;
$product_id_size = 0;
$product_ids_size = 0;
$product_id_gift_size = 0;
$product_gift_line = 0;
foreach($items_gift as $item_gift_k => $item_gift_v) {
if ($item_gift_v['product_id'] == $product_id ) {
$product_id_size = $item_gift_v['quantity'];
}
if ($item_gift_v['product_id'] == $product_ids ) {
$product_ids_size = $item_gift_v['quantity'];
}
if ($item_gift_v['product_id'] == $product_id_gift ) {
$product_id_gift_size = $item_gift_v['quantity'];
$product_gift_line = $item_gift_v['line_total'] / $product_id_gift_size;
}
}
if ($product_id_size > 0 && $product_ids_size > 0 && $product_id_gift_size > 0) {
$product_gift = min($product_id_size, $product_ids_size);
$product_gift_discount = $product_gift_line * $product_gift;
WC()->cart->add_fee( __('PROMO PRODOTTO GRATUITO', 'woocommerce'), -$product_gift_discount);
}
}
}
}
These scripts seem to work well, it adds a product to the cart if there are two other products and it does so based on their quantity. But as already said, if the free product is not already present in the cart and therefore it is added with this part of the script "WC()->cart->add_to_cart( $product_id_gift, $product_gift);", the scrollbar disappears and it is not possible to navigate.
What did I do wrong? And how could the code be improved?
Move your logic to a later, safer hook like woocommerce_before_calculate_totals
add_action('woocommerce_before_calculate_totals', 'add_free_gift_product');
function add_free_gift_product($cart) {
if (is_admin() || !is_cart() || did_action('woocommerce_before_calculate_totals') > 1) return;
$id1 = 33103;
$id2 = 33093;
$gift_id = 34462;
$qty1 = $qty2 = $gift_qty = 0;
$gift_key = '';
foreach ($cart->get_cart() as $key => $item) {
if ($item['product_id'] == $id1) $qty1 = $item['quantity'];
if ($item['product_id'] == $id2) $qty2 = $item['quantity'];
if ($item['product_id'] == $gift_id) {
$gift_qty = $item['quantity'];
$gift_key = $key;
}
}
$add_qty = min($qty1, $qty2);
if ($add_qty > 0 && $gift_qty < $add_qty) {
if ($gift_qty == 0) $cart->add_to_cart($gift_id, $add_qty);
else $cart->set_quantity($gift_key, $add_qty);
}
}