Sortierbare benutzerdefinierte Spalten im Benutzerfenster (users.php)?

8

Ich verwende das Register Plus Redux-Plugin, um ein Registrierungsformular mit benutzerdefinierten Metadatenfeldern zu erweitern. Diese Felder werden unten auf jeder Seite mit Benutzerdatensätzen angezeigt und können mit get_the_author_meta abgerufen werden.

Außerdem kann ich im Benutzerfenster (der Listenansicht) Spalten erstellen und diese Spalten sortierbar machen. Das Problem ist, dass beim Klicken auf die benutzerdefinierte Spaltenüberschrift der Wert orderby = in der URL ignoriert wird. Anders ausgedrückt, die Abfrage, die die Listenansicht der Benutzer generiert, enthält anscheinend keine benutzerdefinierten Metadaten (z. B. ist möglicherweise eine Join-Anweisung erforderlich, wenn sich die Metadaten nicht an der für Benutzerdaten üblichen Stelle befinden?). Es fühlt sich an, als hätte ich einen Schritt verpasst.

Hier ist mein Code zum Erstellen der benutzerdefinierten Spalten:

//add columns to User panel list page
function add_user_columns( $defaults ) {
     $defaults['company'] = __('Company', 'user-column');
     $defaults['title'] = __('Title', 'user-column');
     return $defaults;
}
function add_custom_user_columns($value, $column_name, $id) {
      if( $column_name == 'company' ) {
        return get_the_author_meta( 'company_name', $id );
      }
      if( $column_name == 'title' ) {
        return get_the_author_meta( 'titlefunction', $id );
      }
}
add_action('manage_users_custom_column', 'add_custom_user_columns', 15, 3);
add_filter('manage_users_columns', 'add_user_columns', 15, 1);`

Und hier ist mein Code, um diese Spalten sortierbar zu machen:

function user_sortable_columns( $columns ) {
    $columns['company'] = 'Company';
    return $columns;
}
add_filter( 'manage_users_sortable_columns', 'user_sortable_columns' );

function user_column_orderby( $vars ) {
    if ( isset( $vars['orderby'] ) && 'company' == $vars['orderby'] ) {
        $vars = array_merge( $vars, array(
            'meta_key' => 'company',
            'orderby' => 'meta_value',
            'order'     => 'asc'
        ) );
    }
    return $vars;
}
add_filter( 'request', 'user_column_orderby' );`

Irgendwelche Ideen, wie ich die Abfrage, die die Liste der Benutzer generiert, so aktualisieren kann, dass sie nach meinen benutzerdefinierten Feldern sortiert wird? Oder, wenn dies nicht das Problem ist, wie lassen Sie die benutzerdefinierten Spaltenüberschriften die Liste der Benutzer sortieren, wenn Sie darauf klicken?

Vielen Dank.

FredHead
quelle
Siehe Blog tekina.info/… für eine detaillierte Erklärung
Aniket Singh

Antworten:

6

Meine erste Antwort war völlig falsch und ich schreibe sie komplett neu ...

Aber dank Milos Hinweis habe ich die Lösung hier gefunden:
http://wordpress.mcdspot.com/2011/05/24/search-admin-user-list-on-first-and-last-names/

Nach der Anpassung funktioniert dies bei mir mit 'Facebook' und 'Twitter' author_meta.

add_action('pre_user_query','wpse_27518_pre_user_query');
function wpse_27518_pre_user_query($user_search) {
    global $wpdb,$current_screen;

    if ( 'users' != $current_screen->id ) 
        return;

    $vars = $user_search->query_vars;

    if('facebook' == $vars['orderby']) 
    {
        $user_search->query_from .= " INNER JOIN {$wpdb->usermeta} m1 ON {$wpdb->users}.ID=m1.user_id AND (m1.meta_key='facebook')"; 
        $user_search->query_orderby = ' ORDER BY UPPER(m1.meta_value) '. $vars['order'];
    } 

    elseif ('twitter' == $vars['orderby']) 
    {
        $user_search->query_from .= " INNER JOIN {$wpdb->usermeta} m1 ON {$wpdb->users}.ID=m1.user_id AND (m1.meta_key='twitter')"; 
        $user_search->query_orderby = ' ORDER BY UPPER(m1.meta_value) '. $vars['order'];
   }
}
brasofilo
quelle
1

Ich bin nicht sicher, ob es möglich ist, vielleicht durch Ändern der Abfrage über pre_user_query. Hier ist eine schnelle und schmutzige Funktion zum Anzeigen des Inhalts:

