diff --git a/includes/data-stores/class-wc-product-data-store-cpt.php b/includes/data-stores/class-wc-product-data-store-cpt.php index 1582303fb90c7..b7a27eb082e0c 100644 --- a/includes/data-stores/class-wc-product-data-store-cpt.php +++ b/includes/data-stores/class-wc-product-data-store-cpt.php @@ -997,50 +997,46 @@ public function get_related_products( $cats_array, $tags_array, $exclude_ids, $l public function get_related_products_query( $cats_array, $tags_array, $exclude_ids, $limit ) { global $wpdb; - // Arrays to string. - $exclude_ids = implode( ',', array_map( 'absint', $exclude_ids ) ); - $cats_array = implode( ',', array_map( 'absint', $cats_array ) ); - $tags_array = implode( ',', array_map( 'absint', $tags_array ) ); - - $limit = absint( $limit ); - $query = array(); - $query['fields'] = "SELECT DISTINCT ID FROM {$wpdb->posts} p"; - $query['join'] = " INNER JOIN {$wpdb->term_relationships} tr ON (p.ID = tr.object_id)"; - $query['join'] .= " INNER JOIN {$wpdb->term_taxonomy} tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id)"; - $query['join'] .= " INNER JOIN {$wpdb->terms} t ON (t.term_id = tt.term_id)"; - $query['where'] = ' WHERE 1=1'; - $query['where'] .= " AND p.post_status = 'publish'"; - $query['where'] .= " AND p.post_type = 'product'"; - $query['where'] .= " AND p.ID NOT IN ( {$exclude_ids} )"; - + $include_term_ids = array_merge( $cats_array, $tags_array ); + $exclude_term_ids = array(); $product_visibility_term_ids = wc_get_product_visibility_term_ids(); if ( $product_visibility_term_ids['exclude-from-catalog'] ) { - $query['where'] .= " AND t.term_id !=" . $product_visibility_term_ids['exclude-from-catalog']; + $exclude_term_ids[] = $product_visibility_term_ids['exclude-from-catalog']; } if ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) && $product_visibility_term_ids['outofstock'] ) { - $query['where'] .= " AND t.term_id !=" . $product_visibility_term_ids['outofstock']; + $exclude_term_ids[] = $product_visibility_term_ids['outofstock']; } - if ( $cats_array || $tags_array ) { - $query['where'] .= ' AND ('; - - if ( $cats_array ) { - $query['where'] .= " ( tt.taxonomy = 'product_cat' AND t.term_id IN ( {$cats_array} ) ) "; - if ( $tags_array ) { - $query['where'] .= ' OR '; - } - } + $query = array( + 'fields' => " + SELECT DISTINCT ID FROM {$wpdb->posts} p + ", + 'join' => '', + 'where' => " + WHERE 1=1 + AND p.post_status = 'publish' + AND p.post_type = 'product' + + ", + 'limits' => " + LIMIT " . absint( $limit ) . " + ", + ); - if ( $tags_array ) { - $query['where'] .= " ( tt.taxonomy = 'product_tag' AND t.term_id IN ( {$tags_array} ) ) "; - } + if ( $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"; + } - $query['where'] .= ')'; + if ( $include_term_ids ) { + $query['join'] .= " INNER JOIN ( SELECT object_id FROM {$wpdb->term_relationships} LEFT JOIN wp_term_taxonomy AS tax using( term_taxonomy_id ) WHERE term_id IN ( " . implode( ',', array_map( 'absint', $include_term_ids ) ) . " ) ) AS include_join ON include_join.object_id = p.ID"; } - $query['limits'] = " LIMIT {$limit} "; + if ( $exclude_ids ) { + $query['where'] .= " AND p.ID NOT IN ( " . implode( ',', array_map( 'absint', $exclude_ids ) ) . " )"; + } return $query; }