Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrkaluzny/5c9e08fdca81ec23a06a60d648914cca to your computer and use it in GitHub Desktop.
Save mrkaluzny/5c9e08fdca81ec23a06a60d648914cca to your computer and use it in GitHub Desktop.
WooCommerce -> Popularity custom sorting based on last 30days of sales
<?php
if (!wp_next_scheduled('set_last_month_product_sales_hook')) {
wp_schedule_event(time(), 'daily', 'set_last_month_product_sales_hook');
}
add_action('set_last_month_product_sales_hook', 'cc_set_last_month_sales');
function cc_set_last_month_sales()
{
$orders = wc_get_orders(
array(
'limit' => -1,
'status' => array_map('wc_get_order_status_name', wc_get_is_paid_statuses()),
'date_after' => date('Y-m-d', strtotime('-1 month')),
'return' => 'ids',
)
);
$identifiers = array();
foreach ($orders as $order) {
$items = wc_get_order($order)->get_items();
foreach ($items as $item) {
array_push($identifiers, $item->get_product_id());
};
};
$counted_sales = array_count_values($identifiers);
$keys = array();
foreach ($counted_sales as $key => $val) {
array_push($keys, $val);
add_post_meta($key, 'wc_last_month_sales', $val);
}
};
function cc_add_postmeta_ordering_args($sort_args)
{
$orderby_value = isset($_GET['orderby']) ? wc_clean($_GET['orderby']) : apply_filters('woocommerce_default_catalog_orderby', get_option('woocommerce_default_catalog_orderby'));
switch ($orderby_value) {
case 'popularity':
$sort_args['orderby'] = 'meta_value';
$sort_args['order'] = 'asc';
$sort_args['meta_key'] = 'wc_last_month_sales';
break;
}
return $sort_args;
}
add_filter('woocommerce_get_catalog_ordering_args', 'cc_add_postmeta_ordering_args');
@kosarlukascz
Copy link

Hello!
It looks really good, but what about products that have not been ordered yet and therefore do not have meta_key = "wc_last_month_sales"?

@mrkaluzny
Copy link
Author

mrkaluzny commented May 20, 2022

@kosarlukascz This can be solved by adding a 0 value to all products before each run of the loop.

function handle_unordered_items()
{ 
  $products_ids = get_posts( array(
        'post_type'        => 'product',
        'numberposts'      => -1,
        'post_status'      => 'publish',
        'fields'           => 'ids',
        'meta_query'       => array( array(
            'key'     => 'wc_last_month_sales',
            'compare' => 'NOT EXISTS',
        ) )
    ) );

  foreach($product_ids as $product_id) {
    add_post_meta($product_id, 'wc_last_month_sales', 0);
  }
}

@missvanna
Copy link

Dear mrkaluzny,
How can I apply these code?which file I need to update?

@missvanna
Copy link

I add the code to theme functions.php is not work, how can I do? waiting for your reply, many thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment