前言
由於業主有增加WooCommerce客製化使用者欄位的需求,所以這篇文章想分享一些客製化使用者欄位經歷。因為預期會有許多後續寄送收據、報帳與聯絡需要,業主想在使用者註冊時就先填好資料,或者使用社群網站 (Facebook or Google) 一鍵登入後能繼續填寫客製化欄位,所以在註冊表單、編輯個人帳號、購物車結帳前,後台查詢訂單這四處要加上客制化欄位。
搜尋參考資料有找到一位WooCommerce plugin開發者寫的詳細教學文章,英文文件但值得一看,以下參考他的文章增加業主所需的客製欄位。code的部分要打包成外掛Plugin或者是MU Plugin (Must Use Plugin)都可以。
在WooCommerce加入客製化使用者欄位
定義客製化欄位
要加入客製化欄位得先知道要放哪些欄位、類別跟必塡/選填,所以得先定義這些欄位。
'first_name' => array( 'type' => 'text', 'label' => __('First Name', 'iconic') , 'hide_in_account' => true, 'hide_in_admin' => true, 'hide_in_checkout' => true, 'hide_in_registration' => false, 'required' => true, ) , 'embraced-status' => array( 'type' => 'select', 'label' => __('身份 Status', 'iconic') , 'options' => array( '' => __('身份 Status', 'iconic') , 1 => __('社會人士 Member of society', 'iconic') , 2 => __('學生 Student', 'iconic') , 3 => __('團體 Group', 'iconic') , ) , 'required' => true, ) , 'embraced-type' => array( 'type' => 'select', 'label' => __('類別 Type', 'iconic') , 'options' => array( '' => __('類別 Type', 'iconic') , 1 => __('工商業 Industrial or business marketing', 'iconic') , 2 => __('研究機構 Research institue', 'iconic') , 3 => __('學術 Academia', 'iconic') , 4 => __('其他 Other', 'iconic') , ) , 'required' => true, ) ,
這邊的例子是建立名字(文字欄位),身份與類別兩個下拉式選單:
type是欄位類別可以選:
- Text 文字
- Textarea 文字區塊
- Select 下拉式選單
- Country 國家
- Checkbox 單勾選
- Number 數字
- Password 密碼
- Tel 電話
原文教學內還有教怎麼做單選的radio button與多勾選。
掛上欄位
定義好欄位,使用原文的驗證與更新functions,掛到對應的action hooks:’woocommerce_register_form’, ‘woocommerce_edit_account_form’,如名稱,分別是掛到註冊表單與個人資訊表單就可以用了。
add_action('woocommerce_register_form', 'iconic_print_user_frontend_fields', 10); // 註冊表單 register form of WooCommerce add_action('woocommerce_edit_account_form', 'iconic_print_user_frontend_fields', 10); // 個人資訊 my account section of WooCommerce
更新驗證表單資料 & 訂單成立後更新資料
驗證與更新這邊沒有修改內容就不多說,倒是訂單結帳前也有欄位要填,所以在訂單成立之後得更新資料,因為原本的儲存function是以user為主,所以我另外改了一個以訂單為輸入的function,把資訊填在user/order的meta data,其實寫在user的metadata就好了,只是想說後台是讀取訂單資訊就寫在訂單內了,可以少一次query (誤)。
function iconic_save_account_fields2($order, $data){ $customer_id = $order->get_user_id(); $fields = iconic_get_account_fields(); $sanitized_data = array(); foreach($fields as $key => $field_args) { if (!iconic_is_field_visible($field_args)) { continue; } $sanitize = isset($field_args['sanitize']) ? $field_args['sanitize'] : 'wc_clean'; $value = isset($data[$key]) ? call_user_func($sanitize, $data[$key]) : ''; // 客製化欄位的key前面要有一個底線 _,例如原本定義的key是firstname,就是_firstname,視為private。 $meta_key = '_' . $key; if (iconic_is_userdata($key)) { $sanitized_data[$key] = $value; continue; } update_user_meta($customer_id, $key, $value); $order->update_meta_data($meta_key, $value); } if (!empty($sanitized_data)) { $sanitized_data['ID'] = $customer_id; wp_update_user($sanitized_data); } } function apply_username_field(){ if (is_user_logged_in()) { $current_user = wp_get_current_user(); $user_id = $current_user->ID; $fields = iconic_get_account_fields(); $cname = get_user_meta($user_id, 'embraced-CName'); $ename = get_user_meta($user_id, 'embraced-EngName'); $company = get_user_meta($user_id, 'embraced-organization') [0]; if (!empty($cname[0])) { //依照中文名 -> 英文名 -> User內的first name順序 $firstname = $cname[0]; } else if (!empty($ename[0])) { $firstname = $ename[0]; } else { $firstname = $current_user->user_firstname; } $output = ' <script> var $ = jQuery.noConflict(); $(document).ready(function(){ $("#billing_first_name").attr("value","' . $firstname . '"); $("#billing_company").attr("value","' . $company . '"); }) </script>'; echo $output; } } add_filter('woocommerce_before_checkout_form', 'apply_username_field', 30);
以First Name欄位替代First Name + Last Name欄位
這個部分忘記是參考哪位前輩寫的文章,總之是簡化姓名欄位為一個。
//remove default billing fields function custom_override_checkout_fields( $fields ) { //unset($fields['billing']['billing_first_name']); 保留帳單的first_name替代first name & last Name unset($fields['billing']['billing_last_name']); unset($fields['billing']['billing_country']); //unset($fields['billing']['billing_company']); 保留帳單的公司欄位 unset($fields['billing']['billing_address_1']); unset($fields['billing']['billing_address_2']); unset($fields['billing']['billing_city']); unset($fields['billing']['billing_postcode']); unset($fields['billing']['billing_state']); unset($fields['billing']['billing_phone']); //use first name to fill full name $fields['billing']['billing_first_name'] = array( 'label'=>"姓名", 'required' => true, ); return $fields; } function my_custom_checkout_field_display_admin_order_meta($order){ $fields = iconic_get_account_fields(); $order_id = $order->get_id(); foreach ($fields as $key => $field_args){ if ($field_args['type'] === 'select'){ echo '<p><strong>'.$field_args['label'].':</strong> ' . $field_args['options'][get_post_meta( $order_id, '_'.$key, true )] . '</p>'; }else{ echo '<p><strong>'.$field_args['label'].':</strong> ' . get_post_meta( $order_id, '_'.$key, true ) . '</p>'; } } } add_filter('woocommerce_checkout_fields', 'custom_override_checkout_fields', 10, 1); // 以客製欄位替代帳單欄位 add_filter('woocommerce_checkout_fields', 'iconic_checkout_fields', 20, 1); // 結帳的客製化表單 add_action('woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1); // 後台訂單
結論
照著開頭那篇文章可以好好的客製化需要的欄位,搭配WooCommerce文件與討論,就可以完成此客製化功能。
大概會像這樣:
[ux_slider]
[ux_image id=”311″ image_size=”medium” width=”30″]
[ux_image id=”309″ image_size=”medium” width=”50″]
[ux_image id=”341″ image_size=”medium” width=”50″]
[/ux_slider]