WordPress как на ладони

Как сортировать товары в категории по вложенным пользовательским полям?

Для товаров есть пользовательское поле "cat_position", тип - Повторитель, созданное в ACF. У него есть два вложенных поля "Выбор категории" (cat_position_vybor) и "Номер позиции" (cat_position_number). В товаре это выглядит так:

Т.е. один товар может принадлежать нескольким категориям, которые указываются в "Выбор категории". И для каждой категории указана своя позиция в "Номер позиции". Также может быть несколько позиций в одной категории.

Задача: отсортировать товары по позициям из произвольного поля cat_position_number.

Нашел код для реализации сортировки через хук woocommerce_get_catalog_ordering_args. Но получается отсортировать по простому полю, а вот с сортировкой по вложенным полям повторителя проблема.

Т.е. в простом поле мы можем в параметрах для сортировки указать просто ключ 'meta_key' => 'my-custom-field',а с вложенными полями так не получается. Например, примерно так выглядит массив поля cat_position:

$cat_position = (
[0] => Array
	(
		[cat_position_0_cat_position_vybor] => 20
		[cat_position_0_cat_position_number] => 3
	),

[1] => Array
	(
		[cat_position_1_cat_position_vybor] => 16
		[cat_position_1_cat_position_number] => 5
	),

[2] => Array
	(
		[cat_position_2_cat_position_vybor] => 10
		[cat_position_2_cat_position_number] => 6
	),
...);

Т.е. 'cat_position_X_cat_position_number' для каждого товара может быть разным. Я пробовал в функцию сортировки добавить перебор полей cat_position_vybor. И как только оно совпадет с id категории сформировать переменную $cat_position_number_meta_key и указать ее в 'meta_key'. Но это не работает:

add_filter( 'woocommerce_get_catalog_ordering_args', 'custom_woo_get_catalog_ordering_args' );

function custom_woo_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 ( have_rows('cat_position') ) :
		$count_while_order = 0;
		while ( have_rows('cat_position') ) : the_row();
			$cat_position_vybor = get_sub_field('cat_position_vybor');
			$q_obj = get_queried_object();
			$cat_id = $q_obj->term_id;

			if($cat_id == $cat_position_vybor) {
				$cat_position_number_meta_key = 'cat_position_' . $count_while_order . '_cat_position_number';
				break;
			}
			$count_while++;
		endwhile;
	endif;

	//
	if ( 'position' == $orderby_value ) {
		$args = [
			'orderby'  => 'meta_value_num',
			'meta_key' => $cat_position_number_meta_key,
			'order'    => 'ASC',
		];
	}
	return $args;
}

// Выбор сортировки
add_filter( 'woocommerce_default_catalog_orderby_options', 'custom_woo_catalog_orderby' );
add_filter( 'woocommerce_catalog_orderby', 'custom_woo_catalog_orderby' );
function custom_woo_catalog_orderby( $sortby ) {
	$sortby['position'] = __( 'По Позиции', 'woocommerce' );
	return $sortby;
}

Разве нельзя в 'meta_key' указывать переменную?
Может есть какие-то другие способы отсортировать товары по вложенным полям?

1
nord
4 месяца назад 3
  • 0
    stepan2143 www.weblancer.net/users/stepanko/?affili...

    Мое мнение, что нужно хранить переменные в отдельных ключах.
    Вот вы в удобном виде для пользователя сделали выбор привязки категории и позицию товара в ней.
    При сохран товара - нужно кодом создавать/обновлять простые метаполя в товаре.

    К примеру, вы товар привязали к двум категориям с ID 3 и 5
    Указали позицию товара 10 и 20

    update_post_meta( $post->ID, 'cat_3_position', 10 );
    update_post_meta( $post->ID, 'cat_5_position', 20 );
    $q_obj = get_queried_object();
    $cat_id = $q_obj->term_id;
    
    $args = [
    			'orderby'  => 'meta_value_num',
    			'meta_key' => 'cat_'. $cat_id .'_position',
    			'order'    => 'ASC',
    		];
    Комментировать
На вопросы могут отвечать только зарегистрированные пользователи. Вход . Регистрация