1

I am trying to develop a plugin to extend WooCommerce and I would like to do something with the product id when I land on a single product page (e.g. store it in the database or store it in a session variable).

However whatever hook I try to use, two results are given. So for example I might use the hook woocommerce_single_product_summary as follows:

add_action( 'woocommerce_single_product_summary', 'do_my_thing' );
function do_my_thing() {
    global $post;
    store_the_id( $post->ID ); //some function to do something with the id
}

When a user lands on a product page, the hook is fired twice, the function store_my_id runs twice and with two different post ids. The first is the correct id for the product in questions, and the second is an id for some other product.

This occurs whatever hook I use e.g. get_header. It wouldn't be a problem if I just wanted to echo something to the page because the echo only outputs when the hook fires for the first time.

Can anyone explain to me what is happening here? Is this supposed to be happening? And if so is there some way I can differentiate between the two ids returned to know which is actually the id for the product I have just landed on?

I have tried this on a completely fresh Wordpress install with just the WooCommerce plugin installed, the twentyfifteen theme and 2 products added so I don't think it's being caused by anything custom I am doing.

Any help really appreciated...

EDIT

I wondered whether using get_queried_object would help (as per below) but the same thing happens

add_action( 'woocommerce_single_product_summary', 'do_my_thing' );
function do_my_thing() {
    $queried_object = get_queried_object();
    if ( $queried_object->post_type == 'product' ) {
        store_the_id( $queried_object->ID ); //some function to do something with the id
    }
}

2 Answers 2

1

You need to limit yourself to the main loop and this can be done by checking if is_main_query returns true.

This might not be enough as that hook/filter was probably designed with the intention of augmenting the summery and therefor might be called more then once even during execution of the main loop itself. You have two option here

  1. Use a much better hook. The hook name doesn't sound like something you should trigger any DB write on.

  2. call remove_filter to remove it after the first iteration was done.

3
  • Thanks for the suggestions Mark. Good ideas but they don't seem to work. It is a main query in both cases. Tried get_header but same problem. I can remove the action with remove_action but it looks like it is added again - almost as if the whole wordpress app is being launched again. In further testing I've discovered that a) code in wp-blog-header.php is executed twice and if the page is loaded using a url with a query string on the end, the first time through the query string is present in $_REQUEST and the second time it isn't which seems bizarre to me. Any ideas? Tx v much!
    – jlad26
    Commented Apr 7, 2016 at 18:36
  • if get_header is being triggered twice, then something is fishy in your setting (just guessing, been years since I even looked at the direction of WC so no clue how weird it might be now, but that would be very weird) Commented Apr 7, 2016 at 18:47
  • Hmm does seem weird. I literally started with a completely fresh Wordpress install, installed only WooCommerce plugin, added 2 products, and it still does it. Anyway - thanks for taking the trouble to look into it!
    – jlad26
    Commented Apr 7, 2016 at 18:56
0

I think it was pagination causing the problem. Not sure whether this is a WooCommerce bug or is intentional, but by default on the single product page a relational link is added to a next product. (I can't see why that is there because I would have thought only one product should ever be displayed, but I'm probably missing something.)

So that meant some next post was being loaded and firing all the standard hooks.

At the moment I am using the next_post_rel_link filter (and previous_post_rel_link just in case) as per below to fix the problem. I don't think it will have any knock-on negative consequences but I will update if it does...

add_filter( 'next_post_rel_link', 'jlad_remove_pagination_rel_link' );
//may not be an issue for previous posts but just in case
add_filter( 'previous_post_rel_link', 'jlad_remove_pagination_rel_link' ); 

function jlad_remove_pagination_rel_link($link) {
    global $post;
    //check this is a product so we don't mess with pagination elsewhere
    if ( $post->post_type == 'product' ) $link = '';
    return $link;
}

EDIT And a little more research makes me think it's only a Firefox issue with prefetching - based on this http://www.cre8d-design.com/2010/10/wordpress-relnext-causes-issues-in-firefox/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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