Entfernen Sie Aktionen / Filter, die über anonyme functionen hinzugefügt wurden

Das ist eine verdammt schlechte Übung, muss ich sagen. Habe die letzten zwei Stunden damit verbracht, eine Lösung zu finden, um Aktionen und Filter zu entfernen, die über anonyme functionen hinzugefügt wurden.

Dies ist der Code, der für ein übergeordnetes Thema verwendet wird, und ich muss es entfernen.

/** * 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 tochos Antwort , spielte dabei heftig, aber keine Hilfe. Gibt es also eine andere Alternative, die über anonyme functionen hinzugefügte Aktionen / Filter entfernt?

Vielen Dank

Solutions Collecting From Web of "Entfernen Sie Aktionen / Filter, die über anonyme functionen hinzugefügt wurden"

Das Problem ist, dass Sie nicht zwischen einer anonymen function und einer anderen unterscheiden können, also ja, es ist möglich, eine Schließung zu entfernen (dh eine anonyme function), aber wenn mehr als eine Schließung auf demselben Filter mit derselben Priorität handelt, müssen Sie eine Auswahl treffen , entfernen Sie alle, oder entfernen Sie nur einen (ohne genau zu wissen, was).

Ich zeige Ihnen, wie Sie sie alle entfernen können, indem Sie eine function verwenden, die stark von der Antwort in der Antwort von @toscho abgeleitet ist:

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

Ich habe die function remove_object_filter weil sie alle Arten von remove_object_filter entfernen kann: statische classnmethoden, dynamische Objektmethoden und Closures.

Das Argument $priority ist optional, aber beim Entfernen von Closures sollte es immer verwendet werden. Andernfalls entfernt die function jede dem Filter hinzugefügte Closure, egal mit welcher Priorität, denn wenn $priority ausgelassen wird, werden alle Filter verwendet, die die Zielklasse verwenden. Methode oder Schließung werden entfernt.

Wie benutzt man

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

Was ist, wenn Sie Ihren Filter mit der Priorität 11 hinzufügen, also danach? Das ist hässlich, könnte aber in Ihrem Fall funktionieren.

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

Anonyme Filter und Aktionen können nativ wie folgt entfernt werden:

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

Beim Generieren der eindeutigen ID mithilfe von spl_object_hash() sind anonyme functionen miteinander vergleichbar, sodass das Objekt mit dem vollständigen Abschluss nicht erneut erstellt werden muss.

Wenn mehrere Filter oder Aktionen mit derselben Markierung mit derselben Priorität verbunden sind, wird der zuletzt hinzugefügte Filter oder die letzte Aktion entfernt. Wenn es einen gibt, den Sie behalten müssen, müssen Sie alle Filter entfernen, die Sie entfernen müssen, und dann die anderen nach Bedarf hinzufügen.

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

Dies wird in der Regel auf bewährte Verfahren zurückgehen. Ich werde immer nur anonyme functionen als Teil eines benutzerdefinierten Designs verwenden, das ich für einen Client entwickle, bei dem der Filter nicht überschrieben oder entfernt werden soll. In jedem öffentlichen Thema oder Plugin, das ich entwickle, verwende ich eine Factory, um eine class zu initialisieren, füge alle meine Filter und Aktionen hinzu und speichere die Instanz als statische Variable.