3

I'm trying to remove two of the actions that adds a plugin (sportspress specifically). The actions of this plugins are:

add_action('sportspress_before_single_player','sportspress_output_player_details', 15);
add_action('sportspress_single_player_content','sportspress_output_player_statistics',20);

I've created a plugin, and I want to remove these hooks, this is my code:

<?php
/*
Plugin Name: my plugin

Description: Plugin to override plugins' hooks
Version: 0.1
Author: Company Name
Author URI: http://www.example.com/
License: GPL2
*/


add_action('plugins_loaded','remove_hooks');
function remove_hooks(){
    remove_action( 'sportspress_before_single_player', 'sportspress_output_player_details' );
    remove_action( 'sportspress_single_player_content', 'sportspress_output_player_statistics' );
}

I've searched and tried a lot of things, but I can't make it work.

  • There is no concept of child plugin in WordPress! – Sumit Apr 14 '16 at 8:51
  • Then Google lied to me! I'll update the title then – Doruko Apr 14 '16 at 8:52
  • Cool! Now provide more details in which context action are added like in a class constructor, directly in a file or some WordPress action, also give the same priority to remove actions e.g. 15 and 20 – Sumit Apr 14 '16 at 8:56
  • The actions are added in the plugin's constructor (the constructor calls a function called 'includes', and this functions "include_once" the file with all the hooks). I've tried to maintain the priorities too, but didn't work. – Doruko Apr 14 '16 at 8:58
  • Just guessing: is the plugin doing the output in the area reserved for the post's and pages' content? This is usually the case with plugins that work with their own custom post types to ensure compatibility with different themes. Have you tried using the_content as the hook instead of plugins_loaded? – Luis Sanz Apr 14 '16 at 9:16
6

There are two things that confuse people when trying to remove a hook:

  1. The remove_action() or remove_filter() calls must take place after the add_action() or add_filter() calls, and before the hook is actually fired. This means that you must know the hook when the calls were added and when the hook is fired.
  2. The remove_action() or remove_filter() calls must have the same priority as the add_action() or add_filter() call

If these hooks were added on the init filter at the default priority, then to remove them, we'd simply hook into init at a priority later than 10 and remove them.

add_action( 'init', 'wpse_106269_remove_hooks', 11 );
function wpse_106269_remove_hooks(){
    remove_action( 'sportspress_before_single_player', 'sportspress_output_player_details', 15 );
    remove_action( 'sportspress_single_player_content', 'sportspress_output_player_statistics', 20 );
}

From https://codex.wordpress.org/Function_Reference/remove_action

Important: To remove a hook, the $function_to_remove and $priority arguments must match when the hook was added. This goes for both filters and actions. No warning will be given on removal failure.

2

Plugins are loaded in the order of their file names. e.g. plugin with name abc.php loaded first then xyz.php so if you are trying to remove an action from plugin abc.php and that was added in plugin xyz.php then it is not possible without any tweak. Because action was never added at time you are trying to remove it.

You can simply place a die(__FILE__); in both plugins to see which one echo the output first. If your plugin is loaded earlier than you can do two things to remove the action

  1. Rename your plugin and load it after actual plugin.
  2. I am not sure when parent actions run but there is a long list of actions Action_Reference on which you can hook remove action in your plugin. Now you know when to place remove_action() to make it effective.

Hope it helps.

  • I added the die, and the first plugin loaded is the "parent", so there should be no problem with the order of the loading of the plugins – Doruko Apr 14 '16 at 10:21
  • Yes then there should be no problem, remove plugins_loaded action and directly place remove_action in your plugin with same priority, it will work as per your code structure you've shared. – Sumit Apr 14 '16 at 11:11
1

I was with the same problem. I wanted to remove an action that comes from another plugin and replace it with another function I wrote in the plugin I was developing, but my file name (as @Sumit said) was after the original plugin file in alphabetical order. Even so I was been able to remove the action.

What worked for me was wrapping my remove_action call inside another add_action to run it during after all plugin loading. That is possible by using the action init:

add_action( 'init', 'changeActions' );
function changeActions () {
    remove_action('my_action', 'the_function_from_the_plugin', 10);
}

P.S.: If you want to see if the actions were properly removed, you can print somewhere the functions hooked to the action you want using the code from this answer. I used a test shortcode, since I was not working with the theme files (just add [test_actions] in any page inside the wordpress panel).

add_shortcode('test_actions', 'testActions');
function testActions($attrs) {
    //get the list of all actions using this global variable
    global $wp_filter;

    //get only the actions hooked to 'my_action'
    $r = $wp_filter['my_action'];

    //return the array dump as a string
    return var_export($r, TRUE);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.