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):
function add_course_section_filter( $which ) {
// create sprintf templates for <select> and <option>s
$st = '<select name="course_section_%s" style="float:none;"><option value="">%s</option>%s</select>';
$ot = '<option value="%s" %s>Section %s</option>';
// determine which filter button was clicked, if any and set section
$button = key( array_filter( $_GET, function($v) { return __( 'Filter' ) === $v; } ) );
$section = $_GET[ 'course_section_' . $button ] ?? -1;
// generate <option> and <select> code
$options = implode( '', array_map( function($i) use ( $ot, $section ) {
return sprintf( $ot, $i, selected( $i, $section, false ), $i );
}, range( 1, 3 ) ));
$select = sprintf( $st, $which, __( 'Course Section...' ), $options );
// output <select> and submit button
echo $select;
submit_button(__( 'Filter' ), null, $which, false);
}
add_action('restrict_manage_users', 'add_course_section_filter');
function filter_users_by_course_section($query)
{
global $pagenow;
if (is_admin() && 'users.php' == $pagenow) {
$button = key( array_filter( $_GET, function($v) { return __( 'Filter' ) === $v; } ) );
if ($section = $_GET[ 'course_section_' . $button ]) {
$meta_query = [['key' => 'courses','value' => $section, 'compare' => 'LIKE']];
$query->set('meta_key', 'courses');
$query->set('meta_query', $meta_query);
}
}
}
add_filter('pre_get_users', 'filter_users_by_course_section');
Ich habe einige Ideen von @birgire und @cale_b aufgenommen, die auch unten lesenswerte Lösungen anbieten. Insbesondere ich:
- Verwendete die
$whichVariable, die hinzugefügt wurdev4.6.0
- Verwendete Best Practice für i18n unter Verwendung übersetzbarer Zeichenfolgen, z
__( 'Filter' )
- Ausgetauschte Schlaufen für die (mehr in Mode?)
array_map(), array_filter()Undrange()
- Wird
sprintf()zum Generieren der Markup-Vorlagen verwendet
- Verwendet die eckige Klammer-Array-Notation anstelle von
array()
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_usersAktion zweimal aufgerufen wird: einmal ÜBER der Benutzertabelle und einmal UNTEN. Dies bedeutet, dass ZWEI selectDropdowns mit demselben Namen erstellt werden . Wenn Sie auf die FilterSchaltflä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_usersAktion 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 $whichVariablen, die angibt, ob selectdas Formular über oder unter dem Formular erstellt wird, und ermöglicht es, den beiden Dropdowns unterschiedliche nameAttribute zuzuweisen . Leider wird die $whichVariable nicht an die restrict_manage_usersAktion ü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 FilterKlick 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:
function add_course_section_filter() {
if ( isset( $_GET[ 'course_section' ]) ) {
$section = $_GET[ 'course_section' ];
$section = !empty( $section[ 0 ] ) ? $section[ 0 ] : $section[ 1 ];
} else {
$section = -1;
}
echo ' <select name="course_section[]" style="float:none;"><option value="">Course Section...</option>';
for ( $i = 1; $i <= 3; ++$i ) {
$selected = $i == $section ? ' selected="selected"' : '';
echo '<option value="' . $i . '"' . $selected . '>Section ' . $i . '</option>';
}
echo '</select>';
echo '<input type="submit" class="button" value="Filter">';
}
add_action( 'restrict_manage_users', 'add_course_section_filter' );
function filter_users_by_course_section( $query ) {
global $pagenow;
if ( is_admin() &&
'users.php' == $pagenow &&
isset( $_GET[ 'course_section' ] ) &&
is_array( $_GET[ 'course_section' ] )
) {
$section = $_GET[ 'course_section' ];
$section = !empty( $section[ 0 ] ) ? $section[ 0 ] : $section[ 1 ];
$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' );
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?? :
function add_course_section_filter() {
$section = $_GET[ 'course_section' ][ 0 ] ?? $_GET[ 'course_section' ][ 1 ] ?? -1;
echo ' <select name="course_section[]" style="float:none;"><option value="">Course Section...</option>';
for ( $i = 1; $i <= 3; ++$i ) {
$selected = $i == $section ? ' selected="selected"' : '';
echo '<option value="' . $i . '"' . $selected . '>Section ' . $i . '</option>';
}
echo '</select>';
echo '<input type="submit" class="button" value="Filter">';
}
add_action( 'restrict_manage_users', 'add_course_section_filter' );
function filter_users_by_course_section( $query ) {
global $pagenow;
if ( is_admin() && 'users.php' == $pagenow) {
$section = $_GET[ 'course_section' ][ 0 ] ?? $_GET[ 'course_section' ][ 1 ] ?? null;
if ( null !== $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' );
Genießen!