Top Sellers of the Last 30 Days Widget
Adds a dashboard widget listing your five best-selling products of the past 30 days by units sold, with links to edit each product.
Opens WPIDE on
Code
add_action( 'wp_dashboard_setup', function () {
if ( ! current_user_can( 'view_woocommerce_reports' ) ) {
return;
}
wp_add_dashboard_widget( 'wpide_top_sellers', 'Top sellers (30 days)', function () {
global $wpdb;
$rows = get_transient( 'wpide_top_sellers' );
if ( false === $rows ) {
$since = gmdate( 'Y-m-d H:i:s', time() - 30 * DAY_IN_SECONDS );
$hpos = class_exists( '\Automattic\WooCommerce\Utilities\OrderUtil' ) && \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled();
$join = $hpos
? "INNER JOIN {$wpdb->prefix}wc_orders o ON o.id = oi.order_id AND o.type = 'shop_order' AND o.status IN ('wc-processing','wc-completed') AND o.date_created_gmt >= %s"
: "INNER JOIN {$wpdb->posts} o ON o.ID = oi.order_id AND o.post_type = 'shop_order' AND o.post_status IN ('wc-processing','wc-completed') AND o.post_date_gmt >= %s";
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $join contains only table names and a placeholder.
$rows = $wpdb->get_results( $wpdb->prepare(
"SELECT pid.meta_value AS product_id, SUM(qty.meta_value) AS units
FROM {$wpdb->prefix}woocommerce_order_items oi
{$join}
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta pid ON pid.order_item_id = oi.order_item_id AND pid.meta_key = '_product_id'
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta qty ON qty.order_item_id = oi.order_item_id AND qty.meta_key = '_qty'
WHERE oi.order_item_type = 'line_item'
GROUP BY pid.meta_value ORDER BY units DESC LIMIT 5",
$since
) );
set_transient( 'wpide_top_sellers', $rows, HOUR_IN_SECONDS );
}
if ( ! $rows ) {
echo '<p>' . esc_html( 'No sales in the last 30 days.' ) . '</p>';
return;
}
echo '<ol>';
foreach ( $rows as $row ) {
printf( '<li><a href="%1$s">%2$s</a> – %3$s</li>', esc_url( get_edit_post_link( $row->product_id ) ), esc_html( get_the_title( $row->product_id ) ), esc_html( sprintf( '%s sold', wc_stock_amount( $row->units ) ) ) );
}
echo '</ol>';
} );
} );
Notes
Counts processing and completed orders, caches the list for an hour and works with HPOS and legacy order storage.
How to add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.