How to create custom sort in Woocommerce - php

I am creating a custom sort name "price-asc" which sort products based on highest price.
My solution is:
1- create key_meta called "_highest_price" to store the highest price for each product
2- create a custom "price-asc" in filter woocommerce_catalog_orderby
3- custom "orderby", "order", "meta_key" in filter woocommerce_get_catalog_ordering_args
functions.php
// step 1
function my_save_post_product( $post_id, $post, $update ) {
if( ! $update ) // no further actions if no changes
return;
if( $post->post_status !== 'publish' ) // no further actions if product is not public
return;
$product = wc_get_product( $post_id );
if( $product->product_type == 'variable' ) :
update_post_meta( $post_id, '_highest_price', $product->get_variation_price( 'max', true ) );
elseif( $product->product_type == 'simple' ) :
update_post_meta( $post_id, '_highest_price', $product->get_price() );
endif;
}
add_action( 'save_post_product', 'my_save_post_product', 10, 3 );
// step 2
function my_woocommerce_catalog_orderby( $options ) {
//...
$options['price-asc'] = __( 'A different low to high', 'mytheme' );
return $options;
}
add_filter( 'woocommerce_catalog_orderby', 'my_woocommerce_catalog_orderby' );
// step 3
function my_woocommerce_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 ( $orderby_value == 'price-asc' ) :
$args['orderby'] = 'meta_value_num';
$args['order'] = 'ASC';
$args['meta_key'] = '_highest_price';
endif;
return $args;
}
add_filter( 'woocommerce_get_catalog_ordering_args', 'my_woocommerce_get_catalog_ordering_args' );
Then I go to https://example.com/products/?orderby=price-asc
However, the order doesn't display as expected. Product with _highest_price "22092" should displays before product with _highest_price "1177000" as 22092 < 1177000.
Here are my database and display. Please help
database
display

After a while, I finally got my answer. I just simply changed "price-asc" to "price_asc". Why?
In woocommerce\includes\class-wc-query.php
before line 461: $orderby_value = "price-asc"
line 461:
$orderby_value = is_array( $orderby_value ) ? $orderby_value : explode( '-', $orderby_value );
after this line $orderby_value is an array with [0] => "price", [1] => "asc"
line 462:
$orderby = esc_attr( $orderby_value[0] );
this time, $orderby = "price" which tells the system continuously runs at lines 498-501
case 'price':
$callback = 'DESC' === $order ? 'order_by_price_desc_post_clauses' : 'order_by_price_asc_post_clauses';
add_filter( 'posts_clauses', array( $this, $callback ) );
break;
=> it's wrong. $orderby should not be "price" at the end.
My suggestion: it might only apply for keyword "price" but for the future, we should name our sorting id with "_" instead of "-". E.g custom_sort_id instead of custom-sort-id.

Related

Sort products by custom meta key in Woocommerce archives

