WordPress - remove action defined within plugin cl

2019-06-16 15:55发布

问题:

So I have this plugin code

class WC_List_Grid {

 public function __construct() {
   add_action( 'wp' , array( $this, 'setup_gridlist' ) , 20);
 }

 function setup_gridlist() {
  add_action( 'woocommerce_before_shop_loop', array( $this, 'gridlist_toggle_button' ), 30);
 }

 function gridlist_toggle_button() {?>
                <nav class="gridlist-toggle">
                    <a href="#" id="grid" title="<?php _e('Grid view', 'woocommerce-grid-list-toggle'); ?>"><span class="dashicons dashicons-grid-view"></span> <em><?php _e( 'Grid view', 'woocommerce-grid-list-toggle' ); ?></em></a>
                    <a href="#" id="list" title="<?php _e('List view', 'woocommerce-grid-list-toggle'); ?>"><span class="dashicons dashicons-exerpt-view"></span> <em><?php _e( 'List view', 'woocommerce-grid-list-toggle' ); ?></em></a>
                </nav>
 <?php }
}

I want to change the content of the gridlist_toggle_button function. This is how I am planning to change the content of that function. Like writing another function with almost the same html as the original one but bits of my changes. Something like

add_action('woocommerce_before_shop_loop','new_gridlist_toggle_button')
function new_gridlist_toggle_button() {?>
                <nav class="gridlist-toggle">
                    <a href="#" class="grid-view" title="<?php _e('Grid view', 'woocommerce-grid-list-toggle'); ?>"><span class="dashicons dashicons-grid-view"></span> <em><?php _e( 'Grid view', 'woocommerce-grid-list-toggle' ); ?></em></a>
                    <a href="#" class="list-view" title="<?php _e('List view', 'woocommerce-grid-list-toggle'); ?>"><span class="dashicons dashicons-exerpt-view"></span> <em><?php _e( 'List view', 'woocommerce-grid-list-toggle' ); ?></em></a>
                </nav>
 <?php }
}

That way, I won't have to change the plugin files directly

For that, I am trying to remove its related action.

add_action( 'woocommerce_before_shop_loop', array( $this, 'gridlist_toggle_button' ), 30);

So that I may use my own code. But I can't seem to remove this action. I have tried this so far.

Method 1:

global $WC_List_Grid    ;
remove_action( 'woocommerce_before_shop_loop', array( $WC_List_Grid, 'gridlist_toggle_button' ), 100);  

Method 2:

function remove_plugin_actions(){
 global $WC_List_Grid   ;
 remove_action( 'woocommerce_before_shop_loop', array( $WC_List_Grid, 'gridlist_toggle_button' ), 100); 
}
add_action('init','remove_plugin_actions');

Method 3

remove_action( 'woocommerce_before_shop_loop', array( 'WC_List_Grid', 'gridlist_toggle_button' ), 100); 

None of them seems to work.

With a bit of brainstorming, I think there could be two possible causes.

  1. Its not working because the action I want to remove is not directly attached to the hook. Its action inside action.
  2. I am trying to block the output of gridlist_toggle_button via functions.php. But if the plugins load before functions.php then the function to be blocked away is already being called and hence it is always showing output.

I am no good with OOP at all. Can someone please help me out?

回答1:

Whenever $wc_lg = new WC_List_Grid() is instantiated, its going to trigger wp hook. Right after global WP class object is set up, the instance $wg_lg is going to call setup_gridlist() on itself. Its going to trigger woocommerce_before_shop_loop hook. And whenever that happens, again $wg_lg is going to call a function on itself. Namely gridlist_toggle_button().

I want to change the content of the gridlist_toggle_button function

Why not just to change it inside plugin ? Like override everything whats inside it.

global $WC_List_Grid;

How do you know that $WC_List_Grid has its name? Its just a class name. It can be instantiated under any name like $foo or $bar.

I assume that you are coding in functions.php file of your template. Plugins are being loaded before functions.php and remove_action() can only work after add_action() happend.

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.

http://codex.wordpress.org/Function_Reference/remove_action

So this should actually work just for removing the action, but how that helps you to change content inside of the function? :

remove_action(
    'woocommerce_before_shop_loop',
    array('WC_List_Grid', 'gridlist_toggle_button'),
    30
);

Notice that you were using priority 100

EDIT

I found out that do_action('woocommerce_archive_description') happens in archive-product.php and in wc-template-functions.php right before woocommerce_before_shop_loop hook actions are being executed in plugin. Try to use this:

function remove_plugin_actions(){
   global $WC_List_Grid;
   remove_action( 'woocommerce_before_shop_loop', array( $WC_List_Grid, 'gridlist_toggle_button' ), 30); 
}
add_action('woocommerce_archive_description','remove_plugin_actions');