add_action('pre_user_query', 'my_user_query');
function my_user_query($userquery){
    print_r($userquery);
    die();
}
Milo
quelle
Die Ausgabe von pre_user_query lautet: WP_User_Query Object ([results] => [total_users] => 0 [query_fields] => SQL_CALC_FOUND_ROWS wp_users.ID [query_from] => FROM wp_users [query_where] => WHERE 1 = 1 [query_orderby]> BY user_login ASC [query_limit] => LIMIT 20 [query_vars] => Array ([blog_id] => 1 [role] => [meta_key] => [meta_value] => [meta_compare] => [include] => Array ( ) [exclude] => Array () [search] => [orderby] => Company [order] => ASC [offset] => 0 [number] => 20 [count_total] => 1 [fields] => all_with_meta [who] =>)). Wie würde ich diese Abfrage ändern, z. B. einer DB-Tabelle beitreten?
FredHead
@FredHead, Wenn Sie viel Code veröffentlichen möchten, können Sie Pastebin, Snipplr oder ähnliches verwenden.
Jeremy Jared
@FredHead - ehrlich gesagt, ich weiß es nicht. Ich könnte später versuchen, mich damit zu beschäftigen, oder hoffentlich können einige erfahrene Benutzer etwas Licht ins Dunkel bringen.
Milo
Entschuldigung, ich habe versucht zu antworten, aber in Chrome, Firefox wurden unergründliche kommentarbezogene Fehlermeldungen angezeigt, die die Übermittlung am Do / Fr verhinderten.
FredHead
Versuchen wir es noch einmal: Milo, deine Antwort bringt mich wenigstens in den Ballpark, danke. Jetzt muss ich verstehen, ob / wie die Benutzerabfrage angepasst werden soll. Vielleicht kann mir jemand helfen, diesen Teil des Problems zu verstehen? Jeremy, ich finde diese Kommentaroberfläche schwierig zu benutzen (drücke die Eingabetaste = Kommentar senden) oder ich hätte den Ausgabecode an eine andere Stelle verschoben. Es tut uns leid.
FredHead
1

Der einfachste Weg, dies meiner Meinung nach zu tun:

<?php

/**
 * Sorting logic for custom columns on WP user table
 */
add_action('pre_user_query', function(WP_User_Query $query) {
  global $wpdb, $current_screen;

  // Bail if viewing anything other than user list in WP Admin
  if ( 'users' != $current_screen->id ) {
    return;
  }

  if ( 'company' === $query->query_vars['orderby'] ) {
    $query->orderby = 'meta_value';
    $query->meta_key = 'company_name';
  }

  else if ( 'title' === $query->query_vars['orderby'] ) {
    $query->orderby = 'meta_value';
    $query->meta_key = 'titlefunction';
  }

}, 10, 1);
Ahrengot
quelle
1

Wenn Ihre Metawerte nicht vollständig ausgefüllt sind (Nullen haben), wird durch die hervorragende Antwort von @ brasofilo eine Benutzerliste erstellt, in der Benutzer mit fehlenden meta_values-Werten weggelassen werden.

Die Lösung ist jedoch einfach. Mach einfach einen LEFT JOIN :

add_action('pre_user_query','wpse_27518_pre_user_query');
function wpse_27518_pre_user_query($user_search) {
    global $wpdb,$current_screen;

    if ( 'users' != $current_screen->id ) 
        return;

    $vars = $user_search->query_vars;

    if('facebook' == $vars['orderby']) 
    {
        $user_search->query_from .= " LEFT JOIN {$wpdb->usermeta} m1 ON {$wpdb->users}.ID=m1.user_id AND (m1.meta_key='facebook')"; 
        $user_search->query_orderby = ' ORDER BY UPPER(m1.meta_value) '. $vars['order'];
    } 

    elseif ('twitter' == $vars['orderby']) 
    {
        $user_search->query_from .= " LEFT JOIN {$wpdb->usermeta} m1 ON {$wpdb->users}.ID=m1.user_id AND (m1.meta_key='twitter')"; 
        $user_search->query_orderby = ' ORDER BY UPPER(m1.meta_value) '. $vars['order'];
   }
}

$user_search->query_from .= " LEFT JOIN {$wpdb->usermeta} m1 ON {$wpdb->users}.ID=m1.user_id AND (m1.meta_key='facebook')";

David Roth
quelle
-1

Ich konnte die Benutzersortierung einer benutzerdefinierten Spalte mithilfe des von Ihnen geposteten Codes und der von Ihnen geposteten Hooks erreichen, außer dass ich weder den Filter "Anfrage" verwendet habe noch eine zusätzliche Funktion "Bestellen nach" benötigte. Wordpress sortiert die Daten in der benutzerdefinierten Spalte in meinem Fall ordnungsgemäß nach dem numerischen Wert, den ich im Aktionsrückruf 'manage_users_custom_column' zurückgebe.

Ricosrealm
quelle
Cool. Könnten Sie den aktualisierten Code für mich / alle veröffentlichen? Vielen Dank!
FredHead