Revert "Support Unlimited `wc_get_related_products()`"

This reverts commit 41c837202e.
This commit is contained in:
Christopher Allford 2024-09-11 23:15:03 -07:00
parent 9926d9d20b
commit 3c5b47e2b7
No known key found for this signature in database
GPG Key ID: 80E44C778F08A88E
4 changed files with 14 additions and 179 deletions

View File

@ -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';

View File

@ -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
*/

View File

@ -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 );
}
/**

View File

@ -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 );
}
}