7

I'm new to writing WordPress plugins. I'm trying to write a little plugin that modifies how the woocommerce plugin displays images on the single product page. Specifically, if there is no product image, make the div holding the image "display:none" rather than displaying a placeholder image there. The strategy I'm using is to use add_action to render my own version of woocommerce's product_image.php template and then (trying to) use remove_action to prevent the original product_image.php file from being rendered. The add_action is clearly working, as I can see the "display:none" div in Firebug. However, the remove_action isn't succeeding.

Here is my code:

$add_result = add_action( 'woocommerce_before_single_product_summary', 'eba_wc_show_product_images', 10);

function eba_wc_show_product_images() {
    include( 'eba_product-image.php' );
}

$remove_result = remove_action( 'woocommerce_before_single_product_summary', 'woocommerce_show_product_images', 30);
echo "<hr/>result of add_result = " . $add_result . "<hr/>";
echo "<hr/>result of remove_result = " . $remove_result . "<hr/>";

The priority on the original add_action for the woocommerce_before_single_product_summary hook was 20, so I made the priority on the remove_action 30.

The two debugging statements at the end show that the add_action is returning "1", but the result of the remove_action is empty. Any help would be greatly appreciated.

Erica Ackerman
  • 189
  • 1
  • 2
  • 11

4 Answers4

27

I've stumbled on this question several times now and I wish somebody would've just told me that I can do this:

$priority = has_action('action_name', 'function_name');
remove_action('action_name', 'function_name', $priority);

This saves me from actually hardcoding the priority, which may be different for different environments.

peter
  • 6,067
  • 2
  • 33
  • 44
18

Try removing the action during plugins_loaded, this should ensure that its definitely been added before you try and remove it.

add_action('plugins_loaded','alter_woo_hooks');

function alter_woo_hooks() {
    $add_result = add_action( 'woocommerce_before_single_product_summary', 'eba_wc_show_product_images', 10);
    $remove_result = remove_action( 'woocommerce_before_single_product_summary', 'woocommerce_show_product_images', 10);

    echo "<hr/>result of add_result = " . $add_result . "<hr/>";
    echo "<hr/>result of remove_result = " . $remove_result . "<hr/>";
}

function eba_wc_show_product_images() {
    include( 'eba_product-image.php' );
}
Rob Holmes
  • 366
  • 3
  • 8
  • I'm afraid that didn't seem to make any difference. Any other ideas? – Erica Ackerman May 20 '12 at 15:50
  • 4
    The priority needs to match what was used when registering the action in the first place, which was 10, (line 23 of woocommerce-hooks.php) ive amended the answer above which should work now. – Rob Holmes May 20 '12 at 16:43
  • 3
    For removing WooCommerce action I had to call remove_action within after_setup_theme hook. Hook plugins_loaded doesn't work for me. – fandasson Mar 12 '16 at 18:44
1

one other way that worked for me is that we fire exact hook with earlier priority and remove other hook with later priority

add_action('action_name','alter_some_hook',0);

function alter_some_hook() {
    $priority = has_action('action_name', 'function_name');
    remove_action('action_name', 'function_name', $priority);
}
Mohammad Zaer
  • 638
  • 7
  • 9
1

You will have to understand the code execution sequence. You Must make sure that remove_action is getting called after the add_action has been executed and the action is actually in the queue. If you remove first and then add, it will obviously not work and doesn't make sense as well.

Mehbub Rashid
  • 553
  • 6
  • 6