PluginProbe
UiCore Elements – Free widgets and templates for Elementor / 1.2.0
UiCore Elements – Free widgets and templates for Elementor v1.2.0
1.3.17 1.3.16 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 All 41 releases
uicore-elements / includes / utils / product-component.php

product-component.php in UiCore Elements – Free widgets and templates for Elementor 1.2.0, at includes/utils/product-component.php

300 lines 11.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace UiCoreElements\Utils;
3
4 use UiCoreElements\Helper;
5 use UiCoreElements\Controls\Query;
6
7 use UiCoreElements\Utils\Meta_Trait;
8 use UiCoreElements\Utils\Post_Trait;
9
10 defined('ABSPATH') || exit();
11
12 /**
13 * Product Component
14 *
15 * @since 1.0.11
16 */
17
18 trait Product_Trait {
19
20 use Post_Trait,
21 Meta_Trait;
22
23 /**
24 * Returns the proper query args for the product loop.
25 *
26 * @param array $settings Elementor controls settings.
27 * @param array|WP_Query $default_query The default query variables.
28 *
29 * @return array|stdClass Return the products data, prepared for loop.
30 */
31 function TRAIT_query_products($settings, $default_query)
32 {
33 $post_type = $settings['product-filter_post_type'];
34
35 switch ($post_type){
36 case 'current' :
37 // Makes sure widget will render some products at editor screen
38 if( $this->is_edit_mode() ){
39 $query_args['post_type'] = 'product';
40
41 } else {
42 $query_args = $default_query;
43
44 // Set pagination
45 $query_args['paged'] = Query::get_queried_page($settings);
46
47 // Set tax filters for filter component, if enabled
48 $queried_filters = Query::get_queried_filters($settings, 'product', 'product-filter');
49 $query_args['tax_query'] = empty($queried_filters['tax_query']) ? [] : $queried_filters['tax_query'];
50 }
51 break;
52
53 case 'related' :
54 return Helper::get_product_related($settings['item_limit']['size']);
55 break;
56
57 default :
58 $query_args = Query::get_query_args('product-filter', $settings, true);
59 break;
60 }
61
62 // Set total pages
63 $query_args['total_pages'] = Query::get_total_pages($query_args);
64
65 // Hide out of stock products
66 if( $settings['hide_out_of_stock'] === 'yes' ){
67 $query_args['meta_query'] = [
68 [
69 'key' => '_stock_status',
70 'value' => 'instock',
71 'compare' => '=',
72 ]
73 ];
74 }
75
76 $this->_query = $query_args;
77
78 return wc_get_products($query_args);
79 }
80
81
82 // Render functions
83 function get_product_image(object $product)
84 {
85 if ($this->get_settings_for_display('image') !== 'yes') {
86 return;
87 }
88
89 // Get product image ID
90 $pic_id = $product->get_image_id();
91 if (!$pic_id) {
92 return;
93 }
94
95 // Get image size
96 $size = $this->get_settings_for_display('image_size_select') ?? 'uicore-medium';
97 ?>
98 <a class="ui-e-post-img-wrapp"
99 href="<?php echo esc_url($product->get_permalink()); ?>"
100 title="<?php echo esc_attr__('View Product:', 'uicore-elements') . ' ' . esc_attr($product->get_name()); ?>">
101
102 <?php if ($this->get_settings_for_display('masonry') === 'ui-e-maso') { ?>
103 <?php
104 // Get secondary image if available
105 $sec_img = $this->get_product_secondary_image( $product );
106 $classes = $sec_img ? 'ui-e-post-img ui-e-hover-hide' : 'ui-e-post-img';
107
108 // Print secondary image markup if exists
109 echo $sec_img ? wp_kses_post($sec_img) : '';
110
111 // Print main product image
112 echo wp_get_attachment_image($pic_id, $size, false, ['class' => $classes]);
113 ?>
114 <?php } else { ?>
115 <?php
116 // Get secondary image with size
117 $sec_img = $this->get_product_secondary_image( $product, $size, true );
118 echo $sec_img ? wp_kses_post($sec_img) : '';
119 ?>
120 <div class="ui-e-post-img <?php echo $sec_img ? 'ui-e-hover-hide' : ''; ?>"
121 style="background-image:url(<?php echo esc_url( wp_get_attachment_image_url($pic_id, $size)); ?>)">
122 </div>
123 <?php } ?>
124 </a>
125 <?php
126 }
127 function get_product_secondary_image($product, $size = 'woocommerce_thumbnail', $bg_output = false)
128 {
129 // Requested only for products with change-image animation
130 if( 'ui-e-img-anim-change' !== $this->get_settings_for_display('anim_image') ) {
131 return false;
132 }
133
134 // Get product gallery image IDs
135 $gallery_image_ids = $product->get_gallery_image_ids();
136
137 // Check if there is at least one gallery image
138 if (empty($gallery_image_ids)) {
139 return false;
140 }
141
142 // Get the first image from the gallery
143 $secondary_image_id = $gallery_image_ids[0];
144 $secondary_image_url = wp_get_attachment_image_url($secondary_image_id, $size);
145
146 // Output secondary image as <img> or background <div>
147 if ($bg_output) {
148 return sprintf(
149 '<div class="ui-e-post-img ui-e-post-img-secondary" style="background-image: url(%s);"></div>',
150 esc_url($secondary_image_url)
151 );
152 } else {
153 return wp_get_attachment_image($secondary_image_id, $size, false, [
154 'class' => 'ui-e-post-img ui-e-post-img-secondary'
155 ]);
156 }
157 }
158 function get_product_title($product)
159 {
160 if ($this->get_settings_for_display('title') !== 'yes') {
161 return;
162 }
163
164 ?>
165 <a href="<?php echo esc_url($product->get_permalink()); ?>"
166 title="<?php echo esc_attr__('View Product:', 'uicore-elements') . ' ' . esc_html($product->get_name()); ?>">
167 <h4 class="ui-e-post-title"><span><?php echo esc_html($product->get_name()); ?></span></h4>
168 </a>
169 <?php
170 }
171
172 function get_product_summary($product, $length = 55)
173 {
174 if ( ! $this->get_settings_for_display('excerpt') ) {
175 return;
176 }
177
178 $summary = $product->get_short_description();
179
180 // Get product description if no summary
181 if( empty($summary) ) {
182 $summary = $product->get_description();
183 }
184
185 // returns if no description also
186 if( empty($summary) ) {
187 return;
188 }
189
190 ?>
191 <div class="ui-e-post-text">
192 <?php echo wp_kses_post(wp_trim_words($summary, $length)); ?>
193 </div>
194 <?php
195 }
196
197 /**
198 * Renders a product item with various settings and options.
199 * Important: any changes here should also be considered to `TRAIT_render_item()` from Post Component.
200 *
201 * @param WC_Product $product The product object.
202 * @param bool $carousel Indicates if the item needs carousel classnames.
203 * @param bool $legacy Indicates if the item is using legacy classnames.
204 * @param bool $is_ajax Indicates if the item is being rendered through REST API.
205 *
206 * @return void
207 */
208 function TRAIT_render_product($product, $carousel = false, $legacy = false, $is_ajax = false)
209 {
210 $settings = $this->get_settings_for_display();
211
212 // Classnames but checking if we the widget is APG (legacy version)
213 $item_classes = $legacy ? ['ui-e-post-item', 'ui-e-item'] : ['ui-e-item'] ; // Single item lower wrap class receptor
214 $hover_item_class = $legacy ? 'anim_item' : 'item_hover_animation'; // item hover animation class
215
216 // If widget is not carousel type, we set animations classes directly on item selector
217 if(!$carousel) {
218 $item_classes[] = 'ui-e-animations-wrp';
219 $item_classes[] = $settings['animate_items'] === 'ui-e-grid-animate' ? 'elementor-invisible' : '';
220 $item_classes[] = $settings[$hover_item_class] !== '' ? $settings[$hover_item_class] : '';
221
222 } else {
223 // Get entrance and item hover animation classes
224 $entrance = (isset($settings['animate_items']) && $settings['animate_items'] == 'ui-e-grid-animate') ? 'elementor-invisible' : '';
225 $hover = isset($settings[$hover_item_class]) ? $settings[$hover_item_class] : ''; //$settings[$hover_item_class] : null;
226 $animations = sprintf('%s %s', $entrance, $hover);
227
228 // Check if entrance or hover animation are set
229 $has_animation = !empty($entrance) || !empty($hover)
230
231 // Prints extra wrappers required by the carousel script
232 ?>
233 <div class="ui-e-wrp swiper-slide">
234 <?php if($has_animation) : ?>
235 <div class="ui-e-animations-wrp <?php echo esc_attr($animations);?>">
236 <?php endif; ?>
237
238 <?php } ?>
239
240 <div class="<?php echo esc_attr( implode(' ', $item_classes));?>">
241 <article <?php post_class('product'); ?>>
242 <div class="ui-e-post-top">
243 <?php $this->get_product_image($product); ?>
244 <?php $this->get_post_meta('top'); ?>
245 <?php
246 if($settings['button_position'] === 'ui-e-button-placement-image') {
247 $this->TRAIT_get_button(true);
248 }
249 ?>
250 </div>
251 <div class="ui-e-post-content">
252 <?php $this->get_post_meta('before_title'); ?>
253 <?php
254 if ($this->get_settings_for_display('title') === 'yes')
255 $this->get_product_title($product);
256 ?>
257 <?php $this->get_post_meta('after_title'); ?>
258 <?php $this->get_product_summary($product, $settings['excerpt_trim']); ?>
259 <?php $this->get_post_meta('bottom'); // button
260 ?>
261 <?php
262 if( defined('UICORE_VERSION') && version_compare(UICORE_VERSION, '6.0.1', '>=') && $this->get_settings_for_display('show_swatches') === 'yes' ){
263 // ajax requests works under minimal conditions, wich means Swatches class is not present
264 if ( $is_ajax ) {
265 require_once UICORE_INCLUDES . '/woocommerce/components/class-swatches.php';
266 }
267
268 \UiCore\WooCommerce\Swatches::print_swatches($product); // from Uicore Framework
269 }
270 if ( $this->get_settings_for_display('show_button') === 'yes' ) {
271 // Add match height spacing element if carousel. May look intrusive, but is the simplest method compared
272 // to absolute positioning or catching last content element to apply margin.
273 if($carousel && $settings['match_height'] === 'yes'){
274 ?>
275 <span class="ui-e-match-height"></span>
276 <?php
277 }
278
279 if( !isset($settings['button_position']) || empty($settings['button_position']) ) {
280 $this->TRAIT_get_button(true);
281 }
282 }
283 ?>
284 </div>
285 </article>
286 </div>
287
288 <?php if($carousel) { ?>
289 </div>
290 <?php if($has_animation) : ?>
291 </div>
292 <?php endif; ?>
293
294 <?php }
295 }
296
297 // keep it to avoid fatal error
298 public function content_template() {}
299 }
300