ลบการกระทำ / ตัวกรองเพิ่มผ่านฟังก์ชั่นที่ไม่ระบุชื่อ


10

นั่นเป็นวิธีปฏิบัติที่เลวร้ายที่ฉันต้องพูด ใช้เวลาสองชั่วโมงที่ผ่านมาในการค้นหาโซลูชันเพื่อลบการกระทำและตัวกรองที่เพิ่มผ่านฟังก์ชั่นนิรนาม

นี่คือรหัสที่ใช้กับธีมผู้ปกครองและฉันจำเป็นต้องลบออก

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

ได้รับคำตอบของ toschoเล่นกับมันอย่างหนัก แต่ไม่มีความช่วยเหลือ ดังนั้นมีทางเลือกอื่นที่จะลบการกระทำ / ตัวกรองเพิ่มผ่านฟังก์ชั่นที่ไม่ระบุชื่อหรือไม่

ขอบคุณ


ฉันขอแนะนำให้ติดต่อผู้เขียนของชุดรูปแบบ เป็นการแก้ไขที่ง่ายสำหรับเขา / เธอที่จะใช้ฟังก์ชั่นที่มีชื่อแทนนิรนามและจะปรับปรุงโค้ด
helgatheviking

gmazzap ดูเหมือนว่า @ vishalbasnet23 ทำได้ที่นี่: gist.github.com/vishalbasnet23/5f74df4c800681199ab0246bc037d1d5ฉันทดสอบแล้วและมันก็ทำงานได้อย่างสมบูรณ์
Renan Oliveira

คำตอบ:


10

ปัญหาคือคุณไม่สามารถแยกแยะความแตกต่างของฟังก์ชั่นนิรนามและอื่น ๆ ได้ใช่มันเป็นไปได้ที่จะลบการปิด (เช่นฟังก์ชั่นที่ไม่ระบุชื่อ) แต่ถ้ามีมากกว่าหนึ่งปิดการกระทำในตัวกรองเดียวกัน เอาพวกมันทั้งหมดออกไปเพียงอันเดียว (โดยไม่รู้ว่าอะไร)

ฉันจะแสดงวิธีการลบพวกเขาทั้งหมดโดยใช้ฟังก์ชั่นที่ได้มาอย่างมากจาก @toscho คำตอบที่คุณโพสต์:

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

ฉันได้เปลี่ยนชื่อฟังก์ชั่นremove_object_filterเพราะมันสามารถลบตัวกรองวัตถุทุกประเภท: วิธีการเรียนแบบคงที่วิธีการวัตถุแบบไดนามิกและการปิด

$priorityอาร์กิวเมนต์เป็นตัวเลือก แต่เมื่อถอดฝาปิดก็ควรจะใช้เสมอมิฉะนั้นฟังก์ชั่นจะลบปิดใด ๆ เพิ่มให้กับตัวกรองไม่ว่าที่มีความสำคัญเพราะเมื่อ $priorityถูกละไว้กรองทั้งหมดโดยใช้ระดับเป้าหมาย / วิธีการหรือปิดอยู่ ลบออก

วิธีใช้

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

ฉันได้ลองอันนี้และอื่น ๆ อีกมากมาย แต่ก็ไม่ได้ผล
adamj

@adamj ตั้งแต่เวอร์ชั่น 4.7, WordPress เปิดตัววิธีการใหม่ในการจัดการ hooks ดังนั้นมันจะไม่ทำงานอีกต่อไป ...
gmazzap

คุณรู้ทางเลือกใดบ้างโดยบังเอิญ?
adamj

1
@adamj ฉันสามารถอัปเดตสิ่งนี้เป็นเวลา 4.7+ แต่ไม่มีเวลาแล้วและไม่แน่ใจว่าฉันจะมีเมื่อไหร่ เป็นการดีที่จะเปิดคำถามใหม่ที่คุณเชื่อมโยงกับคำถาม / คำตอบนี้และบอกว่านี่เป็นคำถามที่ล้าสมัยในแบบที่ทุกคนสามารถตอบได้ดังนั้นถ้าฉันไม่มีเวลาบางทีคนอื่นอาจจะ นอกจากนี้คุณสามารถใส่ความโปรดปรานใน Q นี้โดยอธิบายว่าคำตอบ upvoted ส่วนใหญ่ที่นี่ไม่ทำงานใน WP รุ่นปัจจุบัน ...
gmazzap

3

จะเกิดอะไรขึ้นถ้าคุณเพิ่มตัวกรองของคุณด้วยลำดับความสำคัญที่ 11 ดังนั้นจะเกิดอะไรขึ้น มันน่าเกลียด แต่อาจใช้ได้ในกรณีของคุณ

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

    return $default;
}, 11, 1 );

2

ตัวกรองและการดำเนินการที่ไม่ระบุชื่อสามารถลบออกได้โดยใช้สิ่งต่อไปนี้:

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

เมื่อสร้าง id ที่ไม่ซ้ำกันโดยใช้spl_object_hash()ฟังก์ชั่นที่ไม่ระบุชื่อนั้นเปรียบได้กับสิ่งอื่นดังนั้นวัตถุการปิดแบบเต็มไม่จำเป็นต้องถูกสร้างขึ้นใหม่อีกครั้ง

หากตัวกรองหรือการกระทำหลายรายการเชื่อมต่อกับแท็กเดียวกันที่มีลำดับความสำคัญเท่ากันมันจะลบตัวกรองหรือการกระทำล่าสุดที่เพิ่ม หากมีสิ่งที่คุณต้องการเก็บไว้คุณจะต้องลบตัวกรองทั้งหมดถึงตัวกรองที่คุณต้องการลบออกแล้วเพิ่มตัวกรองอื่น ๆ ตามความจำเป็น

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

โดยทั่วไปจะกลับมาสู่แนวทางปฏิบัติที่ดีที่สุด ฉันจะใช้ฟังก์ชั่นที่ไม่ระบุชื่อเป็นส่วนหนึ่งของธีมที่กำหนดเองที่ฉันกำลังพัฒนาสำหรับลูกค้าซึ่งฉันไม่ต้องการให้ตัวกรองถูกเขียนทับหรือลบออก ในชุดรูปแบบสาธารณะหรือปลั๊กอินที่ฉันพัฒนาฉันจะใช้โรงงานเพื่อเริ่มต้นชั้นเรียนเพิ่มตัวกรองและการกระทำทั้งหมดของฉันแล้วเก็บอินสแตนซ์เป็นตัวแปรแบบคงที่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.