• Hello All,
    I have had the following problem to deal with :
    I created a cronjob to update the stock value of the products in our webshop. We get these values from our warehouse partner. So i created the following function to update the stock :

    function cron_yp_update_product_stock_b1f6051b() {
    $oConvexStock = YP_get_stock_per_SKU();

    $oQuery = new WC_Product_Query( array( “return” => “objects”, “virtual” => false ) );

    $oResult = $oQuery->get_products();
    if ( is_array( $oResult ) ) {
    foreach( $oResult as $oProduct ) {
    if ( isset( $oConvexStock[$oProduct->get_sku()] ) ) {
    wc_update_product_stock($oProduct, $oConvexStock[$oProduct->get_sku()], “set” );
    }
    }
    }
    }

    This gets an array with stock amounts keyed by the SKU of the product. When I run this cronjob from within the admin panel everything runs fine. When I let it run from within the cronjob itself, nothing happens when calling get_products(). The script simply ends at once without any error.

    I have been digging into this problem today and found it to come from WP_Query->query(). Looking at this function, this is the code :

    public function query( $query ) {
    $this->init();
    $this->query = $this->query_vars = wp_parse_args( $query );
    return $this->get_posts();
    }

    The scripts stop running after :

    $this->query = $this->query_vars = wp_parse_args( $query );

    When i split this function it happends at the moment $this->query is overwritten. As it seems PHP (I have version 7.2.11) can’t figure out if it needs to override the variable $query or the function query as the variable gets unset while initialising the function and wp_parse_args returns a pointer when you pass an array to it.

    This naming scheme is not really handy when using a weak-typed language like PHP. Although I have no idea why PHP gets it wrong while running the cron and gets it right when triggering from the admin panel.

    I renamed the variable $query to something else and changed all the occurences the script didn’t crash at the given line so the naming is really the problem. But I can’t simply rename since other parts of the WordPress code are dependent on this public variable of the class and all scripts call the ->query() function.

    So I am a bit lost on how to fix this problem, but it stops my website from receiving the latest stock updated from out warehouse.

    Please could some of the developers shed a light on this problem and how to fix it??

    With kind regards,
    Michel van der Breggen

Viewing 5 replies - 1 through 5 (of 5 total)
  • Do you mean an actual cronjob, or a WordPress cron? (How is WordPress being loaded for this?)

    Thread Starter breggen

    (@breggen)

    I mean a WordPress Cron. It gets loaded when a page loads. Or I can trigger it through the use of the Advanced Cron Manager plugin.

    How about triggering an actual crontask from the Control Panels Cron?

    Thread Starter breggen

    (@breggen)

    Well the mystery deepens it seems. I spent yesterday evening further debugging this issue and some strange things happen, which lead me to believe that there might be something going on in PHP. Apart from the problem described above I also found the following ( i will show only a small snippet of WP_Query class )

    	public function query( $query ) {
    		$this->init();
    		$this->query = $this->query_vars = wp_parse_args( $query );
    		return $this->get_posts();
    	}

    As you can see it will call $this->get_posts() and return whatever it gives back. At the end of the get_posts function the return looks like this

    return $this->posts;

    So in this function it will manipulate the $this->posts class variable and return it to the caller. While this all looks nice, the following actually happens:
    The function return nothing ( or null have not checked that ) but the $this->posts actually contains the manipulated posts. This is just as strange as the first problem I found.

    Stranger still is that when calling the function from the admin panel all works as expected. I will need to check how WP calls its cronjob. Maybe this is done by externally calling PHP with the wp_cron.php as script?? I have no clue at this moment. I will also try and upgrade PHP to the latest version, maybe this is a known bug or so.

    To be continued

    Thread Starter breggen

    (@breggen)

    Ok, so I changed the query function to look like :

    	public function query( $query ) {
    		$this->init();
    		$this->query = $this->query_vars = wp_parse_args( $query );
    		$this->get_posts();
    		return $this->posts; 
    	}

    That fixed the problem and now both calls return products. Only one problem now is that the call from the admin panel returns 4 products and the cronjob call returns 2 products. The difference is that the admin panel call also returns products that are member only and the cronjob call doesn’t include the member only products.

    But this is a whole other problem, possibly to do with the query variables I can pass to the query.

    One down, the rest to go.

Viewing 5 replies - 1 through 5 (of 5 total)
  • The topic ‘WP_Query not always returning posts’ is closed to new replies.