Das Problem
WP scheint den Wert meiner Abfragevariablen zu entfernen, bevor er zum Filtern der Benutzerliste verwendet wird.
Mein Code
Diese Funktion fügt meiner Benutzertabelle eine benutzerdefinierte Spalte hinzu /wp-admin/users.php
:
function add_course_section_to_user_meta( $columns ) {
$columns['course_section'] = 'Section';
return $columns;
}
add_filter( 'manage_users_columns', 'add_course_section_to_user_meta' );
Diese Funktion teilt WP mit, wie Werte in die Spalte eingefügt werden sollen:
function manage_users_course_section( $val, $col, $uid ) {
if ( 'course_section' === $col )
return get_the_author_meta( 'course_section', $uid );
}
add_filter( 'manage_users_custom_column', 'manage_users_course_section' );
Dies fügt ein Dropdown und eine Filter
Schaltfläche über der Benutzertabelle hinzu:
function add_course_section_filter() {
echo '<select name="course_section" style="float:none;">';
echo '<option value="">Course Section...</option>';
for ( $i = 1; $i <= 3; ++$i ) {
if ( $i == $_GET[ 'course_section' ] ) {
echo '<option value="'.$i.'" selected="selected">Section '.$i.'</option>';
} else {
echo '<option value="'.$i.'">Section '.$i.'</option>';
}
}
echo '<input id="post-query-submit" type="submit" class="button" value="Filter" name="">';
}
add_action( 'restrict_manage_users', 'add_course_section_filter' );
Diese Funktion ändert die Benutzerabfrage, um my hinzuzufügen meta_query
:
function filter_users_by_course_section( $query ) {
global $pagenow;
if ( is_admin() &&
'users.php' == $pagenow &&
isset( $_GET[ 'course_section' ] ) &&
!empty( $_GET[ 'course_section' ] )
) {
$section = $_GET[ 'course_section' ];
$meta_query = array(
array(
'key' => 'course_section',
'value' => $section
)
);
$query->set( 'meta_key', 'course_section' );
$query->set( 'meta_query', $meta_query );
}
}
add_filter( 'pre_get_users', 'filter_users_by_course_section' );
Andere Informationen
Es erstellt mein Dropdown korrekt. Wenn ich einen Kursabschnitt auswähle und auf Filter
die Seite klicke course_section
, wird sie aktualisiert und in der URL angezeigt, ihr ist jedoch kein Wert zugeordnet. Wenn ich die HTTP-Anforderungen überprüfe, wird angezeigt, dass sie mit dem richtigen Variablenwert gesendet werden, aber es gibt eine 302 Redirect
, die den von mir ausgewählten Wert zu entfernen scheint.
Wenn ich die course_section
Variable durch direkte Eingabe in die URL sende, funktioniert der Filter wie erwartet.
Mein Code basiert ungefähr auf diesem Code von Dave Court .
Ich habe auch versucht, meine Abfragevariable mit diesem Code auf die Whitelist zu setzen, aber ohne Glück:
function add_course_section_query_var( $qvars ) {
$qvars[] = 'course_section';
return $qvars;
}
add_filter( 'query_vars', 'add_course_section_query_var' );
Ich benutze WP 4.4. Irgendwelche Ideen, warum mein Filter nicht funktioniert?
Antworten:
UPDATE 2018-06-28
Während der folgende Code meistens gut funktioniert, ist hier eine Neufassung des Codes für WP> = 4.6.0 (unter Verwendung von PHP 7):
Ich habe einige Ideen von @birgire und @cale_b aufgenommen, die auch unten lesenswerte Lösungen anbieten. Insbesondere ich:
$which
Variable, die hinzugefügt wurdev4.6.0
__( 'Filter' )
array_map()
,array_filter()
Undrange()
sprintf()
zum Generieren der Markup-Vorlagen verwendetarray()
Zuletzt habe ich einen Fehler in meinen früheren Lösungen entdeckt. Diese Lösungen bevorzugen immer das TOP
<select>
gegenüber dem BOTTOM<select>
. Wenn Sie also eine Filteroption aus der oberen Dropdown-Liste ausgewählt und anschließend eine aus der unteren Dropdown-Liste ausgewählt haben, verwendet der Filter immer noch nur den Wert, der oben war (wenn er nicht leer ist). Diese neue Version behebt diesen Fehler.UPDATE 14.02.2018
Dieses Problem wurde seit WP 4.6.0 behoben und die Änderungen sind in den offiziellen Dokumenten dokumentiert . Die folgende Lösung funktioniert jedoch immer noch.
Was hat das Problem verursacht (WP <4.6.0)
Das Problem war, dass die
restrict_manage_users
Aktion zweimal aufgerufen wird: einmal ÜBER der Benutzertabelle und einmal UNTEN. Dies bedeutet, dass ZWEIselect
Dropdowns mit demselben Namen erstellt werden . Wenn Sie auf dieFilter
Schaltfläche klicken,select
überschreibt der Wert im zweiten Element (dh der Wert UNTER der Tabelle) den Wert im ersten Element, dh der Wert ÜBER der Tabelle.Wenn Sie in die WP-Quelle eintauchen möchten, wird die
restrict_manage_users
Aktion von innen ausgelöst.WP_Users_List_Table::extra_tablenav($which)
Dies ist die Funktion, mit der das native Dropdown-Menü erstellt wird, um die Rolle eines Benutzers zu ändern. Diese Funktion hat die Hilfe der$which
Variablen, die angibt, obselect
das Formular über oder unter dem Formular erstellt wird, und ermöglicht es, den beiden Dropdowns unterschiedlichename
Attribute zuzuweisen . Leider wird die$which
Variable nicht an dierestrict_manage_users
Aktion übergeben, daher müssen wir einen anderen Weg finden, um unsere eigenen benutzerdefinierten Elemente zu unterscheiden.Eine Möglichkeit, dies zu tun, besteht, wie @Linnea vorschlägt , darin, JavaScript hinzuzufügen, um den
Filter
Klick abzufangen und die Werte der beiden Dropdowns zu synchronisieren. Ich habe eine reine PHP-Lösung gewählt, die ich jetzt beschreiben werde.Wie man es repariert
Sie können die Möglichkeit nutzen, HTML-Eingaben in Arrays von Werten umzuwandeln und das Array dann zu filtern, um undefinierte Werte zu entfernen. Hier ist der Code:
Bonus: PHP 7 Refactor
Da ich von PHP 7 begeistert bin, ist für den Fall, dass Sie WP auf einem PHP 7-Server ausführen, eine kürzere, sexyere Version mit dem Null-Koaleszenz-Operator
??
:Genießen!
quelle
</select>
Ich habe auch festgestellt, dass es funktioniert. Ich musste es<form method="get">
vor das Auswahlmenü und</form>
nach die Filterschaltfläche setzen.</select>
Tags! Ich habe sie hinzugefügt. Seltsam, dass Sie es in eine einschließen mussten,<form>
da diese gesamte Seite in einer großen Form verpackt ist und dieser Code in die Mitte eingefügt wird. Ich bin froh, dass es funktioniert hat. :)Im Kern sind die unteren Eingabenamen mit der Instanznummer gekennzeichnet, z. B.
new_role
(oben) undnew_role2
(unten). Hier sind zwei Ansätze für eine ähnliche Namenskonvention, nämlichcourse_section1
(oben) undcourse_section2
(unten):Ansatz Nr. 1
Da die
$which
Variable ( oben , unten ) nicht an denrestrict_manage_users
Hook übergeben wird, können wir dies umgehen, indem wir unsere eigene Version dieses Hooks erstellen:Erstellen wir den Aktions-Hook
wpse_restrict_manage_users
, der Zugriff auf eine$which
Variable hat:Dann können wir es einhaken mit:
wo wir jetzt
$name
alscourse_section1
am oberen undcourse_section2
am unteren Rand .Ansatz Nr. 2
Lassen Sie uns
restrict_manage_users
Dropdowns mit einem anderen Namen für jede Instanz anzeigen:wo wir die Kernfunktion
selected()
und die Hilfsfunktion verwendet haben:Dann könnten wir dies auch verwenden, wenn wir im
pre_get_users
Aktionsrückruf nach dem ausgewählten Kursabschnitt suchen.quelle
static
Schlüsselwort noch nie so verwendet (nur innerhalb von Klassen). Wird dabei$instance
eine globale Variable? Müssen Sie sich um Kollisionen mit Variablennamen sorgen? Ich mag auch die Technik, eine neue Aktion zu erstellen, die sich auf eine vorhandene stützt. Vielen Dank!Ich habe Ihren Code sowohl in Wordpress 4.4 als auch in Wordpress 4.3.1 getestet. In Version 4.4 habe ich genau das gleiche Problem wie Sie. Ihr Code funktioniert jedoch in Version 4.3.1 korrekt!
Ich denke, das ist ein Wordpress-Fehler. Ich weiß nicht, ob es noch gemeldet wurde. Ich denke, der Grund für den Fehler könnte sein, dass die Schaltfläche "Senden" die Abfragevariablen zweimal sendet. Wenn Sie sich die Abfragevariablen ansehen, werden Sie feststellen, dass course_section zweimal aufgeführt wird, einmal mit dem richtigen Wert und einmal leer.
Bearbeiten: Dies ist die JavaScript-Lösung
Fügen Sie dies einfach der Datei functions.php Ihres Themas hinzu und ändern Sie NAME_OF_YOUR_INPUT_FIELD in den Namen Ihres Eingabefelds! Da WordPress jQuery automatisch auf der Administratorseite lädt, müssen Sie keine Skripte in die Warteschlange stellen. Dieser Codeausschnitt fügt einfach einen Änderungslistener zu den Dropdown-Eingaben hinzu und aktualisiert dann automatisch die andere Dropdown-Liste, um denselben Wert zu erhalten. Mehr Erklärung hier.
Hoffe das hilft!
quelle
Filter
, wird der richtige Wert gesendet, aber dann wird wieder auf die Seite zurückgeleitet, diesmal wird der Wert entfernt. Ich vermute, dass es sich um eine Art Sicherheitsfunktion handelt, die verhindert, dass zufällige, möglicherweise böswillige Werte übermittelt werden, aber ich weiß nicht, wie ich das umgehen soll. Seufzer.name
Attribut. Wenn ich das Dropdown-Menü UNTER der Tabelle verwende, um die Filterung durchzuführen, funktioniert es wie erwartet. Da dieses Feld nach dem darüber liegenden Feld steht, überschreibt der Nullwert das vorherige. Hmmm ....Dies ist eine andere Javascript-Lösung, die für manche Menschen hilfreich sein kann. In meinem Fall habe ich einfach die 2. (untere) Auswahlliste vollständig entfernt. Ich finde, dass ich sowieso nie die unteren Eingänge benutze ...
quelle
Nicht-JavaScript-Lösung
Geben Sie der Auswahl einen Namen, der "Array-Stil" ist, wie folgt:
Dann werden BEIDE Parameter übergeben (von oben und unten in der Tabelle) und jetzt in einem bekannten Array-Format.
Dann kann der Wert wie folgt in der
pre_get_users
Funktion verwendet werden:quelle
eine andere Lösung
Sie können Ihr Filterauswahlfeld in einer separaten Datei wie platzieren
user_list_filter.php
und verwenden Sie
require_once 'user_list_filter.php'
in Ihrer Aktion Rückruffunktionuser_list_filter.php
Datei:und in Ihrem Aktionsrückruf:
quelle