PluginProbe
ShopBuilder – WooCommerce Builder For Elementor / 3.2.6
ShopBuilder – WooCommerce Builder For Elementor v3.2.6
3.4.2 3.4.1 3.4.0 2.0.1 2.0.2 2.0.3 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.13 2.1.14 2.1.15 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 All 63 releases
← All changes | app/Controllers/Hooks/ActionHooks.php +221 -9 2.2.23.2.6 View file →
@@ -7,12 +7,14 @@
7 7
8 8 namespace RadiusTheme\SB\Controllers\Hooks;
9 9
10 10 use RadiusTheme\SB\Helpers\Fns;
11 +use RadiusTheme\SB\Helpers\Cache;
11 12 use RadiusTheme\SB\Models\GeneralList;
12 13 use RadiusTheme\SB\Helpers\BuilderFns;
13 14 use RadiusTheme\SB\Models\TemplateSettings;
14 15 use RadiusTheme\SB\Elementor\Render\Render;
16 +use RadiusTheme\SB\Elementor\Helper\RenderHelpers;
15 17
16 18 defined( 'ABSPATH' ) || exit();
17 19
18 20 /**
@@ -24,8 +26,9 @@
24 26 *
25 27 * @return void
26 28 */
27 29 public static function init_hooks() {
30 + add_action( 'rtsb/before/save/options', [ __CLASS__, 'clear_cron_schedule' ], 10, 3 );
28 31 add_action( 'wp_head', [ __CLASS__, 'og_metatags_for_sharing' ], 1 );
29 32 add_action( 'woocommerce_share', [ __CLASS__, 'shopbuilder_share' ], 20 );
30 33 add_action( 'rtsb/wcqv/product/summary', [ __CLASS__, 'shopbuilder_share' ], 40 );
31 34 add_action( 'rtsb/shop/product/image', [ __CLASS__, 'render_image' ], 10, 2 );
@@ -60,9 +63,8 @@
60 63
61 64 /**
62 65 * Notices.
63 66 */
64 - // add_action( 'woocommerce_cart_is_empty', [ Fns::class, 'woocommerce_output_all_notices' ], 5 );
65 67 add_action( 'woocommerce_shortcode_before_product_cat_loop', [ Fns::class, 'woocommerce_output_all_notices' ], 10 );
66 68 add_action( 'woocommerce_before_shop_loop', [ Fns::class, 'woocommerce_output_all_notices' ], 10 );
67 69 add_action( 'woocommerce_before_single_product', [ Fns::class, 'woocommerce_output_all_notices' ], 10 );
68 70 add_action( 'woocommerce_before_cart', [ Fns::class, 'woocommerce_output_all_notices' ], 10 );
@@ -81,11 +83,58 @@
81 83 add_action( 'woocommerce_before_checkout_form', [ __CLASS__, 'woocommerce_checkout_coupon_form' ], 10 );
82 84 // My Account Order Page.
83 85 add_action( 'woocommerce_before_account_orders', [ __CLASS__, 'before_account_orders' ], 10 );
84 86 add_action( 'woocommerce_after_account_orders', [ __CLASS__, 'after_account_orders' ], 10 );
87 +
88 + // Product Filter Widget Hooks.
89 + add_action( 'rtsb/before/archive/default/filter/items', [ __CLASS__,'default_filter_header' ], 10 );
90 + add_action( 'rtsb/before/archive/default/filter/items', [ __CLASS__,'default_filter_search' ], 15 );
91 +
92 + // WC Query modifier. Always registered so the free `rtsb-product-filters`
93 + // widget's URL params (product_cat, product_tag, product_brand, rating_filter,
94 + // sale_filter) are applied to the main WooCommerce product query regardless
95 + // of whether the Pro add-on is active.
96 + add_action( 'woocommerce_product_query', [ __CLASS__, 'query_modifier' ], 15 );
97 +
98 + add_action( 'switch_theme', [ __CLASS__, 'clear_cache' ] );
85 99 }
100 + /**
101 + * Clear scheduled cron events when a module is deactivated.
102 + *
103 + * Checks the given block ID against predefined schedules and clears
104 + * related cron hooks if the corresponding module is turned off.
105 + *
106 + * @param string $section_id Section identifier (not used in this function).
107 + * @param string $block_id Module/block identifier to check scheduled hooks.
108 + * @param array $rawOptions Module options array containing 'active' status.
109 + *
110 + * @return void
111 + */
112 + public static function clear_cron_schedule( $section_id, $block_id, $rawOptions ) {
113 + $schedule = [
114 + 'abandoned_cart_recovery' => [
115 + 'rtsb_abandoned_cart_recovery_action',
116 + 'rtsb_send_abandoned_cart_emails',
117 + ],
118 + 'currency_switcher' => [
119 + 'update_exchange_rates_hourly',
120 + ],
121 + ];
122 + if ( ! isset( $schedule[ $block_id ] ) ) {
123 + return;
124 + }
125 + if ( ! isset( $rawOptions['active'] ) ) {
126 + return;
127 + }
128 + if ( 'on' === $rawOptions['active'] ) {
129 + return;
130 + }
131 + // CLear All Custom Schedule If module disabled.
132 + foreach ( $schedule[ $block_id ] as $hook ) {
133 + wp_clear_scheduled_hook( $hook );
134 + }
135 + }
86 136
87 -
88 137 /**
89 138 * @param boolen $has_orders Order exist or not.
90 139 *
91 140 * @return void
@@ -112,9 +161,9 @@
112 161 * @return void
113 162 */
114 163 public static function woocommerce_checkout_coupon_form() {
115 164 echo '<div class="rtsb-notice">';
116 - woocommerce_checkout_coupon_form();
165 + woocommerce_checkout_coupon_form();
117 166 echo '</div>';
118 167 }
119 168
120 169 /**
@@ -134,9 +183,8 @@
134 183 wc_empty_cart_message();
135 184 echo '</div>';
136 185 }
137 186
138 -
139 187 /**
140 188 * @param int $post_id Post Ids.
141 189 * @param object $post Post Object.
142 190 *
@@ -232,9 +280,11 @@
232 280 $settings['share_platforms'] = $share_platforms;
233 281 $settings['layout'] = ! empty( $generalList['social_share']['share_icon_layout'] ) ? $generalList['social_share']['share_icon_layout'] : 1;
234 282 $settings['show_share_icon'] = 1;
235 283
236 - // TODO:: Implement Later ! empty( $generalList['social_share']['share_icon_show_to_product_page'] ) && 'on' === $generalList['social_share']['share_icon_show_to_product_page'];
284 + /**
285 + * Implement Later ! empty( $generalList['social_share']['share_icon_show_to_product_page'] ) && 'on' === $generalList['social_share']['share_icon_show_to_product_page'];
286 + */
237 287 Fns::print_html( Render::instance()->social_share_view( 'elementor/general/social-share', $settings ), true );
238 288 }
239 289
240 290 /**
@@ -271,13 +321,12 @@
271 321 /**
272 322 * Render image.
273 323 *
274 324 * @param array $args Image args.
275 - * @param array $settings Settings array.
276 325 *
277 326 * @return void
278 327 */
279 - public static function render_image( $args, $settings ) {
328 + public static function render_image( $args ) {
280 329 if ( $args['image_link'] ) {
281 330 $aria_label = esc_attr(
282 331 /* translators: Product Name */
283 332 sprintf( __( 'Image link for Product: %s', 'shopbuilder' ), $args['title'] )
@@ -307,10 +356,14 @@
307 356 */
308 357 public static function modify_wc_query_args( $settings ) {
309 358 if ( ( isset( $settings['tax_relation'] ) && 'OR' === $settings['tax_relation'] ) ||
310 359 ( isset( $settings['relation'] ) && 'OR' === $settings['relation'] ) ) {
311 - add_filter( 'woocommerce_product_data_store_cpt_get_products_query', [ FilterHooks::class, 'extra_query_args' ], 10, 2 );
360 + add_filter( 'woocommerce_product_data_store_cpt_get_products_query', [ FilterHooks::class, 'extra_query_args_or' ], 10, 2 );
312 361 }
362 + if ( ( isset( $settings['tax_relation'] ) && 'AND' === $settings['tax_relation'] ) ||
363 + ( isset( $settings['relation'] ) && 'AND' === $settings['relation'] ) ) {
364 + add_filter( 'woocommerce_product_data_store_cpt_get_products_query', [ FilterHooks::class, 'extra_query_args_and' ], 10, 2 );
365 + }
313 366
314 367 if ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) ) {
315 368 add_filter( 'woocommerce_product_data_store_cpt_get_products_query', [ FilterHooks::class, 'extra_query_args_outofstock' ] );
316 369 }
@@ -325,12 +378,171 @@
325 378 */
326 379 public static function reset_wc_query_args( $settings ) {
327 380 if ( ( isset( $settings['tax_relation'] ) && 'OR' === $settings['tax_relation'] ) ||
328 381 ( isset( $settings['relation'] ) && 'OR' === $settings['relation'] ) ) {
329 - remove_filter( 'woocommerce_product_data_store_cpt_get_products_query', [ FilterHooks::class, 'extra_query_args' ] );
382 + remove_filter( 'woocommerce_product_data_store_cpt_get_products_query', [ FilterHooks::class, 'extra_query_args_or' ] );
330 383 }
384 + if ( ( isset( $settings['tax_relation'] ) && 'AND' === $settings['tax_relation'] ) ||
385 + ( isset( $settings['relation'] ) && 'AND' === $settings['relation'] ) ) {
386 + remove_filter( 'woocommerce_product_data_store_cpt_get_products_query', [ FilterHooks::class, 'extra_query_args_and' ] );
387 + }
331 388
332 389 if ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) ) {
333 390 remove_filter( 'woocommerce_product_data_store_cpt_get_products_query', [ FilterHooks::class, 'extra_query_args_outofstock' ] );
334 391 }
392 + }
393 + /**
394 + * Display a filter header.
395 + *
396 + * @param array $settings The settings.
397 + *
398 + * @return void
399 + */
400 + public static function default_filter_header( $settings ) {
401 + if ( empty( $settings['show_filter_header'] ) && empty( $settings['filter_header_text'] ) ) {
402 + return;
403 + }
404 +
405 + $wrapper_class = 'rtsb-default-filter-header ';
406 +
407 + ?>
408 +
409 + <div class="<?php echo esc_attr( $wrapper_class ); ?>">
410 + <h3><?php echo esc_html( $settings['filter_header_text'] ); ?></h3>
411 + </div>
412 +
413 + <?php
414 + }
415 + /**
416 + * Display a filter search form.
417 + *
418 + * @param array $settings The settings.
419 + *
420 + * @return void
421 + */
422 + public static function default_filter_search( $settings ) {
423 + if ( empty( $settings['search_form'] ) ) {
424 + return;
425 + }
426 +
427 + $title = [
428 + 'title' => ! empty( $settings['search_title'] ) ? $settings['search_title'] : '',
429 + 'show_icon' => ! empty( $settings['show_search_title_icon'] ),
430 + 'icon' => ! empty( $settings['filter_search_title_icon'] ) ? $settings['filter_search_title_icon'] : [],
431 + ];
432 + $placeholder = ! empty( $settings['search_placeholder'] ) ? $settings['search_placeholder'] : '';
433 + $btn_icon = ! empty( $settings['search_title_icon'] ) ? $settings['search_title_icon'] : [];
434 + $wrapper_class = 'rtsb-default-filter-search rtsb-default-product-search';
435 + $unique_id = substr( uniqid(), -6 );
436 + $search_term = isset( $_REQUEST['s'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['s'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
437 + ?>
438 +
439 + <div class="<?php echo esc_attr( $wrapper_class ); ?>">
440 + <?php
441 + Fns::print_html( RenderHelpers::get_default_filter_title( $title ) );
442 + ?>
443 + <div class="default-search-content">
444 + <div class="woocommerce-product-search<?php echo ! empty( $search_term ) ? ' active' : ''; ?>">
445 + <div class="search-input">
446 + <label class="screen-reader-text" for="rtsb-product-default-search-form-<?php echo esc_attr( $unique_id ); ?>"><?php echo esc_html( $placeholder ); ?></label>
447 + <input type="search" id="rtsb-product-default-search-form-<?php echo esc_attr( $unique_id ); ?>" class="rtsb-default-search-field" placeholder="<?php echo esc_html( $placeholder ); ?>" value="<?php echo esc_attr( $search_term ); ?>" name="s" autocomplete="off">
448 + </div>
449 + <button class="rtsb-search-submit">
450 + <?php
451 +
452 + Fns::print_html( Fns::icons_manager( $btn_icon, 'search-icon' ) );
453 +
454 + ?>
455 + <span></span>
456 + </button>
457 + </div>
458 + </div>
459 + </div>
460 +
461 + <?php
462 + }
463 + /**
464 + * Query modifier.
465 + *
466 + * @param object $query Query.
467 + * @return object
468 + */
469 + public static function query_modifier( $query ) {
470 + // phpcs:disable WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
471 +
472 + // Sale filter.
473 + $onsale_filter = isset( $_GET['sale_filter'] ) ? sanitize_text_field( wp_unslash( $_GET['sale_filter'] ) ) : '';
474 + $on_sale_products = wc_get_product_ids_on_sale();
475 +
476 + if ( 'onsale' === $onsale_filter ) {
477 + $query->set( 'post__in', ! empty( $on_sale_products ) ? $on_sale_products : [ 0 ] );
478 + } elseif ( 'regular' === $onsale_filter ) {
479 + $query->set( 'post__not_in', $on_sale_products );
480 + }
481 +
482 + // Taxonomy filters (product_cat, product_tag, product_brand) from URL.
483 + $tax_query = (array) $query->get( 'tax_query' );
484 +
485 + $taxonomy_map = [
486 + 'product_cat' => 'product_cat',
487 + 'product_tag' => 'product_tag',
488 + 'product_brand' => 'product_brand',
489 + ];
490 +
491 + foreach ( $taxonomy_map as $param => $taxonomy ) {
492 + if ( empty( $_GET[ $param ] ) || ! taxonomy_exists( $taxonomy ) ) {
493 + continue;
494 + }
495 +
496 + $raw_values = wc_clean( wp_unslash( $_GET[ $param ] ) );
497 + $slugs = array_filter( array_map( 'urldecode', explode( ',', $raw_values ) ) );
498 +
499 + if ( empty( $slugs ) ) {
500 + continue;
501 + }
502 +
503 + $tax_query[] = [
504 + 'taxonomy' => $taxonomy,
505 + 'field' => 'slug',
506 + 'terms' => $slugs,
507 + 'operator' => 'IN',
508 + ];
509 + }
510 +
511 + // Rating filter (rating_filter=4,5).
512 + if ( ! empty( $_GET['rating_filter'] ) ) {
513 + $raw_ratings = wc_clean( wp_unslash( $_GET['rating_filter'] ) );
514 + $ratings = array_filter( array_map( 'intval', explode( ',', $raw_ratings ) ) );
515 +
516 + if ( ! empty( $ratings ) ) {
517 + $rating_terms = [];
518 + foreach ( $ratings as $rating ) {
519 + $rating_terms[] = 'rated-' . $rating;
520 + }
521 +
522 + $tax_query[] = [
523 + 'taxonomy' => 'product_visibility',
524 + 'field' => 'name',
525 + 'terms' => $rating_terms,
526 + 'operator' => 'IN',
527 + ];
528 + }
529 + }
530 +
531 + if ( ! empty( $tax_query ) ) {
532 + $query->set( 'tax_query', $tax_query );
533 + }
534 +
535 + // phpcs:enable WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
536 +
537 + return $query;
538 + }
539 +
540 + /**
541 + * Delete cache when switching to another theme.
542 + *
543 + * @return void
544 + */
545 + public static function clear_cache() {
546 + Cache::clear_all_cache();
335 547 }
336 548 }