'product', 'perpage' => 5, 'excerptLength' => 100, 'offset' => 0, 'linkSlides' => true, 'orderBy' => 'date', 'order' => 'DESC', 'imageSource' => 'featured', 'excludedIds' => '', 'includedIds' => '', 'excludeNonThumbnail' => true, 'taxonomies' => '', 'from' => 'all', // product types - available options => all, best-selling, top-rated, featured, on-sale 'inStockOnly' => true, 'regularProducts' => true, 'downloadableProducts' => true, 'virtualProducts' => true, 'filterByPrice' => false, 'startPrice' => '', 'endPrice' => '', 'startSalePrice' => '', 'endSalePrice' => '' ]; /** * List of valid dynamic tags for this source * * @var string[] */ protected $tags = [ '{{{title}}}', '{{{url}}}', '{{{featuredImage}}}', '{{{secondaryImage}}}', '{{{price}}}', '{{{salePrice}}}', '{{{ratingAverage}}}', '{{{content}}}', '{{{shortDescription}}}', '{{{stockStatus}}}', '{{{stockQuantity}}}', '{{product_catToStr}}', // converts the array of categories to this form cat1, cat2, cat3 '{{product_tagToStr}}' // converts the array of tags to this form tag1, tag2, tag3 ]; /** * Retrieves the list of records based on query params * * @param $args * * @return \WP_Query */ protected function getRecords( $args ){ $queryArgs = [ 'post_type' => $args['postType'], 'posts_per_page' => $args['perpage'], 'order' => $args['order'], 'orderby' => $args['orderBy'], 'offset' => $args['offset'], 'post__in' => $args['includedIds'], 'post__not_in' => $args['excludedIds'], 'tax_query' => [], 'meta_query' => [] ]; if ( !empty( $args['taxonomies'] ) ) { $taxonomies = $args['taxonomies']; if( JSON::isJson( $args['taxonomies'] ) ){ $taxonomies = JSON::decode( $args['taxonomies'] ); } if( !empty( $taxonomies->product_cat ) ){ $queryArgs['tax_query'][] = [ 'taxonomy' => 'product_cat', 'field' => 'slug', 'terms' => $taxonomies->product_cat ]; } if( !empty( $taxonomies->product_tag ) ){ $queryArgs['tax_query'][] = [ 'taxonomy' => 'product_tag', 'field' => 'slug', 'terms' => $taxonomies->product_tag ]; } } if ( !empty( $args['from'] ) ) { switch ( $args['from'] ) { case 'featured': $queryArgs['tax_query'][] = array( 'taxonomy' => 'product_visibility', 'field' => 'name', 'terms' => 'featured', ); break; case 'best-selling': $queryArgs['orderby'] = 'meta_value_num'; break; case 'on-sale': $queryArgs['meta_query'] = WC()->query->get_meta_query(); $queryArgs['post__in'] = wc_get_product_ids_on_sale(); break; case 'top-rated': $queryArgs['meta_query'] = WC()->query->get_meta_query(); add_filter( 'posts_clauses', array( 'WC_Shortcodes', 'order_by_rating_post_clauses' ) ); break; default: // i.e. all products $queryArgs['meta_query'] = WC()->query->get_meta_query(); break; } } if( Data::isTrue( $args['excludeNonThumbnail'] ) ){ $queryArgs['meta_query'][] = [ 'key' => '_thumbnail_id', 'compare' => 'EXISTS' ]; } if ( Data::isTrue( $args['inStockOnly'] ) ) { $queryArgs['meta_query'][] = [ 'key' => '_stock_status', 'value' => 'instock', 'compare' => '=', ]; } if ( ! Data::isTrue( $args['downloadableProducts'] ) ) { $queryArgs['meta_query'][] = [ 'key' => '_downloadable', 'value' => 'yes', 'compare' => '!=', ]; } if ( ! Data::isTrue( $args['virtualProducts'] ) ) { $queryArgs['meta_query'][] = [ 'key' => '_virtual', 'value' => 'yes', 'compare' => '!=', ]; } if ( Data::isTrue( $args['filterByPrice'] ) ) { if ( !empty( $args['startPrice'] ) ) { $queryArgs['meta_query'][] = [ 'key' => '_price', 'value' => $args['startPrice'], 'compare' => '>=', 'type' => 'NUMERIC', ]; } if ( !empty( $args['endPrice'] ) ) { $queryArgs['meta_query'][] = [ 'key' => '_price', 'value' => $args['endPrice'], 'compare' => '<=', 'type' => 'NUMERIC', ]; } if ( !empty( $args['startSalePrice'] ) ) { $queryArgs['meta_query'][] = [ 'key' => '_sale_price', 'value' => $args['startSalePrice'], 'compare' => '>=', 'type' => 'NUMERIC', ]; } if ( !empty( $args['endSalePrice'] ) ) { $queryArgs['meta_query'][] = [ 'key' => '_sale_price', 'value' => $args['endSalePrice'], 'compare' => '<=', 'type' => 'NUMERIC', ]; } } return new \WP_Query( $queryArgs ); } /** * Renders preview for query params * * @param array $args * * @return array */ public function previewRecords( array $args = [] ) { $args = $this->prepare( $args ); $availableRecords = $this->getRecords( $args ); $records = []; if ( $availableRecords && $availableRecords->have_posts() ) { foreach( $availableRecords->posts as $post ) { $product = wc_get_product( $post->ID ); if ( ! $product ) { continue; } $featuredImage = []; if( $featuredImageId = $product->get_image_id() ){ $imageInfo = wp_get_attachment_image_src( $featuredImageId, 'full' ); $featuredImage = [ 'id' => $featuredImageId, 'url' => $imageInfo[0] ?? '', 'width' => $imageInfo[1] ?? '', 'height' => $imageInfo[2] ?? '', ]; } $secondaryImage = []; $attachment_ids = $product->get_gallery_image_ids(); if( !empty( $attachment_ids[0] ) ){ $imageInfo = wp_get_attachment_image_src( $attachment_ids[0], 'full' ); $secondaryImage = [ 'id' => $attachment_ids[0], 'url' => $imageInfo[0] ?? '', 'width' => $imageInfo[1] ?? '', 'height' => $imageInfo[2] ?? '', ]; } $excerpt = !empty( $args['excerptLength'] ) ? Str::trimByChars( get_the_excerpt( $post->ID ), $args['excerptLength'] ) : get_the_excerpt( $post->ID ); $postInfo = [ 'id' => $post->ID, 'title' => $product->get_title(), 'url' => get_permalink( $post->ID ), 'featuredImage' => $featuredImage, 'secondaryImage' => $secondaryImage, 'date' => get_the_date('', $post->ID ), 'excerpt' => $excerpt, 'content' => $product->get_description(), 'taxonomies'=> [], 'shortDescription' => $product->get_short_description(), 'price' => wc_price( $product->get_regular_price() ) . $product->get_price_suffix(), 'salePrice' => $product->is_on_sale() ? wc_price( $product->get_sale_price() ) . $product->get_price_suffix() : '', 'onSale'=> $product->is_on_sale(), 'ratingAverage' => $product->get_average_rating(), 'ratingCount' => $product->get_rating_count(), 'reviewCount' => $product->get_review_count(), 'sku' => $product->get_sku(), 'stockStatus' => $this->getStockStatus( $product ), 'stockQuantity' => $product->get_stock_quantity() ]; $taxonomies = get_object_taxonomies( $args['postType'], 'objects' ); if ( !empty( $taxonomies ) ) { foreach( $taxonomies as $taxonomySlug => $taxonomy ) { $taxonomyInfo = [ "id" => $taxonomySlug, "label" => $taxonomy->label, "terms" => [] ]; if ( $terms = wp_get_post_terms( $post->ID, $taxonomySlug ) ) { foreach( $terms as $term ) { $taxonomyInfo[ "terms" ][] = [ 'id' => $term->term_id, 'value' => $term->slug, 'label' => $term->name, 'link' => get_term_link( $term->term_id ) ]; } } $postInfo['taxonomies'][] = $taxonomyInfo; } } $records[] = $postInfo; } } return $records; } /** * Get list of tags and their values for the query result * * @param array $args * * @return array */ public function getRecordsWithTags( array $args = [] ){ $args = $this->prepare( $args ); $availableRecords = $this->getRecords( $args ); $records = []; if ( $availableRecords && $availableRecords->have_posts() ) { foreach( $availableRecords->posts as $post ) { $product = wc_get_product( $post->ID ); if ( ! $product ) { continue; } $secondaryImage = ''; $attachment_ids = $product->get_gallery_image_ids(); if( !empty( $attachment_ids[0] ) ){ $secondaryImage = $attachment_ids[0]; } $postInfo = [ '{{{url}}}' => get_permalink( $post->ID ), '{{{title}}}' => get_the_title( $post->ID ), '{{{featuredImage}}}' => has_post_thumbnail( $post->ID ) ? get_post_thumbnail_id( $post->ID ) : '', '{{{secondaryImage}}}' => $secondaryImage, '{{{price}}}' => wc_price( $product->get_regular_price() ) . $product->get_price_suffix(), '{{{salePrice}}}' => $product->is_on_sale() ? wc_price( $product->get_sale_price() ) . $product->get_price_suffix() : '', '{{{ratingAverage}}}' => $product->get_average_rating(), '{{{content}}}' => get_the_content(null, false, $post->ID ), '{{{shortDescription}}}' => $product->get_short_description(), '{{{stockStatus}}}' => $this->getStockStatus( $product ), '{{{stockQuantity}}}' => $product->get_stock_quantity(), '{{product_catToStr}}' => $this->getTaxonomyTermsStr( $post->ID, 'product_cat' ), '{{product_tagToStr}}' => $this->getTaxonomyTermsStr( $post->ID, 'product_tag' ), ]; $records[] = $postInfo; } } return $records; } /** * Retrieves product stock status * * @param $product * * @return mixed|void */ protected function getStockStatus( $product ){ if ( $product->is_on_backorder() ) { $stock_html = __( 'On backorder', 'depicter' ); } elseif ( $product->is_in_stock() ) { $stock_html = __( 'In stock', 'depicter' ); } else { $stock_html = __( 'Out of stock', 'depicter' ); } return apply_filters( 'woocommerce_admin_stock_html', $stock_html, $product ); } }