I want to sorting product by discount percentage by high to low or low to high. I am using urna theme but sorting not working properly. I want it discount percentage wise if discount percentage same it will show price high to low or low to high. I using more sorting plugins. But its not working properly. Kindly help this. I am a beginner in woocommerce.
Please help
My code
<?php
add_filter( 'woocommerce_get_catalog_ordering_args', 'mycode_woocommerce_add_salediscount_to_catalog_ordering_args' );
function mycode_woocommerce_add_salediscount_to_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 ( 'discount' == $orderby_value ) {
$args['orderby'] = 'meta_value_num';
$args['order'] = 'DESC';
$args['meta_key'] = '_dfrps_salediscount';
}
return $args;
}
add_filter( 'woocommerce_default_catalog_orderby_options', 'mycode_woocommerce_add_salediscount_to_catalog_orderby' );
add_filter( 'woocommerce_catalog_orderby', 'mycode_woocommerce_add_salediscount_to_catalog_orderby' );
function mycode_woocommerce_add_salediscount_to_catalog_orderby( $sortby ) {
$sortby['discount'] = 'Sort by discount';
return $sortby;
}
You can try to use the following instead:
add_filter( 'woocommerce_get_catalog_ordering_args', 'enable_catalog_ordering_by_meta' );
function enable_catalog_ordering_by_meta( $args ) {
$meta_key = '_dfrps_salediscount';
if ( isset( $_GET['orderby'] ) ) {
if ( 'custom_meta1' == $_GET['orderby'] ) {
return array(
'orderby' => 'meta_value_num',
'order' => 'DESC',
'meta_key' => $meta_key,
);
}
// 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_meta' );
function add_catalog_orderby_by_meta( $orderby_options ) {
// Insert "Sort by product reference (sku)" and the clone of "menu_order"
return array(
'custom_meta1' => __("Sort by discount", "woocommerce");
'natural_order' => __("Sort by natural order", "woocommerce"), // <== To be renamed at your convenience
) + $orderby_options ;
}
add_filter( 'woocommerce_default_catalog_orderby', 'default_catalog_orderby_meta' );
function default_catalog_orderby_meta( $default_orderby ) {
return 'custom_meta1';
}
add_action( 'woocommerce_product_query', 'product_query_by_meta' );
function product_query_by_meta( $q ) {
$meta_key = '_dfrps_salediscount';
if ( ! isset( $_GET['orderby'] ) && ! is_admin() ) {
$q->set( 'orderby', 'meta_value_num' );
$q->set( 'order', 'DESC' );
$q->set( 'meta_key', $meta_key);
}
}
Code goes in functions.php file of the active child theme (or active theme). It should works.
You can try this code.Add this code in cureent active theme functions.php file.
add_action( 'woocommerce_product_query', 'vzm_product_query_by_meta' );
function vzm_product_query_by_meta( $q ) {
$meta_key = 'staff_pick'; //your-meta key
if ( ! isset( $_GET['orderby'] )) {
$q->set( 'orderby', 'meta_value_num' ); // for numeric value
$q->set( 'order', 'ASC' );
$q->set( 'meta_key', $meta_key);
}
}

Sorting in variable products by availability

Im using this code in displaying the sum of the product variable stock quantities from a parent variable products based on:
Display the stock availability for all product types in Woocommerce archive pages.
How can I make the sorting options to look at in the above script rather than the _stock meta? here is the script that i am using to sort the products.
protected function get_settings_options() {
$options = array(
'by_stock' => __( 'Available Stock', 'woocommerce-extra-product-sorting-options' ),
);
if ( ! self::is_wc_gte( '3.0' ) ) {
$options['featured_first'] = __( 'Featured First', 'woocommerce-extra-product-sorting-options' );
}
return $options;
}
foreach( $new_sorting_options as $option ) {
switch ( $option ) {
case 'by_stock':
$sortby['by_stock'] = __( 'Sort by availability', 'woocommerce-extra-product-sorting-options' );
break;
}
}
return $sortby;
}
public function add_new_shop_ordering_args( $sort_args ) {
// If we have the orderby via URL, let's pass it in.
// This means we're on a shop / archive, so if we don't have it, use the default.
if ( isset( $_GET['orderby'] ) ) {
$orderby_value = wc_clean( $_GET['orderby'] );
} else {
$orderby_value = apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
}
// Since a shortcode can be used on a non-WC page, we won't have $_GET['orderby'] --
// grab it from the passed in sorting args instead for non-WC pages.
// Don't use this on WC archives so we don't break the default option
if ( ! is_post_type_archive( 'product' ) && ! is_shop() && isset( $sort_args['orderby'] ) ) {
$orderby_value = $sort_args['orderby'];
}
$fallback = apply_filters( 'wc_extra_sorting_options_fallback', 'title', $orderby_value );
$fallback_order = apply_filters( 'wc_extra_sorting_options_fallback_order', 'ASC', $orderby_value );
switch( $orderby_value ) {
case 'by_stock':
$sort_args['orderby'] = array( 'meta_value_num' => 'DESC', $fallback => $fallback_order );
$sort_args['meta_key'] = '_stock';
break;
}
return $sort_args;
}

Create programmatically a product using CRUD methods in Woocommerce 3

I'd like to create a new Woocommerce product programmatically with PHP code and I have tried it with the Woocommerce 3 CRUD methods:
//Woocommerce CRUD
$objProduct = new WC_Product_Simple();
$objProduct->set_name('My Product 1'); //Set product name.
$objProduct->set_status('publish'); //Set product status.
//$objProduct->set_featured(FALSE); //Set if the product is featured. | bool
$objProduct->set_catalog_visibility('visible'); //Set catalog visibility. | string $visibility Options: 'hidden', 'visible', 'search' and 'catalog'.
$objProduct->set_description('My custom long description'); //Set product description.
//$objProduct->set_short_description('My short description'); //Set product short description.
//$objProduct->set_sku('U-123'); //Set SKU
$objProduct->set_price(5.00); //Set the product's active price.
//$objProduct->set_regular_price(5.00); //Set the product's regular price.
//$objProduct->set_sale_price(); //Set the product's sale price.
//$objProduct->set_date_on_sale_from(); //Set date on sale from. | string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if their is no date.
//$objProduct->set_date_on_sale_to();//Set date on sale to. | string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if their is no date.
//$objProduct->set_manage_stock(TRUE); //Set if product manage stock. | bool
//$objProduct->set_stock_quantity(10); //Set number of items available for sale.
//$objProduct->set_stock_status('instock'); //Set stock status. | string $status 'instock', 'outofstock' and 'onbackorder'
//$objProduct->set_backorders('no'); //Set backorders. | string $backorders Options: 'yes', 'no' or 'notify'.
//$objProduct->set_sold_individually(FALSE); //Set if should be sold individually. | bool
//$objProduct->set_weight(); //Set the product's weight.
//$objProduct->set_length(); //Set the product length.
//$objProduct->set_width(); //Set the product width.
//$objProduct->set_height(); //Set the product height.
//$objProduct->set_upsell_ids($upsell_ids); //Set upsell IDs. | array $upsell_ids IDs from the up-sell products.
//$objProduct->set_cross_sell_ids($cross_sell_ids); //Set crosssell IDs. | array $cross_sell_ids IDs from the cross-sell products.
$objProduct->set_reviews_allowed(TRUE); //Set if reviews is allowed. | bool
//$objProduct->set_purchase_note($purchase_note); //Set purchase note. | string $purchase_note Purchase note.
$attribute = new WC_Product_Attribute();
$attribute->set_id(wc_attribute_taxonomy_id_by_name('pa_color')); //if passing the attribute name to get the ID
$attribute->set_name('pa_color'); //attribute name
$attribute->set_options('red'); // attribute value
$attribute->set_position(1); //attribute display order
$attribute->set_visible(1); //attribute visiblity
$attribute->set_variation(0);//to use this attribute as varint or not
$raw_attributes[] = $attribute; //<--- storing the attribute in an array
$attribute = new WC_Product_Attribute();
$attribute->set_id(25);
$attribute->set_name('pa_size');
$attribute->set_options('XL');
$attribute->set_position(2);
$attribute->set_visible(1);
$attribute->set_variation(0);
$raw_attributes[] = $attribute; //<--- storing the attribute in an array
$objProduct->set_attributes($raw_attributes); //Set product attributes. | array $raw_attributes Array of WC_Product_Attribute objects.
//$objProduct->set_category_ids($term_ids); //Set the product categories. | array $term_ids List of terms IDs.
//$objProduct->set_tag_ids($term_ids); //Set the product tags. | array $term_ids List of terms IDs.
//$objProduct->set_image_id(); //Set main image ID. | int|string $image_id Product image id.
//$objProduct->set_gallery_image_ids(); //Set gallery attachment ids. | array $image_ids List of image ids.
$new_product_id = $objProduct->save(); //Saving the data to create new product, it will return product ID.
return;
}
But I get this error:
22-Oct-2018 20:25:19 UTC] PHP Fatal error: Uncaught Error: Class 'WC_Product_Simple' not found in /home/u1771p590/domains/famyfuerza.com/public_html/store/wp-content/plugins/ff-dropship-data-scraper/ff-dropship-data-scraper.php:165
Stack trace:
- #0 /home/u1771p590/domains/famyfuerza.com/public_html/store/wp-content/plugins/ff-dropship-data-scraper/ff-dropship-data-scraper.php(233): curl_download('https://www.ban...')
- #1 /home/u1771p590/domains/famyfuerza.com/public_html/store/wp-settings.php(305): include_once('/home/u1771p590...')
- #2 /home/u1771p590/domains/famyfuerza.com/public_html/store/wp-config.php(112): require_once('/home/u1771p590...')
- #3 /home/u1771p590/domains/famyfuerza.com/public_html/store/wp-load.php(37): require_once('/home/u1771p590...')
- #4 /home/u1771p590/domains/famyfuerza.com/public_html/store/wp-admin/admin.php(31): require_once('/home/u1771p590...')
- #5 /home/u1771p590/domains/famyfuerza.com/public_html/store/wp-admin/index.php(10): require_once('/home/u1771p590...')
- #6 {main}
thrown in /home/u1771p590/domains/famyfuerza.com/public_html/store/wp-content/plugins/ff-dropship-data-scraper/ff-dropship-data-scraper.php on line 165
I have tried to include the simple product class, but that produced another error which said that another class was missing.
Does somebody know how to fix this? Or has another method to create a woocommerce product via code?
You are not accessing the WC_Product_simple instance object from your custom Dropship Data Scraper plugin.
The guilty can be mostly 2 things:
You have not installed Woocommerce.
The plugin Dropship Data Scraper is outdated and needs changes, to handle woocommerce.
Try to include the global Woocommerce object and to enable Woocommerce support in your plugin.
To create a product programmatically using CRUD methods introduced in Woocommerce 3 here is the correct way to make it work.
If you need to handle product attributes creation or product variations creation, refer to:
Create new product attribute programmatically in Woocommerce
Create programmatically a WooCommerce product variation with new attribute values
Create programmatically a variable product and two new attributes in WooCommerce
All product attributes and their term values need to be created before. Same thing for product categories and product tags.
1) The code functions:
// Custom function for product creation (For Woocommerce 3+ only)
function create_product( $args ){
if( ! function_exists('wc_get_product_object_type') && ! function_exists('wc_prepare_product_attributes') )
return false;
// Get an empty instance of the product object (defining it's type)
$product = wc_get_product_object_type( $args['type'] );
if( ! $product )
return false;
// Product name (Title) and slug
$product->set_name( $args['name'] ); // Name (title).
if( isset( $args['slug'] ) )
$product->set_name( $args['slug'] );
// Description and short description:
$product->set_description( $args['description'] );
$product->set_short_description( $args['short_description'] );
// Status ('publish', 'pending', 'draft' or 'trash')
$product->set_status( isset($args['status']) ? $args['status'] : 'publish' );
// Visibility ('hidden', 'visible', 'search' or 'catalog')
$product->set_catalog_visibility( isset($args['visibility']) ? $args['visibility'] : 'visible' );
// Featured (boolean)
$product->set_featured( isset($args['featured']) ? $args['featured'] : false );
// Virtual (boolean)
$product->set_virtual( isset($args['virtual']) ? $args['virtual'] : false );
// Prices
$product->set_regular_price( $args['regular_price'] );
$product->set_sale_price( isset( $args['sale_price'] ) ? $args['sale_price'] : '' );
$product->set_price( isset( $args['sale_price'] ) ? $args['sale_price'] : $args['regular_price'] );
if( isset( $args['sale_price'] ) ){
$product->set_date_on_sale_from( isset( $args['sale_from'] ) ? $args['sale_from'] : '' );
$product->set_date_on_sale_to( isset( $args['sale_to'] ) ? $args['sale_to'] : '' );
}
// Downloadable (boolean)
$product->set_downloadable( isset($args['downloadable']) ? $args['downloadable'] : false );
if( isset($args['downloadable']) && $args['downloadable'] ) {
$product->set_downloads( isset($args['downloads']) ? $args['downloads'] : array() );
$product->set_download_limit( isset($args['download_limit']) ? $args['download_limit'] : '-1' );
$product->set_download_expiry( isset($args['download_expiry']) ? $args['download_expiry'] : '-1' );
}
// Taxes
if ( get_option( 'woocommerce_calc_taxes' ) === 'yes' ) {
$product->set_tax_status( isset($args['tax_status']) ? $args['tax_status'] : 'taxable' );
$product->set_tax_class( isset($args['tax_class']) ? $args['tax_class'] : '' );
}
// SKU and Stock (Not a virtual product)
if( isset($args['virtual']) && ! $args['virtual'] ) {
$product->set_sku( isset( $args['sku'] ) ? $args['sku'] : '' );
$product->set_manage_stock( isset( $args['manage_stock'] ) ? $args['manage_stock'] : false );
$product->set_stock_status( isset( $args['stock_status'] ) ? $args['stock_status'] : 'instock' );
if( isset( $args['manage_stock'] ) && $args['manage_stock'] ) {
$product->set_stock_status( $args['stock_qty'] );
$product->set_backorders( isset( $args['backorders'] ) ? $args['backorders'] : 'no' ); // 'yes', 'no' or 'notify'
}
}
// Sold Individually
$product->set_sold_individually( isset( $args['sold_individually'] ) ? $args['sold_individually'] : false );
// Weight, dimensions and shipping class
$product->set_weight( isset( $args['weight'] ) ? $args['weight'] : '' );
$product->set_length( isset( $args['length'] ) ? $args['length'] : '' );
$product->set_width( isset( $args['width'] ) ? $args['width'] : '' );
$product->set_height( isset( $args['height'] ) ? $args['height'] : '' );
if( isset( $args['shipping_class_id'] ) )
$product->set_shipping_class_id( $args['shipping_class_id'] );
// Upsell and Cross sell (IDs)
$product->set_upsell_ids( isset( $args['upsells'] ) ? $args['upsells'] : '' );
$product->set_cross_sell_ids( isset( $args['cross_sells'] ) ? $args['upsells'] : '' );
// Attributes et default attributes
if( isset( $args['attributes'] ) )
$product->set_attributes( wc_prepare_product_attributes($args['attributes']) );
if( isset( $args['default_attributes'] ) )
$product->set_default_attributes( $args['default_attributes'] ); // Needs a special formatting
// Reviews, purchase note and menu order
$product->set_reviews_allowed( isset( $args['reviews'] ) ? $args['reviews'] : false );
$product->set_purchase_note( isset( $args['note'] ) ? $args['note'] : '' );
if( isset( $args['menu_order'] ) )
$product->set_menu_order( $args['menu_order'] );
// Product categories and Tags
if( isset( $args['category_ids'] ) )
$product->set_category_ids( $args['category_ids'] );
if( isset( $args['tag_ids'] ) )
$product->set_tag_ids( $args['tag_ids'] );
// Images and Gallery
$product->set_image_id( isset( $args['image_id'] ) ? $args['image_id'] : "" );
$product->set_gallery_image_ids( isset( $args['gallery_ids'] ) ? $args['gallery_ids'] : array() );
## --- SAVE PRODUCT --- ##
$product_id = $product->save();
return $product_id;
}
// Utility function that returns the correct product object instance
function wc_get_product_object_type( $type = 'simple' ) {
// Get an instance of the WC_Product object (depending on his type)
if( $type === 'variable' ){
$product = new WC_Product_Variable();
} elseif( $type === 'grouped' ){
$product = new WC_Product_Grouped();
} elseif( $type === 'external' ){
$product = new WC_Product_External();
} else {
$product = new WC_Product_Simple(); // "simple" By default
}
if( ! is_a( $product, 'WC_Product' ) )
return false;
else
return $product;
}
// Utility function that prepare product attributes before saving
function wc_prepare_product_attributes( $attributes ){
global $woocommerce;
$data = array();
$position = 0;
foreach( $attributes as $taxonomy => $values ){
if( ! taxonomy_exists( $taxonomy ) )
continue;
// Get an instance of the WC_Product_Attribute Object
$attribute = new WC_Product_Attribute();
$term_ids = array();
// Loop through the term names
foreach( $values['term_names'] as $term_name ){
if( term_exists( $term_name, $taxonomy ) )
// Get and set the term ID in the array from the term name
$term_ids[] = get_term_by( 'name', $term_name, $taxonomy )->term_id;
else
continue;
}
$taxonomy_id = wc_attribute_taxonomy_id_by_name( $taxonomy ); // Get taxonomy ID
$attribute->set_id( $taxonomy_id );
$attribute->set_name( $taxonomy );
$attribute->set_options( $term_ids );
$attribute->set_position( $position );
$attribute->set_visible( $values['is_visible'] );
$attribute->set_variation( $values['for_variation'] );
$data[$taxonomy] = $attribute; // Set in an array
$position++; // Increase position
}
return $data;
}
2) USAGE: - Example for a simple product creation with 2 product attributes "Color" and "Size":
$product_id = create_product( array(
'type' => '', // Simple product by default
'name' => __("The product title", "woocommerce"),
'description' => __("The product description…", "woocommerce"),
'short_description' => __("The product short description…", "woocommerce"),
// 'sku' => '',
'regular_price' => '5.00', // product price
// 'sale_price' => '',
'reviews_allowed' => true,
'attributes' => array(
// Taxonomy and term name values
'pa_color' => array(
'term_names' => array('Red', 'Blue'),
'is_visible' => true,
'for_variation' => false,
),
'pa_size' => array(
'term_names' => array('X Large'),
'is_visible' => true,
'for_variation' => false,
),
),
) );
// Displaying the created product ID
echo $product_id;
Tested and works using only Woocommerce 3 CRUD methods.
Another way: https://wordpress.stackexchange.com/a/137578/74284 , Use wp_insert_post function.
https://lukasznowicki.info/insert-new-woocommerce-product-programmatically/
$item = array(
'Name' => 'Product A',
'Description' => 'This is a product A',
'SKU' => '10020030A',
);
$user_id = get_current_user(); // this has NO SENSE AT ALL, because wp_insert_post uses current user as default value
// $user_id = $some_user_id_we_need_to_use; // So, user is selected..
$post_id = wp_insert_post( array(
'post_author' => $user_id,
'post_title' => $item['Name'],
'post_content' => $item['Description'],
'post_status' => 'publish',
'post_type' => "product",
) );
wp_set_object_terms( $post_id, 'simple', 'product_type' );
update_post_meta( $post_id, '_visibility', 'visible' );
update_post_meta( $post_id, '_stock_status', 'instock');
update_post_meta( $post_id, 'total_sales', '0' );
update_post_meta( $post_id, '_downloadable', 'no' );
update_post_meta( $post_id, '_virtual', 'yes' );
update_post_meta( $post_id, '_regular_price', '' );
update_post_meta( $post_id, '_sale_price', '' );
update_post_meta( $post_id, '_purchase_note', '' );
update_post_meta( $post_id, '_featured', 'no' );
update_post_meta( $post_id, '_weight', '' );
update_post_meta( $post_id, '_length', '' );
update_post_meta( $post_id, '_width', '' );
update_post_meta( $post_id, '_height', '' );
update_post_meta( $post_id, '_sku', $item['SKU'] );
update_post_meta( $post_id, '_product_attributes', array() );
update_post_meta( $post_id, '_sale_price_dates_from', '' );
update_post_meta( $post_id, '_sale_price_dates_to', '' );
update_post_meta( $post_id, '_price', '' );
update_post_meta( $post_id, '_sold_individually', '' );
update_post_meta( $post_id, '_manage_stock', 'no' );
update_post_meta( $post_id, '_backorders', 'no' );
update_post_meta( $post_id, '_stock', '' );

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........)

