I’m updating one of my plugins and I’m a little stuck with deprecating functions.
Originally, my plugin had a global variable and the plugin’s main class was instantiated and stored in the global variable. This way users could use the global to access functions in the plugin class.
$GLOBALS['my_custom_plugin'] = new my_custom_plugin();
Then, for example, in my FAQ I had code that showed how to remove one of my class’ functions from a specific hook and add to to a different hook:
function move_input(){
global $my_custom_plugin;
remove_action( 'before_main_content', array( $my_custom_plugin, 'display_input') );
add_action( 'after_main_content', array( $my_custom_plugin, 'display_input' ) );
}
add_action( 'wp_head' , 'move_input' );
Now, in my update the display_input()
function has been moved to another class and I want to let people know how to access it. I tried replacing the original function (in the main plugin class) with the following deprecation notice:
public function display_input() {
_deprecated_function( 'display_price', '2.0', 'my_custom_plugin()->display->display_input' );
return $this->display->display_input();
}
However, the add_action
and remove_action
functions don’t seem to trigger the deprecation notice. Weirdly, completely removing the function doesn’t cause an error either even though array( $my_custom_plugin, 'display_input')
doesn’t exist.
If someone tries to access the function directly:
$my_custom_plugin->display_input();
Then I do see the debug notices. Is this the expected outcome for _deprecated_function()
? or am I missing something? Is it possible to show a debug notice when someone tries to remove or add an action using a deprecated function?
Update
I realized that I was simply not seeing the debug message for the add_action
as I was adding it pretty low on the page. #facepalm! However, I am still not seeing any debug notice for the remove_action
.
Non existing Callbacks
One of the nice things is, that neither
do_action()
, norapply_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 anddo_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: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()
(orremove_all_filters()
).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).