Recently worked with a friend figuring out how to remove/undo/cancel an add_action()
line that’s inside a plugin’s constructor inside a PHP Class with the file having a namespace.
Namespace: Etn\Core\Event\Pages
Class: Event_single_post
Hook: single_template
Function: event_single_page
The use case: Have single event pages be rendered by the corresponding Bricks template instead of the plugin when using Eventin.
I am not an expert in OOP and there may be a better way of doing this, but here are two solutions that work:
Keep this screenshot and the code side-by-side to study it, if you are interested in understanding what’s going on.
Solution 1
add_action( 'wp_loaded', function() {
// globalize the $wp_filter array so it can be used in the code
global $wp_filter;
// $wp_filter contains all the actions and filters that have been added via the add_filter or add_action functions
global $wp_current_filter;
$hook = 'single_template';
$class = '\Etn\Core\Event\Pages\Event_single_post';
// loop through all the filters
foreach ( $wp_filter as $filter_name => $filter ) {
// if the current filter is "single_template"
if ( $filter_name === $hook ) { // https://d.pr/i/JSOPlf
// loop through all the callbacks for the current filter
foreach ( $filter as $priority => $callbacks ) {
// loop through all the callbacks for the current priority
foreach ( $callbacks as $callback ) {
// check if the callback is an array and the first element is the Eventin class
if ( is_array( $callback['function'] ) && $callback['function'][0] instanceof $class ) {
// remove the callback
remove_filter( $filter_name, $callback['function'], $priority );
}
}
}
}
}
});
Solution 2
add_action( 'wp_loaded', function() {
// globalize the $wp_filter array so it can be used in the code
global $wp_filter;
// $wp_filter contains all the actions and filters that have been added via the add_filter or add_action functions
// the relevant portion: https://d.pr/i/JSOPlf
$hook = 'single_template';
// use the isset function to see if an action or filter has been added
if ( ! isset( $wp_filter[$hook] ) ) {
return;
}
$filters = $wp_filter[$hook];
// https://d.pr/i/KgdJrA
foreach ( $filters[10] as $key => $val ) {
if ( str_ends_with( $key, 'event_single_page' ) ) {
$vals = array_values( $val );
// https://d.pr/i/4RVSPx
$isFound = true;
$callbackFn = $vals[0];
// https://d.pr/i/wYY8MG
}
}
if ( $isFound ) {
remove_filter( $hook, $callbackFn );
}
});
Credit: Karthikeyan Ramnath.
References
https://wpaustralia.slack.com/archives/C054S58MK/p1669873227808019
1 comment
Marko Hofmann
This is genius!
I love this solution, it saves so much time! Wow! Nice!
Marry me!