PluginProbe ʕ •ᴥ•ʔ
ShopPress – Shop Builder for Elementor and WooCommerce / trunk
ShopPress – Shop Builder for Elementor and WooCommerce vtrunk
shop-press / includes / functions / functions-general.php
shop-press / includes / functions Last commit date
functions-general.php 1 month ago
functions-general.php
716 lines
1 <?php
2
3 defined( 'ABSPATH' ) || exit;
4
5 use ShopPress\Settings;
6 use ShopPress\Templates;
7 use ShopPress\Modules;
8
9 /**
10 * Check if ShopPress Pro is active.
11 *
12 * @since 1.2.0
13 *
14 * @return bool
15 */
16 function is_active_shoppress_pro() {
17
18 if ( ! function_exists( 'is_plugin_active' ) ) {
19
20 include_once ABSPATH . 'wp-admin/includes/plugin.php';
21 }
22
23 return function_exists( 'shoppress_pro' ) || is_plugin_active( 'shop-press-pro/shop-press-pro.php' );
24 }
25
26 /**
27 * Retrieves the component settings for a specific component.
28 *
29 * @since 1.2.0
30 *
31 * @param string $template_id
32 * @param string $setting_key
33 * @param mixed $default
34 *
35 * @return mixed The value of the component setting.
36 */
37 function sp_get_template_settings( $template_id, $setting_key = null, $default = '' ) {
38 return Settings::get_template_settings( $template_id, $setting_key, $default );
39 }
40
41 /**
42 * Retrieves the module settings for a specific module.
43 *
44 * @since 1.2.0
45 *
46 * @param string $module_id
47 * @param string $setting_key
48 * @param mixed $default
49 *
50 * @return mixed The value of the module setting.
51 */
52 function sp_get_module_settings( $module_id, $setting_key = null, $default = '' ) {
53 return Settings::get_module_settings( $module_id, $setting_key, $default );
54 }
55
56 /**
57 * Checks if a component is active.
58 *
59 * @since 1.2.0
60 *
61 * @param string $template_id
62 *
63 * @return bool
64 */
65 function sp_is_template_active( $template_id ) {
66 return Settings::is_template_active( $template_id );
67 }
68
69 /**
70 * Renders the product collection loop.
71 *
72 * @since 1.4.0
73 *
74 * @param string $loop_name
75 * @param array $attrs
76 */
77 function sp_render_product_collection( $loop_name, $attrs = array() ) {
78 $content = (
79 new Templates\ProductCollection( $loop_name, $attrs )
80 )->render();
81
82 return $content;
83 }
84
85 /**
86 * Renders the shop products.
87 *
88 * @since 1.4.0
89 *
90 * @param array $attrs
91 */
92 function sp_render_shop_products( $attrs = array() ) {
93 $content = (
94 new Templates\ProductShop( $attrs )
95 )->render();
96
97 return $content;
98 }
99
100 /**
101 * Get sp_builder_type meta from post.
102 *
103 * @since 1.4.0
104 *
105 * @param int|string $builder_id
106 *
107 * @return string
108 */
109 function sp_get_builder_type( $builder_id ) {
110 return Templates\Utils::get_builder_type( $builder_id );
111 }
112
113 /**
114 * Renders the dynamic icon.
115 *
116 * @since 1.4.0
117 *
118 * @param string $icon
119 * @param array $attrs
120 */
121 function sp_render_icon( $icon, $attrs = array() ) {
122 return Templates\Utils::render_icon( $icon, $attrs );
123 }
124
125 /**
126 * Renders add to cart button.
127 *
128 * @since 1.4.0
129 */
130 function sp_add_to_cart_button( $product, $icon = '', $icon_position = 'after', $show_text = true, $custom_text = '' ) {
131 return Templates\Utils::AddToCartButton( $product, $icon, $icon_position, $show_text, $custom_text );
132 }
133
134 /**
135 * Renders add to cart link.
136 *
137 * @since 1.4.3
138 */
139 function sp_add_to_cart_link( $product, $icon = '', $icon_position = 'after', $show_text = true, $custom_text = '' ) {
140 return Templates\Utils::AddToCartLink( $product, $icon, $icon_position, $show_text, $custom_text );
141 }
142
143 /**
144 * Returns the template custom type.
145 *
146 * @since 1.4.0
147 *
148 * @param int $post_id
149 *
150 * @return string
151 */
152 function sp_get_template_type( $post_id ) {
153 return get_post_meta( $post_id, 'custom_type', true );
154 }
155
156 /**
157 * Checks if a module is active.
158 *
159 * @since 1.2.0
160 *
161 * @param string $module_id
162 *
163 * @return bool
164 */
165 function sp_is_module_active( $module_id ) {
166 return Settings::is_module_active( $module_id );
167 }
168
169 /**
170 * Returns the URL path of the current page.
171 *
172 * @since 1.2.0
173 *
174 * @return string
175 */
176 function sp_get_url_path() {
177 return trim( wp_parse_url( add_query_arg( array() ), PHP_URL_PATH ), '/' );
178 }
179
180 /**
181 * Returns the last segment of a URL.
182 *
183 * @since 1.2.0
184 *
185 * @return string
186 */
187 function sp_get_url_last_segment() {
188 return basename( sp_get_url_path() );
189 }
190
191 /**
192 * Checks if the current page is a wishlist page.
193 *
194 * @since 1.2.0
195 *
196 * @return bool
197 */
198 function is_sp_wishlist_page() {
199 return Modules\Wishlist\Main::is_wishlist_page();
200 }
201
202 /**
203 * Checks if the current page is a compare page.
204 *
205 * @since 1.2.0
206 *
207 * @return bool
208 */
209 function is_sp_compare_page() {
210 return Modules\Compare::is_compare_page();
211 }
212
213 /**
214 * Checks if the current request is an AJAX request for the quick view feature.
215 *
216 * @since 1.2.0
217 *
218 * @return bool
219 */
220 function is_sp_quick_view_ajax() {
221 return Modules\QuickView::is_quick_view_ajax();
222 }
223
224 /**
225 * Returns an array of the allowd SVG tags.
226 *
227 * @since 1.2.0
228 *
229 * @return array
230 */
231 function sp_allowd_svg_tags() {
232 $allowed_tags = array(
233 'svg' => array(
234 'version' => true,
235 'xmlns' => true,
236 'width' => true,
237 'height' => true,
238 'viewbox' => true,
239 'fill' => true,
240 'stroke' => true,
241 ),
242 'path' => array(
243 'fill' => true,
244 'd' => true,
245 'data-name' => true,
246 'transform' => true,
247 'fill-rule' => true,
248 'stroke' => true,
249 'stroke-linecap' => true,
250 'stroke-linejoin' => true,
251 'stroke-width' => true,
252 'stroke-miterlimit' => true,
253 ),
254 'rect' => array(
255 'height' => true,
256 'width' => true,
257 'data-name' => true,
258 'fill' => true,
259 'id' => true,
260 'stroke' => true,
261 'stroke-width' => true,
262 'stroke-linecap' => true,
263 'stroke-linejoin' => true,
264 'stroke-miterlimit' => true,
265 'transform' => true,
266 ),
267 'clipPath' => array(
268 'id' => true,
269 ),
270 'g' => array(
271 'clip-path' => true,
272 'data-name' => true,
273 'id' => true,
274 'transform' => true,
275 'fill' => true,
276 'stroke-width' => true,
277 ),
278 'defs' => array(),
279 'img' => array(
280 'src' => true,
281 ),
282 'i' => array(
283 'class' => true,
284 ),
285 'time' => array(
286 'class' => true,
287 'datetime' => true,
288 ),
289 );
290
291 return apply_filters( 'sp_allowd_svg_tags', $allowed_tags );
292 }
293
294 /**
295 * Return template path
296 *
297 * @param string $template
298 * @param bool $is_pro
299 *
300 * @since 1.2.0
301 *
302 * @return string
303 */
304 function sp_get_template_path( $template, $is_pro = false ) {
305
306 $filename = SHOPPRESS_PATH . 'public/templates/' . $template . '.php';
307 if ( $is_pro && defined( 'SHOPPRESS_PRO_PATH' ) ) {
308 $filename = SHOPPRESS_PRO_PATH . 'public/templates/' . $template . '.php';
309 }
310
311 /**
312 * Filters the path of the template.
313 *
314 * @since 1.2.5
315 *
316 * @param string $filename
317 * @param string $template
318 * @param bool $is_pro
319 */
320 return apply_filters( 'shoppress/get_template_path', $filename, $template, $is_pro );
321 }
322
323 /**
324 * Render the given icon pack.
325 *
326 * @since 1.2.0
327 *
328 * @param string $name
329 *
330 * @return void
331 */
332 function sp_render_icon_pack( $name ) {
333
334 $parts = explode( '-', $name );
335 $pack = $parts[0];
336
337 $icons_path = SHOPPRESS_PATH . 'public/dist/icons-pack/' . $pack . '/' . $name . '.svg';
338
339 if ( file_exists( $icons_path ) ) {
340
341 $svg = file_get_contents( $icons_path );
342
343 return $svg;
344 }
345 }
346
347 /**
348 * Render builder content.
349 *
350 * @since 1.2.5
351 *
352 * @param int $builder_id
353 */
354 function sp_get_builder_content( $builder_id ) {
355 return Templates\Render::get_builder_content( $builder_id );
356 }
357
358 /**
359 * Load the builder template.
360 *
361 * @since 1.2.5
362 *
363 * @param string $template_file
364 * @param array $args
365 * @param bool $is_pro
366 *
367 * @return void
368 */
369 function sp_load_builder_template( $template_file, $args = array(), $is_pro = false ) {
370 return Templates\Render::load_builder_template( $template_file, $args, $is_pro );
371 }
372
373 /**
374 * Retrieves the content of an SVG icon file.
375 *
376 * @since 1.2.6
377 *
378 * @param string $name The name of the icon file.
379 *
380 * @return string
381 */
382 function sp_get_svg_icon( $name ) {
383 $icons_folder = SHOPPRESS_PATH . 'public/images/icons/';
384
385 /**
386 * Filters the svg folder url.
387 *
388 * @since 1.2.6
389 *
390 * @param string $icons_folder
391 */
392 $icons_url = apply_filters( 'shoppress/svg_icons_folder_url', $icons_folder );
393
394 $svg_url = $icons_url . $name . '.svg';
395
396 /**
397 * Filters the svg file.
398 *
399 * @since 1.2.6
400 *
401 * @param string $svg_url
402 * @param string $name
403 */
404 $svg = apply_filters( 'shoppress/icons/svg_content', $svg_url, $name );
405
406 return file_exists( $svg ) ? file_get_contents( $svg ) : '';
407 }
408
409 /**
410 * Product navigation render html
411 *
412 * @param int $post_id
413 * @param string $product_hover_details
414 *
415 * @since 1.2.6
416 *
417 * @return string
418 */
419 function sp_navigation_render_html( $post_id = null, $product_hover_details = 'none' ) {
420
421 $output = '';
422 if ( ! $post_id || $product_hover_details == 'none' ) {
423 return $output;
424 }
425
426 // Product Details
427 $product = wc_get_product( $post_id );
428
429 // Wrapper Width
430 switch ( $product_hover_details ) {
431 case 'thumb':
432 $wrapper_width = 'width: 62px;';
433 break;
434 case 'title-thumb':
435 $wrapper_width = 'width: 172px;';
436 break;
437 case 'title-thumb-price':
438 $wrapper_width = 'width: 172px;';
439 break;
440 default:
441 $wrapper_width = '';
442 }
443
444 // Thumbnail URL
445 if ( get_the_post_thumbnail_url( $post_id ) ) {
446 $thumbnail_url = get_the_post_thumbnail_url( $post_id, 'full' );
447 } else {
448 $thumbnail_url = '';
449 }
450
451 $output .= '<div class="sp-navigation-details" style=" opacity: 0;visibility: hidden;' . $wrapper_width . '">';
452
453 // Title
454 if ( $product_hover_details == 'title' ) {
455 $output .= '<span class="sp-nav-det-title">' . get_the_title( $post_id ) . '</span>';
456 }
457
458 // Thumbnail
459 if ( $product_hover_details == 'thumb' ) {
460 $output .= '<img style="width: 100px;" src="' . esc_url( $thumbnail_url ) . '" alt="' . esc_attr( get_the_title( $post_id ) ) . '"/>';
461 }
462
463 // Title + Thumbnail
464 if ( $product_hover_details == 'tthumb' ) {
465 $output .= '<div class="sp-navigation-tthumb"><img src="' . esc_url( $thumbnail_url ) . '" alt="' . esc_attr( get_the_title( $post_id ) ) . '"/><span class="sp-nav-det-title">' . get_the_title( $post_id ) . '</span></div>';
466 }
467
468 // Title + Price
469 if ( $product_hover_details == 'tprice' ) {
470 $output .= '<div class="sp-navigation-tprice"><span class="sp-nav-det-title">' . get_the_title( $post_id ) . '</span><span>' . $product->get_price_html() . '</span></div>';
471 }
472
473 // Title + Thumbnail + Price
474 if ( $product_hover_details == 'tthumbprice' ) {
475 $output .= '<div class="sp-navigation-tthumbprice"><img src="' . esc_url( $thumbnail_url ) . '" alt="' . esc_attr( get_the_title( $post_id ) ) . '"/><div><span class="sp-nav-det-title">' . get_the_title( $post_id ) . '</span><span>' . $product->get_price_html() . '</span></div></div>';
476 }
477
478 $output .= '</div>';
479
480 return $output;
481 }
482
483 /**
484 * Return product discount string
485 *
486 * @param \WC_Product $product
487 *
488 * @since 1.3.1
489 *
490 * @return string
491 */
492 function sp_get_product_discount( $product ) {
493
494 $percentage = '';
495 $product = is_numeric( $product ) ? wc_get_product( $product ) : $product;
496 if ( ! is_a( $product, '\WC_Product' ) ) {
497 return $percentage;
498 }
499
500 if ( $product->is_type( 'variable' ) ) {
501 $percentages = array();
502
503 $prices = $product->get_variation_prices();
504
505 foreach ( $prices['price'] as $key => $price ) {
506 if ( $prices['regular_price'][ $key ] !== $price ) {
507 $percentages[] = round( 100 - ( floatval( $prices['sale_price'][ $key ] ) / floatval( $prices['regular_price'][ $key ] ) * 100 ) );
508 }
509 }
510
511 $percentage = count( $percentages ) ? max( $percentages ) . '%' : '';
512 } elseif ( $product->is_type( 'grouped' ) ) {
513 $percentages = array();
514
515 $children_ids = $product->get_children();
516 foreach ( $children_ids as $child_id ) {
517 $child_product = wc_get_product( $child_id );
518
519 $regular_price = (float) $child_product->get_regular_price();
520 $sale_price = (float) $child_product->get_sale_price();
521
522 if ( $sale_price != 0 || ! empty( $sale_price ) ) {
523 $percentages[] = round( 100 - ( $sale_price / $regular_price * 100 ) );
524 }
525 }
526 $percentage = count( $percentages ) ? max( $percentages ) . '%' : '';
527 } else {
528 $regular_price = (float) $product->get_regular_price();
529 $sale_price = (float) $product->get_sale_price();
530
531 if ( $sale_price != 0 || ! empty( $sale_price ) ) {
532 $percentage = round( 100 - ( $sale_price / $regular_price * 100 ) ) . '%';
533 }
534 }
535
536 return $percentage;
537 }
538
539 /**
540 * Kses icon
541 *
542 * @param string $icon
543 *
544 * @since 1.3.1
545 *
546 * @return string
547 */
548 function sp_kses_icon( $icon ) {
549 return sp_kses_post( $icon );
550 }
551
552 /**
553 * Kses post
554 *
555 * @param string $html
556 *
557 * @since 1.3.1
558 *
559 * @return string
560 */
561 function sp_kses_post( $html ) {
562 $allowed_tags = array_merge(
563 wp_kses_allowed_html( 'post' ),
564 sp_allowd_svg_tags()
565 );
566
567 return wp_kses( $html, $allowed_tags );
568 }
569
570 /**
571 * Generate random string
572 *
573 * @param integer $length
574 *
575 * @since 1.3.3
576 *
577 * @return string
578 */
579 function sp_generate_random_string( $length = 10 ) {
580 $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
581 $charactersLength = strlen( $characters );
582 $randomString = '';
583 for ( $i = 0; $i < $length; $i++ ) {
584 $randomString .= $characters[ wp_rand( 0, $charactersLength - 1 ) ];
585 }
586
587 return $randomString;
588 }
589
590 /**
591 * Returns image url.
592 *
593 * @param object $image
594 *
595 * @since 1.3.4
596 *
597 * @return string
598 */
599 function sp_get_image_url( $image ) {
600 $image = sp_get_image_data( $image );
601 $image_url = isset( $image['id'] ) ? wp_get_attachment_url( $image['id'] ) : '';
602
603 return $image_url;
604 }
605
606 /**
607 * Returns image url.
608 *
609 * @param object $image
610 *
611 * @since 1.3.4
612 *
613 * @return object
614 */
615 function sp_get_image_data( $image ) {
616
617 if ( is_array( $image ) ) {
618 return $image;
619 }
620
621 $json_image = json_decode( $image ?? '', true );
622
623 if ( $json_image !== null ) {
624 $image = $json_image;
625 }
626
627 return $image;
628 }
629
630 /**
631 * Returns social share links.
632 *
633 * @since 1.3.7
634 *
635 * @return array
636 */
637 function sp_get_social_share_links() {
638
639 $url = '{url}';
640 $text = '{text}';
641
642 $share_url_patterns = array(
643 'x' => array(
644 'title' => __( 'X', 'shop-press' ),
645 'social' => 'x',
646 'url' => 'https://twitter.com/intent/tweet?url=' . $url . '&text=' . $text,
647 'icon' => sp_get_svg_icon( 'wishlist_share_twitter' ),
648 ),
649 'facebook' => array(
650 'title' => __( 'Facebook', 'shop-press' ),
651 'social' => 'facebook',
652 'url' => 'http://www.facebook.com/sharer.php?u=' . $url,
653 'icon' => sp_get_svg_icon( 'wishlist_share_facebook' ),
654 ),
655 'email' => array(
656 'title' => __( 'Email', 'shop-press' ),
657 'social' => 'email',
658 'url' => 'mailto:""?subject=""',
659 'icon' => sp_get_svg_icon( 'wishlist_share_email' ),
660 ),
661 'linkedin' => array(
662 'title' => __( 'linkedin', 'shop-press' ),
663 'social' => 'linkedin',
664 'url' => 'https://www.linkedin.com/sharing/share-offsite/?url=' . $url,
665 'icon' => sp_get_svg_icon( 'wishlist_share_linkedin' ),
666 ),
667 'reddit' => array(
668 'title' => __( 'Reddit', 'shop-press' ),
669 'social' => 'reddit',
670 'url' => 'https://reddit.com/submit?url=' . $url . '&title=' . $text,
671 'icon' => sp_get_svg_icon( 'wishlist_share_reddit' ),
672 ),
673 'pinterest' => array(
674 'title' => __( 'Pinterest', 'shop-press' ),
675 'social' => 'pinterest',
676 'url' => 'http://pinterest.com/pin/create/button/?url=' . $url,
677 'icon' => sp_get_svg_icon( 'wishlist_share_pinterest' ),
678 ),
679 'tumblr' => array(
680 'title' => __( 'Tumblr', 'shop-press' ),
681 'social' => 'tumblr',
682 'url' => 'https://www.tumblr.com/widgets/share/tool?canonicalUrl=' . $url . '&title=' . $text,
683 'icon' => sp_get_svg_icon( 'wishlist_share_tumblr' ),
684 ),
685 'whatsapp' => array(
686 'title' => __( 'WhatsApp', 'shop-press' ),
687 'social' => 'whatsapp',
688 'url' => 'https://api.whatsapp.com/send?text=' . $text . ' ' . $url,
689 'icon' => sp_get_svg_icon( 'wishlist_share_whatsapp' ),
690 ),
691 );
692
693 return $share_url_patterns;
694 }
695
696 /**
697 * Checks for elementor editor.
698 *
699 * @since 1.4.3
700 *
701 * @return bool
702 */
703 function sp_is_elementor_editor() {
704 return did_action( 'elementor/loaded' ) && \Elementor\Plugin::$instance->editor->is_edit_mode();
705 }
706
707
708 /**
709 * Whitelist HTML tags..
710 *
711 * @since 1.4.11
712 */
713 function sp_whitelist_html_tags( $tag, $default ) {
714 return Templates\Utils::whitelist_html_tags( $tag, $default );
715 }
716