在 WooCommerce 管理订单列表中添加可排序和可搜索的“客户国家/地区”列
Posted
技术标签:
【中文标题】在 WooCommerce 管理订单列表中添加可排序和可搜索的“客户国家/地区”列【英文标题】:Add a sortable and searchable "customer country" column in WooCommerce admin order list 【发布时间】:2022-01-05 06:05:05 【问题描述】:我向 WooCommerce 订单表(在管理仪表板中)添加了一个“客户国家/地区”列,但我不知道如何使其可排序。有什么帮助吗?如果它也可以被搜索,那将是一个很好的奖励。
我当前的代码:
add_filter( 'manage_edit-shop_order_columns', function( $columns )
$columns['customer_country'] = 'Customer Country';
return $columns;
, 10, 1 );
add_action( 'manage_shop_order_posts_custom_column', function( $column )
global $post;
if( 'customer_country' === $column )
$order = wc_get_order( $post->ID );
echo get_user_geo_country( $order->get_customer_ip_address() );
, 10, 1 );
add_filter( 'manage_edit-shop_order_sortable_columns', function( $columns )
$columns['customer_country'] = 'customer_country';
return $columns;
, 10, 1 );
add_action( 'pre_get_posts', function( $query )
if( ! is_admin() ) return;
// ????
, 10, 1 );
/** Get geolocated country name by IP **/
function get_user_geo_country( $user_ip )
$geo = new WC_Geolocation(); // Get WC_Geolocation instance object
$user_geo = $geo->geolocate_ip( $user_ip ); // Get geolocated user data
$country = $user_geo['country']; // Get the country code
return WC()->countries->countries[ $country ]; // return the country name
【问题讨论】:
【参考方案1】:要使其可排序,您可以使用manage_edit-shop_order_sortable_columns
与pre_get_posts
挂钩。
要使其可搜索,您可以使用 woocommerce_shop_order_search_fields
挂钩。
所以你得到:
// Get geolocated country code by IP
function get_user_geo_country( $user_ip )
// Get WC_Geolocation instance object
$geo = new WC_Geolocation();
// Get geolocated user data
$user_geo = $geo->geolocate_ip( $user_ip );
// Get the country code
$country = $user_geo['country'];
// Return the country code
return $country;
// Display new column on WooCommerce admin orders list (header)
function filter_manage_edit_shop_order_columns( $columns )
$columns['customer_country'] = __( 'Customer Country', 'woocommerce' );
return $columns;
add_filter( 'manage_edit-shop_order_columns', 'filter_manage_edit_shop_order_columns', 10, 1 );
// Display details after order status column, on order admin list (populate the column)
function action_manage_shop_order_posts_custom_column( $column, $post_id )
// Compare
if ( $column == 'customer_country' )
// Get order
$order = wc_get_order( $post_id );
// Get shipping country code
$user_geo_country = get_user_geo_country( $order->get_customer_ip_address() );
// NOT empty
if ( ! empty ( $user_geo_country ) )
echo $user_geo_country;
else
echo __( 'N/A', 'woocommerce' );
add_action( 'manage_shop_order_posts_custom_column' , 'action_manage_shop_order_posts_custom_column', 10, 2 );
// Make custom column sortable
function filter_manage_edit_shop_order_sortable_columns( $sortable_columns )
return wp_parse_args( array( 'customer_country' => '_shipping_country' ), $sortable_columns );
add_filter( 'manage_edit-shop_order_sortable_columns', 'filter_manage_edit_shop_order_sortable_columns', 10, 1 );
// Orderby for custom sortable column
function action_pre_get_posts( $query )
// If it is not admin area, exit
if ( ! is_admin() ) return;
global $pagenow;
// Compare
if ( $pagenow === 'edit.php' && isset( $_GET['post_type'] ) && $_GET['post_type'] === 'shop_order' )
// Get orderby
$orderby = $query->get( 'orderby' );
// Set query
if ( $orderby == '_shipping_country' )
$query->set( 'meta_key', '_shipping_country' );
$query->set( 'orderby', 'meta_value' );
add_action( 'pre_get_posts', 'action_pre_get_posts', 10, 1 );
// Make searchable
function filter_woocommerce_shop_order_search_fields( $meta_keys )
$meta_keys[] = '_shipping_country';
return $meta_keys;
add_filter( 'woocommerce_shop_order_search_fields', 'filter_woocommerce_shop_order_search_fields', 10, 1 );
这相对容易。 唯一的缺点是您不会看到完整的国家/地区名称,而只会看到国家/地区代码。这是因为搜索和排序钩子需要一个元键。 WooCommerce 只存储国家代码,作为每个订单的元数据,国家的全名没有存储在数据库中,因此无法使用。
如果您真的想查询完整的国家/地区名称。然后,除了国家代码之外,您还可以通过woocommerce_thankyou
钩子和$order->update_meta_data()
为每个新订单添加完整的国家名称作为元数据
那么你得到:
// Get geolocated country name by IP
function get_user_geo_country( $user_ip )
// Get WC_Geolocation instance object
$geo = new WC_Geolocation();
// Get geolocated user data
$user_geo = $geo->geolocate_ip( $user_ip );
// Get the country code
$country = $user_geo['country'];
// Return the country name
return WC()->countries->countries[ $country ];
function action_woocommerce_thankyou( $order_id )
// Get $order object
$order = wc_get_order( $order_id );
// Is a WC_Order
if ( is_a( $order, 'WC_Order' ) )
// Get full shipping country name
$user_geo_country = get_user_geo_country( $order->get_customer_ip_address() );
// NOT empty
if ( ! empty( $user_geo_country ) )
// Update meta data
$order->update_meta_data( '_shipping_country_full_name', $user_geo_country );
else
// NOT available
$na = __( 'N/A', 'woocommerce' );
// Update meta data
$order->update_meta_data( '_shipping_country_full_name', $na );
// Save
$order->save();
add_action( 'woocommerce_thankyou', 'action_woocommerce_thankyou', 10, 1 );
// Display new column on WooCommerce admin orders list (header)
function filter_manage_edit_shop_order_columns( $columns )
$columns['customer_country'] = __( 'Customer Country', 'woocommerce' );
return $columns;
add_filter( 'manage_edit-shop_order_columns', 'filter_manage_edit_shop_order_columns', 10, 1 );
// Display details after order status column, on order admin list (populate the column)
function action_manage_shop_order_posts_custom_column( $column, $post_id )
// Compare
if ( $column == 'customer_country' )
// Get order
$order = wc_get_order( $post_id );
// Get meta
$shipping_country_full_name = $order->get_meta( '_shipping_country_full_name' );
// NOT empty
if ( ! empty ( $shipping_country_full_name ) )
echo $shipping_country_full_name;
else
echo __( 'N/A', 'woocommerce' );
add_action( 'manage_shop_order_posts_custom_column' , 'action_manage_shop_order_posts_custom_column', 10, 2 );
// Make custom column sortable
function filter_manage_edit_shop_order_sortable_columns( $sortable_columns )
return wp_parse_args( array( 'customer_country' => '_shipping_country_full_name' ), $sortable_columns );
add_filter( 'manage_edit-shop_order_sortable_columns', 'filter_manage_edit_shop_order_sortable_columns', 10, 1 );
// Orderby for custom sortable column
function action_pre_get_posts( $query )
// If it is not admin area, exit
if ( ! is_admin() ) return;
global $pagenow;
// Compare
if ( $pagenow === 'edit.php' && isset( $_GET['post_type'] ) && $_GET['post_type'] === 'shop_order' )
// Get orderby
$orderby = $query->get( 'orderby' );
// Set query
if ( $orderby == '_shipping_country_full_name' )
$query->set( 'meta_key', '_shipping_country_full_name' );
$query->set( 'orderby', 'meta_value' );
add_action( 'pre_get_posts', 'action_pre_get_posts', 10, 1 );
// Make searchable
function filter_woocommerce_shop_order_search_fields( $meta_keys )
$meta_keys[] = '_shipping_country_full_name';
return $meta_keys;
add_filter( 'woocommerce_shop_order_search_fields', 'filter_woocommerce_shop_order_search_fields', 10, 1 );
这样做的缺点是现有订单没有该数据,因此您还必须为所有这些订单添加此数据, 然后可以使用以下函数再次添加:
function action_wp_footer()
$limit = 50;
// Args
$args = array(
'limit' => $limit,
'meta_key' => '_shipping_country_full_name',
'meta_compare' => 'NOT EXISTS',
);
// Get orders
$orders = wc_get_orders( $args );
// NOT empty
if ( ! empty ( $orders ) )
// Loop through orders
foreach ( $orders as $order )
// Is a WC_Order
if ( is_a( $order, 'WC_Order' ) )
// Get full shipping country name
$user_geo_country = get_user_geo_country( $order->get_customer_ip_address() );
// NOT empty
if ( ! empty( $user_geo_country ) )
// Update meta data
$order->update_meta_data( '_shipping_country_full_name', $user_geo_country );
else
// NOT available
$na = __( 'N/A', 'woocommerce' );
// Update meta data
$order->update_meta_data( '_shipping_country_full_name', $na );
// Save
$order->save();
add_action( 'wp_footer', 'action_wp_footer' );
每次您/访问者浏览您网站的前端页面时,都会触发该功能。按 50(限制)处理订单更加安全,并且可以避免超时或错误。现有订单全部更新后,可取消此功能
【讨论】:
以上是关于在 WooCommerce 管理订单列表中添加可排序和可搜索的“客户国家/地区”列的主要内容,如果未能解决你的问题,请参考以下文章
在 WooCommerce 管理订单列表中添加可排序和可搜索的“客户国家/地区”列
将自定义批量操作添加到 Woocommerce 3 中的管理订单列表
在 Woocommerce 订单管理列表中显示用户失败并取消订单计数
在 WooCommerce 管理员订单列表上显示产品图片的问题