WP_Query: Помогите отсортировать записи :)
имеется запрос:
add_action('pre_get_posts', 'exclude_expired_event');
function exclude_expired_event($query) {
if ( ! is_admin() && $query->is_main_query() ) {
$current_date = date('Ymd');
$meta_query = [
'relation' => 'OR',
'first' => [
'key' => 'date',
'type' => 'DATE',
'value' => $current_date,
'compare' => '>=',
],
'second' => [
'key' => 'date',
'value' => '',
'compare' => '=',
],
];
$query->set('meta_query', $meta_query);
//$query->set('orderby', 'none'); //для add_filter('posts_results',...
}
return $query;
}
тут я оставляю записи только со свежей датой относительно текущей даты (ключ date), а также оставляю записи, у которых дата не указана, то есть value для ключа пустое.
так вот, как отсортировать записи, чтобы сперва отображались по дате, самые ближайшие, то есть: 20230102 (2.01.2023) 20230106 (6.01.2023) 20231003 (3.10.2023) - а после них записи без дат (где value пустое значение).
пробовал добавить данный код:
add_filter('posts_results', 'custom_sort_results');
function custom_sort_results($posts) {
usort($posts, function($a, $b) {
$dateA = get_post_meta($a->ID, 'date', true);
$dateB = get_post_meta($b->ID, 'date', true);
// Проверка на наличие значения 'date' и сравнение дат
if (empty($dateA) && empty($dateB)) {
return 0; // Если оба не имеют дату, оставляем без изменений
} elseif (empty($dateA)) {
return 1; // Если $a не имеет дату, перемещаем $b вверх
} elseif (empty($dateB)) {
return -1; // Если $b не имеет дату, перемещаем $a вверх
} else {
return strtotime($dateA) - strtotime($dateB);
}
});
return $posts;
}
но фильтр применяется на постраничную навигацию, то есть сортировка происходит по новой на каждой странице /page/2/ /page/3/
фух, решил задачу.
нужно в массив второго запроса добавить еще relation and
полный код:
add_action('pre_get_posts', 'exclude_expired_event');
function exclude_expired_event($query) {
if ( ! is_admin() && $query->is_main_query() ) {
$current_date = date('Ymd');
$meta_query = [
'relation' => 'OR',
'first' => [
'key' => 'date',
'value' => $current_date,
'compare' => '>=',
],
[
'relation' => 'AND', //gold :)
[
'key' => 'date',
'value' => '',
'compare' => '=',
]
]
];
$query->set('meta_query', $meta_query);
$query->set('orderby', array(
'meta_value_num' => 'ASC',
));
}
return $query;
}
Странный формат даты у тебя, он как число идет... Поэтому тебе нужно указать тип не DATE, а NUMERIC и добавить сортировку по метаполю
$query->set('orderby', 'meta_value_num'); // или укажи ключ $query->set('orderby', 'first'); // возможно надо будет еще поиграться с сортировкой по двум полям $query->set('orderby', [ 'first' => 'DESC', 'second' => 'ASC' ] );изменил NUMERIC type, и пробовал разные варианты orderby. но все равно получаю сортировку

без даты - с заполненной датой или
с датой (но не по возрастающей) - без даты
удалось отсортировать по дате (возрастание) и далее без даты таким способом
//....... 'first' => [ 'key' => 'date', // 'value' => $current_date, // 'compare' => '>=', 'compare' => 'EXISTS', ], //........ $query->set('orderby', array( 'meta_value_num' => 'ASC', ));но просроченные записи по дате относительно текущей даты также отображаются