remove_action fails on woocommerce_template_loop_product_thumbnail - wordpress

I wrote a simple plugin that performs some logic on thumbnails in WooCommerce. This plugin worked great for about a year, until the client switched to a new theme. Now the plugin is no longer working and I've narrowed the problem to remove_action() failing.
add_action( 'woocommerce_before_shop_loop_item_title', 'woocommerce_template_loop_product_thumbnail', 10);
if (! remove_action( 'woocommerce_before_shop_loop_item_title', 'woocommerce_template_loop_product_thumbnail', 10) ) {
echo 'FAILED to remove action<br/>';
}
/**
* WooCommerce Loop Product Thumbs
**/
if ( ! function_exists( 'woocommerce_template_loop_product_thumbnail' ) ) {
function woocommerce_template_loop_product_thumbnail() {
echo woocommerce_get_product_thumbnail();
}
}
I don't know if this is because of the order plugins are loaded, or if I'm making the call incorrectly due to a change in WooCommerce. I've read some topics that indicate the remove_action() should follow my custom add_action() so I reversed the order accordingly. It doesn't work either way - remove_action() is always returning FALSE.
I've been banging my head against a wall all day trying to figure this out. Can anyone give me a clue on a sure-fire way to execute the remove, or a way to debug it?
Thanks.

Try changing the priority flag of [add/remove]_action() to something higher, like 90.
It's a little hard to guess without seeing what the theme is actually doing!
add_action( 'woocommerce_before_shop_loop_item_title', 'woocommerce_template_loop_product_thumbnail', 90);
if (! remove_action( 'woocommerce_before_shop_loop_item_title', 'woocommerce_template_loop_product_thumbnail', 90) ) {
echo 'FAILED to remove action<br/>';
}

Related

how to remove "added-to-cart notice" from every page except product archive pages?

Note: In looking for an answer to my question I came across this post but it is NOT duplicate: Remove add to cart notice and change "add to cart" button in Woocommerce the answer there gives the option to remove the notice from the entire site. I want to remove it only from the cart page and I don't want to do it with CSS.
I use external links to my site to send people directly to the shopping cart with the item already added to the cart. When doing so, the "added-to-cart notification" shows up on the cart page which I do not want.
I found this code which removes the added-to-cart notification: add_filter( 'wc_add_to_cart_message_html', '__return_false' ); but it removes the notification from all pages of my site which is not what I want.
To be more specific, I want the added-to-cart notification to show on every product archive page and nowhere else.
I tried to add a filter but it doesn't work the way I would expect it to, I tried the following two ways (and tested it with various pages to see if I could make anything work but it seems my general syntax is off because I Can't get it to do anything...
function hide_cart_notes() {
if ( ! is_archive() ) {
add_filter( 'wc_add_to_cart_message_html', '__return_false' );
}
}
add_action( 'woocommerce', 'hide_cart_notes' );
function hide_cart_notes() {
if ( is_archive() ) {
return;
}
add_filter( 'wc_add_to_cart_message_html', '__return_false' );
}
add_action( 'woocommerce', 'hide_cart_notes' );
when woocommerce hook starts? where it's docs? does it run at all?
these question should be answered before.
i know that WordPress parses query at parse_query hook, so i would try this
add_action('parse_query', function() {
if (!is_archive()) {
add_filter( 'wc_add_to_cart_message_html', '__return_false' );
}
});
because is_shop(), is_archive(), is_* need query to be parsed first.

Conditionally Hiding Pricing; Need to Make Visible from Tag/Custom Taxonomy

