From 3c5b47e2b7ee11fec4fbc745c44f660461d4dec9 Mon Sep 17 00:00:00 2001 From: Christopher Allford <6451942+ObliviousHarmony@users.noreply.github.com> Date: Wed, 11 Sep 2024 23:15:03 -0700 Subject: [PATCH] Revert "Support Unlimited `wc_get_related_products()`" This reverts commit 41c837202ebad27031b82f4227cba0b307bc7905. --- .../class-wc-product-data-store-cpt.php | 24 +-- .../class-wc-product-data-store-interface.php | 2 +- .../includes/wc-product-functions.php | 20 +-- .../includes/wc-product-functions-test.php | 147 ------------------ 4 files changed, 14 insertions(+), 179 deletions(-) diff --git a/plugins/woocommerce/includes/data-stores/class-wc-product-data-store-cpt.php b/plugins/woocommerce/includes/data-stores/class-wc-product-data-store-cpt.php index 68234967684..b5a611d6f8a 100644 --- a/plugins/woocommerce/includes/data-stores/class-wc-product-data-store-cpt.php +++ b/plugins/woocommerce/includes/data-stores/class-wc-product-data-store-cpt.php @@ -1453,7 +1453,7 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da * @param array $cats_array List of categories IDs. * @param array $tags_array List of tags IDs. * @param array $exclude_ids Excluded IDs. - * @param int $limit Limit of results, -1 for no limit. + * @param int $limit Limit of results. * @param int $product_id Product ID. * @return array */ @@ -1464,20 +1464,13 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da 'categories' => $cats_array, 'tags' => $tags_array, 'exclude_ids' => $exclude_ids, - 'limit' => $limit, + 'limit' => $limit + 10, ); - $related_product_query = (array) apply_filters( - 'woocommerce_product_related_posts_query', - $this->get_related_products_query( $cats_array, $tags_array, $exclude_ids, $limit ), - $product_id, - $args - ); + $related_product_query = (array) apply_filters( 'woocommerce_product_related_posts_query', $this->get_related_products_query( $cats_array, $tags_array, $exclude_ids, $limit + 10 ), $product_id, $args ); // phpcs:ignore WordPress.VIP.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.NotPrepared - $products = $wpdb->get_col( implode( ' ', $related_product_query ) ); - - return array_map( 'intval', $products ); + return $wpdb->get_col( implode( ' ', $related_product_query ) ); } /** @@ -1488,7 +1481,7 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da * @param array $cats_array List of categories IDs. * @param array $tags_array List of tags IDs. * @param array $exclude_ids Excluded IDs. - * @param int $limit Limit of results, -1 for no limit. + * @param int $limit Limit of results. * * @return array */ @@ -1518,12 +1511,11 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da AND p.post_type = 'product' ", + 'limits' => ' + LIMIT ' . absint( $limit ) . ' + ', ); - if ( $limit > 0 ) { - $query['limits'] = ' LIMIT ' . absint( $limit ); - } - if ( count( $exclude_term_ids ) ) { $query['join'] .= " LEFT JOIN ( SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id IN ( " . implode( ',', array_map( 'absint', $exclude_term_ids ) ) . ' ) ) AS exclude_join ON exclude_join.object_id = p.ID'; $query['where'] .= ' AND exclude_join.object_id IS NULL'; diff --git a/plugins/woocommerce/includes/interfaces/class-wc-product-data-store-interface.php b/plugins/woocommerce/includes/interfaces/class-wc-product-data-store-interface.php index 4199fefa857..ed9244ae56a 100644 --- a/plugins/woocommerce/includes/interfaces/class-wc-product-data-store-interface.php +++ b/plugins/woocommerce/includes/interfaces/class-wc-product-data-store-interface.php @@ -86,7 +86,7 @@ interface WC_Product_Data_Store_Interface { * @param array $cats_array List of categories IDs. * @param array $tags_array List of tags IDs. * @param array $exclude_ids Excluded IDs. - * @param int $limit Limit of results, -1 for no limit. + * @param int $limit Limit of results. * @param int $product_id Product ID. * @return array */ diff --git a/plugins/woocommerce/includes/wc-product-functions.php b/plugins/woocommerce/includes/wc-product-functions.php index 7f2450df9f5..7232ef7ccc7 100644 --- a/plugins/woocommerce/includes/wc-product-functions.php +++ b/plugins/woocommerce/includes/wc-product-functions.php @@ -976,15 +976,14 @@ function wc_get_product_backorder_options() { * * @since 3.0.0 * @param int $product_id Product ID. - * @param int $limit Limit of results, -1 for no limit. + * @param int $limit Limit of results. * @param array $exclude_ids Exclude IDs from the results. * @return array */ function wc_get_related_products( $product_id, $limit = 5, $exclude_ids = array() ) { $product_id = absint( $product_id ); - $limit = intval( $limit ); - $limit = $limit < -1 ? -1 : $limit; // Any negative number will default to no limit. + $limit = $limit >= -1 ? $limit : 5; $exclude_ids = array_merge( array( 0, $product_id ), $exclude_ids ); $transient_name = 'wc_related_' . $product_id; $query_args = http_build_query( @@ -998,7 +997,7 @@ function wc_get_related_products( $product_id, $limit = 5, $exclude_ids = array( $related_posts = $transient && is_array( $transient ) && isset( $transient[ $query_args ] ) ? $transient[ $query_args ] : false; // We want to query related posts if they are not cached, or we don't have enough. - if ( false === $related_posts || ( $limit > 0 && count( $related_posts ) < $limit ) ) { + if ( false === $related_posts || count( $related_posts ) < $limit ) { $cats_array = apply_filters( 'woocommerce_product_related_posts_relate_by_category', true, $product_id ) ? apply_filters( 'woocommerce_get_related_product_cat_terms', wc_get_product_term_ids( $product_id, 'product_cat' ), $product_id ) : array(); $tags_array = apply_filters( 'woocommerce_product_related_posts_relate_by_tag', true, $product_id ) ? apply_filters( 'woocommerce_get_related_product_tag_terms', wc_get_product_term_ids( $product_id, 'product_tag' ), $product_id ) : array(); @@ -1007,13 +1006,8 @@ function wc_get_related_products( $product_id, $limit = 5, $exclude_ids = array( if ( empty( $cats_array ) && empty( $tags_array ) && ! apply_filters( 'woocommerce_product_related_posts_force_display', false, $product_id ) ) { $related_posts = array(); } else { - // For backward compatibility we need to grab 10 extra products. This was done so that when we shuffle the - // output below it will appear to be random by including different products rather than the same ones - // in a different order. - $query_limit = $limit > 0 ? $limit + 10 : -1; - $data_store = WC_Data_Store::load( 'product' ); - $related_posts = $data_store->get_related_products( $cats_array, $tags_array, $exclude_ids, $query_limit, $product_id ); + $related_posts = $data_store->get_related_products( $cats_array, $tags_array, $exclude_ids, $limit + 10, $product_id ); } if ( $transient && is_array( $transient ) ) { @@ -1039,11 +1033,7 @@ function wc_get_related_products( $product_id, $limit = 5, $exclude_ids = array( shuffle( $related_posts ); } - if ( $limit > 0 ) { - return array_slice( $related_posts, 0, $limit ); - } - - return $related_posts; + return array_slice( $related_posts, 0, $limit ); } /** diff --git a/plugins/woocommerce/tests/php/includes/wc-product-functions-test.php b/plugins/woocommerce/tests/php/includes/wc-product-functions-test.php index 30f4b47b980..247c74e4fe7 100644 --- a/plugins/woocommerce/tests/php/includes/wc-product-functions-test.php +++ b/plugins/woocommerce/tests/php/includes/wc-product-functions-test.php @@ -240,151 +240,4 @@ class WC_Product_Functions_Tests extends \WC_Unit_Test_Case { $this->assertEquals( 100, wc_get_product( $product->get_id() )->get_price() ); } - - /** - * @testDox Products related by tag or category should be returned. - */ - public function test_wc_get_related_products() { - add_filter( 'woocommerce_product_related_posts_relate_by_category', '__return_true', 100 ); - add_filter( 'woocommerce_product_related_posts_relate_by_tag', '__return_true', 100 ); - - $related_tag = wp_insert_term( 'Related Tag', 'product_tag' ); - $related_cat = wp_insert_term( 'Related Category', 'product_cat' ); - - $product = WC_Helper_Product::create_simple_product(); - $product->set_tag_ids( array( $related_tag['term_id'] ) ); - $product->set_category_ids( array( $related_cat['term_id'] ) ); - $product->save(); - - $related_product_1 = WC_Helper_Product::create_simple_product(); - $related_product_1->set_category_ids( array( $related_cat['term_id'] ) ); - $related_product_1->save(); - - $related_product_2 = WC_Helper_Product::create_simple_product(); - $related_product_2->set_tag_ids( array( $related_tag['term_id'] ) ); - $related_product_2->save(); - - $related = wc_get_related_products( $product->get_id() ); - - remove_filter( 'woocommerce_product_related_posts_relate_by_category', '__return_true', 100 ); - remove_filter( 'woocommerce_product_related_posts_relate_by_tag', '__return_true', 100 ); - - $this->assertEquals( 2, count( $related ) ); - $this->assertContains( $related_product_1->get_id(), $related ); - $this->assertContains( $related_product_2->get_id(), $related ); - } - - /** - * @testDox Only products related by tag should be returned when the appropriate filters are set. - */ - public function test_wc_get_related_products_by_tag() { - add_filter( 'woocommerce_product_related_posts_relate_by_category', '__return_false', 100 ); - add_filter( 'woocommerce_product_related_posts_relate_by_tag', '__return_true', 100 ); - - $related_tag = wp_insert_term( 'Related Tag', 'product_tag' ); - $related_cat = wp_insert_term( 'Related Category', 'product_cat' ); - - $product = WC_Helper_Product::create_simple_product(); - $product->set_tag_ids( array( $related_tag['term_id'] ) ); - $product->set_category_ids( array( $related_cat['term_id'] ) ); - $product->save(); - - $related_product_1 = WC_Helper_Product::create_simple_product(); - $related_product_1->set_tag_ids( array( $related_tag['term_id'] ) ); - $related_product_1->set_category_ids( array( $related_cat['term_id'] ) ); - $related_product_1->save(); - - $related_product_2 = WC_Helper_Product::create_simple_product(); - $related_product_2->set_tag_ids( array( $related_tag['term_id'] ) ); - $related_product_2->set_category_ids( array( $related_cat['term_id'] ) ); - $related_product_2->save(); - - $unrelated_product = WC_Helper_Product::create_simple_product(); - $unrelated_product->set_category_ids( array( $related_cat['term_id'] ) ); - $unrelated_product->save(); - - $related = wc_get_related_products( $product->get_id() ); - - remove_filter( 'woocommerce_product_related_posts_relate_by_category', '__return_false', 100 ); - remove_filter( 'woocommerce_product_related_posts_relate_by_tag', '__return_true', 100 ); - - $this->assertEquals( 2, count( $related ) ); - $this->assertContains( $related_product_1->get_id(), $related ); - $this->assertContains( $related_product_2->get_id(), $related ); - } - - /** - * @testDox Only products related by category should be returned when the appropriate filters are set. - */ - public function test_wc_get_related_products_by_category() { - add_filter( 'woocommerce_product_related_posts_relate_by_category', '__return_true', 100 ); - add_filter( 'woocommerce_product_related_posts_relate_by_tag', '__return_false', 100 ); - - $related_tag = wp_insert_term( 'Related Tag', 'product_tag' ); - $related_cat = wp_insert_term( 'Related Category', 'product_cat' ); - - $product = WC_Helper_Product::create_simple_product(); - $product->set_tag_ids( array( $related_tag['term_id'] ) ); - $product->set_category_ids( array( $related_cat['term_id'] ) ); - $product->save(); - - $related_product_1 = WC_Helper_Product::create_simple_product(); - $related_product_1->set_tag_ids( array( $related_tag['term_id'] ) ); - $related_product_1->set_category_ids( array( $related_cat['term_id'] ) ); - $related_product_1->save(); - - $related_product_2 = WC_Helper_Product::create_simple_product(); - $related_product_2->set_tag_ids( array( $related_tag['term_id'] ) ); - $related_product_2->set_category_ids( array( $related_cat['term_id'] ) ); - $related_product_2->save(); - - $unrelated_product = WC_Helper_Product::create_simple_product(); - $unrelated_product->set_tag_ids( array( $related_tag['term_id'] ) ); - $unrelated_product->save(); - - $related = wc_get_related_products( $product->get_id() ); - - remove_filter( 'woocommerce_product_related_posts_relate_by_category', '__return_true', 100 ); - remove_filter( 'woocommerce_product_related_posts_relate_by_tag', '__return_false', 100 ); - - $this->assertEquals( 2, count( $related ) ); - $this->assertContains( $related_product_1->get_id(), $related ); - $this->assertContains( $related_product_2->get_id(), $related ); - } - - /** - * @testDox Products related by tag or category should apply a limit to the results. - */ - public function test_wc_get_related_products_limit() { - add_filter( 'woocommerce_product_related_posts_relate_by_category', '__return_true', 100 ); - add_filter( 'woocommerce_product_related_posts_relate_by_tag', '__return_true', 100 ); - - $related_tag = wp_insert_term( 'Related Tag', 'product_tag' ); - $related_cat = wp_insert_term( 'Related Category', 'product_cat' ); - - $product = WC_Helper_Product::create_simple_product(); - $product->set_tag_ids( array( $related_tag['term_id'] ) ); - $product->set_category_ids( array( $related_cat['term_id'] ) ); - $product->save(); - - $related_product_1 = WC_Helper_Product::create_simple_product(); - $related_product_1->set_category_ids( array( $related_cat['term_id'] ) ); - $related_product_1->save(); - - $related_product_2 = WC_Helper_Product::create_simple_product(); - $related_product_2->set_tag_ids( array( $related_tag['term_id'] ) ); - $related_product_2->save(); - - $related = wc_get_related_products( $product->get_id(), 1 ); - $unlimited_related = wc_get_related_products( $product->get_id(), -1 ); - - remove_filter( 'woocommerce_product_related_posts_relate_by_category', '__return_true', 100 ); - remove_filter( 'woocommerce_product_related_posts_relate_by_tag', '__return_true', 100 ); - - $this->assertEquals( 1, count( $related ) ); - $this->assertContains( $related[0], array( $related_product_1->get_id(), $related_product_2->get_id() ) ); - $this->assertEquals( 2, count( $unlimited_related ) ); - $this->assertContains( $related_product_1->get_id(), $unlimited_related ); - $this->assertContains( $related_product_2->get_id(), $unlimited_related ); - } }