Deprecating functions in a plugin class

Non existing Callbacks

One of the nice things is, that neither do_action(), nor apply_filters() do trigger an error if a callback isn’t present. This means that its the safest way to insert plugin data into templates: If a plugin is turned off and do_action()/apply_filters() don’t find the callback in the global $wp_filters array, nothing happens.

Error Output

Now when you’re calling remove_filter() in the function/method that originally hooked the callback, the callback simply will be removed from the global array, which means that the callback will never be executed as it’s not registered anymore.

The solution is simple: Remove the callback after it was triggered, by removing it from within the callback itself.

Removing Callbacks

We all know that WPs plugin “API” is a pain when it comes to removing. The problem mainly is the strange construct to add “unique” names to keys in the global $wp_filter; array. A very simple solution is to just use __METHOD__ and call filters that you want to remove in static context:

class FOoooo
{
    public function __construct()
    {
        add_filter( 'hook', array( __CLASS__, 'bar' ) );
    }
    public static function bar( $baz )
    {
        remove_filter( current_filter(), __METHOD__ );

        return $baz;
    }
}

While this isn’t nice, it’s … sort of a solution for some use cases. But don’t even think about removing a closure.

Above just removes the callback, still executes it. Still you can go further and use remove_all_actions() (or remove_all_filters()).

// Check if a callback is attached and tell about the deprecated stuff
if ( has_action( 'before_main_content' ) )
    _deprecated_function( 'display_price', '2.0', 'my_custom_plugin()->display->display_input' );
// Remove the callback
remove_all_actions( 'before_main_content' );

You maybe could even go further, extract the callback from the global filters array and re-attach it to the new hook/filter (if they’re compatible).

Leave a Comment