php - Woocommerce - 第二个 T&C 复选框在未选中时不会阻止结账

标签 php wordpress checkbox woocommerce hook

我有一个特殊的复选框,仅当客户购买两种特定产品之一时才需要放置。下面的代码查找这些product_id,如果找到,则在常规条款和条件复选框旁边显示附加条款和条件框。虽然这部分正在工作,但即使未选中该框,结帐仍然会完成,所以我猜测问题出在 aym_not_approved_amb_terms() 函数内,但我似乎无法弄清楚是什么这个问题是。

add_action( 'woocommerce_after_checkout_form', 'aym_add_ambassador_terms_box' );
function aym_add_ambassador_terms_box() {
    // set product IDs:
    $product_ids = array( 17558, 17563 );
    $bool = false;
    foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
        $item = $cart_item['data'];
        if ( in_array( $item->id, $product_ids ) )
            $bool = true;
    }
    // If product IDs detected
    if ($bool)
        // add ambassador terms checkbox
            add_action('woocommerce_review_order_after_order_total', 'aym_add_checkout_tickbox' );

            function aym_add_checkout_tickbox() {
        echo '<script>console.log("checkbox")</script>';

                echo '<p class="form-row-wide terms">';
                echo '<input type="checkbox" class="input-checkbox" name="amb-terms-check" id="amb-terms-check" />';
                echo '<label for="amb-terms-check" class="checkbox">I accept Ambassador terms and Conditions</label>';
                echo '</p>';

            }

            // Show notice if customer does not tick

            add_action('woocommerce_checkout_process', 'aym_not_approved_amb_terms');

            function aym_not_approved_amb_terms() {
                if ( ! $_POST['amb-terms-check'] )
                    wc_add_notice( __( 'Please agree to the Ambassador Terms and Conditions' ), 'error' );
            }

}

预期行为:如果未选中该框,页面将滚动回错误消息区域并显示消息“请同意大使条款和条件”。也许我没有为 aym_not_approved_amb_terms 函数使用正确的钩子(Hook)...?

最佳答案

由于您的验证位于仅在加载表单后才加载的条件内,因此在实际验证表单时,您的验证回调不存在。

因此,我们要做的就是从条件检查内部解开 add_action() 调用,并将条件检查放入回调中。现在,这有点意味着我们必须检查购物车两次,我认为必须有一种更有效的方法来做到这一点,但我考虑在添加商品时在购物车中添加一个标志,但是购物车类 magic __get() 方法现在将阻止 $cart->my_flag 返回任何有用的值。所以,我们现在只检查购物车两次。

由于我们将检查购物车两次,因此我将您的条件推断为我们可以重用的函数。

function aym_is_item_in_cart() {

    $matching_product_ids = array( 17558, 17563 );

    $bool = false;
    foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
        if ( in_array( $cart_item['product_id'], $matching_product_ids ) ) {
            $bool = true;
        }
    }
    return $bool;
}

然后我们添加复选框。在 WooCommerce 3.0 中,我发现了 issue添加到 woocommerce_review_order_after_order_total Hook 时,该字段重复,因此我将其添加到 woocommerce_checkout_after_customer_details 中。请注意我总是如何将回调添加到此 Hook ,但复选框位于条件内部。另请注意,我使用内置的 woocommerce_form_field() 辅助函数来创建表单字段,而不是通过 JavaScript 添加它。

// add ambassador terms checkbox
add_action( 'woocommerce_checkout_order_review', 'aym_maybe_add_ambassador_terms_box', 5 );

function aym_maybe_add_ambassador_terms_box() {

    // If product IDs detected
    if ( aym_is_item_in_cart() ) {

    $checkout = WC()->checkout();

        $field = array(
            'type'              => 'checkbox',
            'label'             => __( 'I accept Ambassador terms and Conditions', 'your-plugin' ),
            'required'          => true,
            'class'             => array( 'form-row-wide', 'terms'),
            'validate'          => array( 'terms' ),
        );

        woocommerce_form_field( 'amb-terms-check', $field, $checkout->get_value( 'amb-terms-check' ) );

    }

}

最后,进行一些验证。我们需要检查是否需要该复选框,然后检查它是否被选中,否则这将阻止结帐中没有触发产品的结帐。

add_action( 'woocommerce_before_checkout_process', 'aym_not_approved_amb_terms' );

function aym_not_approved_amb_terms() {

    if ( aym_is_item_in_cart() && ! isset( $_POST['amb-terms-check'] ) ) {
        wc_add_notice( __( 'Please agree to the Ambassador Terms and Conditions' ), 'error' );
    }
}

关于php - Woocommerce - 第二个 T&C 复选框在未选中时不会阻止结账,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43684653/

相关文章:

mysql - 将 PYQT 与 WordPress 结合使用

javascript - 使用 .serializeArray 从所有选中的复选框中获取值

java - 遍历 Swing 中的所有复选框

php - 优化 Trie 实现

php - 购物车更新后 WooCommerce 购物车数量不会改变

css - 在 Wordpress 中指示文本链接的更好方法

javascript - 在jQuery中获取数组中选中复选框列表的值

PHP-管理服务器

javascript - Yii CGridView/CListView 在 AJAX 更新上调用 JavaScript 函数

php - 使用带有数据库信息 PHP 的 for 循环输入