Merge pull request #27175 from woocommerce/fix/27162

Fix incorrect adjustment of post count in WC_Query
This commit is contained in:
Claudio Sanches 2020-07-30 14:33:35 -03:00 committed by GitHub
commit 2d468a4d27
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 14 deletions

View File

@ -368,8 +368,9 @@ class WC_Query {
}
/**
* When the request is filtering by attributes via layered nav plugin we need to adjust the total posts count
* to account for variable products having stock in some variations but not in others.
* When we are listing products and the request is filtering by attributes via layered nav plugin
* we need to adjust the total posts count to account for variable products having stock
* in some variations but not in others.
* We do that by just checking if each product is visible.
*
* We also cache the post visibility so that it isn't checked again when displaying the posts list.
@ -385,18 +386,22 @@ class WC_Query {
return $count;
}
$count = 0;
foreach ( $posts as $post ) {
$id = is_object( $post ) ? $post->ID : $post;
$product = wc_get_product( $id );
if ( is_object( $post ) && 'product' !== $post->post_type ) {
continue;
}
$product_id = is_object( $post ) ? $post->ID : $post;
$product = wc_get_product( $product_id );
if ( ! is_object( $product ) ) {
continue;
}
if ( $product->is_visible() ) {
wc_set_loop_product_visibility( $id, true );
$count++;
wc_set_loop_product_visibility( $product_id, true );
} else {
wc_set_loop_product_visibility( $id, false );
wc_set_loop_product_visibility( $product_id, false );
$count--;
}
}

View File

@ -441,12 +441,13 @@ class WC_Tests_WC_Query extends WC_Unit_Test_Case {
/**
* Setup for a test for adjust_posts.
*
* @param bool $with_nav_filtering_data Should WC_Query::get_layered_nav_chosen_attributes return filtering data?.
* @param bool $use_objects If true, get_current_posts will return objects with an ID property; if false, it will returns the ids.
* @param bool $with_nav_filtering_data Should WC_Query::get_layered_nav_chosen_attributes return filtering data?.
* @param bool $use_objects If true, get_current_posts will return objects with an ID property; if false, it will returns the ids.
* @param string $post_type The value of the 'post_type' property for the objects generated when $use_objects is true.
*
* @return array An array where the first element is the instance of WC_Query, and the second is an array of sample products created.
*/
private function setup_adjust_posts_test( $with_nav_filtering_data, $use_objects ) {
private function setup_adjust_posts_test( $with_nav_filtering_data, $use_objects, $post_type = 'product' ) {
update_option( 'woocommerce_hide_out_of_stock_items', 'yes' );
if ( $with_nav_filtering_data ) {
@ -460,7 +461,10 @@ class WC_Tests_WC_Query extends WC_Unit_Test_Case {
for ( $i = 0; $i < 5; $i++ ) {
$product = WC_Helper_Product::create_simple_product();
array_push( $products, $product );
$post = $use_objects ? (object) array( 'ID' => $product->get_id() ) : $product->get_id();
$post = $use_objects ? (object) array(
'ID' => $product->get_id(),
'post_type' => $post_type,
) : $product->get_id();
array_push( $posts, $post );
}
@ -495,8 +499,8 @@ class WC_Tests_WC_Query extends WC_Unit_Test_Case {
$products[1]->set_stock_status( 'outofstock' );
$products[1]->save();
$this->assertEquals( 3, $sut->adjust_posts_count( 34 ) );
$this->assertEquals( 3, wc_get_loop_prop( 'total' ) );
$this->assertEquals( 32, $sut->adjust_posts_count( 34 ) );
$this->assertEquals( 32, wc_get_loop_prop( 'total' ) );
$this->assertEquals( false, wc_get_loop_product_visibility( $products[0]->get_id() ) );
$this->assertEquals( false, wc_get_loop_product_visibility( $products[1]->get_id() ) );
foreach ( array_slice( $products, 2 ) as $product ) {
@ -517,4 +521,16 @@ class WC_Tests_WC_Query extends WC_Unit_Test_Case {
$this->assertEquals( 34, $sut->adjust_posts_count( 34 ) );
}
/**
* @testdox adjust_posts should return the input unmodified if the posts do not represent products.
*/
public function test_adjust_posts_count_when_the_posts_are_not_products() {
list( $sut, $products ) = $this->setup_adjust_posts_test( true, true, 'page' );
$products[0]->set_stock_status( 'outofstock' );
$products[0]->save();
$this->assertEquals( 34, $sut->adjust_posts_count( 34 ) );
}
}