[WooCommerce] 根據選擇運送方式修改結帳欄位的方法

一直以為自己筆記過,但後來想想應該是根據金流而已,新需求就來寫!

寫到這邊就會想到綠界物流外掛的痛! 到底他是金流還是物流?這個決定可是會影響很多邏輯。始終沒有一個版本的外掛是套上去就真的可以不用改啥來配合了。(不過我也相信這是無解的問題)

本文需求明確的說是:選到了 A 運送方式,結帳欄位不該出現 X 項目,所以想拿掉/修改/新增怎辦?

舉例:自取的時候,還要人填寫地址是不是怪怪的?

首先,要實作這塊的邏輯也一定是從結帳表單方法下手。([WooCommerce] 調整結帳欄位的終極指南

把結帳欄位的 hook 方法中補上判斷式,判別當前選擇的運送方式來決定是否開啟或關閉欄位項目。

function mxp_checkout_fields_modify_base_on_shipping_method($fields) {
    //讀取當前選擇的運送方式方法
    $chosen_methods = WC()->session->get('chosen_shipping_methods');
    //因為取得的是某個方法,而不是某種方法,所以要拆解一下。我知道這邊有點難懂,請搭配下文補充
    $chosen_shipping = current(explode(':', $chosen_methods[0]));
    //判斷是否符合自取條件
    if ($chosen_shipping == 'local_pickup') {
        //使用覆寫的方式,不是重新建立,重新建立反而可能會有其他問題!
        $fields['billing']['billing_postcode']['required'] = false;
        $fields['billing']['billing_postcode']['class'] = array('hidden');
        $fields['billing']['billing_postcode']['type'] = 'hidden';
        $fields['billing']['billing_address_1']['required'] = false;
        $fields['billing']['billing_address_1']['class'] = array('hidden');
        $fields['billing']['billing_address_1']['type'] = 'hidden';
        $fields['billing']['billing_state']['required'] = false;
        $fields['billing']['billing_state']['class'] = array('hidden');
        $fields['billing']['billing_state']['type'] = 'hidden';
        $fields['billing']['billing_city']['required'] = false;
        $fields['billing']['billing_city']['class'] = array('hidden');
        $fields['billing']['billing_city']['type'] = 'hidden';
    }
    return $fields;
}

add_filter('woocommerce_checkout_fields', 'mxp_checkout_fields_modify_base_on_shipping_method', 999, 1);

關於註解提到的那方法讀取到的是「某個運送方法」而不是「某種運送方法」這件事,雖沒特別在 [WooCommerce] 運送方法項目的排序控制(依照運費、指定順序) 這篇提到,但算是滿重要的觀念!

WooCommerce 的運送方式可以設定的很細,出發點是一個集合概念,還可以從這個集合下去延伸個別的子項目,所以會這樣形容。

像「宅配」是一個運送方式種類,但「海外宅配」跟「國內宅配」就是不同的子集合了!只針對「宅配」去實作可能會不夠彈性,導致影響其他設定的操作。

到這邊這題只解一半。從購物車頁選好運送方式過去結帳頁面的人會正常,但如果是結帳頁面反悔要改選運送方式的人就會感覺奇怪了。

這時候會需要使用 [WooCommerce] 片段(fragments)互動程式設計要點 這篇提到的開發方法來補強了!

更改運送方式的時候會觸發 woocommerce_update_order_review_fragments 的 hook ,在這邊去判斷當前選擇運送方式來處理輸出更新的欄位替換。

function mxp_hidden_checkout_fields_base_on_shipping_method($value) {
    // 判斷當前選擇到的運送方式
    $chosen_methods = WC()->session->get('chosen_shipping_methods');
    $chosen_shipping = current(explode(':', $chosen_methods[0]));
    if ($chosen_shipping == 'local_pickup') {
        $fields = WC()->checkout->get_checkout_fields('billing');
        $html = "";
        foreach ($fields as $key => $field) {
            $field['return'] = true;
            // 判斷對應需要調整的欄位來改參數重新產生欄位結構輸出
            if ($key == 'billing_postcode' || $key == 'billing_address_1' || $key == 'billing_state' || $key == 'billing_city') {
                $field['class'] = array('hidden');
                $field['type'] = 'hidden';
                $field['required'] = false;
            }
            $html .= woocommerce_form_field($key, $field, WC()->checkout->get_value($key));
        }
        $value['.woocommerce-billing-fields__field-wrapper'] = '<div class="woocommerce-billing-fields__field-wrapper">' . $html . '</div>';
    } else {
        // 不符合條件的就照常輸出
        $fields = WC()->checkout->get_checkout_fields('billing');
        $html = "";
        foreach ($fields as $key => $field) {
            $field['return'] = true;
            $html .= woocommerce_form_field($key, $field, WC()->checkout->get_value($key));
        }
        $value['.woocommerce-billing-fields__field-wrapper'] = '<div class="woocommerce-billing-fields__field-wrapper">' . $html . '</div>';
    }

    return $value;
}
add_filter('woocommerce_update_order_review_fragments', 'mxp_hidden_checkout_fields_base_on_shipping_method', 999, 1);

Gist: Link

到這邊就能滿足本命題最預設情境的條件拉! 打完收工~

Facebook 外掛功能


Share:

作者: Chun

資訊愛好人士。主張「人人都該為了偷懶而進步」。期許自己成為斜槓到變進度條 100% 的年輕人。[//////////____30%_________]

參與討論

2 則留言

  1. 你好
    请问一下我现在做一个网站,想在客人选择送货的情况下到达一定金额有礼物送,但是自取就没有,我找了一些插件但是都不能单独设定送货,请问有什么办法吗?谢谢

    1. Hi! 你的需求看起來就是只能客製化來開發了,應用本篇的程式邏輯,改寫成「當選到某些送貨條件」且「購物車滿足一定金額」就觸發,沒有就是移除購物車的禮物或是折扣。這塊還可以搭配我這篇參考: https://www.mxp.tw/8300/

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *