CẬP NHẬT 2018-06-28
Mặc dù mã bên dưới hầu hết hoạt động tốt, đây là cách viết lại mã cho WP> = 4.6.0 (sử dụng 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');
Tôi đã kết hợp một số ý tưởng từ @birgire và @cale_b, những người cũng cung cấp các giải pháp dưới đây đáng để đọc. Cụ thể, tôi:
- Đã sử dụng
$which
biến được thêm vàov4.6.0
- Được sử dụng thực tiễn tốt nhất cho i18n bằng cách sử dụng các chuỗi có thể dịch, ví dụ:
__( 'Filter' )
- Trao đổi vòng cho (thời trang hơn?)
array_map()
, array_filter()
Vàrange()
- Được sử dụng
sprintf()
để tạo các mẫu đánh dấu
- Đã sử dụng ký hiệu mảng vuông thay vì
array()
Cuối cùng, tôi phát hiện ra một lỗi trong các giải pháp trước đây của tôi. Những giải pháp đó luôn ưu tiên TOP <select>
trên BOTTOM <select>
. Vì vậy, nếu bạn đã chọn tùy chọn bộ lọc từ danh sách thả xuống trên cùng, sau đó chọn một tùy chọn từ danh sách thả xuống dưới cùng, bộ lọc sẽ vẫn chỉ sử dụng bất kỳ giá trị nào ở trên cùng (nếu nó không trống). Phiên bản mới này sửa lỗi đó.
CẬP NHẬT 2018/02/14
Đây vấn đề đã được vá từ WP 4.6.0 và những thay đổi được diễn tả trong các tài liệu chính thức . Các giải pháp dưới đây vẫn hoạt động, mặc dù.
Điều gì gây ra vấn đề (WP <4.6.0)
Vấn đề là restrict_manage_users
hành động được gọi hai lần: một lần TRÊN bảng Người dùng và một lần DƯỚI ĐÂY. Điều này có nghĩa là các select
danh sách thả xuống HAI được tạo với cùng tên . Khi Filter
nhấp vào nút, bất kỳ giá trị nào nằm trong select
phần tử thứ hai (tức là phần DƯỚI bảng) sẽ ghi đè giá trị trong phần đầu tiên, tức là phần TRÊN bảng.
Trong trường hợp bạn muốn đi sâu vào nguồn WP, restrict_manage_users
hành động được kích hoạt từ bên trong WP_Users_List_Table::extra_tablenav($which)
, đó là chức năng tạo ra trình đơn thả xuống gốc để thay đổi vai trò của người dùng. Hàm đó có sự trợ giúp của $which
biến cho nó biết liệu nó đang tạo select
biểu mẫu trên hay dưới biểu mẫu và cho phép nó đưa ra hai name
thuộc tính khác nhau . Thật không may, $which
biến không được chuyển sang restrict_manage_users
hành động, vì vậy chúng tôi phải đưa ra một cách khác để phân biệt các yếu tố tùy chỉnh của riêng chúng tôi.
Một cách để làm điều này, như @Linnea gợi ý , sẽ là thêm một số JavaScript để bắt Filter
nhấp và đồng bộ hóa các giá trị của hai danh sách thả xuống. Tôi đã chọn một giải pháp chỉ dành cho PHP mà tôi sẽ mô tả ngay bây giờ.
Cách khắc phục
Bạn có thể tận dụng khả năng biến các đầu vào HTML thành các mảng giá trị và sau đó lọc mảng để loại bỏ mọi giá trị không xác định. Đây là mã:
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' );
Phần thưởng: Tái cấu trúc PHP 7
Vì tôi rất hào hứng với PHP 7, trong trường hợp bạn đang chạy WP trên máy chủ PHP 7, đây là phiên bản ngắn hơn, hấp dẫn hơn bằng cách sử dụng toán tử hợp nhất null??
:
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' );
Thưởng thức!