由于某种原因,当我运行WooCommerce_Available_Payment_Gateways过滤器时,它在 checkout 页面上运行了两次

作为一个测试,我让它在 checkout 页面上 echo 123123,它显示1231235555(在Else语句中)<-这意味着它运行了两次,并且以某种方式绕过/满足了这两个条件

我如何防止这种行为?

function selected_custom_checkout_gateways( $available_gateways ) {

    global $woocommerce;

    if(
        
        isset( $_GET[ 'checkoutid' ] ) &&
        $_GET[ 'checkoutid' ] == '50'
    
    ){

        echo 123123;
        unset( $available_gateways[ 'cod' ] ) ;
        unset( $available_gateways[ 'cheque' ] ) ;

        return $available_gateways;
        exit;

    }else{
    
        echo 5555;
    return $available_gateways;
    
    }
}

Condition to filter and see which `IF` statement logic is hitting.

推荐答案

当加载 checkout 时以及在AJAX事件(其中$_GET被绕过)时,过滤器挂钩woocommerce_available_payment_gateways被多次触发.因此,您需要尽早将URL变量保存在WC会话变量中.

try 以下操作:

// Save the url variable in a WC Session variable
add_action( 'template_redirect', 'save_checkoutid_as_wc_session_variable' );
function save_checkoutid_as_wc_session_variable() {
    if( is_checkout() && isset($_GET[ 'checkoutid']) && $_GET['checkoutid' ] == '50' ){
        WC()->session->set('checkout_id', esc_attr($_GET['checkoutid']));
    }
}

add_filter( 'woocommerce_available_payment_gateways', 'selected_custom_checkout_gateways' );
function selected_custom_checkout_gateways( $available_gateways ) {
    // Not in backend (admin)
    if( ! is_admin() && isset(WC()->session) ) {
        $checkout_id = WC()->session->get('checkout_id');

        if( $checkout_id  == '50' ){
            $code = 123123; // For testing
            unset( $available_gateways[ 'cod' ], $available_gateways[ 'cheque' ] ) ;
        }
        else{
            $code = 5555; // for testing
        }
        
        $debug = "code: {$code} | checkout_id: {$checkout_id}"; // for testing
        error_log($debug); // for testing
    }
    return $available_gateways;
}

// Remove the WC Session variable once the order is created
add_action( 'woocommerce_checkout_order_created', 'remove_checkout_id_wc_session_variable' );
function remove_checkout_id_wc_session_variable() {
    if ( WC()->session->__isset('checkout_id') ){ 
        WC()->session->__unset('checkout_id');
    }
}

代码位于您的子主题的unctions.php文件中(或在插件中).现在应该行得通了.

Php相关问答推荐

Woocommerce自定义变体html表仅显示带值的列

如何将对我的域的请求重定向到子文件夹中的索引,同时保留域URL并使用.htaccess?

在WooCommerce管理订单列表中显示项目总权重

让所有具有相同名称的产品在WooCommerce中更改价格

添加登录:需要app.yaml仍然允许所有拥有Google帐户的人访问

PHP从响应应用程序json获取文件代码和URL

在指定的约束内使用随机量填充数据集

PHP:使用FORT从数据库获取USERS表到AUTH表

防止同时从Laravel中的用户帐户中提取

重命名 WordPress 中现有的自定义分类法名称和标签

将自定义字段添加到管理产品中 WooCommerce 3.2+ 中的快速编辑

在 WooCommerce 中何时何地执行 woocommerce_order_status_completed_notification 挂钩?

laravel Eloquent 模型的问题

单个产品页面 WooCommerce 订阅价格字符串的更改

PHP文件如何从CSS执行

为 WordPress 页面创建新功能

无法在 Laravel 10 中安装 jenssegers/mongodb

使用循环和引用而不是递归创建分层/父子数组

如何使用先前 SELECT 的结果来 SELECT SQL 数据

Laravel - 关联与设置观察者事件的 ID