Reputation:
I've managed to put this together even though I do not fully understand it all. The goal is to have a custom tab called "Customer List" and in that tab (WooCommerce Settings -> Customer List) show a list of all customers and their details.
It also only works if there's only one user.
Problem is, I'm getting array
only for the Order Count
and for Last Order
I don't even know how to get it.
The table itself is kind of pressed together, making it hard to read. Anyway, any help on getting this to work and to look good is very much appreciated.
Here's the code:
add_action( 'woocommerce_settings_tabs', 'add_customer_tab_to_wc' );
function add_customer_tab_to_wc() {
$current_tab = ( $_GET['tab'] == 'customer' ) ? 'nav-tab-active' : '';
echo '<a href="admin.php?page=wc-settings&tab=customer" class="nav-tab '.$current_tab.'">'.__( "Customer List", "astra" ).'</a>'; }
add_action( 'woocommerce_settings_custom', 'customer_list_content' );
function customer_list_content() {
global $wpdb;
$user_id = get_current_user_id();
$customer_total_purchase_sum = $wpdb->get_var( "
SELECT SUM(pm.meta_value) FROM {$wpdb->prefix}postmeta as pm
INNER JOIN {$wpdb->prefix}posts as p ON pm.post_id = p.ID
INNER JOIN {$wpdb->prefix}postmeta as pm2 ON pm.post_id = pm2.post_id
WHERE p.post_status LIKE 'wc-completed' AND p.post_type LIKE 'shop_order'
AND pm.meta_key LIKE '_order_total' AND pm2.meta_key LIKE '_customer_user'
AND pm2.meta_value LIKE $user_id
" );
$customer = wp_get_current_user();
$customer_orders = get_posts( array(
'numberposts' => -1,
'meta_key' => '_customer_user',
'meta_value' => get_current_user_id(),
'post_type' => wc_get_order_types(),
'post_status' => array_keys( wc_get_order_statuses() ),
) );
global $user_login;
$user = get_user_by('login', $user_login );
$customeremail = $user->billing_email;
$customers = get_users( 'orderby=nicename&role=customer' );
foreach ( $customers as $user) {
$table_display = '<table class="user-data">
<thead>
<tr>
<th style="font-weight: bold;">'. __( 'First Name', 'woocommerce' ) .'</th>
<th style="font-weight: bold;">'. __( 'Lat Name', 'woocommerce' ) .'</th>
<th style="font-weight: bold;">'. __( 'Address', 'woocommerce' ) .'</th>
<th style="font-weight: bold;">'. __( 'ZIP Code', 'woocommerce' ) .'</th>
<th style="font-weight: bold;">'. __( 'City', 'woocommerce' ) .'</th>
<th style="font-weight: bold;">'. __( 'Phone', 'woocommerce' ) .'</th>
<th style="font-weight: bold;">'. __( 'Email', 'woocommerce' ) .'</th>
<th style="font-weight: bold;">'. __( 'Money Spent', 'woocommerce' ) .'</th>
<th style="font-weight: bold;">'. __( 'Order Count', 'woocommerce' ) .'</th>
<th style="font-weight: bold;">'. __( 'Last Order', 'woocommerce' ) .'</th>
</tr>
</thead>
<tbody>';
$table_display .= '
<tr>
<td>' . esc_html( $user->first_name ) .'</td>
<td>' . esc_html( $user->last_name ) .'</td>
<td>' . get_user_meta( $user->ID, 'billing_address_1', true ) .'</td>
<td>' . get_user_meta( $user->ID, 'billing_postcode', true ) .'</td>
<td>' . get_user_meta( $user->ID, 'billing_city', true ) .'</td>
<td>' . get_user_meta( $user->ID, 'billing_phone', true ) .'</td>
<td>' . $customeremail .'</td>
<td>'. $customer_total_purchase_sum .'</td>
<td>'. $customer_orders .'</td>
<td>last order</td>
</tr>';
$table_display .= '
</tbody>
</table>';
echo $table_display;
}
}
Upvotes: 2
Views: 3922
Reputation: 254378
There are a lot of mistakes and errors in your code. I have revisited your code deeply and make it much more lighter:
// Add a custom setting tab to Woocommerce > Settings section
add_action( 'woocommerce_settings_tabs', 'wc_settings_tabs_customer_list_tab' );
function wc_settings_tabs_customer_list_tab() {
$current_tab = ( isset($_GET['tab']) && $_GET['tab'] === 'customer_list' ) ? 'nav-tab-active' : '';
echo '<a href="admin.php?page=wc-settings&tab=customer_list" class="nav-tab '.$current_tab.'">'.__( "Customer List", "woocommerce" ).'</a>';
}
// The setting tab content
add_action( 'woocommerce_settings_customer_list', 'display_customer_list_tab_content' );
function display_customer_list_tab_content() {
global $wpdb;
// Styling the table a bit
echo '<style> table.user-data th { font-weight: bold; } table.user-data, th, td { border: solid 1px #999; } </style>';
$table_display = '<table class="user-data" cellspacing="0" cellpadding="6"><thead><tr>
<th>'. __( 'ID', 'woocommerce' ) .'</th>
<th>'. __( 'First Name', 'woocommerce' ) .'</th>
<th>'. __( 'Lat Name', 'woocommerce' ) .'</th>
<th>'. __( 'Address', 'woocommerce' ) .'</th>
<th>'. __( 'ZIP Code', 'woocommerce' ) .'</th>
<th>'. __( 'City', 'woocommerce' ) .'</th>
<th>'. __( 'Phone', 'woocommerce' ) .'</th>
<th>'. __( 'Email', 'woocommerce' ) .'</th>
<th>'. __( 'Total Spent', 'woocommerce' ) .'</th>
<th>'. __( 'Order count', 'woocommerce' ) .'</th>
<th>'. __( 'Last order', 'woocommerce' ) .'</th>
</tr></thead>
<tbody>';
// Loop through customers
foreach ( get_users( 'orderby=nicename&role=customer' ) as $key => $customer ) {
// Customer total purchased
$total_purchased = (float) $wpdb->get_var( "
SELECT SUM(pm.meta_value) FROM {$wpdb->prefix}postmeta as pm
INNER JOIN {$wpdb->prefix}posts as p ON pm.post_id = p.ID
INNER JOIN {$wpdb->prefix}postmeta as pm2 ON pm.post_id = pm2.post_id
WHERE p.post_status = 'wc-completed' AND p.post_type = 'shop_order'
AND pm.meta_key = '_order_total' AND pm2.meta_key = '_customer_user'
AND pm2.meta_value = {$customer->ID}
" );
// Customer orders count
$orders_count = (int) $wpdb->get_var( "
SELECT DISTINCT COUNT(p.ID) FROM {$wpdb->prefix}posts as p
INNER JOIN {$wpdb->prefix}postmeta as pm ON p.ID = pm.post_id
WHERE p.post_type = 'shop_order' AND pm.meta_key = '_customer_user'
AND pm.meta_value = {$customer->ID}
" );
// Customer last order ID
$last_order_id = (int) $wpdb->get_var( "
SELECT MAX(p.ID) FROM {$wpdb->prefix}posts as p
INNER JOIN {$wpdb->prefix}postmeta as pm ON p.ID = pm.post_id
WHERE p.post_type = 'shop_order' AND pm.meta_key = '_customer_user'
AND pm.meta_value = {$customer->ID}
" );
$user_link = 'user-edit.php?user_id=' . $customer->ID;
$last_order_link = 'post.php?post='.$last_order_id.'&action=edit';
$table_display .= '<tr>
<td align="center"><a href="'.$user_link.'">' . esc_attr( $customer->ID ) .'</a></td>
<td>' . esc_html( $customer->first_name ) .'</td>
<td>' . esc_html( $customer->last_name ) .'</td>
<td>' . esc_html( $customer->billing_address_1 ) .'</td>
<td>' . esc_attr( $customer->billing_postcode ) .'</td>
<td>' . esc_attr( $customer->billing_city ) .'</td>
<td>' . esc_attr( $customer->billing_phone ) .'</td>
<td><a href="mailto:'.$customer->billing_email.'">' . esc_attr( $customer->billing_email ) .'</a></td>
<td align="right">'. ( $total_purchased > 0 ? wc_price( $total_purchased ) : ' - ' ) . '</td>
<td align="center">'. $orders_count . '</td>
<td align="center"><a href="'.$last_order_link.'">' . ( $last_order_id > 0 ? $last_order_id : ' - ' ) . '</a></td>
</tr>';
}
// Output the table
echo $table_display . '</tbody></table>';
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Note: When you will have more customers, your approach will be too heavy (too many queries and data to display)… So you should need to make a
WP_User_Query
including pagination to split the data in multiple subpages.
Upvotes: 1