Removing Action/Filter Inside a Plugin’s Namespaced Class Constructor

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

https://wordpress.stackexchange.com/a/329517/14380

https://stackoverflow.com/a/29379933

Leave the first comment