Hapus Tindakan / Filter yang ditambahkan melalui Fungsi Anonim

10

Saya harus mengatakan itu adalah praktik buruk yang menakutkan. Menghabiskan dua jam terakhir menemukan solusi untuk menghapus tindakan dan filter yang ditambahkan melalui fungsi Anonim.

Ini adalah kode yang digunakan pada Tema Induk, dan saya harus menghapusnya.

/**
 * 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 );
});

Mendapat jawaban toscho , bermain dengan itu, tetapi tidak membantu. Jadi, apakah ada alternatif lain yang akan menghapus tindakan / filter yang ditambahkan melalui fungsi anonim?

Terima kasih

Abhik
sumber
Saya sarankan menghubungi penulis tema. Ini adalah perbaikan yang relatif mudah baginya untuk menggunakan fungsi bernama di tempat anonim dan akan meningkatkan kode.
Helgatheviking
gmazzap sepertinya @ vishalbasnet23 melakukannya di sini: gist.github.com/vishalbasnet23/5f74df4c800681199ab0246bc037d1d5 Saya mengujinya dan sejauh ini berfungsi dengan baik.
Renan Oliveira

Jawaban:

10

Masalahnya adalah Anda tidak dapat membedakan bentuk fungsi anonim dan lainnya, jadi ya, dimungkinkan untuk menghapus penutupan (yaitu fungsi anonim) tetapi jika lebih dari satu penutupan bertindak pada filter yang sama pada prioritas yang sama Anda harus membuat pilihan , hapus semuanya, jangan hanya menghapus satu (tanpa mengetahui persisnya).

Saya akan menunjukkan cara menghapus semuanya menggunakan fungsi yang sangat berasal dari yang ada di @toscho jawaban yang Anda poskan:

/**
 * 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] );
      }
    }
  }
}

Saya telah mengganti nama fungsinya remove_object_filterkarena dapat menghapus semua jenis filter objek: metode kelas statis, metode objek dinamis, dan penutup.

The $priorityargumen adalah opsional, tetapi ketika menghapus penutupan itu harus selalu digunakan, jika tidak fungsi akan menghapus setiap penutupan ditambahkan ke filter, tidak peduli di mana prioritas, karena ketika $prioritydihilangkan, semua filter menggunakan kelas target / metode atau penutupan yang dihapus.

Cara Penggunaan

// 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 );
gmazzap
sumber
Saya sudah mencoba yang ini dan banyak yang lain, tetapi tidak berhasil
adamj
@adamj sejak versi 4.7, WordPress memperkenalkan cara baru untuk menangani kait, jadi ini tidak berfungsi lagi ...
gmazzap
apakah Anda tahu ada alternatif lain?
adamj
1
@adamj Saya bisa memperbarui ini untuk 4.7+, tetapi tidak ada waktu sekarang, dan tidak yakin kapan saya akan punya. Tidak apa-apa untuk membuka pertanyaan baru, di mana Anda menautkan ke Q / A ini dan mengatakan ini sudah usang, dengan cara itu siapa pun dapat menjawab, jadi jika saya tidak punya waktu, mungkin orang lain akan melakukannya. Sebagai alternatif, Anda dapat memberi hadiah pada Q ini, menjelaskan bahwa sebagian besar jawaban yang dipilih di sini tidak berfungsi dalam versi WP saat ini ...
gmazzap
3

Bagaimana jika Anda menambahkan filter Anda, dengan prioritas 11, begitu seterusnya? Itu jelek, tetapi mungkin berhasil dalam kasus Anda.

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

    return $default;
}, 11, 1 );
tivnet
sumber
2

Filter dan tindakan anonim dapat dihapus secara native menggunakan yang berikut:

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

Saat membuat id unik menggunakan spl_object_hash(), fungsi anonim dapat dibandingkan satu sama lain, sehingga objek penutupan penuh tidak perlu dibuat ulang lagi.

Jika beberapa filter atau tindakan terhubung ke tag yang sama dengan prioritas yang sama, maka itu akan menghapus filter atau tindakan terbaru yang ditambahkan. Jika ada satu yang perlu Anda pertahankan, Anda harus menghapus semua filter hingga yang Anda perlu hapus, kemudian tambahkan lagi yang lain seperlunya.

// 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(){} );

Ini umumnya akan kembali ke praktik terbaik. Saya hanya akan menggunakan fungsi anonim sebagai bagian dari tema khusus yang saya kembangkan untuk klien, di mana saya tidak ingin filter ditimpa atau dihapus. Dalam setiap tema atau plugin publik yang saya kembangkan, saya akan menggunakan pabrik untuk menginisialisasi kelas, menambahkan semua filter dan tindakan saya, lalu menyimpan instance tersebut sebagai variabel statis.

Shaun Cockerill
sumber