当前位置: 首页 > 知识库问答 >
问题:

WooCommerce:如果未填写所有购物车项目自定义字段,则避免签出

牧飞鹏
2023-03-14

我写了一个函数,当每个产品中的附加字段(在购物车中显示)还没有完成(字段仅在购物车中有2个以上的项目时才出现)时,禁用ordering按钮。

function disable_checkout_button_no_shipping() {
    global $woocommerce;
    $quantity = $woocommerce->cart->cart_contents_count;        
 
    if( $quantity > 1 ){
        foreach ( WC()->cart->get_cart() as $cart_item ) {
            $item_name = $cart_item['data']->get_title();
            $notes = $cart_item['notes'];
            printf("[%s]\n",      $notes);

            if ( empty( $notes ) ) {
                remove_action( 'woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20 );
                printf(
                    '<div class="wc-cart-note-warning"><span>Przed złożeniem zamówienia dodaj informację dla kogo jest kartka!</span></div>',
                );
            }
        }
    }
}
add_action( 'woocommerce_proceed_to_checkout', 'disable_checkout_button_no_shipping', 1 );

但它只在浏览器中刷新页面时才起作用。

每次在分配给产品的文本字段中输入一些东西,并且带有order按钮的部分将用Ajax刷新时,我如何使函数刷新?

下面是负责添加注释的代码:

保存在update-cart-item-ajax.js文件名(自定义文件)下的Javascrit代码:

(function($) {
    // $(document).ready(function(){
    $('.prefix-cart-notes').on('change keyup paste', function() {
        $('.cart_totals').block({
            message: null,
            overlayCSS: {
                background: '#fff',
                opacity: 0.6
            }
        });
        var cart_id = $(this).data('cart-id');
        $.ajax({
            type: 'POST',
            url: prefix_vars.ajaxurl,
            data: {
                action: 'prefix_update_cart_notes',
                security: $('#woocommerce-cart-nonce').val(),
                notes: $('#cart_notes_' + cart_id).val(),
                cart_id: cart_id
            },
            success: function(response) {
                $('.cart_totals').unblock();
            }
        })
    });
});

保存在活动主题functions.PHP文件中的PHP代码:

/**
 * Add a text field to each cart item
 */
function prefix_after_cart_item_name( $cart_item, $cart_item_key ) {
    $notes = isset( $cart_item['notes'] ) ? $cart_item['notes'] : '';
    global $woocommerce;
    $quantity = $woocommerce->cart->cart_contents_count;
    if( $quantity > 1 ){
        printf(
            '<div><textarea rows="1"  placeholder="Dla kogo jest kartka?" maxlength="30" class="%s" id="cart_notes_%s" data-cart-id="%s">%s</textarea></div>',
            'prefix-cart-notes',
            $cart_item_key,
            $cart_item_key,
            $notes
        );
    }
}
add_action( 'woocommerce_after_cart_item_name', 'prefix_after_cart_item_name', 10, 2 );

/**
 * Enqueue our JS file
 */
function prefix_enqueue_scripts() {
    //trailingslashit( plugin_dir_url( __FILE__ ) )
    wp_register_script( 'prefix-script', trailingslashit( get_home_url() ) . '/wp-content/themes/boomb_theme/assets/update-cart-item-ajax.js', array( 'jquery-blockui' ), time(), true );
    wp_localize_script(
        'prefix-script',
        'prefix_vars',
        array(
            'ajaxurl' => admin_url( 'admin-ajax.php' )
        )
    );
    wp_enqueue_script( 'prefix-script' );
}
add_action( 'wp_enqueue_scripts', 'prefix_enqueue_scripts' );

/**
 * Update cart item notes
 */
function prefix_update_cart_notes() {
    // Do a nonce check
    if( ! isset( $_POST['security'] ) || ! wp_verify_nonce( $_POST['security'], 'woocommerce-cart' ) ) {
        wp_send_json( array( 'nonce_fail' => 1 ) );
        exit;
    }

    // Save the notes to the cart meta
    $cart = WC()->cart->cart_contents;
    $cart_id = $_POST['cart_id'];
    $notes = $_POST['notes'];
    $cart_item = $cart[$cart_id];
    $cart_item['notes'] = $notes;
    WC()->cart->cart_contents[$cart_id] = $cart_item;
    WC()->cart->set_session();
    wp_send_json( array( 'success' => 1 ) );
    exit;
}
add_action( 'wp_ajax_prefix_update_cart_notes', 'prefix_update_cart_notes' );
add_action( 'wp_ajax_nopriv_prefix_update_cart_notes', 'prefix_update_cart_notes' );

function prefix_checkout_create_order_line_item( $item, $cart_item_key, $values, $order ) {
    if( isset( $values['notes'] ) ) {
        $item->add_meta_data( 'notes', $values['notes'], true );
    }
}
add_action( 'woocommerce_checkout_create_order_line_item', 'prefix_checkout_create_order_line_item', 10, 4 );

共有1个答案

乌骏
2023-03-14

在您的情况下,为了避免签出,可以使用woocommerce_checkout_process专用钩子,如:

add_action( 'woocommerce_checkout_process', 'check_cart_notes_to_disable_checkout' );
function check_cart_notes_to_disable_checkout() {
    foreach ( WC()->cart->get_cart() as $cart_item ) {
        if ( ! isset($cart_item['notes']) || empty($cart_item['notes']) ) {
            $button = '<a href="'. wc_get_cart_url() .'" tabindex="1" class="button wc-forward">'. __("Back to cart", "woocommerce") .'</a>';
            wc_add_notice( $button . __("Przed złożeniem zamówienia dodaj informację dla kogo jest kartka!", "woocommerce"), 'error' );
        }
    }
}

代码放在活动子主题(或活动主题)的functions.php文件中。经过测试并起作用。

 类似资料:
  • 我正在尝试获取WooCommerce产品的自定义字段值,以显示在商店系统的不同页面上。我成功地对单个产品页面执行了此操作,但相同的代码不适用于购物车。 对于单个产品,我在函数中使用了此代码。php,它可以很好地工作: 我为购物车尝试了相同的代码,但这次值没有显示在页面上。我还提到了这个线程(获取自定义属性),将$post更改为$product,但仍然没有输出。。。 有什么建议吗?

  • 问题内容: 我有上面的代码。 如果我在cart_item上运行print_r,我将得到一个多维数组: 我如何只获得product_id? 我试过$ test = 没用 问题答案: 要获取 foreach循环中的每个购物车商品(对于简单产品): 如果是可变产品,请获取 : 或在两种情况下 ( Woocommerce 3+中 的 Object在哪里) : 更新: 循环外使用产品ID 1)打破循环 (仅

  • 我见过很多例子,都是用客户价格将商品添加到WC购物车中,但没有一个是动态添加的。我正在尝试在一个接收POST变量的短代码函数中执行。。。。 这当然会将项目添加到购物车,但价格为零,我意识到我需要以某种方式将此数组保存回WC购物车数据。这种方法是可能的还是只能通过过滤器或操作钩子来完成?如果是这样,我如何保存改变的数组回到购物车的内容,或使其工作添加一个项目与公布的价格?非常感谢任何指导。 感谢do

  • 问题在于当我的客户尝试从购物车中编辑一个产品时。因为所有产品都有相同的ID(我只有一个产品),所以添加到购物车的最后一个产品的元加载到文本字段中。我当前使用产品id检索中的元,但该id与购物车中的所有其他产品相同。有没有其他方法可以在不使用/(如或使用会话)的情况下检索元?