I’ve been doing some research and it seems to be a bad practice from the WC Bookings team to instantiate a class without assigning it to a variable.
But knowing just that doesn’t help me in this case.
Fortunately, I was able to find this comment from @MikeSchinkel where he teaches and presents a function on how to remove a filter of an anonymous object.
This is how I implemented it in my case. First, the original function found in Mike’s comment:
if ( ! function_exists( 'remove_anonymous_object_filter' ) ) {
/**
* Remove an anonymous object filter.
*
* @param string $tag Hook name.
* @param string $class Class name
* @param string $method Method name
*
* @return void
*
*/
function remove_anonymous_object_filter( $tag, $class, $method ) {
$filters = false;
if ( isset( $GLOBALS['wp_filter'][$tag] ) )
$filters = $GLOBALS['wp_filter'][$tag];
if ( $filters )
foreach ( $filters as $priority => $filter ) {
foreach ( $filter as $identifier => $function ) {
if ( ! is_array( $function ) )
continue;
if ( ! $function['function'][0] instanceof $class )
continue;
if ( $method == $function['function'][1] ) {
remove_filter( $tag, array( $function['function'][0], $method ), $priority );
}
}
}
}
}
Finally, the call to the removal of the filter:
add_filter( 'woocommerce_payment_complete_order_status', 'unhook_booking_complete_order', 0 );
function unhook_booking_complete_order($status) {
remove_anonymous_object_filter( 'woocommerce_payment_complete_order_status', 'WC_Booking_Order_Manager', 'complete_order' );
return $status;
}
Basically, we are filtering woocommerce_payment_complete_order_status
again whith a higher priority in order to remove the filter manually (with the remove_anonymous_object_filter
function) based in its hook, class name and method.
All credits to Mike and the original answer that inspired his code.