Anonim İşlevler aracılığıyla eklenen İşlemleri / Filtreleri Kaldır


10

Bu söylemeliyim ki korkutucu bir kötü uygulama. Anonim işlevler aracılığıyla eklenen eylemleri ve filtreleri kaldırmak için bir çözüm bulmak için son iki saat geçirdim.

Bu, bir Ana Tema üzerinde kullanılan koddur ve kaldırmam gerekiyor.

/**
 * Add custom columns to admin comments grid
 *  * Rate that user set.
 */
add_filter( 'manage_edit-comments_columns', function( $default ) {
    $columns['smr_comment_rate']  = __( 'Rate', 'txtdmn' );

    return array_slice( $default, 0, 3, true ) + $columns + array_slice( $default, 2, NULL, true );
});

Got toscho cevabı ağır onunla oynanan, ancak yardım yok. Yani, anonim işlevlerle eklenen eylemleri / filtreleri kaldıracak başka bir alternatif var mı?

Teşekkürler


Temanın yazarı ile iletişime geçmenizi öneririm. Anonim yerine adlandırılmış bir işlevi kullanması nispeten kolay bir çözümdür ve kodu geliştirir.
Mart'ta

gmazzap @ vishalbasnet23 gibi görünüyor burada yaptım: gist.github.com/vishalbasnet23/5f74df4c800681199ab0246bc037d1d5 Test ediyorum ve şimdiye kadar mükemmel çalışıyor.
Renan Oliveira

Yanıtlar:


10

Sorun, anonim bir işlev ve diğerini formdan ayırt edememenizdir, bu nedenle evet, bir kapağı (yani anonim işlev) kaldırmak mümkündür, ancak birden fazla kapatma aynı filtrede aynı önceliğe göre hareket ediyorsa bir seçim yapmanız gerekir , hepsini kaldırın, cevher sadece birini kaldırın (tam olarak hangisini bilmeden).

Gönderdiğiniz @toscho cevabındaki fonksiyondan oldukça türetilmiş bir fonksiyon kullanarak hepsini nasıl kaldıracağınızı göstereceğim:

/**
 * Remove an object filter.
 *
 * @param  string $tag                Hook name.
 * @param  string $class              Class name. Use 'Closure' for anonymous functions.
 * @param  string|void $method        Method name. Leave empty for anonymous functions.
 * @param  string|int|void $priority  Priority
 * @return void
 */
function remove_object_filter( $tag, $class, $method = NULL, $priority = NULL ) {
  $filters = $GLOBALS['wp_filter'][ $tag ];
  if ( empty ( $filters ) ) {
    return;
  }
  foreach ( $filters as $p => $filter ) {
    if ( ! is_null($priority) && ( (int) $priority !== (int) $p ) ) continue;
    $remove = FALSE;
    foreach ( $filter as $identifier => $function ) {
      $function = $function['function'];
      if (
        is_array( $function )
        && (
          is_a( $function[0], $class )
          || ( is_array( $function ) && $function[0] === $class )
        )
      ) {
        $remove = ( $method && ( $method === $function[1] ) );
      } elseif ( $function instanceof Closure && $class === 'Closure' ) {
        $remove = TRUE;
      }
      if ( $remove ) {
        unset( $GLOBALS['wp_filter'][$tag][$p][$identifier] );
      }
    }
  }
}

Ben remove_object_filterstatik sınıf yöntemleri, dinamik nesne yöntemleri ve kapanış: nesne filtreleri her türlü kaldırabilirsiniz çünkü fonksiyonu yeniden adlandırdım .

$priorityArgüman isteğe bağlı, ancak her zaman kullanılması gerektiğini kapakların çıkarılması, aksi takdirde işlev çünkü ne zaman, ne olursa olsun bu öncelikli olarak, filtresine ilave edilen bir kapatma kaldırır $priorityatlanırsa, hedef sınıfı / yöntem veya kapatma kullanarak tüm filtrelerdir çıkarıldı.

Nasıl kullanılır

// remove a static method
remove_object_filter( 'a_filter_hook', 'AClass', 'a_static_method', 10 );

// remove a dynamic method
remove_object_filter( 'a_filter_hook', 'AClass', 'a_dynamic_method', 10 );

// remove a closure
remove_object_filter( 'a_filter_hook', 'Closure', NULL, 10 );

Ben bunu ve daha pek çok denedim, ama sadece işe yaramıyor
adamj

@adamj 4.7 sürümünden bu yana, WordPress kancaları işlemek için yeni bir yol tanıttı, bu yüzden artık çalışmıyor ...
gmazzap

şans eseri alternatif biliyor musun?
adamj

1
@adamj Bunu 4.7+ için güncelleyebilirdim, ama şimdi vakit yok ve ne zaman alacağımdan emin değilim. Bu Q / A'ya bağlandığınız ve bunun eski olduğunu söylediğiniz yeni bir soru açmak iyidir, böylece herkes cevap verebilir, bu yüzden zamanım olmayacaksa, belki başka biri olacaktır. Alternatif olarak, bu Q üzerinde bir ödül koyabilirsiniz, burada en çok oylanan cevabın mevcut WP sürümünde çalışmadığını ...
gmazzap

3

Filtrenizi önceliği 11 olan eklerseniz, bu filtreyi sonra alır? Bu çirkin, ama sizin durumunuzda işe yarayabilir.

add_filter( 'manage_edit-comments_columns', function( $default ) {
    unset( $default['smr_comment_rate'] );

    return $default;
}, 11, 1 );

2

Anonim filtreler ve eylemler aşağıdakiler kullanılarak yerel olarak kaldırılabilir:

remove_filter( $tag, function(){}, $priority )

Kullanarak benzersiz kimlik oluştururken spl_object_hash()anonim işlevler birbiriyle karşılaştırılabilir olduğundan tam kapatma nesnesinin yeniden oluşturulması gerekmez.

Aynı etikete aynı önceliğe sahip birden fazla filtre veya işlem bağlanırsa, eklenen en son filtreyi veya işlemi kaldırır. Tutmanız gereken bir tane varsa, kaldırmanız gereken filtrelerin tümünü kaldırmanız ve ardından diğerlerini gerektiği gibi yeniden eklemeniz gerekir.

// Filter which was added and needs to be removed
add_filter( 'manage_edit-comments_columns', function( $default ) {
    $columns['smr_comment_rate']  = __( 'Rate', 'txtdmn' );

    return array_slice( $default, 0, 3, true ) + $columns + array_slice( $default, 2, NULL, true );
} );

// Removes the last anonymous filter to be added
remove_filter( 'manage_edit-comments_columns', function(){} );

Bu genellikle en iyi uygulamalara geri dönecektir. Sadece istemcinin geliştirdiğim özel bir temanın parçası olarak anonim işlevleri kullanacağım, burada filtrenin üzerine yazılmasını veya kaldırılmasını istemiyorum. Geliştirdiğim herhangi bir genel tema veya eklentide, bir sınıfı başlatmak, tüm filtrelerimi ve eylemlerimi eklemek, ardından örneği statik bir değişken olarak depolamak için bir fabrika kullanacağım.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.