標籤: newebpay

  • WordPress 之中藍新金流開啟後, Elementor 外掛有時會打不開的問題處理

    WordPress 之中藍新金流開啟後, Elementor 外掛有時會打不開的問題處理

    WordPress 有很多外掛,在藍新金流啟用時,同時有使用 Elementor 這個 page builder 外掛,在某些編輯視窗中,可能會造成 AJAX “/wp-json/elementor/v1/globals” 路徑中抓不到 wc_get_chosen_shipping_method_ids() 這個 function 的錯誤訊息。

    這邊查了一下資料,不只是藍新金流外掛會這樣,應該 woocommerce 外掛和 page builder 都有可能造成類似的錯誤。紀錄一下避免老了忘記。

    最近又遇到一樣的問題,查看 log 發現是 wc_get_chosen_shipping_method_ids() 裡面的問題:

    2024/01/02 19:30:32 [error] 1870242#1870242: *46728 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught Error: Call to a member function get() on null in /xxx/xxx/wp-content/plugins/woocommerce/includes/wc-cart-functions.php:394
    Stack trace:
    #0 /xxx/xxx/wp-content/plugins/newebpay/class-newebpay.php(1673): wc_get_chosen_shipping_method_ids()
    
    ...

    查看 woocommerce 的程式碼(參考),並且參考有類似問題的 stackoverflow

    function wc_get_chosen_shipping_method_ids() {
    	$method_ids     = array();
    	$chosen_methods = WC()->session->get( 'chosen_shipping_methods', array() );
    	foreach ( $chosen_methods as $chosen_method ) {
    		$chosen_method = explode( ':', $chosen_method );
    		$method_ids[]  = current( $chosen_method );
    	}
    	return $method_ids;
    }

    判斷應該是 WC()->session 取不到 get 參數,實際上就是這樣沒錯, woocommerce 當下這個沒有判斷 session 為空的狀況。
    可以參考原文,於 class-newebpay.php:1676 附近, wc_get_chosen_shipping_method_ids() 呼叫之前判斷 WC()->session 是否為空。這邊於底下原文中添加新的 code 。

    附上錯誤訊息:

    Fatal error: Uncaught Error: Call to undefined function wc_get_chosen_shipping_method_ids() in /xxx/wp-content/plugins/newebpay/class-newebpay.php:1676 Stack trace: #0 /xxx/wp-includes/class-wp-hook.php(303): newebpay_alter_payment_gateways(Array) ...

    附上發現錯誤的版本資訊,wordpress 核心版本為 5.8.1 , Elementor 版本為 3.4.3:

    /**
     * newebpay Payment Gateway
     * Plugin URI: http://www.newebpay.com/
     * Description: 藍新金流收款/物流 模組
     * Version: 1.0.3
     * Author URI: http://www.newebpay.com/
     * Author: 藍新金流 newebpay
     * Plugin Name:   藍新金流
     * @class       newebpay
     * @extends     WC_Payment_Gateway
     * @version
     * @author  Pya2go Libby
     * @author  Pya2go Chael
     * @author  Spgateway Geoff
     * @author  Spgateway_Pay2go Q //20170217 1.0.1
     * @author  Spgateway_Pay2go jack //20170622 1.0.2
     * @author  Spgateway_Pay2go Stally //20180420 1.0.3 20181018 1.0.4 20181222 newebpay 1.0.0 20190417 1.0.1 20190711 1.0.2 20200326 1.0.3
     */

    目前的解決方法是在 class-newebpay.php:1676 的 newebpay_alter_payment_gateways() 內添加判斷,檢查是否有方法,沒方法就直接跳回不動作。
    另外也在 plugin meta 上修改版本號和描述,避免被直接更新。不過這個外掛也沒上版控,所以屆時可能需要也是手動更新嘍。

    附上修改後資訊:

    <?php
    /**
     * newebpay Payment Gateway
     * Plugin URI: http://www.newebpay.com/
     * Description: 藍新金流收款/物流 模組 修復了 elementor 開啟會有 wc_get_chosen_shipping_method_ids 錯誤的問題 
     * Version: 99.99.99
     * Author URI: http://www.newebpay.com/
     * Author: 藍新金流 newebpay 修改過 By Jerry
     * Plugin Name:   藍新金流
     * @class       newebpay
     * @extends     WC_Payment_Gateway
     * @version
     * @author  Pya2go Libby
     * @author  Pya2go Chael
     * @author  Spgateway Geoff
     * @author  Spgateway_Pay2go Q //20170217 1.0.1
     * @author  Spgateway_Pay2go jack //20170622 1.0.2
     * @author  Spgateway_Pay2go Stally //20180420 1.0.3 20181018 1.0.4 20181222 newebpay 1.0.0 20190417 1.0.1 20190711 1.0.2 20200326 1.0.3
     */
    add_action('plugins_loaded', 'newebpay_gateway_init', 0);
    
    function newebpay_gateway_init() {
        if (!class_exists('WC_Payment_Gateway')) {
            return;
        }
    
        class WC_newebpay extends WC_Payment_Gateway {
    
     ...
    
        // 選擇藍新金流超商取貨後 payment只輸出藍新金流
        function newebpay_alter_payment_gateways($list) {
            if(isset($_GET['pay_for_order']) && isset($_GET['key'])) {
                $order_id = wc_get_order_id_by_order_key($_GET['key']);
                $order = wc_get_order($order_id);
                if($order->has_shipping_method('newebpay_cvscom')) {
                    $list = array('WC_newebpay');
                }
            } elseif(!is_admin()) { //後台無wc_get_chosen_shipping_method_ids function
                if ( !function_exists( 'wc_get_chosen_shipping_method_ids' ) ) { 
                    return $list;
                } 
    
                // 2024-01-02 更新判斷
                $session = WC()->session;
                if($session){
                    $chosen_shipping = wc_get_chosen_shipping_method_ids();
                    //判斷購物車內商品是否全為虛擬商品 全為虛擬商品時會無法選擇物流方式 導致session的chosen_shipping會維持上次所選
                    $virtual_count = 0;
                    $cart_items = WC()->cart->get_cart();
                    foreach ($cart_items as $key => $cart_item) {
                        $virtual_count += ($cart_item['data']->is_virtual()) ? 1 : 0;
                    }
                    if (@in_array('newebpay_cvscom', $chosen_shipping) && $virtual_count < count($cart_items)) {
                        $list = array('WC_newebpay');
                    }
                } // end 判斷
            }
    
            return $list;
        }
        add_filter('woocommerce_payment_gateways', 'newebpay_alter_payment_gateways', 100);
    
    ...