Skip to content

Instantly share code, notes, and snippets.

@doiftrue
Last active March 11, 2024 00:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save doiftrue/96435ed8df7a20c49f9628c4e635ed13 to your computer and use it in GitHub Desktop.
Save doiftrue/96435ed8df7a20c49f9628c4e635ed13 to your computer and use it in GitHub Desktop.
[wp-kama embed] https://wp-kama.com/2409 Remove WP action/filter of instance
<?php
/**
* Remove Class Action Without Access to Class Object
*
* @see remove_object_filter()
*/
function remove_object_action( string $hook_name, $static_callback, $priority = null ): bool {
return remove_object_filter( $hook_name, $static_callback, $priority );
}
/**
* Remove filters without access to class object (instance).
*
* To use remove_filter() function you need to have access to class instance,
* or the filter should be added using static method as hook callback.
* This function allows you to remove filters with callbacks you don't have access to.
*
* @param string $hook_name Filter name to remove.
* @param string|array $static_callback Hook callback where instance represented as class name.
* Eg: [ '\Space\My_Class', 'my_method' ] OR '\Space\My_Class' to remove all methods added to hook.
* @param int|null $priority (optional) Priority of the filter. If not set all hooks with any priority will be removed.
*
* @return bool Whether the hook is removed.
*
* @requires WP 4.7+
* @author Kama (wp-kama.com)
* @version 2.0
*/
function remove_object_filter( string $hook_name, $static_callback, $priority = null ): bool {
if( is_string( $static_callback ) ){
// '\Space\My_Class::my_method' or '\Space\My_Class'
$static_callback = explode( '::', $static_callback ) + [ '', '' ];
}
$found = _find_hook_callback_instances( $hook_name, $static_callback, $priority );
$res = 0;
foreach( $found as $item ){
$callback = [ $item['instance'], $item['method'] ];
$res += (int) remove_filter( $hook_name, $callback, $item['priority'] );
}
return (bool) $res;
}
/**
* Finds the instance of the object whose specified method is added for the specified hook.
*
* To use remove_filter() function you need to have access to class instance,
* or the filter should be added using static method as hook callback.
* This function allows you to find class instance that was used when the hook was added.
*
* @param string $hook_name Filter name.
* @param string|array $static_callback Hook callback where instance represented as class name.
* Eg: [ '\Space\My_Class', 'my_method' ]
* or [ '\Space\My_Class' ] to get all methods added for the hook.
* @param int|null $priority (optional) Priority of the filter.
*
* @return array{ instance: object|string, method:string, priority:int }[]
*
* @author Kama (wp-kama.com)
* @version 1.1
*/
function _find_hook_callback_instances( string $hook_name, array $static_callback, $priority = null ): array {
global $wp_filter;
/** @var \WP_Hook $wp_hook WP hooks. */
$wp_hook = $wp_filter[ $hook_name ] ?? null;
if( empty( $wp_hook->callbacks ) ){
return [];
}
$find_class_name = ltrim( $static_callback[0], '\\' ); //> \Space\My_Class >>> Space\My_Class
$find_method_name = $static_callback[1] ?? '';
$found = [];
foreach( $wp_hook->callbacks as $the_priority => $hooks_data ){
foreach( $hooks_data as $hook_data ){
$real_callback = $hook_data['function'] ?? null;
if( ! is_array( $real_callback ) ){
continue;
}
[ $object, $the_method_name ] = $real_callback;
$class_name = is_object( $object ) ? get_class( $object ) : $object;
if(
$class_name !== $find_class_name
|| ( $find_method_name && $the_method_name !== $find_method_name )
|| ( null !== $priority && $the_priority !== $priority )
){
continue;
}
$found[] = [
'instance' => $object,
'method' => $the_method_name,
'priority' => $the_priority,
];
}
}
return $found;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment