Temporarily overriding a WordPress filter

Tags:

I am using a plugin which uses filters to handle what-to-output.

Now I am writing a widget that will call the plugin directly, but would like to override the filters on a per-widget-instance basis. That means I need to "push" or save the plugin's filters, reset them to new values, call the plugin, and "pop" or restore the filter settings. I cannot merely set the filters, because the user's theme might have carefully set them ahead of me; simply overriding that would cause any invocation of the plugin which occurs after mine, to be broken.

Unfortunately although WordPress has a has_filter() to see whether a specific function is hooked to a filter, the user's theme or other plugins could have set the filters to be anything.

I studied plugin.php and discovered WP has no get_filters() to retrieve the entire current list of functions assigned to a filter. There really should be a get_filters($tag) and a get_actions($tag) which basically return what is currently WP's internal array.

To answer this need, here are two rather unfortunately hacked subroutines that will return the entire current state of a filter, and reset a filter to such a saved state. This works on 3.4.1.

function get_filter($tag) {
  # Returns the current state of the given WordPress filter.
  global $wp_filter;
  return $wp_filter[$tag];
}

function set_filter($tag, $saved) {
  # Sets the given WordPress filter to a state saved by get_filter.
  remove_all_filters($tag);
  foreach ($saved as $priority => $func_list) {
    foreach ($func_list as $func_name => $func_args) {
      add_filter($tag,$func_args['function'], $priority, $func_args['accepted_args']);
    }
  }
}

Example usage:

$was_filter = get_filter('autonav_create_list_item');
# Erase filters
remove_all_filters('autonav_create_list_item');
# .... do something clever with the filter
# and now restore it to the user's settings
set_filter('autonav_create_list_item', $was_filter );

-- Originally published here