Woocommerce - filter by featured products in admin

Since version 3.0 Woocommerce removed sorting option for featured products on the backend. I tried this solution here but it seems to be not working any more https://wordpress.stackexchange.com/questions/104537/woocommerce-filter-by-featured-products-in-admin
It created nice dropdown filters but unfortunately is not filtering Featured products.
Since we have more than 2000 products it is very tidious to seek them one by one. Is there a way to sort or filter our featured products?
Thanks
Ok, here is the code which seems to be working and as a bonus you can filter out of stock products and rated products
add_action('restrict_manage_posts', 'featured_products_sorting');
function featured_products_sorting() {
global $typenow;
$post_type = 'product'; // change to your post type
$taxonomy = 'product_visibility'; // change to your taxonomy
if ($typenow == $post_type) {
$selected = isset($_GET[$taxonomy]) ? $_GET[$taxonomy] : '';
$info_taxonomy = get_taxonomy($taxonomy);
wp_dropdown_categories(array(
'show_option_all' => __("Show all {$info_taxonomy->label}"),
'taxonomy' => $taxonomy,
'name' => $taxonomy,
'orderby' => 'name',
'selected' => $selected,
'show_count' => true,
'hide_empty' => true,
));
};
}
add_filter('parse_query', 'featured_products_sorting_query');
function featured_products_sorting_query($query) {
global $pagenow;
$post_type = 'product'; // change to your post type
$taxonomy = 'product_visibility'; // change to your taxonomy
$q_vars = &$query->query_vars;
if ( $pagenow == 'edit.php' && isset($q_vars['post_type']) && $q_vars['post_type'] == $post_type && isset($q_vars[$taxonomy]) && is_numeric($q_vars[$taxonomy]) && $q_vars[$taxonomy] != 0 ) {
$term = get_term_by('id', $q_vars[$taxonomy], $taxonomy);
$q_vars[$taxonomy] = $term->slug;
}
}
/**
* Add custom sorting options (Featured)
*/
add_filter( 'woocommerce_get_catalog_ordering_args', 'custom_woocommerce_get_catalog_ordering_args' );
function custom_woocommerce_get_catalog_ordering_args( $args ) {
$orderby_value = isset( $_GET['orderby'] ) ? wc_clean( $_GET['orderby'] ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
if ( 'random_list' == $orderby_value ) {
$args['orderby'] = 'featured';
$args['order'] = '';
$args['meta_key'] = '';
}
return $args;
}
add_filter( 'woocommerce_default_catalog_orderby_options', 'custom_woocommerce_catalog_orderby' );
add_filter( 'woocommerce_catalog_orderby', 'custom_woocommerce_catalog_orderby' );
function custom_woocommerce_catalog_orderby( $sortby ) {
$sortby['featured'] = 'Featured';
return $sortby;
}

Categories