• Resolved riille

    (@riille)


    Hi,

    The woocommerce_is_purchasable filter gets triggered 5 times for each product on the shop page. In my method isPurchasable I do one database call to fetch relevant information to determine if the product should be purchasable. When I visit the shop page, the backend does 5 database calls per product.

    For debug purposes I added echo "Hello"; to my isPurchasable method and I end up seeing 5 “Hello”s under each product.

    This slows down my site because it is doing a lot of unnecessary database calls.

    Why does this filter seem to be triggered 5 times for each product?

    Here is the structure of my plugin and how I use the filter hook.

    class MyPlugin{
    
      private $controller;
    
      public function __construct() {
        $this->controller = new Controller();
        $this->addHooks();
      }
    
      /*
      * Method: Adding necessary hooks
      */
      private function addHooks (){
        //Determine if the product is purchasable
        add_filter('woocommerce_is_purchasable', array($this->controller, 'isPurchasable'), 10, 2 );
      }
    }
    
    if ( class_exists( 'MyPlugin' ) ){
          $myPlugin = new MyPlugin();
    }
Viewing 6 replies - 1 through 6 (of 6 total)
  • I don’t know but it seems to be common for filters to be called several times per page load. One fix is to declare a static variable to keep track of whether your function has already been called. A static variable maintains its value across calls. So:

    function ...
      static $nr_calls = 0; // static var is not reset to 0 on subsequent exections
      if( 1 == $nr_calls ) {
        // function has run before
        return;
      }
      $nr_calls = 1;
      // here go things you want to do only once
    
    }
    Thread Starter riille

    (@riille)

    If I understand you correctly it seems like this static variable will be declared and then my code will only be executed for the first loading product in the list and not the others.

    I want my custom code to be executed once for every product in the list because my code returns different results depending on the products.

    Am I right?

    But very much thanks for the answer and I’ll give it a try even tho I might not understand how the static variable will affect the other products.

    You are right. You will need to make your static variable an array of the product_ids for which the function has run. Then, on entry to your function, check if the new product_id is in_array( $product_ids ), if so, return, if not, do your code and add the new product_id to the static array.

    Thread Starter riille

    (@riille)

    That could work, the only thing is that I’m also basing the purchasablility on the logged in user, so the static list would become very big and complex.

    It also feels like that solution would go against best practices in Object Oriented Programming. So the best would be to find a more suitable solution.

    Any ideas? Thanks for your time btw!

    The static variable gets reset when the script finishes. Its value is carried between function calls but not between page loads.

    laceyrod

    (@laceyrod)

    Automattic Happiness Engineer

    Hi @riille

    Since we haven’t heard back from you, and this thread has been inactive for a bit, I’m going to mark it as Resolved now for the overall health of the forums. Please feel free to open a new one if you have any further questions.

    Cheers!

Viewing 6 replies - 1 through 6 (of 6 total)
  • The topic ‘woocommerce_is_purchasable filter is fired 5 times!’ is closed to new replies.