woocommerce custom sort option set as default - php

I have an extension to count the post views of my woocommerce products.
With this extension I have built a custom sort option.
I have used the following code in functions.php, which I have taken from several tutorials:
//Sort by views
function views_woocommerce_shop_ordering( $sort_args ) {
$orderby_value = isset( $_GET['orderby'] ) ? woocommerce_clean( $_GET['orderby'] ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
if ( 'pageviews' == $orderby_value ) {
$sort_args['orderby'] = 'post_views';
$sort_args['order'] = 'desc';
}
return $sort_args;
}
add_filter( 'woocommerce_get_catalog_ordering_args', 'views_woocommerce_shop_ordering' );
function views_custom_woocommerce_catalog_orderby( $sortby ) {
$sortby['pageviews'] = 'Sort by pageviews';
return $sortby;
}
add_filter( 'woocommerce_default_catalog_orderby_options', 'views_custom_woocommerce_catalog_orderby' );
add_filter( 'woocommerce_catalog_orderby', 'views_custom_woocommerce_catalog_orderby' );
Sadly, like this it is not working. So I deleted the top part and used only this:
//PageViews Sorting
add_filter( 'woocommerce_get_catalog_ordering_args', 'custom_woocommerce_get_catalog_ordering_args' );
add_filter( 'woocommerce_default_catalog_orderby_options', 'custom_woocommerce_catalog_orderby' );
add_filter( 'woocommerce_catalog_orderby', 'custom_woocommerce_catalog_orderby',30 );
function custom_woocommerce_catalog_orderby( $sortby ) {
$sortby['post_views'] = 'Nach Beliebtheit sortiert';
return $sortby;
}
Like this it works, but when I set this custom sort option as default in the woocommerce backend, the sorting stays still default on page load, even though the new option is selected in the dropdown.
Then I have to set another option, and then back to the custom sort option - then it sorts the products correctly.
Anyone have a clue why this is happening?
Is there something wrong with my functions.php?

Related

Change ordering in WooCommerce Shop Page to be random but going via category

I need to make my WooCommerce shop page have a different type of randomizing. Basically I want it to randomize by category and display that method going forward. So one category of items then another category of items but the products in those categories need to be randomized as well so it looks mixed up. Could anyone assist with this ?
Once you have added the code above to your active theme’s "functions" file, head to Appearance > Customise to configure your Woo Commerce product catalogue sorting options.
add_filter( 'woocommerce_get_catalog_ordering_args', 'custom_woo_catalog_ordering_args' );
function custom_woo_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 ( 'random_list' == $orderby_value ) {
$args['orderby'] = 'rand';
$args['order'] = '';
$args['meta_key'] = '';
}
return $args;
}
add_filter( 'woocommerce_default_catalog_orderby_options', 'woocommerce_catalog_random_orderby' );
add_filter( 'woocommerce_catalog_orderby', 'woocommerce_catalog_random_orderby' );
function woocommerce_catalog_random_orderby( $sortby ) {
$sortby['random_list'] = 'Random';
return $sortby;
}

Change WooCommerce product availability In stock text by a custom text

