Masalah
WP muncul untuk menghapus nilai variabel kueri saya sebelum digunakan untuk memfilter daftar pengguna.
Kode Saya
Fungsi ini menambahkan kolom khusus ke tabel Pengguna saya di /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' );
Fungsi ini memberi tahu WP cara mengisi nilai di kolom:
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' );
Ini menambahkan dropdown dan Filter
tombol di atas tabel Users:
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' );
Fungsi ini mengubah permintaan pengguna untuk menambahkan 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' );
Informasi lainnya
Itu membuat dropdown saya dengan benar. Ketika saya memilih bagian kursus dan mengklik Filter
halaman menyegarkan dan course_section
muncul di URL, tetapi tidak memiliki nilai yang terkait dengannya. Jika saya memeriksa permintaan HTTP, itu menunjukkan bahwa itu akan dikirimkan dengan nilai variabel yang benar, tetapi kemudian ada302 Redirect
yang tampaknya menghapus nilai yang saya pilih.
Jika saya kirimkan course_section
variabel dengan mengetikkannya langsung ke URL, filter berfungsi seperti yang diharapkan.
Kode saya secara kasar didasarkan pada kode ini dari Dave Court .
Saya juga mencoba memasukkan var dalam daftar putih menggunakan kode ini, tetapi tidak berhasil:
function add_course_section_query_var( $qvars ) {
$qvars[] = 'course_section';
return $qvars;
}
add_filter( 'query_vars', 'add_course_section_query_var' );
Saya menggunakan WP 4.4. Adakah gagasan mengapa filter saya tidak berfungsi?
Jawaban:
UPDATE 2018-06-28
Sementara kode di bawah sebagian besar berfungsi dengan baik, berikut adalah penulisan ulang kode untuk WP> = 4.6.0 (menggunakan PHP 7):
Saya memasukkan beberapa ide dari @birgire dan @cale_b yang juga menawarkan solusi di bawah ini yang layak dibaca. Secara khusus, saya:
$which
variabel yang ditambahkan div4.6.0
__( 'Filter' )
array_map()
,array_filter()
Danrange()
sprintf()
untuk membuat templat markuparray()
Terakhir, saya menemukan bug dalam solusi saya sebelumnya. Solusi-solusi itu selalu mendukung TOP
<select>
daripada BOTTOM<select>
. Jadi jika Anda memilih opsi filter dari dropdown atas, dan kemudian memilih satu dari dropdown bawah, filter masih akan hanya menggunakan nilai apa pun yang ada di atas (jika tidak kosong). Versi baru ini memperbaiki bug itu.PEMBARUAN 2018-02-14
Ini masalah telah ditambal sejak WP 4.6.0 dan perubahan didokumentasikan dalam dokumen resmi . Namun, solusi di bawah masih berfungsi.
Apa yang Menyebabkan Masalah (WP <4.6.0)
Masalahnya adalah bahwa
restrict_manage_users
tindakan dipanggil dua kali: sekali DI ATAS tabel Pengguna, dan sekali DI BAWAH. Ini berarti bahwa DUAselect
dropdown dibuat dengan nama yang sama . KetikaFilter
tombol diklik, nilai apa pun yang ada diselect
elemen kedua (yaitu yang DI BAWAH tabel) menimpa nilai di yang pertama, yaitu yang di atas tabel.Jika Anda ingin masuk ke sumber WP,
restrict_manage_users
tindakan dipicu dari dalamWP_Users_List_Table::extra_tablenav($which)
, yang merupakan fungsi yang menciptakan dropdown asli untuk mengubah peran pengguna. Fungsi itu memiliki bantuan dari$which
variabel yang memberitahukannya apakah itu membuatselect
formulir di atas atau di bawah, dan memungkinkannya untuk memberikan dua dropdownname
atribut yang berbeda . Sayangnya,$which
variabel tidak diteruskan kerestrict_manage_users
tindakan, jadi kami harus menemukan cara lain untuk membedakan elemen khusus kami.Salah satu cara untuk melakukan ini, seperti yang disarankan oleh @Linnea , adalah menambahkan beberapa JavaScript untuk menangkap
Filter
klik dan menyinkronkan nilai-nilai dari kedua dropdown. Saya memilih solusi khusus PHP yang akan saya jelaskan sekarang.Bagaimana memperbaikinya
Anda dapat memanfaatkan kemampuan untuk mengubah input HTML menjadi array nilai, dan kemudian menyaring array untuk menghilangkan nilai yang tidak ditentukan. Berikut kodenya:
Bonus: PHP 7 Refactor
Karena saya senang dengan PHP 7, jika Anda menjalankan WP pada server PHP 7, inilah versi yang lebih pendek dan seksi menggunakan operator penggabungan nol
??
:Nikmati!
sumber
</select>
Saya juga menemukan untuk mendapatkannya bekerja aku harus meletakkan<form method="get">
sebelum pilih menu dan</form>
setelah filter tombol.</select>
tag yang hilang ! Saya menambahkannya. Aneh bahwa Anda perlu membungkusnya<form>
karena seluruh halaman ini dibungkus dalam satu bentuk besar, dan kode ini akan disuntikkan ke tengah-tengahnya. Senang Anda berhasil, meskipun. :)Pada intinya, nama input bawah ditandai dengan nomor instance, mis.
new_role
( Atas ) dannew_role2
(bawah). Berikut adalah dua pendekatan untuk konvensi penamaan yang serupa, yaitucourse_section1
(atas) dancourse_section2
(bawah):Pendekatan # 1
Karena
$which
variabel ( atas , bawah ) tidak diteruskan kerestrict_manage_users
hook, kita dapat menyiasatinya dengan membuat versi kita sendiri dari hook itu:Mari kita membuat kait tindakan
wpse_restrict_manage_users
yang memiliki akses ke$which
variabel:Lalu kita bisa mengaitkannya dengan:
di mana kita sekarang memiliki
$name
sebagaicourse_section1
di atas dancourse_section2
di bawah .Pendekatan # 2
Mari menghubungkan
restrict_manage_users
, untuk menampilkan dropdown, dengan nama yang berbeda untuk setiap instance:tempat kami menggunakan fungsi inti
selected()
dan fungsi pembantu:Kemudian kita juga bisa menggunakan ini ketika kita memeriksa bagian kursus yang dipilih di
pre_get_users
callback tindakan.sumber
static
kata kunci dengan cara ini (hanya di dalam kelas). Apakah$instance
menjadi variabel global saat Anda melakukan ini? Apakah Anda harus khawatir tentang tabrakan nama variabel? Saya juga suka teknik menciptakan tindakan baru yang mendukung yang sudah ada. Terima kasih!Saya menguji kode Anda di Wordpress 4.4 dan Wordpress 4.3.1. Dengan versi 4.4, saya menemukan masalah yang persis sama dengan Anda. Namun, kode Anda berfungsi dengan benar dalam versi 4.3.1!
Saya pikir ini adalah bug Wordpress. Saya tidak tahu apakah ini sudah dilaporkan. Saya pikir alasan di balik bug mungkin karena tombol kirim mengirimkan vars permintaan dua kali. Jika Anda melihat kueri vars, Anda akan melihat bahwa course_section terdaftar dua kali, sekali dengan nilai yang benar dan sekali kosong.
Sunting: Ini adalah Solusi JavaScript
Cukup tambahkan ini ke file functions.php tema Anda dan ubah NAME_OF_YOUR_INPUT_FIELD menjadi nama bidang input Anda! Karena WordPress secara otomatis memuat jQuery di sisi admin, Anda tidak perlu membuat skrip apa pun. Potongan kode ini hanya menambah pendengar perubahan ke input dropdown dan kemudian secara otomatis memperbarui dropdown lainnya agar sesuai dengan nilai yang sama. Penjelasan lebih lanjut di sini.
Semoga ini membantu!
sumber
Filter
mengirimkan nilai yang benar, tetapi kemudian mengarahkan kembali ke halaman lagi, kali ini membuang nilainya. Dugaan saya adalah bahwa ini adalah semacam "fitur" keamanan untuk mencegah nilai-nilai acak, yang berpotensi berbahaya, dikirimkan, tetapi saya tidak tahu bagaimana cara mengatasinya. Mendesah.name
atribut yang sama . Jika saya menggunakan dropdown DI BAWAH tabel untuk melakukan penyaringan, ini berfungsi seperti yang diharapkan. Karena bidang itu muncul setelah yang di atasnya, nilainya nol menimpa yang sebelumnya. Hmmm ....Ini adalah solusi Javascript berbeda yang mungkin bermanfaat bagi sebagian orang. Dalam kasus saya, saya hanya menghapus daftar pilih ke-2 (bawah) seluruhnya. Saya menemukan bahwa saya tidak pernah menggunakan input terbawah ...
sumber
Solusi Non-JavaScript
Beri nama yang dipilih "gaya array", seperti:
Kemudian KEDUA parameter dilewatkan (dari atas dan bawah tabel), dan sekarang dalam format array yang dikenal.
Kemudian, nilai tersebut dapat digunakan seperti ini dalam
pre_get_users
fungsi:sumber
solusi lain
Anda dapat menempatkan kotak pilih filter Anda dalam file terpisah seperti
user_list_filter.php
dan gunakan
require_once 'user_list_filter.php'
dalam fungsi callback tindakan Andauser_list_filter.php
mengajukan:dan dalam callback tindakan Anda:
sumber