Multiple orderby arguments on WooCommerce archive page product query - php

I want to order products on archive pages by stock status (outofstock at the end of list) and price (lowest first).
For now menu order set to default and this code is used:
add_action( 'woocommerce_product_query', 'sort_by_stock_status', 999 );
function sort_by_stock_status( $query ) {
if ( is_admin() ) return;
$query->set( 'meta_key', '_stock_status' );
$query->set( 'orderby', array( 'meta_value' => 'ASC' ) );
}
And this gives me ability to show products ordered by stock status.
I was trying to edit code so it will order by stock AND price...no luck
Here is what i have tried:
add_action( 'woocommerce_product_query', 'sort_by_stock_status_and_menu_order', 999 );
function sort_by_stock_status_and_menu_order( $query ) {
if ( is_admin() ) return;
$query->set( 'meta_key', '_stock_status' );
$query->set( 'orderby', array( 'meta_value' => 'ASC', 'menu_order' => 'ASC' ) );
}
If i set menu to "order by price" i see products order only by price instock and outofstock together...
Could someone please help me with this? Maybe it`s already achieved in some of your websites...))

YOU were very near… You need to make some changes in your code get multiple "orderby" arguments using one string only instead of an array (each argument is separated by a space in this unique string):
add_action( 'woocommerce_product_query', 'sort_by_stock_status_and_menu_order', 999 );
function sort_by_stock_status_and_menu_order( $query ) {
if ( is_admin() ) return;
$query->set( 'meta_key', '_stock_status' );
$query->set( 'orderby', 'meta_value menu_order' );
// $query->set( 'order', 'ASC' ); // <== 'order' argument is already "ASC" by default
}
The "order" query argument is already ASC by default, so there is no need to change it.
Code goes in functions.php file of your active child theme (or active theme). Tested and works.

Related

Query products and order by date and stocks status in WooCommerce

I've set my default orderby query to date.
How do I also include another argument to show in stock products first.
add_filter('woocommerce_get_catalog_ordering_args', 'shop_default_orderby_date');
function shop_default_orderby_date ( $args ) {
if( is_shop() && ( ! isset($_GET['orderby']) || 'menu_order' === $_GET['orderby'] ) ) {
$args['meta_key'] = '';
$args['orderby'] = 'date';
$args['order'] = 'desc';
return $args;
}
}
I came across Multiple orderby arguments on WooCommerce archive page product query.
Is there a way to combine these two?
add_action( 'woocommerce_product_query', 'sort_by_stock_status_and_menu_order', 999 );
function sort_by_stock_status_and_menu_order( $query ) {
if ( is_admin() ) return;
$query->set( 'meta_key', '_stock_status' );
$query->set( 'orderby', 'meta_value menu_order' );
}
Here's the solution to display products by date in descending order (show new products first) and move out-of-stock products to the end of the list:
add_action( 'woocommerce_product_query', 'sort_by_stock_status_and_date', 999 );
function sort_by_stock_status_and_date( $query ) {
if ( is_admin() ) return;
$query->set( 'meta_key', '_stock_status' );
$query->set( 'orderby', array( 'meta_value' => 'ASC', 'date' => 'DESC' ) );
}

Allow to sort products by featured on WooCommerce archive pages

I am trying to give users the ability to sort products on a store page by featured. I use the following code for this purpose:
add_filter( 'woocommerce_get_catalog_ordering_args', 'victor_get_catalog_ordering_args' );
function victor_get_catalog_ordering_args( $args ) {
$orderby_value = isset( $_GET['orderby'] ) ? woocommerce_clean( $_GET['orderby'] ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
if ( 'featured' == $orderby_value ) {
$args['orderby'] = '_featured';
$args['order'] = 'DESC';
$args['meta_key'] = '_featured';
}
return $args;
}
add_filter( 'woocommerce_default_catalog_orderby_options', 'victor_catalog_orderby' );
add_filter( 'woocommerce_catalog_orderby', 'victor_catalog_orderby' );
function victor_catalog_orderby( $sortby ) {
$sortby['featured'] = 'Featured';
return $sortby;
}
But it doesn't work. I'm trying to sort products by featured using: /?orderby=featured But nothing is displayed, except for the message that no products were found for the request. But I know that in the admin panel I have more than 10 products marked as featured. Please help with this issue.I need to be sure to understand what I'm doing wrong.
Your code is a bit outdated and deprecated since Woocommerce 3, where featured products are now set as product_visibility taxonomy for the term name featured, so this needs to be handled in a different way as follows:
add_filter( 'woocommerce_catalog_orderby', 'hugo_boss_catalog_orderby' );
function hugo_boss_catalog_orderby( $orderby ) {
$orderby['featured'] = __('Featured', 'woocommerce');
return $orderby;
}
add_action( 'woocommerce_product_query', 'obama_trump_product_query' );
function obama_trump_product_query( $q ) {
if ( ! is_admin() && isset($_GET['orderby']) && 'featured' === esc_attr($_GET['orderby']) ) {
$tax_query = $q->get('tax_query');
$tax_query[] = array(
'taxonomy' => 'product_visibility',
'field' => 'name',
'terms' => 'featured',
);
$q->set( 'tax_query', $tax_query );
$q->set( 'order', 'DESC' ); // Or "ASC"
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
Related:
Get WooCommerce featured products in a WP_Query
Woocommerce meta_query not working for featured products

Add a new custom default ordering catalog option in Woocommerce

I am trying to get the default order of Woocommerce to be order by SKU.
I have changed the order in the woocommerce settings and added SKU like this:
function sv_add_sku_sorting( $args ) {
$orderby_value = isset( $_GET['orderby'] ) ? wc_clean( $_GET['orderby'] ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
if ( 'sku' == $orderby_value ) {
$args['orderby'] = 'meta_value';
$args['order'] = 'asc';
// ^ lists SKUs alphabetically 0-9, a-z; change to desc for reverse alphabetical
$args['meta_key'] = '_sku';
}
return $args;
}
add_filter( 'woocommerce_get_catalog_ordering_args', 'sv_add_sku_sorting' );
function sv_sku_sorting_orderby( $sortby ) {
$sortby['sku'] = 'Sorteer op referentie';
// Change text above as desired; this shows in the sorting dropdown
return $sortby;
}
add_filter( 'woocommerce_catalog_orderby', 'sv_sku_sorting_orderby' );
add_filter( 'woocommerce_default_catalog_orderby_options', 'sv_sku_sorting_orderby' );
On pageload it still orders on popularity instead of on SKU.
But the dropdown shows order by SKU (Sorteer op referentie)
If I go to another ordering and go back it will correctly order them with ?orderby=sku in the querystring.
Updated (Dec 2018)
You are not using the right hooks in the right way to get default ordering catalog by sku. There is also some missing needed additional code:
add_filter( 'woocommerce_get_catalog_ordering_args', 'enable_catalog_ordering_by_sku' );
function enable_catalog_ordering_by_sku( $args ) {
if ( isset( $_GET['orderby'] ) ) {
if ( 'sku' == $_GET['orderby'] ) {
return array(
'orderby' => 'meta_value_num',
'order' => 'ASC',
'meta_key' => '_sku',
);
}
// Make a clone of "menu_order" (default option)
elseif ( 'natural_order' == $_GET['orderby'] ) {
return array( 'orderby' => 'menu_order title', 'order' => 'ASC' );
}
}
return $args;
}
add_filter( 'woocommerce_catalog_orderby', 'add_catalog_orderby_by_sku' );
function add_catalog_orderby_by_sku( $orderby_options ) {
// Insert "Sort by product reference (sku)" and the clone of "menu_order"
return array(
'sku' => __("Sort by product reference (sku)", "woocommerce"),
'natural_order' => __("Sort by natural shop order", "woocommerce"), // <== To be renamed at your convenience
) + $orderby_options ;
}
add_filter( 'woocommerce_default_catalog_orderby', 'default_catalog_orderby_sku' );
function default_catalog_orderby_sku( $default_orderby ) {
return 'sku';
}
add_action( 'woocommerce_product_query', 'product_query_by_sku' );
function product_query_by_sku( $q ) {
if ( ! isset( $_GET['orderby'] ) && ! is_admin() ) {
$q->set( 'orderby', 'meta_value_num' );
$q->set( 'order', 'ASC' );
$q->set( 'meta_key', '_sku');
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
Related: Sort WooCommerce Products by SKU Numeric (1.2.3.4.5.6........)

Weird Order of Wordpress Category Post

Does anyone have ever seen this?
When we're accessing one of wordpress category post here:
On the top item, it's not the latest posted article instead it's the oldest one.
Which part of the php code should be changed ? It's for wordpress version of 4.5 from this link.
function change_category_order( $query ) {
$category = get_queried_object();
$cat_id=$category->term_id;
if ( $query->is_category($cat_id) && $query->is_main_query() ) {
$query->set( 'order', 'DESC' );
}
}
add_action( 'pre_get_posts', 'change_category_order' );
If you use any custom query add this also in post loop 'order' => 'DESC'
$args = array(
'post_type' => 'post',
'order' => 'DESC', );
$q = new WP_Query($args);
or paste this in function.php
add_action( 'pre_get_posts', 'my_change_sort_order');
function my_change_sort_order($query){
if(is_archive()):
//If you wanted it for the archive of a custom post type use: is_post_type_archive( $post_type )
//Set the order ASC or DESC
$query->set( 'order', 'DESC' );
//Set the orderby
//$query->set( 'orderby', 'title' );
endif;
};

Adding random to Wordpress Query

I have an existing Wordpress page and use for a page to display post the pre_get_post funtions below. The Query filters in the website all posts for the custom post types "branchenbuch" and orders it DESC for a field profiltyp (People with a logo and people without a logo) This way all records are displayed in this sepcific order (people with a logo first). Now within these results (people with a logo) I also want the results to be displayed randomly, that not always the same post comes up first.
Currently this is in my funtions.php:
add_action( 'pre_get_posts', 'custom_post_type_archive' );
function custom_post_type_archive( $query ) {
if( $query->is_main_query() && !is_admin() && is_post_type_archive( 'branchenbuch' ) ) {
$query->set( 'meta_key', 'profiltyp' );
$query->set( 'orderby', 'meta_value' );
$query->set( 'order', 'DESC' );
}
}
I have no idea how to do this? Thanks for your help
I'm not sure I understand your question...but you can use 'orderby' => 'rand' to randomly order query results in WordPress:
if( $query->is_main_query() && !is_admin() && is_post_type_archive( 'branchenbuch' ) ) {
$query->set( 'meta_key', 'profiltyp' );
$query->set( 'orderby', 'rand' );
}
Read more about orderby options in the Codex.
Use the code
get all the selected posts which you need to be shown in the Top in an array let us say $allowed_posts = array(121,233,144,900);
$query->set( 'post__in', $allowed_posts );
$query->set( 'meta_key', 'profiltyp' );
$query->set( 'orderby', 'rand' );

Categories