I would like to change the text "in stock" behind the number in stock. I tried adding this PHP code in my wordpress php editor but it doesn't work.
Do you have any idea why?
Thank you !
add_filter( 'woocommerce_get_availability_text', 'bbloomer_custom_get_availability_text', 99, 2 );
function bbloomer_custom_get_availability_text( $availability, $product ) {
$stock = $product->get_stock_quantity();
if ( $product->is_in_stock() && $product->managing_stock() ) $availability = $stock. 'remaining copies' ;
return $availability;
}
Try the following instead:
add_filter( 'woocommerce_get_availability', 'filter_product_availability', 10, 2 );
function filter_product_availability( $availability, $product ) {
$stock_quantity = $product->get_stock_quantity(); // get stock quantity
if ( $product->is_in_stock() && $stock_quantity > 0 ) {
$availability['availability'] = sprintf( __('%d remaining copies'), $stock_quantity );
}
return $availability;
}
Or also you can try this:
add_filter( 'woocommerce_get_availability_text', 'filter_product_availability_text', 10, 2 );
function filter_product_availability_text( $availability_text, $product ) {
return str_replace( 'in stock', __('remaining copies', 'woocommerce'), $availability_text );
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
You can use the in build option for this go to WooCommerce->Preferences->Products->Inventar
and choose the first option. Show available Products and save.

Remove columns from WooCommerce admin coupon list

I am trying to remove some default columns (amount & products) from the WooCommerce admin coupon list.
For that I make use of the following code:
add_filter( 'manage_posts_columns', 'custom_post_columns', 10, 2 );
function custom_post_columns( $columns, $post_type ) {
switch ( $post_type ) {
case 'shop_coupon':
unset(
$columns['amount'],
$columns['products']
);
break;
}
return $columns;
}
But it doesn't work and I'm not getting any errors. I think the code I'm using is just not being applied correctly.
You can use the manage_edit-{post type or taxonomy}_columns filter hook
So you get:
function filter_manage_edit_shop_coupon_columns( $columns ) {
// Remove
unset( $columns['products'] );
unset( $columns['amount'] );
return $columns;
}
add_filter( 'manage_edit-shop_coupon_columns', 'filter_manage_edit_shop_coupon_columns', 10, 1 );

Hide WooCommerce Payment Method Function Disables WordPress nav-menus.php

I have made hidden the other payment methods if selected COD method (which is flat_rate:5 in my case). I. am using Show hide payment methods based on selected shipping method in Woocommerce answer where I have made some minor edits.
The code works exactly as it should be however, I can't edit menus in "Appearance -> Menus" screen. It seems no problem in front-end.
function payment_gateways_based_on_chosen_shipping_method( $gateways ) {
// Get chosen shipping methods
$chosen_shipping_methods = (array) WC()->session->get( 'chosen_shipping_methods' );
if ( in_array( 'flat_rate:5', $chosen_shipping_methods ) )
{
unset( $gateways['bacs'] );
unset( $gateways['iyzico'] );
}
return $gateways;
}
add_filter( 'woocommerce_available_payment_gateways', 'payment_gateways_based_on_chosen_shipping_method' );
I am totally confused where is the bug and why it only appears on "Appearence -> Menus" page.
Also this guy from WordPress support forum had encounter similar issue with different code but in same filter (woocommerce_available_payment_gateways).
Thank you.
That's because WC()->session is null on backoffice. So you can't call method "get".
You need to check if you are in admin area before execute your code:
function payment_gateways_based_on_chosen_shipping_method( $gateways ) {
if(is_admin()){
return $gateways;
}
// Get chosen shipping methods
$chosen_shipping_methods = (array) WC()->session->get( 'chosen_shipping_methods' );
if ( in_array( 'flat_rate:5', $chosen_shipping_methods ) ){
unset( $gateways['bacs'] );
unset( $gateways['iyzico'] );
}
return $gateways;
}
add_filter( 'woocommerce_available_payment_gateways', 'payment_gateways_based_on_chosen_shipping_method' );

Override Avada Catalog sorting hook back to default in Woocommerce

I am trying to modify Woocommerce sorting option to get a customized one by adding the following code to Avada child function.php file:
// add custom sorting option
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'] ) ? woocommerce_clean(
$_GET['orderby'] ) : apply_filters( 'woocommerce_default_catalog_orderby',
get_option( 'woocommerce_default_catalog_orderby' ) );
if ( 'random_list' == $orderby_value ) {
$args['orderby'] = 'menu_order Date';
$args['order'] = 'ASC';
$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['random_list'] = 'Menu_order_date';
return $sortby;
}
//end custom ordering code
this code work fine if i didn't enable WooCommerce Shop Page Ordering Boxes and actually i wanted the ordering box to be displayed on my shop page and product category, so i contact Avada Support for this issue and it turn out Avada use thier own hook for WooCommerce Shop Page Ordering Boxes with the following code:
/**
* Controls the actions adding the ordering boxes.
*
* #access public
* #since 5.0.4
* #param object $query The main query.
* #return void
*/
public function product_ordering( $query ) {
// We only want to affect the main query.
if ( ! $query->is_main_query() || $query->is_search() ) {
return;
}
if ( $query->get( 'page_id' ) ) {
$page_id = absint( $query->get( 'page_id' ) );
} else {
$page_id = absint( Avada()->fusion_library->get_page_id() );
}
if ( wc_get_page_id( 'shop' ) === $page_id || $query->is_post_type_archive( 'product' ) || $query->is_tax( get_object_taxonomies( 'product' ) ) ) {
if ( Avada()->settings->get( 'woocommerce_avada_ordering' ) ) {
remove_action( 'woocommerce_before_shop_loop', 'woocommerce_catalog_ordering', 30 );
add_action( 'woocommerce_before_shop_loop', array( $this, 'catalog_ordering' ), 30 );
add_action( 'woocommerce_get_catalog_ordering_args', array( $this, 'get_catalog_ordering_args' ), 20 );
}
}
}
Avada Support said I can remove Avada function from this hook and add my own using child theme.
add_action( 'woocommerce_get_catalog_ordering_args', array( $this,
'get_catalog_ordering_args' ), 20 );
I searched all over the interent seeking help and I found many pepole asked about almost same question but without answer.
if anyone could help removing avada function that will be very helpful for me and other pepole who's looking for that as well.
How I can remove Avada hooked function from woocommerce_get_catalog_ordering_args action hook?
after several test i disocoverd the following code which added by Avada team as follow:
/**
* Modified the ordering of products.
*
* #access public
* #since 5.1.0
*/
public function catalog_ordering() {
get_template_part( 'templates/wc-catalog-ordering' );
}
/**
* Gets the catalogue ordering arguments.
*
* #access public
* #since 5.1.0
* #param array $args The arguments.
* #return array
*/
function get_catalog_ordering_args( $args ) {
global $woocommerce;
$woo_default_catalog_orderby = get_option( 'woocommerce_default_catalog_orderby' );
// Get the query args.
if ( isset( $_SERVER['QUERY_STRING'] ) ) {
parse_str( sanitize_text_field( wp_unslash( $_SERVER['QUERY_STRING'] ) ), $params );
}
// Get order by.
$pob = ( ! empty( $params['product_orderby'] ) ) ? $params['product_orderby'] : $woo_default_catalog_orderby;
// Get order.
$po = 'asc';
if ( isset( $params['product_order'] ) ) {
// Dedicated ordering.
$po = $params['product_order'];
} else {
// Get the correct default order.
$po = 'asc';
if ( 'date' === $pob || 'popularity' === $pob || 'rating' === $pob || 'price-desc' === $pob ) {
$po = 'desc';
}
}
// Remove posts_clause filter, if default ordering is set to rating or popularity to make custom ordering work correctly.
if ( 'default' !== $pob ) {
if ( 'popularity' === $woo_default_catalog_orderby || 'rating' === $woo_default_catalog_orderby ) {
WC()->query->remove_ordering_args();
}
}
$orderby = 'date';
$order = strtoupper( $po );
$meta_key = '';
switch ( $pob ) {
case 'menu_order':
case 'default':
$orderby = $args['orderby'];
break;
case 'date':
$orderby = 'date';
break;
case 'price':
case 'price-desc':
add_filter( 'posts_clauses', array( $this, 'order_by_price_post_clauses' ) );
add_action( 'wp', array( $this, 'remove_ordering_args_filters' ) );
break;
case 'popularity':
$meta_key = 'total_sales';
add_filter( 'posts_clauses', array( $this, 'order_by_popularity_post_clauses' ) );
add_action( 'wp', array( $this, 'remove_ordering_args_filters' ) );
break;
case 'rating':
$meta_key = '_wc_average_rating';
$orderby = array(
'meta_value_num' => strtoupper( $po ),
'ID' => 'ASC',
);
break;
case 'name':
$orderby = 'title';
break;
}
$args['orderby'] = $orderby;
$args['order'] = $order;
$args['meta_key'] = $meta_key;
return $args;
}
if i just modify the following:
// Remove posts_clause filter, if default ordering is set to rating or popularity to make custom ordering work correctly.
if ( 'default' !== $pob ) {
if ( 'popularity' === $woo_default_catalog_orderby || 'rating' === $woo_default_catalog_orderby ) {
WC()->query->remove_ordering_args();
}
}
$orderby = 'date';
$order = strtoupper( $po );
$meta_key = '';
to
// Remove posts_clause filter, if default ordering is set to rating or popularity to make custom ordering work correctly.
if ( 'default' !== $pob ) {
if ( 'popularity' === $woo_default_catalog_orderby || 'rating' === $woo_default_catalog_orderby ) {
WC()->query->remove_ordering_args();
}
}
$orderby = 'menu_order Date';
$order = strtoupper( $po );
$meta_key = '';
$orderby = 'menu_order Date'; instead of $orderby = 'date';
it's simply am forcing the avada to use my own custom ordering instead of date.
but that not really practical solution as i modified class-avada-woocommerce.php
is there any suggestion to do find solution by add some code to avada child them instead
There is nothing wrong with the Avada Code.
Avada intentionally unhooks the filter 'woocommerce_get_catalog_ordering_args' and writes its own filter "catalog_ordering" in
'/wp-content/themes/Avada/includes/class-avada-woocommerce.php'
That calls
'/wp-content/themes/Avada/templates/wc-catalog-ordering.php'
Please overwrite the template by using your child theme and copying the contents of wc-catalog-ordering.php.
i.e. "/wp-content/themes/Avada-Child-Theme/templates/wc-catalog-ordering.php"
You'll be able to handle the orders however you'd like once complete.
Previously mentioned, the function "remove_avada_function" is hooked on 'after_setup_theme' and is used to remove the hook. However since 'remove_avada_function' is called before the action 'pre_get_post' is called, 'remove_avada_function' won't remove the action that does not currently exist.
Update 2:
I think that if you add a highest priority than Avada's theme hook it will work (here I have set it to 100), and the only change to do in this function is $args['orderby'] = 'menu_order date'; to get the similar change you have done on Avada's files.
The code:
add_filter( 'woocommerce_get_catalog_ordering_args', 'custom_catalog_ordering_args', 100 );
function custom_woocommerce_get_catalog_ordering_args( $args ) {
$args['orderby'] = 'menu_order date';
return $args;
}
This code goes in function.php file of your active child theme.
It should work
The very strange thing is that woocommerce_get_catalog_ordering_args is a filter hook, but NOT an action hook (so I have changed my code)…
Then something is wrong in the Avada's theme code and you should report it to the support.
You just need to increase your hooked function, so it will override Avada's:
add_action('after_setup_theme', 'remove_avada_function' );
function remove_avada_function(){
remove_action( 'woocommerce_before_shop_loop', 'catalog_ordering', 30 );
add_action( 'woocommerce_before_shop_loop', 'custom_catalog_ordering', 30 );
}
You can use this code to set Avada catalog sort hook back to woocommerce default.
function avada_remove_ordering() {
global $avada_woocommerce;
remove_action('pre_get_posts', array( $avada_woocommerce, 'product_ordering' ), 5);
add_action( 'woocommerce_before_shop_loop', 'woocommerce_catalog_ordering', 30 );
}
add_action( 'init', 'avada_remove_ordering' );
add_filter( 'woocommerce_get_catalog_ordering_args', 'custom_woocommerce_get_catalog_ordering_args' , 12);
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 ( 'sale_price' == $orderby_value ) {
$args['orderby'] = 'meta_value_num';
$args['order'] = 'ASC';
$args['meta_key'] = '_sale_price';
}
return $args;
}
add_filter( 'woocommerce_default_catalog_orderby_options', 'custom_woocommerce_catalog_orderby', 12 );
add_filter( 'woocommerce_catalog_orderby', 'custom_woocommerce_catalog_orderby', 12 );
function custom_woocommerce_catalog_orderby( $sortby ) {
$sortby['sale_price'] = 'Sale';
return $sortby;
}

Categories