Сортировка товаров по атрибуту и мета полям Woocommerce

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5
Загрузка...

Изменить стандартную сортировку отображения товаров в каталоге довольно просто, если конечно использовать стандартные мета поля, а не атрибуты.

Для изменения сортировки есть специальный фильтр woocommerce_get_catalog_ordering_args, давай посмотрим как он работает.

Предположим мы хотим сделать сортировку по названию товара для этого создадим функцию, и пропишем необходимые переменные.

add_action( 'woocommerce_get_catalog_ordering_args', 'new_sort' );

function new_sort($args){

$args['order'] = 'ASC';

$args['orderby'] = 'title';

return $args;
}

Вместо значения «title» можно подставить любое из существующих полей в бд например author или status. Если в переменную «orderby» прописать несуществующие поле, то каталог покажет уведомление об отсутствие товаров.

Так же можно сделать сортировку по метаполю, которых у товара ни так уж и мало:

  • _price (цена)
  • _sku (артикул)
  • _stock_status (Наличие)
  • _stock (Кол-во товаров в наличие)
  • _weight (Вес товара)
  • _length — Длина
  • _width — Ширина
  • _height — Высота

Пример сортировки по Артикулу

function new_sort($args){
$args['order'] = 'ASC';
$args['meta_key'] = '_sku';
$args['orderby'] = 'meta_value';
return $args;
}

Предположим у нас есть атрибут размер или цвет, с альтернативным названием (Слаг) color и razmer.

Как сортировать по атрибутам, если значения не сохраняются отдельной ячейкой pa_color и pa_razmer, как это делается с Артикулом или Ценой товара.

Пример из PhpMyAdmin таблица wp_postmeta

Сохраняются атрибуты товара в поле meta_key со значением _product_attributes, и хранится в виде сериализованного массива. Естественно сортировать по таким данным будет не правильно, и результата не будет.

Чтобы убедиться в этом, сделайте обычный sql запрос в phpmyadmin, только не забываем подставить ID товара.

SELECT * FROM `wp_postmeta` WHERE post_id='id продукта'

 

Что делать?

Как вариант сохранять атрибуты товара в базе данных как отдельные записи, например вот так:

Для это задачи есть специальная функция update_post_meta, которая должна выполняться после нажатия кнопки обновить внутри карточки товара.

В файле function.php вашей темы пишем следующий код.

//Для обычного товара

add_action( 'woocommerce_process_product_meta_simple', 'update_attr_to_meta' );

//Для вариативного товара

add_action( 'woocommerce_process_product_meta_variable', 'update_attr_to_meta' );


function update_attr_to_meta($post_id){

  //Проверяем наличие атрибутов

  if(isset($_POST['attribute_names']) and !empty($_POST['attribute_names'])){
  
  //Перебираем массив с атрибутами
  
    foreach($_POST['attribute_names'] as $num=>$pa_name){
    
    //Проверяем добавлено ли значение к атрибуту
      
      if(isset($_POST['attribute_values'][$num])){
      
        //Если у атрибута несколько значений, берём самое первое
      
        if(is_array($_POST['attribute_values'][$num])){
        
          $pa_value=$_POST['attribute_values'][$num][0];
          
        }else{
        
          //Если одно, обычно это Индивидуальный атрибут
        
          $pa_value=$_POST['attribute_values'][$num];
        
        }		
        
        //Обновляем мета данные всех добавленных атрибутов	
                
        update_post_meta($post_id,'_'.$pa_name,$pa_value);      

        
      }
    

    }
    
  }



}

Обратите внимание, что добавление нижнего подчёркивания к _pa_name скрывает его отображение в Произвольных полях.

Если нужно добавить мета поля определённых атрибутов, строчку

update_post_meta($post_id,'_'.$pa_name,$pa_value);

Меняем на нижнюю строку, предварительно заменив строку pa_razmer на слаг вашего атрибута,например pa_color, pa_cvet,pa_shirina и т.д

if($pa_name=='pa_razmer')update_post_meta($post_id,'_'.$pa_name,$pa_value);

Что делает php скрипт?

При сохранение товара в админ.панели, проверяются добавленные атрибуты, и они сохраняются в БД.

Предупреждение! Для одного атрибута по которому предполагается сортировка, может быть добавлено лишь ОДНО значение, иначе будет взято самое первое из массива.

Когда у всех товаров будут добавлены мета поля , в нашем случае _pa_razmer и _pa_color мы можем выполнить сортировку

Сортировка по Размеру

add_action( 'woocommerce_get_catalog_ordering_args', 'new_sort');
function new_sort($args){

$args['order'] = 'ASC';
$args['meta_key'] = '_pa_razmer';
$args['orderby'] = 'meta_value_num';
return $args;
}

Сортировка по цвету

add_action( 'woocommerce_get_catalog_ordering_args', 'new_sort');
function new_sort($args){
$args['order'] = 'ASC';
$args['meta_key'] = '_pa_color';
$args['orderby'] = 'meta_value';
return $args;
}

В моём случае нужно было сделать сортировку уже заполненному каталогу, в котором более 5000 товаров, поэтому понадобилась ещё одна функция, которая заполнит мета поля Размер и Цвет каждому товару автоматически.

Данную функцию нужно выполнить всего один раз, а затем либо удалить её из файла function.php , либо закоментировать её, чтобы не создавать лишнюю нагрузку на базу данных.

add_action('woocommerce_loaded','new_attribute_to_meta');

function new_attribute_to_meta(){

  global $wpdb;
  
  $num=3000; //Кол-во обрабатываемых записей

  foreach(wc_get_products(array('numberposts' => $num)) as $pr){

    foreach($pr->get_attributes() as $key=>$attr){

      $val=wc_get_product_terms( $pr->get_id(), $attr->get_name(), array( 'fields' => 'all' ) );

      if($key=='pa_razmer' or $key=='pa_marka' or $key=='pa_size'){

        update_post_meta($pr->get_id(),'_'.$key,$val[0]->name);
    
      }

    }
  }

}

Обратите внимание на условие, я использую СЛАГ существующего атрибута, в вашем случае слаг атрибута может иметь другое название. Данную функцию так же нужно подключить в файл function.php, при условие если необходимо создать мета поля уже существующим товарам.

Один комментарий

    Анатолий

    Делаю по этой инструкции, на первый взгляд всё работает, но на самом деле у меня сортировка происходит не по атрибутам, а по их ID. Т.е. в ‘meta_value’ хранится не значение атрибута, а его ID. Подскажите, пожалуйста, какой ещё момент я упускаю из виду?

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*
*