Hướng dẫn thêm, cập nhật, xóa trường (fields) vào checkout woocommerce
- 13-05-2022
- Toanngo92
- 0 Comments
Hôm nay mình có một dự án cần bổ sung trường vào checkout woocommerce, nếu sửa trực tiếp core thì không nói, mỗi lần update mất code là hết hơi nên tiện mình viết lại luôn để các bạn về sau tiết kiệm thời gian nghiên cứu.
Docs: https://woocommerce.com/document/tutorial-customising-checkout-fields-using-actions-and-filters/
Giải thích nôm na là bên trong trang checkout của woocommerce thông thường, sẽ có 2 cột chứa danh sách các trường input, cột dầu tiên là billing, cột thứ 2 là shipping address. Toàn bộ chúng được lưu trữ trong một biến mảng, chúng ta có thể thêm, cập nhật, xóa các trường để bổ sung các input cho form woocommerce bằng cách sử dụng hàm:
add_filter('woocommerce_checkout_fields', 'custom_override_checkout_fields');
function custom_override_checkout_fields($fields)
{
/* todo, biến fields là biến mảng có cấu trúc, bên trong là các phần tử billing,shipping,account,order và các phần tử này lại là các mảng con, mô tả cấu trúc của các fields nhập liệu khi người dùng checkout */
}
nếu dump biến $fields được hứng thông qua filter sẽ được cấu trúc như sau:
array(4) {
["billing"]=>
array(11) {
["billing_first_name"]=>
array(5) {
["label"]=>
string(4) "Tên"
["required"]=>
bool(true)
["class"]=>
array(1) {
[0]=>
string(14) "form-row-first"
}
["autocomplete"]=>
string(10) "given-name"
["priority"]=>
int(10)
}
["billing_last_name"]=>
array(5) {
["label"]=>
string(4) "Họ"
["required"]=>
bool(true)
["class"]=>
array(1) {
[0]=>
string(13) "form-row-last"
}
["autocomplete"]=>
string(11) "family-name"
["priority"]=>
int(20)
}
["billing_company"]=>
array(5) {
["label"]=>
string(13) "Tên công ty"
["class"]=>
array(1) {
[0]=>
string(13) "form-row-wide"
}
["autocomplete"]=>
string(12) "organization"
["priority"]=>
int(30)
["required"]=>
bool(false)
}
["billing_country"]=>
array(6) {
["type"]=>
string(7) "country"
["label"]=>
string(16) "Country / Region"
["required"]=>
bool(true)
["class"]=>
array(3) {
[0]=>
string(13) "form-row-wide"
[1]=>
string(13) "address-field"
[2]=>
string(23) "update_totals_on_change"
}
["autocomplete"]=>
string(7) "country"
["priority"]=>
int(40)
}
["billing_address_1"]=>
array(6) {
["label"]=>
string(12) "Địa chỉ"
["placeholder"]=>
string(12) "Địa chỉ"
["required"]=>
bool(true)
["class"]=>
array(2) {
[0]=>
string(13) "form-row-wide"
[1]=>
string(13) "address-field"
}
["autocomplete"]=>
string(13) "address-line1"
["priority"]=>
int(50)
}
["billing_address_2"]=>
array(5) {
["placeholder"]=>
string(39) "Apartment, suite, unit, etc. (optional)"
["class"]=>
array(2) {
[0]=>
string(13) "form-row-wide"
[1]=>
string(13) "address-field"
}
["autocomplete"]=>
string(13) "address-line2"
["priority"]=>
int(60)
["required"]=>
bool(false)
}
["billing_postcode"]=>
array(6) {
["label"]=>
string(16) "Mã bưu điện"
["required"]=>
bool(false)
["class"]=>
array(2) {
[0]=>
string(13) "form-row-wide"
[1]=>
string(13) "address-field"
}
["validate"]=>
array(1) {
[0]=>
string(8) "postcode"
}
["autocomplete"]=>
string(11) "postal-code"
["priority"]=>
int(65)
}
["billing_city"]=>
array(5) {
["label"]=>
string(21) "Tỉnh / Thành phố"
["required"]=>
bool(true)
["class"]=>
array(2) {
[0]=>
string(13) "form-row-wide"
[1]=>
string(13) "address-field"
}
["autocomplete"]=>
string(14) "address-level2"
["priority"]=>
int(70)
}
["billing_state"]=>
array(9) {
["type"]=>
string(5) "state"
["label"]=>
string(12) "Bang / Hạt"
["required"]=>
bool(false)
["class"]=>
array(2) {
[0]=>
string(13) "form-row-wide"
[1]=>
string(13) "address-field"
}
["validate"]=>
array(1) {
[0]=>
string(5) "state"
}
["autocomplete"]=>
string(14) "address-level1"
["priority"]=>
int(80)
["country_field"]=>
string(15) "billing_country"
["country"]=>
string(2) "VN"
}
["billing_phone"]=>
array(7) {
["label"]=>
string(20) "Số điện thoại"
["required"]=>
bool(true)
["type"]=>
string(3) "tel"
["class"]=>
array(1) {
[0]=>
string(13) "form-row-wide"
}
["validate"]=>
array(1) {
[0]=>
string(5) "phone"
}
["autocomplete"]=>
string(3) "tel"
["priority"]=>
int(100)
}
["billing_email"]=>
array(7) {
["label"]=>
string(18) "Địa chỉ email"
["required"]=>
bool(true)
["type"]=>
string(5) "email"
["class"]=>
array(1) {
[0]=>
string(13) "form-row-wide"
}
["validate"]=>
array(1) {
[0]=>
string(5) "email"
}
["autocomplete"]=>
string(14) "email username"
["priority"]=>
int(110)
}
}
["shipping"]=>
array(9) {
["shipping_first_name"]=>
array(5) {
["label"]=>
string(4) "Tên"
["required"]=>
bool(true)
["class"]=>
array(1) {
[0]=>
string(14) "form-row-first"
}
["autocomplete"]=>
string(10) "given-name"
["priority"]=>
int(10)
}
["shipping_last_name"]=>
array(5) {
["label"]=>
string(4) "Họ"
["required"]=>
bool(true)
["class"]=>
array(1) {
[0]=>
string(13) "form-row-last"
}
["autocomplete"]=>
string(11) "family-name"
["priority"]=>
int(20)
}
["shipping_company"]=>
array(5) {
["label"]=>
string(13) "Tên công ty"
["class"]=>
array(1) {
[0]=>
string(13) "form-row-wide"
}
["autocomplete"]=>
string(12) "organization"
["priority"]=>
int(30)
["required"]=>
bool(false)
}
["shipping_country"]=>
array(6) {
["type"]=>
string(7) "country"
["label"]=>
string(16) "Country / Region"
["required"]=>
bool(true)
["class"]=>
array(3) {
[0]=>
string(13) "form-row-wide"
[1]=>
string(13) "address-field"
[2]=>
string(23) "update_totals_on_change"
}
["autocomplete"]=>
string(7) "country"
["priority"]=>
int(40)
}
["shipping_address_1"]=>
array(6) {
["label"]=>
string(12) "Địa chỉ"
["placeholder"]=>
string(12) "Địa chỉ"
["required"]=>
bool(true)
["class"]=>
array(2) {
[0]=>
string(13) "form-row-wide"
[1]=>
string(13) "address-field"
}
["autocomplete"]=>
string(13) "address-line1"
["priority"]=>
int(50)
}
["shipping_address_2"]=>
array(5) {
["placeholder"]=>
string(39) "Apartment, suite, unit, etc. (optional)"
["class"]=>
array(2) {
[0]=>
string(13) "form-row-wide"
[1]=>
string(13) "address-field"
}
["autocomplete"]=>
string(13) "address-line2"
["priority"]=>
int(60)
["required"]=>
bool(false)
}
["shipping_postcode"]=>
array(6) {
["label"]=>
string(16) "Mã bưu điện"
["required"]=>
bool(false)
["class"]=>
array(2) {
[0]=>
string(13) "form-row-wide"
[1]=>
string(13) "address-field"
}
["validate"]=>
array(1) {
[0]=>
string(8) "postcode"
}
["autocomplete"]=>
string(11) "postal-code"
["priority"]=>
int(65)
}
["shipping_city"]=>
array(5) {
["label"]=>
string(21) "Tỉnh / Thành phố"
["required"]=>
bool(true)
["class"]=>
array(2) {
[0]=>
string(13) "form-row-wide"
[1]=>
string(13) "address-field"
}
["autocomplete"]=>
string(14) "address-level2"
["priority"]=>
int(70)
}
["shipping_state"]=>
array(9) {
["type"]=>
string(5) "state"
["label"]=>
string(12) "Bang / Hạt"
["required"]=>
bool(false)
["class"]=>
array(2) {
[0]=>
string(13) "form-row-wide"
[1]=>
string(13) "address-field"
}
["validate"]=>
array(1) {
[0]=>
string(5) "state"
}
["autocomplete"]=>
string(14) "address-level1"
["priority"]=>
int(80)
["country_field"]=>
string(16) "shipping_country"
["country"]=>
string(2) "VN"
}
}
["account"]=>
array(0) {
}
["order"]=>
array(1) {
["order_comments"]=>
array(4) {
["type"]=>
string(8) "textarea"
["class"]=>
array(1) {
[0]=>
string(5) "notes"
}
["label"]=>
string(20) "Ghi chú đơn hàng"
["placeholder"]=>
string(107) "Ghi chú về đơn hàng, ví dụ: thời gian hay chỉ dẫn địa điểm giao hàng chi tiết hơn."
}
}
}
Woocommerce dựng sẵn và cập nhật lại biến fields bằng cách bổ sung phần tử hoặc cập nhật lại phần tử có sẵn . Ví dụ code mẫu như sau để bổ sung một trường có label birthday và type bằng date để người dùng có thể chọn ngày tháng năm:
// Hook in
add_filter('woocommerce_checkout_fields', 'custom_override_checkout_fields');
// Our hooked in function - $fields is passed via the filter!
function custom_override_checkout_fields($fields)
{
// add birthday fields
$fields['billing']['birthday'] = array(
'label' => __('Birthday', 'woocommerce'), // nội dung text thẻ label cho input
'type' => 'date', // type của input
'required' => false, // trường required hay không
'class' => array('form-row-wide'), // class html trong input
'clear' => true
);
return $fields;
}
Sau khi bổ sung trường, khi update chúng ta sẽ cần lưu dữ liệu vào custom field trong CSDL cho order
/**
* Update the order meta with field value
*/
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' );
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['birthday'] ) ) {
update_post_meta( $order_id, 'birthday', sanitize_text_field( $_POST['birthday'] ) );
}
}
Sau khi đã có dữ liệu trong CSDL, dùng code sau để hiển thị ra backend order
/**
* Display field value on the order edit page
*/
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('Sinh nhật').':</strong> ' . get_post_meta( $order->id, 'birthday', true ) . '</p>';
}
Ngoài ra, nếu muốn hiển thị dữ liệu ở quickview order trong backend, tham khảo code sau:
/**
* Add to quickview order
*/
add_filter( 'woocommerce_admin_order_preview_get_order_details', 'admin_order_preview_add_custom_billing_data', 10, 2 );
function admin_order_preview_add_custom_billing_data( $data, $order ) {
$custom_billing_data = []; // initializing
// Custom field 1: Replace '_custom_meta_key1' by the correct custom field metakey
if( $custom_value1 = $order->get_meta('birthday') ) {
$custom_billing_data[] = $custom_value1;
}
## ……… And so on (for each additional custom field).
// Check that our custom fields array is not empty
if( count($custom_billing_data) > 0 ) {
// Converting the array in a formatted string
$formatted_custom_billing_data = implode( '<br>', $custom_billing_data );
if( $data['formatted_billing_address'] === __( 'N/A', 'woocommerce' ) ) {
$data['formatted_billing_address'] = $formatted_custom_billing_data;
} else {
$data['formatted_billing_address'] .= '<br>' .'<strong>Sinh nhật</strong>'. $formatted_custom_billing_data;
}
}
return $data;
}
Code trên tham khảo tại: https://stackoverflow.com/questions/57846511/show-custom-fields-in-woocommerce-quick-order-preview
Chúc bạn thành công !