Hide product pricing & add to cart button unless logged in
Sale items be visible, logged in or not, if visited from some kind of tag, category, or other taxonomy so that nobody sees the sales unless they are directed to them explicitly.
Example: All product prices are hidden, except on URLs with the tag "waffles-sale". This is a simple example but I think that explains what I'm after with 2.
I've accomplished 1. with a plugin, and more recently a short code; this works great:
add_action( 'init', 'bbloomer_hide_price_add_cart_not_logged_in' );
function bbloomer_hide_price_add_cart_not_logged_in() {
if ( ! is_user_logged_in() ) {
remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10 );
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_price', 10 );
remove_action( 'woocommerce_after_shop_loop_item_title', 'woocommerce_template_loop_price', 10 );
add_action( 'woocommerce_single_product_summary', 'bbloomer_print_login_to_see', 31 );
add_action( 'woocommerce_after_shop_loop_item', 'bbloomer_print_login_to_see', 11 );
}
}
function bbloomer_print_login_to_see() {
echo '' . __('Please login for pricing.', 'theme_name') . '';
}
But this leaves me with two, which is making things visible conditionally. I am sorry if this is vague. I've scoured the web for answers but I'm coming up short. I feel like my vocabulary is holding me back; I don't know the words for the hooks or phrases that I'm describing. I would love to stop reinventing the wheel (I'm having to clone products/product categories to make only them visible from temporarily published pages for sales).
Can anyone point me in the right direction? Is controlling product visibility in this way possible? I would greatly appreciate anyone's more experienced two cents or solution to this. Thank you.
You could try this (haven't tested), wrote it on rush, but it should help you in achieving what you need.
You need to define the query string then add/remove actions depending on what you need based on that query string.
Use the get_query_string:
// register query var
add_action('init','register_query_string');
function register_query_string() {
global $wp;
$wp->add_query_var('my_query_string_name');
}
//check if it's in the url
if ( get_query_var('my_query_string_name') ) {
// remove/add actions for the query string
elseif ( !user_not_logged_in()){
//something when not logged in
}
}
in case you need to check for query string and logged in, you can do something like
if ( !get_query_var('my_query_string_name') && ( !user_not_logged_in()){
// insert magic here
}
Code goes into functions.php from your child theme (or a plugin).

Wordpress : add_action not working in plugin or functions.php

I've got two functions:
add_action( 'woocommerce_order_status_completed' , 'after_order_complete' , 10);
function after_order_complete( $order_id )
{
error_log("woocommerce_order_status_completed", 0);
}
add_action( 'wp_login', 'after_login', 10, 2);
function after_login( $user_login, $user ) {
error_log("wp_login", 0);
}
that I can't seem to get called, tried in a plugin and functions.php but they never fire and no errors are logged.
How is it I debug this to find out why they fail or does anyone know how to get these to work?
In the same code I have another add_action but this time using user_register and that works as expected from plugin or functions.php
Edit:
I have the wp_login figured out, action does get called but only when first visiting the back end, site is front end only for users so used membership system hook instead.

Disable caching in WordPress Feeds generation

i'm working on a plugin that adds another parameter to feeds, i want to add a numberOfItems on the url and the feed returns that number of articles. I dont want to use the builtin option from WP Admin because the feed will be added on other websites with different number of items, it's a little bit complicated, the point is i need this implementation. i've added something like
function _my_custom_option( $option )
{
global $wp_query, $wp_rewrite;;
remove_filter( 'pre_option_posts_per_rss', '_my_custom_option' );
//$number = get_query_var('number');
$number = $wp_query->query_vars['numberOfItems'];
if(isset($number))
$option = $number;
else
$option = 10;
//$wp_rewrite->flush_rules();
add_filter( 'pre_option_posts_per_rss', '_my_custom_option' );
return $option;
}
add_filter( 'pre_option_posts_per_rss', '_my_custom_option' );
It seems that the feed is cached somehow and doesnt generate with the number of items, because when i add paged=2, it works. But if i change on page=2 numberOfItems with another number, it doesnt change. Plus, i added some junk text in wp-includes >feed-rss2.php just to verify if it cached or not. And it doesnt show after the first 2-3 page refreshes.
To be honest, i'm stuck, i don't know how to approach this, i've looked on the wordpress code and i dont see where the caching is done.
What about this?
function do_not_cache_feeds(&$feed) {
$feed->enable_cache(false);
}
add_action( 'wp_feed_options', 'do_not_cache_feeds' );

remove_action() not working in WordPress plugin

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.
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.
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' );
}
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);
}
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.

Resources