Link to home
Start Free TrialLog in
Avatar of sharingsunshine
sharingsunshineFlag for United States of America

asked on

In WooCommerce How Do Complex Sort On Category Page

this is a follow-on to this question
https://www.experts-exchange.com/questions/29142368/Need-Help-With-WooCommerce-Custom-Sort.html

Open in new window

I need to have a multiple layer sort.  I now have it sorting on Parent ID but then I need within the the Parent ID for it to be alphabetical.  For example, I have a $2 Off, Buy 4 and a Buy 9.  They need to be in that order but now they are Buy 9, Buy 4 and $2.  I know I can do menu order but that is another tedious task.

If someone can show me how in the code below to do a sort on Alphabetical within Parent ID that would be great.

[code]unction jk_add_custom_sku() {
$args = array(
'label' => __( 'Parent ID', 'woocommerce' ),
'placeholder' => __( 'Enter custom SKU here', 'woocommerce' ),
'id' => 'jk_sku',
'desc_tip' => true,
'description' => __( 'This SKU is for internal use only.', 'woocommerce' ),
);
woocommerce_wp_text_input( $args );
}
add_action( "woocommerce_product_options_sku", "jk_add_custom_sku" );

function jk_save_custom_sku( $post_id ) {
// grab the custom SKU from $_POST
$custom_sku = isset( $_POST[ 'jk_sku' ] ) ? sanitize_text_field( $_POST[ 'jk_sku' ] ) : '';

// grab the product
$product = wc_get_product( $post_id );

// save the custom SKU using WooCommerce built-in functions
$product->update_meta_data( 'jk_sku', $custom_sku );
$product->save();
}

add_action( "woocommerce_process_product_meta", "jk_save_custom_sku" );
//add_action( "save_post_product", "jk_save_custom_sku" );

####### Custom Sort Option ######################

// 1. Create new product filter
 
add_filter( 'woocommerce_get_catalog_ordering_args', 'bbloomer_sort_by_name_woocommerce_shop' );
 
function bbloomer_sort_by_name_woocommerce_shop( $args ) {
     
    $orderby_value = isset( $_GET['orderby'] ) ? wc_clean( (string) wp_unslash( $_GET['orderby'] ) ) : wc_clean( get_query_var( 'orderby' ) );
     
    if ( 'jk_sku' == $orderby_value ) {
        $args['orderby'] = 'jk_sku';
        $args['order'] = 'asc';
        $args['meta_key'] = 'jk_sku';
    }
     
    return $args;
     
}
 
// 2. Add new product filter to Sorting dropdown
 
add_filter( 'woocommerce_catalog_orderby', 'bbloomer_load_custom_woocommerce_catalog_sorting' );
 
function bbloomer_load_custom_woocommerce_catalog_sorting( $options ) {
$options['jk_sku'] = 'Sort by Parent ID (asc)';
return $options;
}

Open in new window

[/code]

Thanks,
Avatar of Robert Granlund
Robert Granlund
Flag of United States of America image

You need to seperate the query into an array, multiple arrays actually, so then you can run each query and then sort.  An example of the structure would be:

$args = array(
    'meta_query' => array(
        'relation' => 'AND',
        'query_one' => array(
            ' $args['orderby'] = 'jk_sku';
        $args['order'] = 'asc';
        $args['meta_key'] = 'jk_sku
        ),
        'query_two' => array(
            'key' => 'key_two',
            'compare' => 'EXISTS', // Optional
        ), 
    ),
    'orderby' => array( 
        'query_one' => 'ASC',
        'query_two' => 'DESC',
    ),
) );

Open in new window

Avatar of sharingsunshine

ASKER

I made an attempt but I am a novice in PHP.  Here is what I came up with.  Hoping the sort would group by parent id and within that be alphabetical.  

add_filter( 'woocommerce_get_catalog_ordering_args', 'bbloomer_sort_by_name_woocommerce_shop' );
 
function bbloomer_sort_by_name_woocommerce_shop( $args ) {
     
    $orderby_value = isset( $_GET['orderby'] ) ? wc_clean( (string) wp_unslash( $_GET['orderby'] ) ) : wc_clean( get_query_var( 'orderby' ) );
     
       
      
		  
	$args = array(
    'meta_query' => array(
        'relation' => 'AND',
        'query_one' => array(
            $args['orderby'] = 'jk_sku',
        $args['order'] = 'asc',
        $args['meta_key'] = 'jk_sku'),
        'query_two' => array(
            'key' => 'name',
            'compare' => 'EXISTS', // Optional
        ),
    ),
    'orderby' => array( 
        'query_one' => 'ASC',
        'query_two' => 'ASC',
    ),
);
    return $args;
}

Open in new window


Here is the sorting option in the dropdown

add_filter( 'woocommerce_catalog_orderby', 'bbloomer_load_custom_woocommerce_catalog_sorting' );
 
function bbloomer_load_custom_woocommerce_catalog_sorting( $options ) {
$options[$args] = 'Sort by Parent ID (asc)';
return $options;
}

