PluginProbe ʕ •ᴥ•ʔ
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 4.5.0
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v4.5.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 1.0.6 1.1.0 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.11.0 1.11.1 1.11.2 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.9.0 1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 2.0.0 2.0.1 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.10.0 2.10.1 2.11.0 2.11.1 2.11.2 2.11.3 2.11.4 2.12.0 2.13.0 2.14.0 2.14.1 2.15.0 2.15.1 2.16.0 2.16.1 2.16.2 2.16.3 2.17.0 2.17.1 2.17.2 2.18.0 2.19.0 2.19.2 2.19.3 2.19.4 2.2.0 2.2.1 2.20.0 2.20.1 2.20.2 2.20.3 2.20.4 2.20.5 2.20.6 2.21.0 2.22.0 2.22.1 2.23.0 2.24.0 2.25.0 2.25.1 2.25.2 2.26.0 2.27.0 2.27.1 2.28.0 2.29.0 2.29.1 2.29.2 2.29.3 2.29.4 2.3.0 2.3.1 2.30.0 2.31.0 2.31.1 2.31.2 2.31.3 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.40.0 2.40.1 2.5.0 2.5.1 2.5.2 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.9.0 3.0.0 3.0.0-RC1 3.0.0-RC2 3.0.0-beta1 3.0.0-beta2 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.10.0 3.10.1 3.11.0 3.12.0 3.13.0 3.13.1 3.13.2 3.13.3 3.13.4 3.14.0 3.15.0 3.15.1 3.15.2 3.15.3 3.15.4 3.15.5 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.16.6 3.16.7 3.16.8 3.17.0 3.17.1 3.17.2 3.17.3 3.17.4 3.17.5 3.17.6 3.18.0 3.19.0 3.19.1 3.19.2 3.2.0 3.2.1 3.2.2 3.20.0 3.20.1 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 4.0.0 4.0.1 4.0.2 4.0.3 trunk 4.1.0 0.2.19.1 4.1.1 1.0.0 4.2.0 1.0.1 1.0.2
surecart / app / src / Models / Blocks / RelatedProductsBlock.php
surecart / app / src / Models / Blocks Last commit date
AbstractProductListBlock.php 2 months ago ProductListBlock.php 2 months ago ProductPageBlock.php 2 months ago ProductReviewBlock.php 4 months ago ProductReviewListBlock.php 4 months ago RelatedProductsBlock.php 2 months ago
RelatedProductsBlock.php
140 lines
1 <?php
2
3 namespace SureCart\Models\Blocks;
4
5 /**
6 * The product list block.
7 */
8 class RelatedProductsBlock extends AbstractProductListBlock {
9 /**
10 * Build the query.
11 *
12 * @param array $include_term_ids The term ids to include in the query.
13 *
14 * @return array
15 */
16 public function parse_query( $include_term_ids = [] ) {
17 global $wpdb;
18
19 $per_page = $this->getQueryAttribute( 'perPage', 15 );
20 $total_pages = $this->getQueryAttribute( 'pages', 3 );
21 $offset = $this->getQueryAttribute( 'offset', 0 );
22 $exclude_term_ids = $this->getQueryAttribute( 'exclude_term_ids', [] );
23 $limit = absint( apply_filters( 'surecart_product_related_posts_query_limit', ( $per_page * $total_pages ) + $offset ) );
24
25 $query = array(
26 'fields' => "
27 SELECT DISTINCT ID FROM {$wpdb->posts} p
28 ",
29 'join' => '',
30 'where' => "
31 WHERE 1=1
32 AND p.post_status = 'publish'
33 AND p.post_type = 'sc_product'
34 ",
35 'limits' => $wpdb->prepare( 'LIMIT %d', $limit ),
36 );
37
38 if ( count( $exclude_term_ids ) ) {
39 $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';
40 $query['where'] .= ' AND exclude_join.object_id IS NULL';
41 }
42
43 if ( count( $include_term_ids ) ) {
44 $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';
45 }
46
47 return $query;
48 }
49
50 /**
51 * Offset the found posts.
52 * See: https://codex.wordpress.org/Making_Custom_Queries_using_Offset_and_Pagination
53 *
54 * @param int $found_posts The found posts.
55 *
56 * @return int The found posts with offset.
57 */
58 public function offsetFoundPosts( $found_posts ) {
59 $offset = absint( $this->getQueryAttribute( 'offset', 0 ) );
60
61 return max( 0, $found_posts - $offset );
62 }
63
64 /**
65 * Run the query.
66 *
67 * This first gets post ids based on shared object terms.
68 * Then it creates a WP_Query object with the post ids.
69 *
70 * @return $this|\WP_Error
71 */
72 public function query() {
73 global $wpdb;
74
75 $page = $this->url->getCurrentPage();
76 $per_page = $this->getQueryAttribute( 'perPage', 3 );
77 $offset = $this->getQueryAttribute( 'offset', 0 );
78 $order = $this->getQueryAttribute( 'order', 'desc' );
79 $orderby = $this->getQueryAttribute( 'orderBy', 'date' );
80 $taxonomy = $this->getQueryAttribute( 'taxonomy', 'sc_collection' );
81
82 // get the current posts terms.
83 $term_ids = wp_get_object_terms(
84 get_the_ID(),
85 $taxonomy,
86 [ 'fields' => 'ids' ]
87 );
88
89 // If there are term ids, get the post ids.
90 if ( ! empty( $term_ids ) && ! is_wp_error( $term_ids ) ) {
91 $query = $this->parse_query( $term_ids );
92 // phpcs:ignore WordPress.VIP.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.NotPrepared
93 $post_ids = $wpdb->get_col( implode( ' ', (array) apply_filters( 'surecart_product_related_posts_query', $query, get_the_ID() ) ) );
94
95 // Maybe shuffle the post ids. We don't want to shuffle if there are more posts than the per page limit.
96 // This is because shuffle does not work with pagination.
97 if ( ! $this->has_pagination ) {
98 if ( $this->getQueryAttribute( 'shuffle', false ) ) {
99 shuffle( $post_ids );
100 }
101 }
102 }
103
104 // If there are no related products, show all products.
105 $fallback_to_all = $this->getQueryAttribute( 'fallback', true );
106
107 // Exclude the current post ID.
108 $post_in = array_diff(
109 ! empty( $post_ids ) ? array_map( 'absint', $post_ids ) : ( ! $fallback_to_all ? [ 0 ] : [] ),
110 [ get_the_ID() ]
111 );
112
113 add_filter( 'found_posts', [ $this, 'offsetFoundPosts' ], 1 );
114
115 $this->query = new \WP_Query(
116 apply_filters(
117 'surecart_related_products_query_args',
118 [
119 'post_type' => 'sc_product',
120 'post__in' => $post_in, // Use 0 to return no results if empty.
121 'orderby' => esc_sql( $orderby ),
122 'post_status' => 'publish',
123 'order' => esc_sql( $order ),
124 'posts_per_page' => absint( $per_page ),
125 'offset' => ( $per_page * ( $page - 1 ) ) + $offset,
126 'paged' => absint( $page ),
127 'post__not_in' => [ get_the_ID() ],
128 ],
129 )
130 );
131
132 remove_filter( 'found_posts', [ $this, 'offsetFoundPosts' ], 1 );
133
134 $this->primeAttachmentCaches();
135
136 // return the query.
137 return $this;
138 }
139 }
140