#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 (лимит) просто более безопасна и позволит избежать тайм-аута или ошибок. Когда все существующие заказы будут обновлены, эта функция может быть удалена