• Никакой политики на форуме. Иначе - бан!
  • Вопрос без рабочей ссылки на проблему считается риторическим. Без ссылки и скриншота - провокацией!
  • Темы озаглавленные с маленькой буквы или капсом удаляются без предупреждения!

Обработка $posts_clauses

Delf

Форумчанин
Для сортировки товаров использую $posts_clauses, но это ломает другие блоки, например, Последние статьи и другие.

Видимо надо какие то дополнительные параметры или фильтры вводить, есть идеи?

/**
* 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;​
 

Nikolays93

Новичок
Если я не ошибаюсь, вы хотите отсортировать отсутствующие товары в конец. Проблема в том что is_woocommerce не хотят работать в этом фильтре..

Попробуйте код Mario62RUS (https://stackoverflow.com/questions...k-products-at-the-end-in-woocommerce/25113728)
Код:
add_action( 'pre_get_posts', function( $query ) {
if ( $query->is_main_query() && is_woocommerce() && ( is_shop() || is_product_category() || is_product_tag() ) ) {
   if( $query->get( 'orderby' ) == 'menu_order title' ) {  // only change default sorting
       $query->set( 'orderby', 'meta_value' );
       $query->set( 'order', 'ASC' );
       $query->set( 'meta_key', '_stock_status' );
   }
}
});

Хотя ответ который признали решением в вышестоящей ссылке, это исключить из показа в настройках WooCommerce.
 

Nikolays93

Новичок
Блин, к сожалению, эти оба кода выдают ошибки, вроде:
Код:
Notice: Trying to get property of non-object in /var/www/.../wp-includes/class-wp-query.php on line 3750

Notice: Trying to get property of non-object in /var/www/.../wp-includes/class-wp-query.php on line 3752

Notice: Trying to get property of non-object in /var/www/.../wp-includes/class-wp-query.php on line 3754

Notice: Trying to get property of non-object in /var/www/.../wp-includes/class-wp-query.php on line 3884
если узнаю как исправить отпишусь..
 

Nikolays93

Новичок
Определил что такие ошибки выводятся в результате запроса к $this->get_queried_object(); функциями типа is_{page, woocommerce...}
Теперь у меня работает так: (глобально тестить нет времени)
Код:
add_action( 'pre_get_posts', 'resort_unstock', 10);
function resort_unstock( $query ) {
  if ( $query->is_main_query() && get_queried_object() && is_woocommerce() && ( is_shop() || is_product_category() || is_product_tag() ) ) {
      if( $query->get( 'orderby' ) == 'menu_order title' ) {  // Изменять только стандартную сортировку
        $query->set( 'orderby', 'meta_value' );
        $query->set( 'order', 'ASC' );
        $query->set( 'meta_key', '_stock_status' );
      }

      return $query;
  }
}
 
Сверху Снизу