0

I use this code for some kind of sorting but it brakes some theme parts, like "Last articles" in footer, and content part after products.

I understand that $posts_clauses brakes other content, how to filter it?

/**
* Sorting out of stock WooCommerce products - Order product collections by stock status, in-stock products first.
*/
class iWC_Orderby_Stock_Status
{

    public function __construct()
    {
        // Check if WooCommerce is active
        if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
            add_filter('posts_clauses', array($this, 'order_by_stock_status'), 2000);
        }
    }

    public function order_by_stock_status($posts_clauses)
    {
        global $wpdb;

        // only change query on WooCommerce loops
        if( is_woocommerce() && ( is_shop() || is_product_category() || is_product_tag() ) ) {
            $posts_clauses['join']      .= " INNER JOIN $wpdb->postmeta istockstatus ON ($wpdb->posts.ID = istockstatus.post_id) ";
            $posts_clauses['orderby']    = " istockstatus.meta_value ASC, " . $posts_clauses['orderby'];
            $posts_clauses['where']      = " AND istockstatus.meta_key = '_stock_status' AND istockstatus.meta_value <> '' " . $posts_clauses['where'];
        }


        return $posts_clauses;
    }
}
new iWC_Orderby_Stock_Status;
  • Untested, but you could try changing your conditional statement to if($query->is_main_query() && is_woocommerce() && ( is_shop() || is_product_category() || is_product_tag() ) ) {. Note that you should also pass the $query parameter to your method, e.g. public function order_by_stock_status($posts_clauses, $query). – Dave Romsey May 2 '17 at 19:31
  • @DaveRomsey Thank you, but unfortunately it breaks my site. – Horhe Garcia May 3 '17 at 8:04
0

I had the same problem of needing to only apply $post_clauses to specific loops/queries and was able to use THIS solution provided by Stephen Harris:

You can access query variables (including custom ones) via the WP_Query::get() method.

For example:

$my_query = new WP_Query( array(
      ...
      'wpse105219_custom_var' => 'foobar',
      ...
) );

To 'catch' this at pre_get_posts:

add_action( 'pre_get_posts', 'wpse105219_pre_get_posts', 10 );
function wpse105219_pre_get_posts( $query ){
      if( $query->get( 'wpse105219_custom_var' ) == 'foobar' ){
         //Alter $query
      }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.