Добавьте сортируемый и доступный для поиска столбец «страна клиента» в список заказов администратора WooCommerce

#php #wordpress #woocommerce #orders #country

#php #wordpress #woocommerce #заказы #Страна

Вопрос:

Я добавил столбец «Страна клиента» в таблицу заказов 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-gt;ID );  echo get_user_geo_country( $order-gt;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-gt;geolocate_ip( $user_ip ); // Get geolocated user data  $country = $user_geo['country']; // Get the country code   return WC()-gt;countries-gt;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-gt;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-gt;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' =gt; '_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' amp;amp; isset( $_GET['post_type'] ) amp;amp; $_GET['post_type'] === 'shop_order' ) {   // Get orderby  $orderby = $query-gt;get( 'orderby' );   // Set query  if ( $orderby == '_shipping_country' ) {   $query-gt;set( 'meta_key', '_shipping_country' );  $query-gt;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-gt;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-gt;geolocate_ip( $user_ip );    // Get the country code  $country = $user_geo['country'];   // Return the country name  return WC()-gt;countries-gt;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-gt;get_customer_ip_address() );   // NOT empty  if ( ! empty( $user_geo_country ) ) {  // Update meta data  $order-gt;update_meta_data( '_shipping_country_full_name', $user_geo_country );  } else {  // NOT available  $na = __( 'N/A', 'woocommerce' );   // Update meta data   $order-gt;update_meta_data( '_shipping_country_full_name', $na );  }    // Save  $order-gt;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-gt;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' =gt; '_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' amp;amp; isset( $_GET['post_type'] ) amp;amp; $_GET['post_type'] === 'shop_order' ) {   // Get orderby  $orderby = $query-gt;get( 'orderby' );   // Set query  if ( $orderby == '_shipping_country_full_name' ) {   $query-gt;set( 'meta_key', '_shipping_country_full_name' );  $query-gt;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' =gt; $limit,  'meta_key' =gt; '_shipping_country_full_name',  'meta_compare' =gt; '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-gt;get_customer_ip_address() );    // NOT empty  if ( ! empty( $user_geo_country ) ) {  // Update meta data  $order-gt;update_meta_data( '_shipping_country_full_name', $user_geo_country );  } else {  // NOT available  $na = __( 'N/A', 'woocommerce' );   // Update meta data   $order-gt;update_meta_data( '_shipping_country_full_name', $na );  }    // Save  $order-gt;save();  }  }  } } add_action( 'wp_footer', 'action_wp_footer' );  

Каждый раз, когда вы/посетитель просматриваете главную страницу вашего сайта, эта функция будет срабатывать. Обработка заказов на 50 (лимит) просто более безопасна и позволит избежать тайм-аута или ошибок. Когда все существующие заказы будут обновлены, эта функция может быть удалена