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
$which
Variable, 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_users
Aktion zweimal aufgerufen wird: einmal ÜBER der Benutzertabelle und einmal UNTEN. Dies bedeutet, dass ZWEI select
Dropdowns mit demselben Namen erstellt werden . Wenn Sie auf die Filter
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, ob select
das Formular über oder unter dem Formular erstellt wird, und ermöglicht es, den beiden Dropdowns unterschiedliche name
Attribute zuzuweisen . Leider wird die $which
Variable nicht an die restrict_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:
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!