Вопрос или проблема
Постепенно схожу с ума, пытаясь сделать админские колонки таксономии сортируемыми по числовому пользовательскому полю. У меня есть пользовательская таксономия под названием “typer”, и эти таксономии имеют пользовательское поле под названием “prioritet”.
Мне удалось заставить мой код отображать колонку и сделать ее сортируемой. Единственная проблема в том, что поля сортируются алфавитно, несмотря на то, что все они являются числами. Это означает, что набор полей [1, 3, 14, 22] будет отображаться как:
1
14
22
3
Мой код на данный момент
function create_date_column_for_issues($issue_columns) {
$issue_columns['prioritet'] = 'Prioritet / sortering';
return $issue_columns;
}
add_filter('manage_edit-typer_columns', 'create_date_column_for_issues');
function populate_date_column_for_issues($value, $column_name, $term_id) {
$issue = get_term($term_id, 'typer');
$date = get_field('prioritet', $issue);
switch($column_name) {
case 'prioritet':
$value = $date;
break;
default:
break;
}
return $value;
}
add_filter('manage_typer_custom_column', 'populate_date_column_for_issues', 10, 3);
function register_date_column_for_issues_sortable($columns) {
$columns['prioritet'] = 'prioritet';
return $columns;
}
add_filter('manage_edit-typer_sortable_columns', 'register_date_column_for_issues_sortable');
add_filter( 'terms_clauses', 'filter_terms_clauses', 10, 3 );
/**
* Filter WP_Term_Query meta query
*
* @param object $query WP_Term_Query
* @return object
*/
function filter_terms_clauses( $pieces, $taxonomies, $args ) {
global $pagenow, $wpdb;
// Require ordering
$orderby = ( isset( $_GET['orderby'] ) ) ? trim( sanitize_text_field( $_GET['orderby'] ) ) : '';
if ( empty( $orderby ) ) { return $pieces; }
// set taxonomy
$taxonomy = $taxonomies[0];
// only if current taxonomy or edit page in admin
if ( !is_admin() || $pagenow !== 'edit-tags.php' || !in_array( $taxonomy, [ 'typer' ] ) ) { return $pieces; }
// and ordering matches
if ( $orderby === 'prioritet' ) {
$pieces['join'] .= ' INNER JOIN ' . $wpdb->termmeta . ' AS tm ON t.term_id = tm.term_id ';
$pieces['where'] .= ' AND tm.meta_key = "prioritet"';
$pieces['orderby'] = ' ORDER BY tm.meta_value ';
}
return $pieces;
}
Мои знания MySQL почти нулевые, поэтому я не знаю, что с этим делать дальше.
Как дополнение:
Сейчас сортировка исключает все таксономии с пустыми полями. Было бы неплохо иметь их внизу, но я понимаю, что это требует намного более сложного запроса. Поэтому добавляйте это только в том случае, если вдруг у вас есть готовое решение.
Код, который я выкладываю, это измененная и упрощенная версия вашего. Я нашел свое решение, используя ваш код.
/**
* Filter WP_Term_Query meta query
*
* @param object $query WP_Term_Query
* @return object
*/
function filter_terms_clauses( $pieces, $taxonomies, $args ) {
global $pagenow, $wpdb;
if(!is_admin()) {
return $pieces;
}
if(
is_admin()
&& $pagenow == 'edit-tags.php'
&& $taxonomies[0] == 'typer'
&& ( isset($_GET['orderby']) && $_GET['orderby'] == 'prioritet' )
) {
$pieces['join'] .= ' INNER JOIN ' . $wpdb->termmeta . ' AS tm ON t.term_id = tm.term_id ';
$pieces['where'] .= ' AND tm.meta_key = "prioritet"';
$pieces['orderby'] = ' ORDER BY tm.meta_value ';
$pieces['order'] = isset($_GET['order']) ? $_GET['order'] : "DESC";
}
return $pieces;
}
add_filter( 'terms_clauses', 'filter_terms_clauses', 10, 3 );
Надеюсь, это поможет.
Для меня, я создал пользовательскую таксономию, и в этой пользовательской таксономии у меня есть свой мета. Я хотел, чтобы в админке была колонка и сделал её сортируемой. Чтобы сделать пользовательскую таксономию в пользовательской мета сортируемой, я сделал это.
public function pre_get_terms( $query ) {
$meta_query_args = array(
'relation' => 'AND', // Optional, defaults to "AND"
array(
'key' => 'order_index',
'value' => 0,
'compare' => '>='
)
);
$meta_query = new WP_Meta_Query( $meta_query_args );
$query->meta_query = $meta_query;
$query->orderby = 'position_clause';
}
Я нашел ответ по этой ссылке https://core.trac.wordpress.org/ticket/34996
Мне просто пришлось адаптировать ответ, предоставленный в комментариях @eherman24
Я прочитал много постов и большое количество запросов к базе данных, я знал, что где-то есть небольшая загвоздка и не хватает небольшого значения. Это классный код, но я нашел ответ
https://wordpress.stackexchange.com/a/247691/259060
Ответ — +0 : tm.meta_value+0
/**
* Filter WP_Term_Query meta query
*
* @param object $query WP_Term_Query
* @return object
*/
function filter_terms_clauses( $pieces, $taxonomies, $args ) {
global $pagenow, $wpdb;
if(!is_admin()) {
return $pieces;
}
if(
is_admin()
&& $pagenow == 'edit-tags.php'
&& $taxonomies[0] == 'typer'
&& ( isset($_GET['orderby']) && $_GET['orderby'] == 'prioritet' )
) {
$pieces['join'] .= ' INNER JOIN ' . $wpdb->termmeta . ' AS tm ON t.term_id = tm.term_id ';
$pieces['where'] .= ' AND tm.meta_key = "prioritet"';
$pieces['orderby'] = ' ORDER BY tm.meta_value+0 ';
$pieces['order'] = isset($_GET['order']) ? $_GET['order'] : "DESC";
}
return $pieces;
}
add_filter( 'terms_clauses', 'filter_terms_clauses', 10, 3 );
Ответ или решение
Для решения задачи сортировки столбцов таксономии в WordPress по числовому значению мета-поля следует рассмотреть несколько аспектов, связанных с особенностями работы с пользовательскими таксономиями и мета-полями в WordPress. В данной ситуации у вас есть пользовательская таксономия "typer" и к ней привязано мета-поле "prioritet", содержащее числовые значения. Основная проблема заключается в том, что данные сортируются по этому мета-полю как строки, что приводит к неправильной сортировке числовых значений (например, последовательность [1, 3, 14, 22] отображается как 1, 14, 22, 3). Рассмотрим, как можно решить эту проблему.
Теория:
В WordPress мета-поля (в том числе те, что связаны с таксономиями) хранятся как строки в таблице wp_termmeta
, и по умолчанию сортировка по ним выполняется как по строковым данным. Это объясняет, почему при сортировке мета-значений, они отображаются не в числовом порядке, а в строковом. Чтобы выполнить сортировку числовых данных корректно, необходимо преобразовать строковые значения в числа непосредственно в SQL-запросе. Для этого можно воспользоваться приемом, который заключается в добавлении +0
к значению поля в SQL-запросе, что заставит MySQL воспринимать его как число.
Пример:
В вашем случае исправленная версия функции, которая реализует сортировку, будет выглядеть следующим образом:
function filter_terms_clauses( $pieces, $taxonomies, $args ) {
global $pagenow, $wpdb;
if (!is_admin()) {
return $pieces;
}
if (
is_admin()
&& $pagenow === 'edit-tags.php'
&& $taxonomies[0] === 'typer'
&& (isset($_GET['orderby']) && $_GET['orderby'] === 'prioritet')
) {
$pieces['join'] .= ' INNER JOIN ' . $wpdb->termmeta . ' AS tm ON t.term_id = tm.term_id ';
$pieces['where'] .= ' AND tm.meta_key = "prioritet"';
$pieces['orderby'] = ' ORDER BY tm.meta_value+0 ';
$pieces['order'] = isset($_GET['order']) ? $_GET['order'] : "DESC";
}
return $pieces;
}
add_filter('terms_clauses', 'filter_terms_clauses', 10, 3);
Применение:
-
Создание и регистрация колонок:
Используйте хукmanage_edit-typer_columns
для регистрации новой колонки ‘prioritet’ в админке, и хукmanage_edit-typer_sortable_columns
для того, чтобы сделать эту колонку сортируемой. -
Вывод и сортировка:
Хукmanage_typer_custom_column
позволяет выводить значения мета-полей в соответствующих колонках, что вы уже учли в текущей кодовой базе. -
Фильтрация и изменение SQL-запроса:
Используя хукterms_clauses
, мы можем модифицировать части SQL-запроса для сортировки терминов по числовым значениям мета-полей. Добавление ‘ORDER BY tm.meta_value+0’ обеспечивает правильную математическую сортировку. -
Обработка пустых значений:
Чтобы пустые значения отображались в конце списка, убедитесь, что ваш SQL-запрос обрабатывает нулевые или пустые значения должным образом, а порядок сортировки определяется явно (используя ‘DESC’ или ‘ASC’, как требуется).
Фактически, данное решение позволяет WordPress корректно обрабатывать числовые мета-значения и отображать их в правильном порядке. Убедитесь, что вы тестируете изменения в контролируемой среде, чтобы гарантировать, что функциональность ведет себя ожидаемым образом и не вызывает побочных эффектов. Также, при необходимости, может быть полезно оптимизировать запросы к базе данных для повышения производительности, учитывая объем данных, с которыми вы работаете.