PluginProbe
Depicter — Popup & Slider Builder / trunk
Depicter — Popup & Slider Builder vtrunk
4.8.1 trunk 1.0.0 1.1.0 1.1.2 1.1.4 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.5 1.3.8 1.5.0 1.5.1 1.5.2 1.5.5 1.6.0 1.6.1 1.6.2 1.7.0 All 76 releases
depicter / app / src / DataSources / Products.php

Products.php in Depicter — Popup & Slider Builder trunk, at app/src/DataSources/Products.php

420 lines 11.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Depicter\DataSources;
3
4 use Averta\Core\Utility\Data;
5 use Averta\Core\Utility\Str;
6 use Averta\WordPress\Utility\JSON;
7 use Averta\WordPress\Utility\Post;
8
9 class Products extends Posts implements DataSourceInterface {
10
11 /**
12 * DataSource name
13 *
14 * @var string
15 */
16 protected string $type = 'wooProducts';
17
18 /**
19 * DataSource properties
20 *
21 * @var array
22 */
23 protected array $properties = [
24 'type' => 'wooProducts',
25 'postType' => 'product'
26 ];
27
28 /**
29 * Default input params for retrieving dataSource records
30 *
31 * @var array
32 */
33 protected array $defaultInputParams = [
34 'postType' => 'product',
35 'perpage' => 5,
36 'excerptLength' => 100,
37 'offset' => 0,
38 'linkSlides' => false,
39 'orderBy' => 'date',
40 'order' => 'DESC',
41 'imageSource' => 'featured',
42 'excludedIds' => '',
43 'includedIds' => '',
44 'excludeNonThumbnail' => true,
45 'taxonomies' => '',
46 'from' => 'all', // product types - available options => all, best-selling, top-rated, featured, on-sale
47 'inStockOnly' => true,
48 'regularProducts' => true,
49 'downloadableProducts' => true,
50 'virtualProducts' => true,
51 'filterByPrice' => false,
52 'startPrice' => '',
53 'endPrice' => '',
54 'startSalePrice' => '',
55 'endSalePrice' => ''
56 ];
57
58 /**
59 * Asset groups of this DataSource
60 *
61 * @var array
62 */
63 protected array $assetGroupNames = [ 'post', 'product', 'taxonomy', 'acf', 'metaboxio' ];
64
65 /**
66 * Retrieves the list of records based on query params
67 *
68 * @param $args
69 *
70 * @return \WP_Query
71 */
72 protected function getRecords( $args ){
73
74 if ( !function_exists('WC') ) {
75 return [];
76 }
77
78 $queryArgs = [
79 'post_type' => $args['postType'],
80 'posts_per_page' => $args['perpage'],
81 'order' => $args['order'],
82 'orderby' => $args['orderBy'],
83 'offset' => $args['offset'],
84 'post__in' => $args['includedIds'],
85 'post__not_in' => $args['excludedIds'],
86 'tax_query' => [],
87 'meta_query' => [],
88 'post_status' => 'publish'
89 ];
90
91 if ( !empty( $args['taxonomies'] ) ) {
92 $taxonomies = $args['taxonomies'];
93
94 if( JSON::isJson( $args['taxonomies'] ) ){
95 $taxonomies = JSON::decode( $args['taxonomies'] );
96 }
97
98 if( !empty( $taxonomies->product_cat ) ){
99 $queryArgs['tax_query'][] = [
100 'taxonomy' => 'product_cat',
101 'field' => 'slug',
102 'terms' => $taxonomies->product_cat
103 ];
104 }
105
106 if( !empty( $taxonomies->product_tag ) ){
107 $queryArgs['tax_query'][] = [
108 'taxonomy' => 'product_tag',
109 'field' => 'slug',
110 'terms' => $taxonomies->product_tag
111 ];
112 }
113 }
114
115 if ( !empty( $args['from'] ) ) {
116 switch ( $args['from'] ) {
117 case 'featured':
118 $queryArgs['tax_query'][] = array(
119 'taxonomy' => 'product_visibility',
120 'field' => 'name',
121 'terms' => 'featured',
122 );
123 break;
124
125 case 'best-selling':
126 $queryArgs['meta_key'] = 'total_sales';
127 $queryArgs['orderby'] = 'meta_value_num';
128 break;
129
130 case 'on-sale':
131 $queryArgs['meta_query'] = WC()->query->get_meta_query();
132 $queryArgs['post__in'] = wc_get_product_ids_on_sale();
133 break;
134
135 case 'top-rated':
136 $queryArgs['meta_query'] = WC()->query->get_meta_query();
137 add_filter( 'posts_clauses', array( 'WC_Shortcodes', 'order_by_rating_post_clauses' ) );
138 break;
139 default: // i.e. all products
140 $queryArgs['meta_query'] = WC()->query->get_meta_query();
141 break;
142 }
143 }
144
145 if( Data::isTrue( $args['excludeNonThumbnail'] ) ){
146 $queryArgs['meta_query'][] = [
147 'key' => '_thumbnail_id',
148 'compare' => 'EXISTS'
149 ];
150 }
151
152 if ( Data::isTrue( $args['inStockOnly'] ) ) {
153 $queryArgs['meta_query'][] = [
154 'key' => '_stock_status',
155 'value' => 'instock',
156 'compare' => '=',
157 ];
158 }
159
160 if ( ! Data::isTrue( $args['regularProducts'] ) ) {
161 if ( ! Data::isTrue( $args['downloadableProducts'] ) && ! Data::isTrue( $args['virtualProducts'] ) ) {
162 return new \WP_Query();
163 }
164
165 if ( Data::isTrue( $args['downloadableProducts'] ) ) {
166
167 if ( Data::isTrue( $args['virtualProducts'] ) ) {
168 $queryArgs['meta_query'][] = [
169 'relation' => 'OR',
170 [
171 'key' => '_downloadable',
172 'value' => 'yes',
173 'compare' => '==',
174 ],
175 [
176 'key' => '_virtual',
177 'value' => 'yes',
178 'compare' => '==',
179 ]
180
181 ];
182 } else {
183 $queryArgs['meta_query'][] = [
184 'key' => '_downloadable',
185 'value' => 'yes',
186 'compare' => '==',
187 ];
188 }
189
190 } else if ( Data::isTrue( $args['virtualProducts'] ) ) {
191 $queryArgs['meta_query'][] = [
192 'key' => '_virtual',
193 'value' => 'yes',
194 'compare' => '==',
195 ];
196 }
197
198
199
200 } else {
201 if ( ! Data::isTrue( $args['downloadableProducts'] ) ) {
202 $queryArgs['meta_query'][] = [
203 'key' => '_downloadable',
204 'value' => 'yes',
205 'compare' => '!=',
206 ];
207 }
208
209 if ( ! Data::isTrue( $args['virtualProducts'] ) ) {
210 $queryArgs['meta_query'][] = [
211 'key' => '_virtual',
212 'value' => 'yes',
213 'compare' => '!=',
214 ];
215 }
216 }
217
218 if ( Data::isTrue( $args['filterByPrice'] ) ) {
219
220 if ( !empty( $args['startPrice'] ) ) {
221 $queryArgs['meta_query'][] = [
222 'key' => '_price',
223 'value' => $args['startPrice'],
224 'compare' => '>=',
225 'type' => 'NUMERIC',
226 ];
227 }
228
229 if ( !empty( $args['endPrice'] ) ) {
230 $queryArgs['meta_query'][] = [
231 'key' => '_price',
232 'value' => $args['endPrice'],
233 'compare' => '<=',
234 'type' => 'NUMERIC',
235 ];
236 }
237
238 if ( !empty( $args['startSalePrice'] ) ) {
239 $queryArgs['meta_query'][] = [
240 'key' => '_sale_price',
241 'value' => $args['startSalePrice'],
242 'compare' => '>=',
243 'type' => 'NUMERIC',
244 ];
245 }
246
247 if ( !empty( $args['endSalePrice'] ) ) {
248 $queryArgs['meta_query'][] = [
249 'key' => '_sale_price',
250 'value' => $args['endSalePrice'],
251 'compare' => '<=',
252 'type' => 'NUMERIC',
253 ];
254 }
255
256 }
257
258 return new \WP_Query( $queryArgs );
259 }
260
261 /**
262 * Renders preview for query params
263 *
264 * @param array $args
265 *
266 * @return array
267 */
268 public function previewRecords( array $args = [] ) {
269 if ( !function_exists('WC') ) {
270 return [];
271 }
272 $args = $this->prepare( $args );
273 $availableRecords = $this->getRecords( $args );
274
275 $records = [];
276
277 if ( $availableRecords && $availableRecords->have_posts() ) {
278
279 foreach( $availableRecords->posts as $post ) {
280 $product = wc_get_product( $post->ID );
281 if ( ! $product ) {
282 continue;
283 }
284
285 $featuredImage = [];
286
287 if( $featuredImageId = $product->get_image_id() ){
288 $imageInfo = wp_get_attachment_image_src( $featuredImageId, 'full' );
289 $featuredImage = [
290 'id' => $featuredImageId,
291 'src' => $imageInfo[0] ?? '',
292 'width' => $imageInfo[1] ?? '',
293 'height' => $imageInfo[2] ?? '',
294 ];
295 } else {
296 $featuredImage = [
297 'id' => null,
298 'src' => '',
299 'width' => '',
300 'height' => '',
301 ];
302 }
303
304 $secondaryImage = [];
305 $attachment_ids = $product->get_gallery_image_ids();
306 if( !empty( $attachment_ids[0] ) ){
307 $imageInfo = wp_get_attachment_image_src( $attachment_ids[0], 'full' );
308 $secondaryImage = [
309 'id' => $attachment_ids[0],
310 'src' => $imageInfo[0] ?? '',
311 'width' => $imageInfo[1] ?? '',
312 'height' => $imageInfo[2] ?? '',
313 ];
314 }
315
316 $excerpt = Post::getExcerptTrimmedByWords( $post->ID );
317 if ( ! empty( $args['excerptLength'] ) ) {
318 $excerpt = Str::trimByChars( $excerpt, $args['excerptLength'] );
319 }
320
321 $postInfo = [
322 'id' => $post->ID,
323 'title' => $product->get_title(),
324 'url' => get_permalink( $post->ID ),
325 'featuredImage' => $featuredImage,
326 'secondaryImage' => $secondaryImage,
327 'date' => get_the_date('Y-m-d h:m:s', $post->ID ),
328 'excerpt' => $excerpt,
329 'author' => [
330 'name' => get_the_author_meta( 'display_name', $post->post_author ),
331 'page' => get_author_posts_url( $post->post_author ),
332 ],
333 'content' => $product->get_description(),
334 'taxonomy'=> [],
335 'shortDescription' => $product->get_short_description(),
336 'price' => wc_price( $product->get_price() ) . $product->get_price_suffix(),
337 'regularPrice' => wc_price( $product->get_regular_price() ) . $product->get_price_suffix(),
338 'salePrice' => $product->is_on_sale() ? wc_price( $product->get_sale_price() ) . $product->get_price_suffix() : '',
339 'onSale' => $product->is_on_sale(),
340 'onSaleText' => $product->is_on_sale() ? __( 'Sale', 'depicter' ) : '',
341 'rating' => $product->get_average_rating(),
342 'ratingCount' => $product->get_rating_count(),
343 'reviewCount' => $product->get_review_count(),
344 'sku' => $product->get_sku(),
345 'stockStatus' => $this->getStockStatus( $product ),
346 'stockStatusClass' => $product->is_in_stock() ? 'in-stock' : 'out-of-stock',
347 'isInStock' => $product->is_in_stock(),
348 'stockQuantity'=> $product->get_stock_quantity(),
349 'isPurchasable'=> $product->is_purchasable(),
350 'addToCart' => [
351 'url' => esc_url( $product->add_to_cart_url() ),
352 'text' => null !== $product->add_to_cart_text() ? $product->add_to_cart_text() : __( 'Add to cart', 'depicter' ),
353 'cartUrl' => esc_url( apply_filters( 'woocommerce_add_to_cart_redirect', wc_get_cart_url(), null ) ),
354 'purchasable' => $product->is_purchasable() && $product->is_in_stock(),
355 'canUseAjax' => $this->productSupportsAjaxAddToCart( $product ),
356 ],
357 ];
358
359 $taxonomies = get_object_taxonomies( $args['postType'], 'objects' );
360
361 if ( !empty( $taxonomies ) ) {
362 foreach( $taxonomies as $taxonomySlug => $taxonomy ) {
363 $taxonomyInfo = [
364 "id" => $taxonomySlug,
365 "label" => $taxonomy->label,
366 "terms" => []
367 ];
368
369 if ( $terms = wp_get_post_terms( $post->ID, $taxonomySlug ) ) {
370 foreach( $terms as $term ) {
371 $taxonomyInfo[ "terms" ][] = [
372 'id' => $term->term_id,
373 'value' => $term->slug,
374 'label' => $term->name,
375 'link' => get_term_link( $term->term_id )
376 ];
377 }
378 }
379
380 $postInfo['taxonomy'][ $taxonomySlug ] = $taxonomyInfo;
381 }
382 }
383
384 $records[] = $postInfo;
385 }
386 }
387
388 return $records;
389 }
390
391 /**
392 * Retrieves product stock status
393 *
394 * @param $product
395 *
396 * @return mixed|void
397 */
398 protected function getStockStatus( $product ){
399 if ( $product->is_on_backorder() ) {
400 $stock_html = __( 'On backorder', 'depicter' );
401 } elseif ( $product->is_in_stock() ) {
402 $stock_html = __( 'In stock', 'depicter' );
403 } else {
404 $stock_html = __( 'Out of stock', 'depicter' );
405 }
406 return apply_filters( 'woocommerce_admin_stock_html', $stock_html, $product );
407 }
408
409 /**
410 * Whether product can be added to cart via ajax or not
411 *
412 * @param $product
413 *
414 * @return bool
415 */
416 protected function productSupportsAjaxAddToCart( $product ) {
417 return (get_option( 'woocommerce_enable_ajax_add_to_cart' ) === 'yes') && $product->supports( 'ajax_add_to_cart' ) && $product->is_purchasable() && $product->is_in_stock();
418 }
419 }
420