GÜNCELLEME 2018-06-28
Aşağıdaki kod çoğunlukla iyi çalışıyor olsa da, WP> = 4.6.0 (PHP 7 kullanarak) kodunun yeniden yazılması:
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');
Aşağıda okumaya değer çözümler sunan @birgire ve @cale_b'den birkaç fikir ekledim. Özellikle, ben:
$which
Eklenen değişken kullanıldıv4.6.0
- Çevrilebilir dizeler kullanarak i18n için en iyi uygulama kullanılır, örn.
__( 'Filter' )
- İçin döngüler alışverişinde (daha şık?)
array_map()
, array_filter()
Verange()
sprintf()
İşaretleme şablonlarını oluşturmak için kullanılır
- Yerine köşeli ayraç dizi gösterimi kullanıldı
array()
Son olarak, önceki çözümlerimde bir hata buldum. Bu çözümler her zaman <select>
ÜSTÜN ÜSTÜNÜ tercih eder <select>
. Bu nedenle, üst açılır menüden bir filtre seçeneği belirledikten sonra alt açılır menüden bir filtre seçeneği belirlediyseniz, filtre yine de yalnızca en üstte olan değeri (boş değilse) kullanır. Bu yeni sürüm bu hatayı düzeltir.
GÜNCELLEME 2018-02-14
Bu sorun WP 4.6.0'dan beri düzeltilmiştir ve değişiklikler resmi belgelerde belgelenmiştir . Yine de aşağıdaki çözüm hala işe yarıyor.
Problemin Sebebi (WP <4.6.0)
Sorun, restrict_manage_users
eylemin iki kez çağrılmasıydı: bir kez Kullanıcılar tablosunun üstünde ve bir kez aşağıda. Bu select
, aynı adla İKİ açılır listenin oluşturulduğu anlamına gelir . Zaman Filter
düğmesi tıklatıldığında, herhangi bir değer ikinci bir select
(örneğin aşağıda Tablo biri) örneğin, tablo yukarıda, birinci değeri geçersiz kılar elemanı.
WP kaynağına dalmak isterseniz, restrict_manage_users
eylem içeriden tetiklenir WP_Users_List_Table::extra_tablenav($which)
; bu, kullanıcının rolünü değiştirmek için yerel açılır listeyi oluşturan işlevdir. Bu işlev, formun üstünü $which
mü yoksa altını mı oluşturduğunu söyleyen değişkenin yardımına sahiptir select
ve iki açılır listeye farklı name
özellikler vermesine izin verir . Ne yazık ki, $which
değişken restrict_manage_users
eyleme geçmez , bu nedenle kendi özel öğelerimizi farklılaştırmanın başka bir yolunu bulmalıyız.
@Linnea'nın önerdiği gibi , bunu yapmanın bir yolu , Filter
tıklamayı yakalamak ve iki açılır listenin değerlerini senkronize etmek için biraz JavaScript eklemek olacaktır . Şimdi anlatacağım sadece PHP çözümünü seçtim.
Nasıl düzeltilir?
HTML girişlerini değer dizilerine dönüştürme özelliğinden faydalanabilir ve ardından tanımlanmamış değerlerden kurtulmak için diziyi filtreleyebilirsiniz. İşte kod:
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
PHP 7 hakkında heyecanlandığım için, bir PHP 7 sunucusunda WP çalıştırıyorsanız, burada boş birleştirme operatörünü??
kullanan daha kısa, daha seksi bir sürüm :
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' );
Zevk almak!