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

Get access to all 524 Bricks code tutorials with BricksLabs Pro

1 comment

  • Marko Hofmann

    This is genius!

    I love this solution, it saves so much time! Wow! Nice!

    Marry me!

Leave your comment

 

Related Tutorials..

Pro
Conditionally Hiding Bricks Filters based on Select Filter Value

Conditionally Hiding Bricks Filters based on Select Filter Value

How show or hide Bricks' filter based on the selection made by another filter.
Categories:
Tags:
Pro
Random Row from ACF Repeater in Bricks

Random Row from ACF Repeater in Bricks

In the past, we shared how the first row of a ACF Repeater can be output in a Bricks query loop here. This Pro tutorial…
Pro
“Truncate text to these many characters” Bricks Control

“Truncate text to these many characters” Bricks Control

Bricks provides a :<number> dynamic data tag modifier that can be used to limit the amount of text by the specified number of words. Ex.:…