El problema es que no se puede distinguir entre una función anónima y otra, así que sí, es posible eliminar un cierre (es decir, una función anónima) pero si más de un cierre actúa en el mismo filtro con la misma prioridad tienes que elegir, eliminarlos todos, o eliminar solo uno (sin saber exactamente cuál).
Mostraré cómo eliminarlos a todos mediante una función altamente derivada de la respuesta en @toscho que publicaste:
/**
* 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] );
}
}
}
}
He cambiado el nombre de la función remove_object_filter
porque puede eliminar todos los tipos de filtros de objetos: métodos de clase estáticos, métodos de objetos dinámicos y cierres.
El argumento $priority
es opcional, pero al eliminar cierres siempre se debe usar, de lo contrario, la función eliminará cualquier cierre agregado al filtro, sin importar la prioridad, porque cuando se omite $priority
, todos los filtros utilizando la clase / método de destino o el cierre se eliminan.
Cómo utilizar
// 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 );