Сортировка столбцов таксономии по числовому значению мета.

Вопрос или проблема

Постепенно схожу с ума, пытаясь сделать админские колонки таксономии сортируемыми по числовому пользовательскому полю. У меня есть пользовательская таксономия под названием “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 );

Надеюсь, это поможет.

Для меня, я создал пользовательскую таксономию, и в этой пользовательской таксономии у меня есть свой мета. Я хотел, чтобы в админке была колонка и сделал её сортируемой. Чтобы сделать пользовательскую таксономию в пользовательской мета сортируемой, я сделал это.

https://pastebin.com/vr2sCKzX

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);

Применение:

  1. Создание и регистрация колонок:
    Используйте хук manage_edit-typer_columns для регистрации новой колонки ‘prioritet’ в админке, и хук manage_edit-typer_sortable_columns для того, чтобы сделать эту колонку сортируемой.

  2. Вывод и сортировка:
    Хук manage_typer_custom_column позволяет выводить значения мета-полей в соответствующих колонках, что вы уже учли в текущей кодовой базе.

  3. Фильтрация и изменение SQL-запроса:
    Используя хук terms_clauses, мы можем модифицировать части SQL-запроса для сортировки терминов по числовым значениям мета-полей. Добавление ‘ORDER BY tm.meta_value+0’ обеспечивает правильную математическую сортировку.

  4. Обработка пустых значений:
    Чтобы пустые значения отображались в конце списка, убедитесь, что ваш SQL-запрос обрабатывает нулевые или пустые значения должным образом, а порядок сортировки определяется явно (используя ‘DESC’ или ‘ASC’, как требуется).

Фактически, данное решение позволяет WordPress корректно обрабатывать числовые мета-значения и отображать их в правильном порядке. Убедитесь, что вы тестируете изменения в контролируемой среде, чтобы гарантировать, что функциональность ведет себя ожидаемым образом и не вызывает побочных эффектов. Также, при необходимости, может быть полезно оптимизировать запросы к базе данных для повышения производительности, учитывая объем данных, с которыми вы работаете.

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

Капча загружается...