WordPress如何将变量从一个Add_action传递到另一个?

时间:2020-09-03 作者:Digital Essence

如果某个产品类别在购物篮中,我试图在结帐表单上添加一个自定义字段,然后在提交时,检查该字段是否已完成,并将结果添加到订单详细信息中。

我的表单字段工作正常,但其他操作没有工作,这是因为变量$course\\u in\\u cart没有传递给其他操作。如果我删除$course\\u in\\u cart测试,所有操作都会正常工作,但它需要有条件,这就是我失败的地方。

第一个操作检查购物车中是否有课程类别产品,编写html并将变量设置为true。

// Set course in cart to false
$course_in_cart = false;

add_action( \'woocommerce_after_checkout_billing_form\', \'digitalessence_check_course_category_in_cart\' );
function digitalessence_check_course_category_in_cart($checkout) {
    global $course_in_cart;
    // Loop through all products in cart and if there is a course.
        foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
            // If Cart has a course category, set $cat_in_cart to true
            if ( has_term( \'courses\', \'product_cat\', $cart_item[\'product_id\'] ) ) {
                $course_in_cart = true;
                break;
            }
    }
    // If there is a course in the cart, write HTML form field
    if ( $course_in_cart) {
           echo \'<div id="ebike-question">\';
           echo \'  <div class="woocommerce-additional-fields__field-wrapper">\';
             woocommerce_form_field( \'E-Bike__Present\', array(
        \'type\'          => \'text\',
        \'class\'         => array(\'E-Bike__Present\'),
        \'placeholder\'   => __(\'Are you bringing an e-bike on the course?\'),
        \'required\'  => true,
        \'label\'     => __(\'E-Bike\', \'woocommerce\'),
        ), $checkout->get_value( \'E-Bike__Present\' ));
            echo \'</div>\';
           echo \'  <div class="ebike-question-end-div"></div>\';
           echo \'</div>\';      
    }
    }
我要执行的下一个操作是检查$course\\u in\\u cart的状态,如果是真的,则添加一个必填字段通知。这就是我跌倒的地方,因为它总是显示为错误。

add_action(\'woocommerce_checkout_process\', \'my_custom_checkout_field_process\');
// Check if set, if its not set add an error.
function my_custom_checkout_field_process() {
    global $course_in_cart;
    if ( $course_in_cart) {
        if ( ! $_POST[\'E-Bike__Present\'] )
        wc_add_notice( __( \'<strong>For our legs, we need to know if you are bringing an e-bike!</strong>\' ), \'error\' );
        }
    else {
        wc_add_notice( __( \'<strong>course in cart variable is showing as false</strong>\' ), \'error\' );
        
    }
}
我将所有内容都剥离到了最基本的部分,以确保将变量从一个函数传递到另一个函数会起作用。

<?php
$course_in_cart = false;
declareVariable();
displayVariable();

function declareVariable() {
  global $course_in_cart;
  $course_in_cart = true;
}
function displayVariable() {
    global $course_in_cart;
    //echo $course_in_cart; // outputs 1
    if ( $course_in_cart) {
        echo "Its working. The variable is showing as: " . $course_in_cart;
    }
}
?>
确实如此。我得到;它正在工作。变量显示为:1“;在浏览器中。

感谢所有帮助。我已经搜索了其他问题,但没有找到任何类似的问题,所以希望这不是重复的问题。如果是,请骂我!我希望我已经提供了足够的信息。如果不是。。。

非常感谢。

1 个回复
最合适的回答,由SO网友:Jacob Peattie 整理而成

您不应该试图在操作之间传递变量。变量不会在请求之间持久存在,第一次定义变量是在加载签出时,第二次是在提交签出后,这是一个完全独立的请求。要在请求之间传递值,需要将值存储在数据库或cookie中。

但这是错误的做法。实际上,您并不需要该变量。您想在每个动作中了解的是;车里有课程吗"E;。没有理由只执行一次检查,然后尝试传递结果。只需在两个位置执行相同的检查:

/**
 * Check if the cart contains a product in the Courses category.
 */
function digitalessence_is_course_in_cart() {
    $course_in_cart = false;
    
    foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
        if ( has_term( \'courses\', \'product_cat\', $cart_item[\'product_id\'] ) ) {
            $course_in_cart = true;
            break;
        }
    }

    return $course_in_cart;
}

/**
 * Add a form field if the cart contains a product in the Courses category.
 */
function digitalessence_checkout_billing_form( $checkout ) {
    $course_in_cart = digitalessence_is_course_in_cart();

    if ( $course_in_cart ) {
        // Output form field.
    }
}
add_action( \'woocommerce_after_checkout_billing_form\', \'digitalessence_checkout_billing_form\' );

/**
 * Validate the form field added if the cart contains a product in the Courses category.
 */
function digitalessence_checkout_validation( $data, $errors ) {
    $course_in_cart = digitalessence_is_course_in_cart();

    if ( $course_in_cart ) {
        // Validate form field.
        // $errors->add( \'ebike\', \'For our legs, we need to know if you are bringing an e-bike!\' );
    }
}
add_action( \'woocommerce_after_checkout_validation\', \'digitalessence_checkout_validation\', 10, 2 );
请注意,我已将上一个函数更改为使用woocommerce_after_checkout_validation 钩如果要验证签出字段,这是要使用的挂钩。如果验证失败,请将错误添加到WP_Error 作为第二个参数传递的对象。我的代码包括一个注释掉的示例。