public function orddd_capabilities() {
$role = get_role( 'shop_manager' );
if ( $role != '' ) {
$role->add_cap( 'manage_options' );
}
}
add_action( 'admin_init', array( &$this, 'orddd_capabilities' ) );
this action was added by a plugin and would always reapply the "manage_options" capabilities to shop_manager after I disable it using User Role Editor. How can I disable this action using the function.php of my child theme?
public function orddd_capabilities() {
$role = get_role( 'shop_manager' );
if ( $role != '' ) {
$role->add_cap( 'manage_options' );
}
}
add_action( 'admin_init', array( &$this, 'orddd_capabilities' ) );
this action was added by a plugin and would always reapply the "manage_options" capabilities to shop_manager after I disable it using User Role Editor. How can I disable this action using the function.php of my child theme?
Share Improve this question edited Jul 2, 2020 at 3:46 codeinwill asked Jul 1, 2020 at 20:06 codeinwillcodeinwill 413 bronze badges 3 |1 Answer
Reset to default 1This one is tricky. You need to remove a hooked function which is a member of dynamically created class instance and the usual methods like remove_action( 'hook_name', 'hook_function', priority )
and even remove_action( 'hook_name', array( 'class_name', 'member_function' ), priority )
won't work. I once had to solve a similar problem. Mine was more complicated, I had to change the priority of such a hooked function. After spending a couple of time I've finished up with the following code (modified according to your needs):
function get_hooked_function( $hook = '', $function = '' ) {
global $wp_filter;
if ( isset( $wp_filter[$hook]->callbacks ) ) {
array_walk( $wp_filter[$hook]->callbacks, function( $callbacks, $priority ) use ( &$hooks ) {
foreach ( $callbacks as $id => $callback )
$hooks[] = array_merge( [ 'id' => $id, 'priority' => $priority ], $callback );
});
} else {
return NULL;
}
foreach( $hooks as &$item ) {
// skip if callback does not exist
if ( !is_callable( $item['function'] ) ) continue;
// function name as string or static class method eg. 'Foo::Bar'
if ( is_string( $item['function'] ) ) {
if ( $item['function'] === $function ) return [ $function, $item['priority'] ];
} elseif ( is_array( $item['function'] ) ) {
if ( $item['function'][1] === $function ) return [ $item['function'], $item['priority'] ];
}
}
return NULL;
}
add_action( 'admin_init', function () {
if ( $hooked_function = get_hooked_function( 'admin_init', 'orddd_capabilities' ) )
remove_action( 'admin_init', $hooked_function[0], $hooked_function[1] );
}, 9 );
The get_hooked_function()
function walks through global $wp_filter
array of WP_Hook
objects where all hooks are registered (to be more precise only through its item named as this function first parameter) and searches for the function named as its second parameter. When a hook is registered with a global function, it returns its name and registered priority, e.g.
$result = Array (
[0] => register_admin_color_schemes
[1] => 1
)
but when a hook is registered with a class member function, it returns an array like
$result = Array (
[0] => Array (
[0] => order_delivery_date Object
[1] => orddd_capabilities
)
[1] => 10
)
(the basic idea of this function is taken from this stackoverflow answer, you can look there for additional technical details). Then the $result[0]
array is applicable to use with remove_action()
function. Next we should make sure that our code will be called after the hook is set by plugin, but before it is fired. The most simple way to do it is to register our code to the same hook with a slightly less priority. Since your plugin register its hook with the default priority 10
, to deregister it we can use a priority of 9
.
Please note that this solution won't work with WordPress earlier than 4.7 due to this change in filter processing mechanism (though I believe you don't use something that ancient).
Afterwords
If someone would search an answer on how to change the priority on such a hooked function, the solution is
add_action( '<HOOK_NAME>', function () {
if ( $hooked_function = get_hooked_function( '<HOOK_NAME>', '<FUNCTION_NAME>' ) )
if ( remove_action( '<HOOK_NAME>', $hooked_function[0], $hooked_function[1] ) )
add_action( '<HOOK_NAME>', $hooked_function[0], <NEW_PRIORITY> );
}, <SOME_PRIORITY_LESS_THAN_MIN_OF_OLD_AND_NEW_PRIORITIES> );
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742299413a4417756.html
&$this
, it should be$this
, the use of&
is for compatibility with PHP v4 which hasn't worked with WordPress in decades. Which plugin is this? – Tom J Nowell ♦ Commented Jul 1, 2020 at 21:12Order Delivery Date Pro
from Tyche Software. Their coding style sometimes make me cry. – Ivan Shatsky Commented Jul 1, 2020 at 21:22$this
is referring to and if we can get references to it – Tom J Nowell ♦ Commented Jul 1, 2020 at 21:24