PluginProbe
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 3.4.1
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v3.4.1
4.7.2 4.7.1 4.7.0 4.6.6 4.6.5 4.6.4 4.6.3 4.6.2 4.6.1 4.6.0 4.5.1 4.5.0 4.4.2 4.4.1 4.4.0 4.3.3 4.3.2 4.3.1 4.3.0 4.2.3 4.2.2 4.2.1 1.0.3 1.0.4 1.0.5 All 281 releases
surecart / app / src / Models / Blocks / RelatedProductsBlock.php
RelatedProductsBlock.php
135 lines 4.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace SureCart\Models\Blocks;
4
5 /**
6 * The product list block.
7 */
8 class RelatedProductsBlock extends AbstractProductListBlock {
9 /**
10 * The cached query result.
11 *
12 * @var \WP_Query|null
13 */
14 protected static $cached_query = null;
15
16 /**
17 * Build the query.
18 *
19 * @param array $include_term_ids The term ids to include in the query.
20 *
21 * @return array
22 */
23 public function parse_query( $include_term_ids = [] ) {
24 global $wpdb;
25
26 $per_page = $this->getQueryAttribute( 'perPage', 15 );
27 $total_pages = $this->getQueryAttribute( 'pages', 3 );
28 $exclude_term_ids = $this->getQueryAttribute( 'exclude_term_ids', [] );
29
30 $query = array(
31 'fields' => "
32 SELECT DISTINCT ID FROM {$wpdb->posts} p
33 ",
34 'join' => '',
35 'where' => "
36 WHERE 1=1
37 AND p.post_status = 'publish'
38 AND p.post_type = 'sc_product'
39 ",
40 'limits' => '
41 LIMIT ' . absint( apply_filters( 'surecart_product_related_posts_query_limit', ( $per_page * $total_pages ) + 10 ) ) . '
42 ',
43 );
44
45 if ( count( $exclude_term_ids ) ) {
46 $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';
47 $query['where'] .= ' AND exclude_join.object_id IS NULL';
48 }
49
50 if ( count( $include_term_ids ) ) {
51 $query['join'] .= " INNER JOIN ( SELECT object_id FROM {$wpdb->term_relationships} INNER JOIN {$wpdb->term_taxonomy} 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';
52 }
53
54 return $query;
55 }
56
57 /**
58 * Run the query.
59 *
60 * This first gets post ids based on shared object terms.
61 * Then it creates a WP_Query object with the post ids.
62 *
63 * @return $this|\WP_Error
64 */
65 public function query() {
66 // Return cached query if it exists.
67 if ( null !== self::$cached_query ) {
68 $this->query = self::$cached_query;
69 return $this;
70 }
71
72 global $wpdb;
73
74 $page = $this->url->getCurrentPage();
75 $per_page = $this->getQueryAttribute( 'perPage', 3 );
76 $order = $this->getQueryAttribute( 'order', 'desc' );
77 $orderby = $this->getQueryAttribute( 'orderBy', 'date' );
78 $taxonomy = $this->getQueryAttribute( 'taxonomy', 'sc_collection' );
79
80 // get the current posts terms.
81 $term_ids = wp_get_object_terms(
82 get_the_ID(),
83 $taxonomy,
84 [ 'fields' => 'ids' ]
85 );
86
87 // If there are term ids, get the post ids.
88 if ( ! empty( $term_ids ) && ! is_wp_error( $term_ids ) ) {
89 $query = $this->parse_query( $term_ids );
90 // phpcs:ignore WordPress.VIP.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.NotPrepared
91 $post_ids = $wpdb->get_col( implode( ' ', (array) apply_filters( 'surecart_product_related_posts_query', $query, get_the_ID() ) ) );
92
93 // Maybe shuffle the post ids. We don't want to shuffle if there are more posts than the per page limit.
94 // This is because shuffle does not work with pagination.
95 if ( ! $this->has_pagination ) {
96 if ( $this->getQueryAttribute( 'shuffle', false ) ) {
97 shuffle( $post_ids );
98 }
99 }
100 }
101
102 // If there are no related products, show all products.
103 $fallback_to_all = $this->getQueryAttribute( 'fallback', true );
104
105 // Exclude the current post ID.
106 $post_in = array_diff(
107 ! empty( $post_ids ) ? array_map( 'absint', $post_ids ) : ( ! $fallback_to_all ? [ 0 ] : [] ),
108 [ get_the_ID() ]
109 );
110
111 // Create WP_Query object with found post IDs.
112 $this->query = new \WP_Query(
113 apply_filters(
114 'surecart_related_products_query_args',
115 [
116 'post_type' => 'sc_product',
117 'post__in' => $post_in, // Use 0 to return no results if empty.
118 'orderby' => esc_sql( $orderby ),
119 'post_status' => 'publish',
120 'order' => esc_sql( $order ),
121 'posts_per_page' => absint( $per_page ),
122 'paged' => absint( $page ),
123 'post__not_in' => [ get_the_ID() ],
124 ],
125 )
126 );
127
128 // Cache the query result.
129 self::$cached_query = $this->query;
130
131 // return the query.
132 return $this;
133 }
134 }
135