0

I am trying to sort the products based on views, view counter is working fine, on findings I found that filter (woocommerce_get_catalog_ordering_args) and I checked this is implemented in woocommerce (/includes/class-wc-query.php Line no 583), it should be working fine but it's sorting product based on latest date instead of the views, I don't know what is causing the problem, can anyone check my code and suggest me the good solution or highlight my mistake.

//Product View Counter
add_action("wp", "product_view_counter");
function product_view_counter() {
    global $post;
    if ( is_product() ){
        $meta = get_post_meta( $post->ID, "_total_views_count", true );
        $meta = (int)($meta) ? $meta + 1 : 1;
        update_post_meta( $post->ID, "_total_views_count", $meta );
    }
}

add_filter( 'woocommerce_get_catalog_ordering_args', 'woo_add_postmeta_ordering_args' );
function woo_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' ) );
    if ($orderby_value == "popularity"){
        $sort_args['meta_key'] = '_total_views_count';
        $sort_args['orderby'] = 'meta_value_num';
        $sort_args['order'] = 'desc';
        $sort_args['meta_type'] = 'NUMERIC';
    }
    return $sort_args;
}

Thank you

  • Check this answer - https://stackoverflow.com/questions/52273655/add-a-new-custom-default-ordering-catalog-option-in-woocommerce – Snuffy Jun 09 '22 at 13:35
  • Thanks for sharing this Martin, my code is also similar to this one, I have seen this before but it’s not working for view counter – Qamar Ul Din Hamza Jun 11 '22 at 22:52

1 Answers1

0

When you first implement the code, the product list you want to sort don't have the meta _total_views_count yet. First, you should initialize once all products with the meta (0 view). And then also add the meta when a product is saved.

  1. Initialize your existing products with the new meta. Run this only once. Visit any page and erase the code.
function initialize_total_views_count_for_existing_products() {
    $args = array(
        'post_type' => 'product',
        'posts_per_page' => -1,
    );

    $products = new WP_Query($args);

    if ($products->have_posts()) {
        while ($products->have_posts()) {
            $products->the_post();

            $product_id = get_the_ID();

            // Check if the meta key already exists
            $total_views_count = get_post_meta($product_id, '_total_views_count', true);

            if (empty($total_views_count)) {
                // If meta key doesn't exist, set it to 0
                update_post_meta($product_id, '_total_views_count', 0);
            }
        }
    }

    wp_reset_postdata();
}
  1. Add the meta for new and saved products.
add_action('woocommerce_new_product', 'initialize_total_views_count');
function initialize_total_views_count($product_id)
{
    add_post_meta($product_id, '_total_views_count', 0, true);
}

BONUS Part

//Product View Counter
add_action("woocommerce_before_single_product", "product_view_counter"); 

function product_view_counter() {
    $meta = get_post_meta( get_the_ID(), "_total_views_count", true );
    $meta = (int)($meta) ? $meta + 1 : 1;
    update_post_meta( get_the_ID(), "_total_views_count", $meta );
}

a. Hooking to wp is unecessary as the code will load on every page. Change to woocommerce_before_single_product so the code only run at product detail page.

b. Removing the need for conditional checking.

c. Removing the need for global variable and change to get_the_ID() as we're on product page.