通过 URL 将免费产品添加到 WooCommerce 自动生成的优惠券

Posted

技术标签:

【中文标题】通过 URL 将免费产品添加到 WooCommerce 自动生成的优惠券【英文标题】:Add free product to WooCommerce auto generated coupon by URL 【发布时间】:2022-01-09 20:37:58 【问题描述】:

感谢@Bhautik 帮助更正了一些功能,以便在应用 URL 时自动生成 WooCommerce 优惠券。帖子在这里 - How to auto generate a coupon in WooCommerce and apply it to the cart?

我现在正尝试向同一功能添加免费产品。我有点让它工作但有错误。如果有人可以提供一些建议或帮助,将不胜感激。请看下面的截图。提前致谢。

https://i.imgur.com/gJVyW5O.gif

https://i.imgur.com/tzxyM83.gif

https://i.imgur.com/OIBbHlS.gif

这是我目前的代码。

function coupon_exists( $coupon_code ) 
    global $wpdb;
    $sql = $wpdb->prepare( "SELECT post_name FROM $wpdb->posts WHERE post_type = 'shop_coupon' AND post_name = '%s'", $coupon_code );
    $coupon_codes = $wpdb->get_results($sql);

    if ( count( $coupon_codes ) > 0 ) 
        return true;
     else 
        return false;
    

// Generate coupon
function generate_coupon($coupon_generated) 
    
    // Set some coupon data by default
    $date_expires     = date('Y-m-d H:i:s', strtotime('+24 hours'));
    $discount_type    = 'percent';
    $coupon_amount    = '100';

    $coupon = new WC_Coupon();
    $coupon->set_code($coupon_generated);
    $coupon->set_discount_type($discount_type);
    $coupon->set_amount($coupon_amount);
    $coupon->set_date_expires($date_expires);
    $coupon->set_individual_use(true);
    $coupon->set_product_ids (array(74)); 
    $coupon->set_usage_limit(1);    
    $coupon->set_limit_usage_to_x_items(1);
    $coupon->set_usage_limit_per_user(1);
    $coupon->set_exclude_sale_items(true);
    $coupon->set_minimum_amount('100');
    $coupon->set_maximum_amount('150');

    $coupon->save();

    return $coupon_generated;


// Add coupon and product to cart
function generate_coupon_add_product_to_cart ( $cart ) 
    
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;
    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;
    
    $coupon_code = ( isset( $_GET['coupon-code'] ) && $_GET['coupon-code'] != '' ) ? $_GET['coupon-code'] : '' ;

    if( $coupon_code == '' )
        return;
    

    $applied_coupons = $cart->get_applied_coupons();

    if( empty( $applied_coupons ) || ! in_array( $coupon_code, $applied_coupons ) )
        if ( !coupon_exists( $coupon_code ) ) 
            generate_coupon( $coupon_code );
         
     
    
    // I'm having trouble with the code below this point
    $free_product_id  = 74;
    $free_product_in_cart = false;
    
    foreach( $cart->get_cart() as $cart_item_key => $cart_item ) 
        $cart_count = $cart->get_cart_contents_count();
        $free_product = $cart_item['data'];
     if ( $free_product->get_id() == $free_product_id ) 
        $free_product_key = $cart_item_key; 
        $regular_price = $cart_item['data']->get_regular_price();
        $cart_item['data']->set_price(0);

        $free_product_in_cart = true;  
       
    

    if ( !in_array($coupon_code, $applied_coupons) && !$free_product_in_cart )
        $cart->add_to_cart( $free_product_id, 1 );
        $cart->add_discount( $coupon_code );
        wc_add_notice( sprintf(__('<strong>FREE</strong> product valued at %s has been added to your cart.', 'woocommerce'),'<strong>' . get_woocommerce_currency_symbol() . $regular_price . '</strong>'), 'notice');
    
    // Removing coupon
    elseif( !in_array($coupon_code, $applied_coupons) && $free_product_in_cart )
        $cart->remove_coupon( $coupon_code );
        wc_add_notice( __("Coupon removed"), 'notice' );
    
    // Removing free product if it is the only one left in cart
    elseif ( $free_product_in_cart && $cart_count <= 1 )
        $cart->remove_cart_item( $free_product_key );
        wc_add_notice( __("Product removed"), 'notice' );
    

add_action('woocommerce_before_calculate_totals', 'generate_coupon_add_product_to_cart');```

【问题讨论】:

【参考方案1】:

我现在已经完成了这项工作,但仅通过 URL 添加产品,我无法通过使用 php 添加产品来使其正常工作。所以现在产品和优惠券都是用这种方法添加的。

www.mytheme.com/cart/?add-to-cart=74&coupon-code=mycoupon

检查此答案后,我创建了一个新的用户会话,但尚未取消设置,因为转到结帐页面时价格显示不正确。

GET a coupon code via URL and apply it in WooCommerce Checkout page

我添加了带有“woocommerce_before_cart_table”挂钩的优惠券,并使用了“woocommerce_before_calculate_totals”挂钩来显示价格和横幅。

代码现在根据 URL 输入在 WooCommerce 中生成一个 24 小时有效期的新优惠券,将免费产品添加到购物车,并将显示的价格设置为“免费”。迷你购物车不反映免费产品价格,但如果迷你购物车被编辑,则会这样做。据我所知,这似乎是一个很长一段时间以来的错误。

我对 PHP 不是很熟悉,所以如果有人有任何改进建议,请随时加入。谢谢

    // Check if coupon exists
function coupon_exists( $coupon_code ) 
    global $wpdb;

    $sql = $wpdb->prepare( "SELECT post_name FROM $wpdb->posts WHERE post_type = 'shop_coupon' AND post_name = '%s'", $coupon_code );

    $coupon_codes = $wpdb->get_results($sql);

    if ( count( $coupon_codes ) > 0 ) 
        return true;
     else 
        return false;
    

// Generate coupon
function generate_coupon($coupon_generated) 
    
    // Set some coupon data by default
    $date_expires     = date('Y-m-d H:i:s', strtotime('+24 hours'));
    $discount_type    = 'percent'; // 'store_credit' doesn't exist
    $coupon_amount    = '100';

    $coupon = new WC_Coupon();
    $coupon->set_code($coupon_generated);
    $coupon->set_discount_type($discount_type);
    $coupon->set_amount($coupon_amount);
    $coupon->set_date_expires($date_expires);
    $coupon->set_individual_use(true);
    $coupon->set_product_ids (array(74)); 
    $coupon->set_usage_limit(1);    
    $coupon->set_limit_usage_to_x_items(1);
    $coupon->set_usage_limit_per_user(1);
    $coupon->set_exclude_sale_items(true);
    $coupon->set_minimum_amount('100');
    //$coupon->set_maximum_amount('150');

    $coupon->save();

    return $coupon_generated;


// Generate coupon and set session
function ts_get_custom_coupon_code_to_session() 
    if( isset( $_GET[ 'coupon-code' ] ) ) 
        // Ensure that customer session is started
        if( !WC()->session->has_session() )
            WC()->session->set_customer_session_cookie(true);
        
    $coupon_code = ( isset( $_GET['coupon-code'] ) && $_GET['coupon-code'] != '' ) ? $_GET['coupon-code'] : '' ;
    
    if( $coupon_code == '' )
        return;
    
    if( empty( $applied_coupons ) || ! in_array( $coupon_code, $applied_coupons ) )
        if ( !coupon_exists( $coupon_code ) ) 
            generate_coupon( $coupon_code );
         
       
        // Check and register coupon code in a custom session variable
        $coupon_code = WC()->session->get( 'coupon-code' );
        if( empty( $coupon_code ) && isset( $_GET[ 'coupon-code' ] ) ) 
            $coupon_code = esc_attr( $_GET[ 'coupon-code' ] );
            WC()->session->set( 'coupon-code', $coupon_code ); // Set the coupon code in session
        
    

add_action( 'init', 'ts_get_custom_coupon_code_to_session' );

// Apply the coupon to the cart
function ts_apply_discount_to_cart() 
    // Set coupon code
    $coupon_code      = WC()->session->get( 'coupon-code' );
    $applied_coupons  = WC()->session->get('applied_coupons');

    $free_product_id  = 74;
    $minimum_amount   = 100;
    
    foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) 
        $cart_subtotal += $cart_item['line_total'] + $cart_item['line_tax'];
        $free_product = $cart_item['data']->get_id();
     
    
    if ( ! empty( $coupon_code ) && ! WC()->cart->has_discount($coupon_code) && $free_product == $free_product_id && $cart_subtotal >= $minimum_amount)
        WC()->cart->apply_coupon( $coupon_code ); // apply the coupon discount
        //WC()->session->__unset( 'coupon-code' ); // remove coupon code from session - have disabled this as it caused the price of the free prouct to display as full on the ckecout page
    

add_action( 'woocommerce_before_cart_table', 'ts_apply_discount_to_cart', 10, 0 );


// Change cart items prices (and order items prices)
function set_free_prod_cart_item_prices ( $cart ) 
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;
    
    $coupon_code      = WC()->session->get( 'coupon-code' );
    $applied_coupons  = WC()->session->get('applied_coupons');
    
    $free_product_id  = 74;
    $minimum_amount   = 100;
    
    foreach( $cart->get_cart() as $cart_item_key => $cart_item )       
        $free_product = $cart_item['data']->get_id();
        $regular_price = $cart_item['data']->get_regular_price();
        $prod_name = $cart_item ['data']->post->post_title;
        $cart_subtotal += $cart_item['line_total'] + $cart_item['line_tax'];
     if ( $applied_coupons = $coupon_code && $free_product == $free_product_id && $cart_item['quantity'] == 1 && $cart_subtotal >= $minimum_amount ) 
        $cart_item['data']->set_price(0); // Set free product price to zero
      
    elseif ( $free_product == $free_product_id && $cart_item['quantity'] > 2 || !$cart->has_discount()) 
        $cart_item['data']->get_regular_price();
         
    
    if ($applied_coupons = $coupon_code && $free_product == $free_product_id && is_cart() && $cart_subtotal >= $minimum_amount ) 
        wc_add_notice( sprintf(__('<strong>FREE</strong> %s valued at %s has been added to your cart.', 'woocommerce'), $prod_name,'<strong>' . get_woocommerce_currency_symbol() . $regular_price . '</strong>'), 'notice');
    

add_action('woocommerce_before_calculate_totals', 'set_free_prod_cart_item_prices', 100, 1 );

// Change price display from $0.00 to FREE
function filter_cart_item_price( $price, $cart_item, $cart_item_key ) 
    $free_product_id  = 74;
    
    if ( $cart_item[ 'data' ]->price == 0 && $cart_item['data']->get_id() == $free_product_id ) 
        $price = __( 'FREE', 'textdomain' );
    
    return $price;

add_filter( 'woocommerce_cart_item_price', 'filter_cart_item_price', 10, 3 );

// Prevent page refresh for adding item to cart using add-to-cart url
function resolve_dupes_add_to_cart_redirect($url = false) 
  if(!empty($url))  
  return $url; 
  
  return get_home_url() .add_query_arg(array(), remove_query_arg('add-to-cart'));

add_action('woocommerce_add_to_cart_redirect', 'resolve_dupes_add_to_cart_redirect');

// Remonve redirect to cart banner on cart and checkout pages
function misha_remove_add_to_cart_message( $message )
    if( is_cart() || is_checkout() ) 
    return '';
        

add_filter( 'wc_add_to_cart_message_html', 'misha_remove_add_to_cart_message' );

【讨论】:

以上是关于通过 URL 将免费产品添加到 WooCommerce 自动生成的优惠券的主要内容,如果未能解决你的问题,请参考以下文章

在 Shopify 中,如何通过 url 将不同数量的多个产品添加到购物车

如何通过 API 将 URL 或 Zoom 会议 ID 添加到 Google 日历

WooCommerce 使用 add_to_cart 添加产品

将多个产品添加到 Woocommerce 购物篮脚本

在 Woocommerce 购物车中自动添加或删除免费产品

除某些 WooCommerce 产品类别外,自动将产品添加到购物车