PluginProbe ʕ •ᴥ•ʔ
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 3.0.0-beta1
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v3.0.0-beta1
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 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 / ProductListBlock.php
surecart / app / src / Models / Blocks Last commit date
ProductListBlock.php 2 years ago ProductPageBlock.php 2 years ago
ProductListBlock.php
287 lines
1 <?php
2
3 namespace SureCart\Models\Blocks;
4
5 /**
6 * The product list block.
7 */
8 class ProductListBlock {
9 /**
10 * The block.
11 *
12 * @var \WP_Block
13 */
14 protected $block;
15
16 /**
17 * The URL.
18 *
19 * @var object
20 */
21 protected $url;
22
23 /**
24 * The query vars.
25 *
26 * @var array
27 */
28 protected $query_vars = [];
29
30 /**
31 * The query.
32 *
33 * @var \WP_Query
34 */
35 protected $query;
36
37 /**
38 * Constructor.
39 *
40 * @param \WP_Block $block The block.
41 */
42 public function __construct( \WP_Block $block = null ) {
43 $this->block = $block ? $block : \WP_Block_Supports::$block_to_render;
44 $this->url = \SureCart::block()->urlParams( 'products' );
45 }
46
47 /**
48 * Get the URL.
49 *
50 * @return object|null
51 */
52 public function urlParams() {
53 return $this->url;
54 }
55
56 /**
57 * Get the query context.
58 *
59 * @return array
60 */
61 public function getQueryContext() {
62 return $this->block->context['query'] ?? [];
63 }
64
65 /**
66 * Build the query
67 *
68 * @return $this
69 */
70 public function parse_query() {
71 $query = $this->getQueryContext();
72
73 $offset = absint( $query['offset'] ?? 0 );
74 $per_page = $query['perPage'] ?? $this->block->context['surecart/product-list/limit'] ?? $this->block->parsed_block['attrs']['limit'] ?? 15;
75 $page = $this->url->getCurrentPage();
76
77 // build up the query.
78 $this->query_vars = array_filter(
79 array(
80 'post_type' => 'sc_product',
81 'post_status' => 'publish',
82 'ignore_sticky_posts' => 1,
83 'posts_per_page' => $query['perPage'] ?? $this->block->context['surecart/product-list/limit'] ?? $this->block->parsed_block['attrs']['limit'] ?? 15,
84 'offset' => ( $per_page * ( $page - 1 ) ) + $offset,
85 'paged' => $this->url->getCurrentPage(),
86 'order' => $this->url->getArg( 'order' ),
87 'orderby' => $this->url->getArg( 'orderby' ),
88 's' => $this->url->getArg( 'search' ),
89 )
90 );
91
92 // put together price query.
93 if ( 'price' === $this->url->getArg( 'orderby' ) ) {
94 $this->query_vars['meta_key'] = 'min_price_amount';
95 $this->query_vars['orderby'] = 'meta_value_num';
96 }
97
98 $collection_id = $this->block->context['surecart/product-list/collection_id'] ?? $this->block->parsed_block['attrs']['collection_id'] ?? ''; // collection id from block context from "sc_product_collection" shortcode.
99
100 $collection_ids_to_filter = array();
101
102 // handle collection id send from "sc_product_collection" shortcode.
103 if ( ! empty( $collection_id ) ) {
104 $collection_ids = explode( ',', $collection_id );
105
106 $legacy_collection_ids = get_terms(
107 array(
108 'taxonomy' => 'sc_collection',
109 'field' => 'term_id',
110 'meta_query' => array(
111 array(
112 'key' => 'sc_id',
113 'value' => $collection_ids,
114 'compare' => 'IN',
115 ),
116 ),
117 )
118 ); // platform collection ids converted to WP taxonomy ids.
119
120 // only get the term_id.
121 $legacy_collection_ids = array_map(
122 function ( $term ) {
123 return $term->term_id;
124 },
125 $legacy_collection_ids
126 );
127
128 $collection_ids_to_filter = array_merge( $legacy_collection_ids, $collection_ids_to_filter );
129 } elseif ( is_tax() ) {
130 $term = get_queried_object();
131 $collection_ids_to_filter = [ $term->term_id ];
132 }
133
134 $new_collection_ids = $this->url->getArg( 'sc_collection' );
135
136 // handle collections query.
137 if ( ! empty( $new_collection_ids ) ) {
138 $collection_ids_to_filter = array_merge( $new_collection_ids, $collection_ids_to_filter );
139 }
140
141 if ( ! empty( $collection_ids_to_filter ) ) {
142 $this->query_vars['tax_query'] =
143 array(
144 array(
145 'taxonomy' => 'sc_collection',
146 'field' => 'term_id',
147 'terms' => array_unique( array_map( 'intval', $collection_ids_to_filter ?? array() ) ),
148 ),
149 );
150 }
151
152 // handle featured.
153 if ( 'featured' === ( $this->block->context['surecart/product-list/type'] ?? 'all' ) ) {
154 $this->query_vars['meta_query'] = [
155 [
156 'key' => 'featured',
157 'value' => '1',
158 'compare' => '=',
159 ],
160 ];
161 }
162
163 if ( 'custom' === ( $this->block->context['surecart/product-list/type'] ?? 'all' ) ) {
164 $query = $this->getQueryContext();
165 // backward compatibility.
166 $ids = $query['include'] ?? $this->block->context['surecart/product-list/ids'] ?? $this->block->parsed_block['attrs']['ids'] ?? [];
167 // fallback for older strings - get the ids of legacy products.
168 $legacy_ids = [];
169 $ids_that_are_strings = array_filter( $ids, 'is_string' );
170 if ( ! empty( $ids_that_are_strings ) ) {
171 $legacy_ids = get_posts(
172 [
173 'post_type' => 'sc_product',
174 'status' => 'publish',
175 'fields' => 'ids',
176 'posts_per_page' => -1,
177 'meta_query' => [
178 [
179 'key' => 'sc_id',
180 'value' => $ids_that_are_strings,
181 'compare' => 'IN',
182 ],
183 ],
184 ]
185 );
186 }
187
188 // get only ids that are integers.
189 $ids_that_are_integers = array_filter( $ids, 'is_int' );
190
191 // post in.
192 $this->query_vars['post__in'] = array_merge( $legacy_ids, $ids_that_are_integers );
193
194 // order by posts if there is not an order by.
195 if ( empty( $this->query_vars['orderby'] ) ) {
196 $this->query_vars['orderby'] = 'post__in';
197 }
198 }
199
200 return $this;
201 }
202
203 /**
204 * Offset the found posts.
205 * See: https://codex.wordpress.org/Making_Custom_Queries_using_Offset_and_Pagination
206 *
207 * @param int $found_posts The found posts.
208 *
209 * @return int The found posts with offset.
210 */
211 public function offsetFoundPosts( $found_posts ) {
212 $query = $this->getQueryContext();
213 $offset = absint( $query['offset'] ?? 0 );
214
215 return $found_posts - $offset;
216 }
217
218 /**
219 * Run the query
220 *
221 * @return $this|\WP_Error
222 */
223 public function query() {
224 $this->parse_query();
225 wp_reset_postdata();
226
227 add_filter( 'found_posts', [ $this, 'offsetFoundPosts' ], 1 );
228 $this->query = new \WP_Query( $this->query_vars );
229 remove_filter( 'found_posts', [ $this, 'offsetFoundPosts' ], 1 );
230
231 return $this;
232 }
233
234 /**
235 * Get the query attribute.
236 *
237 * @param string $key The key.
238 * @return \WP_Query
239 */
240 public function __get( $key ) {
241 // handle pagination.
242 if ( 'next_page_link' === $key ) {
243 return $this->max_num_pages && $this->max_num_pages !== $this->paged ? $this->url->addPageArg( $this->paged + 1 )->url() : '';
244 }
245
246 if ( 'previous_page_link' === $key ) {
247 return $this->paged > 1 ? $this->url->addPageArg( $this->paged - 1 )->url() : '';
248 }
249
250 if ( 'pagination_links' === $key ) {
251 return array_map(
252 function ( $i ) {
253 return array(
254 'href' => $this->url->addPageArg( $i )->url(),
255 'name' => $i,
256 'current' => (int) $i === (int) $this->paged,
257 );
258 },
259 range( 1, $this->max_num_pages )
260 );
261 }
262
263 if ( 'products' === $key ) {
264 return array_map(
265 function ( $post ) {
266 return sc_get_product( $post );
267 },
268 $this->query->posts
269 );
270 }
271
272 return $this->query->$key ?? $this->query->query[ $key ] ?? $this->query->query_vars[ $key ] ?? null;
273 }
274
275 /**
276 * Call the query method.
277 *
278 * @param string $method The method.
279 * @param array $args The arguments.
280 *
281 * @return mixed
282 */
283 public function __call( $method, $args ) {
284 return $this->query->$method( ...$args );
285 }
286 }
287