Open in new window


In this last function I am wanting to use the logic from the complex sort function.
Put this in your file.... I am assuming this is in functions.php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

Before return $args put:
var_dump ($args);
die();

does anything show up?

This may not be right:
add_filter( 'woocommerce_catalog_orderby', 'bbloomer_load_custom_woocommerce_catalog_sorting' );
 
function bbloomer_load_custom_woocommerce_catalog_sorting( $options ) {
$options[$args] = 'Sort by Parent ID (asc)';
return $options;
}

It may need to be:
add_filter( 'woocommerce_catalog_orderby', 'bbloomer_load_custom_woocommerce_catalog_sorting' );
 
function bbloomer_load_custom_woocommerce_catalog_sorting( $args ) {
$options[$args] = 'Sort by Parent ID (asc)';
return $options;
}

Open in new window


Not sure on that though.  Do the first thing first to see if there is a return.
yes it gives this
array(2) { ["meta_query"]=> array(3) { ["relation"]=> string(3) "AND" ["query_one"]=> array(3) { [0]=> string(6) "jk_sku" [1]=> string(3) "asc" [2]=> string(6) "jk_sku" } ["query_two"]=> array(2) { ["key"]=> string(4) "name" ["compare"]=> string(6) "EXISTS" } } ["orderby"]=> array(2) { ["query_one"]=> string(3) "ASC" ["query_two"]=> string(3) "ASC" } } 

Open in new window

when you take out die(); does anything happen on the page?
array(2) { ["meta_query"]=> array(3) { ["relation"]=> string(3) "AND" ["query_one"]=> array(3) { [0]=> string(6) "jk_sku" [1]=> string(3) "asc" [2]=> string(6) "jk_sku" } ["query_two"]=> array(2) { ["key"]=> string(4) "name" ["compare"]=> string(6) "EXISTS" } } ["orderby"]=> array(2) { ["query_one"]=> string(3) "ASC" ["query_two"]=> string(3) "ASC" } }
Notice: Undefined index: order in C:\xampp\htdocs\tfl\wp-content\plugins\woocommerce\includes\class-wc-query.php on line 388

Open in new window


Warning: Illegal offset type in C:\xampp\htdocs\tfl\wp-content\themes\flatsome-child\functions.php on line 420

Open in new window


this is line 420
$options[$args] = 'Sort by Parent ID (asc)';

Open in new window

$options[$args] = 'Sort by Parent ID (asc)';
var_dump ($options[$args]);
die();

What does that say?
array(2) { ["meta_query"]=> array(3) { ["relation"]=> string(3) "AND" ["query_one"]=> array(3) { [0]=> string(6) "jk_sku" [1]=> string(3) "asc" [2]=> string(6) "jk_sku" } ["query_two"]=> array(2) { ["key"]=> string(4) "name" ["compare"]=> string(6) "EXISTS" } } ["orderby"]=> array(2) { ["query_one"]=> string(3) "ASC" ["query_two"]=> string(3) "ASC" } }
Notice: Undefined index: order in C:\xampp\htdocs\tfl\wp-content\plugins\woocommerce\includes\class-wc-query.php on line 388
Skip to content

Open in new window


Showing 1–12 of 42 results
Warning: Illegal offset type in C:\xampp\htdocs\tfl\wp-content\themes\flatsome-child\functions.php on line 420

Warning: Illegal offset type in C:\xampp\htdocs\tfl\wp-content\themes\flatsome-child\functions.php on line 421
NULL 

Open in new window

Can I see this entire piece of code that has this line:
$options[$args] = 'Sort by Parent ID (asc)';
// 2. Add new product filter to Sorting dropdown
 
add_filter( 'woocommerce_catalog_orderby', 'bbloomer_load_custom_woocommerce_catalog_sorting' );
 
function bbloomer_load_custom_woocommerce_catalog_sorting( $args ) {
$options[$args] = 'Sort by Parent ID (asc)';
	var_dump ($options[$args]);
	die();
//return $options;
}

Open in new window

What happens when you replace it with:

add_filter( 'woocommerce_catalog_orderby', 'bbloomer_load_custom_woocommerce_catalog_sorting' );
 
function bbloomer_load_custom_woocommerce_catalog_sorting( $args ) {
$options[$args] = 'Sort by Parent ID (asc)';
return $options;
}

Open in new window

Is there a url you can share?
it takes away all sort options on every category page.  It is sorting by post_title but not with the parent id or jk_sku.   In other words, it is grouping all the $2 off products then the buy 4 then the buy 9.  Rather than grouping all product together.  It should be $2 off, Buy 4, Buy 9 of the same product.

I can't leave it up since all the options are taken away.
you can see it sorting on parent id only at
https://www.theherbsplace.com/product-category/on-sale/?orderby=jk_sku&paged=1

Open in new window

this is correct except within each product grouping I would like to see it sorted on post_title.
This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.