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
shopbuilder / app / Controllers / Hooks / ActionHooks.php

ActionHooks.php in ShopBuilder – WooCommerce Builder For Elementor 3.2.6, at app/Controllers/Hooks/ActionHooks.php

549 lines 19.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Main ActionHooks class.
4 *
5 * @package RadiusTheme\SB
6 */
7
8 namespace RadiusTheme\SB\Controllers\Hooks;
9
10 use RadiusTheme\SB\Helpers\Fns;
11 use RadiusTheme\SB\Helpers\Cache;
12 use RadiusTheme\SB\Models\GeneralList;
13 use RadiusTheme\SB\Helpers\BuilderFns;
14 use RadiusTheme\SB\Models\TemplateSettings;
15 use RadiusTheme\SB\Elementor\Render\Render;
16 use RadiusTheme\SB\Elementor\Helper\RenderHelpers;
17
18 defined( 'ABSPATH' ) || exit();
19
20 /**
21 * Main ActionHooks class.
22 */
23 class ActionHooks {
24 /**
25 * Init Hooks.
26 *
27 * @return void
28 */
29 public static function init_hooks() {
30 add_action( 'rtsb/before/save/options', [ __CLASS__, 'clear_cron_schedule' ], 10, 3 );
31 add_action( 'wp_head', [ __CLASS__, 'og_metatags_for_sharing' ], 1 );
32 add_action( 'woocommerce_share', [ __CLASS__, 'shopbuilder_share' ], 20 );
33 add_action( 'rtsb/wcqv/product/summary', [ __CLASS__, 'shopbuilder_share' ], 40 );
34 add_action( 'rtsb/shop/product/image', [ __CLASS__, 'render_image' ], 10, 2 );
35
36 add_action(
37 'admin_init',
38 function () {
39 remove_post_type_support( BuilderFns::$post_type_tb, 'revisions' );
40 }
41 );
42 add_action( 'deleted_post', [ __CLASS__, 'deleted_post' ], 10, 2 );
43 add_action( 'rtsb/elements/render/before_query', [ __CLASS__, 'modify_wc_query_args' ] );
44 add_action( 'rtsb/elements/render/after_query', [ __CLASS__, 'reset_wc_query_args' ] );
45 // Cart Table.
46 remove_action( 'woocommerce_cart_is_empty', 'wc_empty_cart_message', 10 );
47 add_action( 'woocommerce_cart_is_empty', [ __CLASS__, 'cart_is_empty' ], 10 );
48 /**
49 * Notices.
50 */
51 remove_action( 'woocommerce_cart_is_empty', 'woocommerce_output_all_notices', 5 );
52 remove_action( 'woocommerce_shortcode_before_product_cat_loop', 'woocommerce_output_all_notices', 10 );
53 remove_action( 'woocommerce_before_shop_loop', 'woocommerce_output_all_notices', 10 );
54 remove_action( 'woocommerce_before_single_product', 'woocommerce_output_all_notices', 10 );
55 remove_action( 'woocommerce_before_cart', 'woocommerce_output_all_notices', 10 );
56 remove_action( 'woocommerce_before_checkout_form_cart_notices', 'woocommerce_output_all_notices', 10 );
57 remove_action( 'woocommerce_before_checkout_form', 'woocommerce_output_all_notices', 10 );
58 remove_action( 'woocommerce_account_content', 'woocommerce_output_all_notices', 5 );
59 remove_action( 'woocommerce_before_customer_login_form', 'woocommerce_output_all_notices', 10 );
60 remove_action( 'woocommerce_before_lost_password_form', 'woocommerce_output_all_notices', 10 );
61 remove_action( 'before_woocommerce_pay', 'woocommerce_output_all_notices', 10 );
62 remove_action( 'woocommerce_before_reset_password_form', 'woocommerce_output_all_notices', 10 );
63
64 /**
65 * Notices.
66 */
67 add_action( 'woocommerce_shortcode_before_product_cat_loop', [ Fns::class, 'woocommerce_output_all_notices' ], 10 );
68 add_action( 'woocommerce_before_shop_loop', [ Fns::class, 'woocommerce_output_all_notices' ], 10 );
69 add_action( 'woocommerce_before_single_product', [ Fns::class, 'woocommerce_output_all_notices' ], 10 );
70 add_action( 'woocommerce_before_cart', [ Fns::class, 'woocommerce_output_all_notices' ], 10 );
71 add_action( 'woocommerce_before_checkout_form_cart_notices', [ Fns::class, 'woocommerce_output_all_notices' ], 10 );
72 add_action( 'woocommerce_before_checkout_form', [ Fns::class, 'woocommerce_output_all_notices' ], 10 );
73 add_action( 'woocommerce_account_content', [ Fns::class, 'woocommerce_output_all_notices' ], 5 );
74 add_action( 'woocommerce_before_customer_login_form', [ Fns::class, 'woocommerce_output_all_notices' ], 10 );
75 add_action( 'woocommerce_before_lost_password_form', [ Fns::class, 'woocommerce_output_all_notices' ], 10 );
76 add_action( 'before_woocommerce_pay', [ Fns::class, 'woocommerce_output_all_notices' ], 10 );
77 add_action( 'woocommerce_before_reset_password_form', [ Fns::class, 'woocommerce_output_all_notices' ], 10 );
78
79 // Checkout Page.
80 remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_login_form', 10 );
81 remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form', 10 );
82 add_action( 'woocommerce_before_checkout_form', [ __CLASS__, 'woocommerce_checkout_login_form' ], 10 );
83 add_action( 'woocommerce_before_checkout_form', [ __CLASS__, 'woocommerce_checkout_coupon_form' ], 10 );
84 // My Account Order Page.
85 add_action( 'woocommerce_before_account_orders', [ __CLASS__, 'before_account_orders' ], 10 );
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' ] );
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 }
136
137 /**
138 * @param boolen $has_orders Order exist or not.
139 *
140 * @return void
141 */
142 public static function after_account_orders( $has_orders ) {
143 if ( ! $has_orders ) {
144 echo '</div>';
145 }
146 }
147
148 /**
149 * @param boolen $has_orders Order exist or not.
150 *
151 * @return void
152 */
153 public static function before_account_orders( $has_orders ) {
154 if ( ! $has_orders ) {
155 echo '<div class="rtsb-notice">';
156 }
157 }
158
159
160 /**
161 * @return void
162 */
163 public static function woocommerce_checkout_coupon_form() {
164 echo '<div class="rtsb-notice">';
165 woocommerce_checkout_coupon_form();
166 echo '</div>';
167 }
168
169 /**
170 * @return void
171 */
172 public static function woocommerce_checkout_login_form() {
173 echo '<div class="rtsb-notice">';
174 woocommerce_checkout_login_form();
175 echo '</div>';
176 }
177
178 /**
179 * @return void
180 */
181 public static function cart_is_empty() {
182 echo '<div class="rtsb-notice">';
183 wc_empty_cart_message();
184 echo '</div>';
185 }
186
187 /**
188 * @param int $post_id Post Ids.
189 * @param object $post Post Object.
190 *
191 * @return void
192 */
193 public static function deleted_post( $post_id, $post ) {
194 if ( BuilderFns::$post_type_tb !== $post->post_type ) {
195 return;
196 }
197
198 $options = BuilderFns::option_name_for_specific_product_set_default( $post_id );
199 TemplateSettings::instance()->delete_option( $options );
200
201 $template_options = BuilderFns::option_name_by_template_id( $post_id );
202 TemplateSettings::instance()->delete_option( $template_options );
203
204 $archive_options = BuilderFns::archive_option_name_by_template_id( $post_id );
205 TemplateSettings::instance()->delete_option( $archive_options );
206
207 $category_options = BuilderFns::option_name_for_specific_category_set_default( $post_id );
208 TemplateSettings::instance()->delete_option( $category_options );
209
210 $selected_category_options = BuilderFns::archive_option_name_by_template_id( $post_id );
211 TemplateSettings::instance()->delete_option( $selected_category_options );
212
213 // Delete Data From Options.
214 $options_product_selected_cat = BuilderFns::option_name_product_page_selected_cat( $post_id );
215 $cat_list = TemplateSettings::instance()->get_option( $options_product_selected_cat );
216 if ( ! empty( $cat_list ) ) {
217 foreach ( $cat_list as $old_slug ) {
218 $OldcatList = get_term_by( 'slug', $old_slug, 'product_cat' );
219 if ( ! empty( $OldcatList ) && ! is_wp_error( $OldcatList ) ) {
220 delete_term_meta( $OldcatList->term_id, BuilderFns::$categories_product_page_template, $post_id );
221 }
222 }
223 }
224 TemplateSettings::instance()->delete_option( $options_product_selected_cat );
225
226 $set_default_option = BuilderFns::option_name_product_page_specific_cat_set_default( $post_id );
227 TemplateSettings::instance()->delete_option( $set_default_option );
228
229 // Tags Remove.
230 $options_product_selected_tag = BuilderFns::option_name_product_page_selected_tag( $post_id );
231 $tag_list = TemplateSettings::instance()->get_option( $options_product_selected_tag );
232 if ( ! empty( $tag_list ) ) {
233 foreach ( $tag_list as $old_slug ) {
234 $OldTagList = get_term_by( 'slug', $old_slug, 'product_tag' );
235 if ( ! empty( $OldTagList ) && ! is_wp_error( $OldTagList ) ) {
236 delete_term_meta( $OldTagList->term_id, BuilderFns::$tags_product_page_template, $post_id );
237 }
238 }
239 }
240 TemplateSettings::instance()->delete_option( $options_product_selected_tag );
241
242 // Tag Set Default Option.
243 $tag_set_default_option = BuilderFns::option_name_product_page_specific_tag_set_default( $post_id );
244 TemplateSettings::instance()->delete_option( $tag_set_default_option );
245
246 global $wpdb;
247 // Prepare and execute the SQL query.
248 $sql = $wpdb->prepare( "DELETE FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %d", BuilderFns::$view_template_for_products_meta, $post_id );
249 $wpdb->query( $sql ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.NoCaching
250
251 // Prepare and execute the SQL query.
252 $sql = $wpdb->prepare( "DELETE FROM $wpdb->termmeta WHERE meta_key = %s AND meta_value = %d", BuilderFns::$view_template_for_archive_meta, $post_id );
253 $wpdb->query( $sql ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.NoCaching
254 }
255 /**
256 * Meta tags for social sharing.
257 *
258 * @return void
259 */
260 public static function shopbuilder_share() {
261 $generalList = GeneralList::instance()->get_data();
262
263 if (
264 empty( $generalList['social_share']['share_platforms_to_product_page'] ) ||
265 'on' !== $generalList['social_share']['share_platforms_to_product_page'] ||
266 empty( $generalList['social_share']['share_platforms'] )
267 ) {
268 return;
269 }
270
271 $share_platforms = [];
272
273 foreach ( $generalList['social_share']['share_platforms'] as $value ) {
274 $share_platforms[ $value ] = [
275 'share_items' => $value,
276 'share_text' => ucwords( $value ),
277 ];
278 }
279
280 $settings['share_platforms'] = $share_platforms;
281 $settings['layout'] = ! empty( $generalList['social_share']['share_icon_layout'] ) ? $generalList['social_share']['share_icon_layout'] : 1;
282 $settings['show_share_icon'] = 1;
283
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 */
287 Fns::print_html( Render::instance()->social_share_view( 'elementor/general/social-share', $settings ), true );
288 }
289
290 /**
291 * Meta tags for social sharing.
292 *
293 * @return void
294 */
295 public static function og_metatags_for_sharing() {
296 global $post;
297
298 if ( ! isset( $post ) ) {
299 return;
300 }
301
302 if ( ! is_singular( 'product' ) ) {
303 return;
304 }
305
306 Fns::print_html( '<meta property="og:url" content="' . get_the_permalink() . '" />', true );
307 Fns::print_html( '<meta property="og:type" content="article" />', true );
308 Fns::print_html( '<meta property="og:title" content="' . $post->post_title . '" />', true );
309 Fns::print_html( '<meta property="og:description" content="' . wp_trim_words( $post->post_content, 150 ) . '" />' );
310
311 $attachment = get_the_post_thumbnail_url();
312
313 if ( ! empty( $attachment ) ) {
314 Fns::print_html( '<meta property="og:image" content="' . $attachment . '" />', true );
315 }
316
317 Fns::print_html( '<meta property="og:site_name" content="' . get_bloginfo( 'name' ) . '" />', true );
318 Fns::print_html( '<meta name="twitter:card" content="summary" />', true );
319 }
320
321 /**
322 * Render image.
323 *
324 * @param array $args Image args.
325 *
326 * @return void
327 */
328 public static function render_image( $args ) {
329 if ( $args['image_link'] ) {
330 $aria_label = esc_attr(
331 /* translators: Product Name */
332 sprintf( __( 'Image link for Product: %s', 'shopbuilder' ), $args['title'] )
333 );
334 ?>
335 <figure>
336 <a class="woocommerce-LoopProduct-link rtsb-img-link" href="<?php echo esc_url( $args['p_link'] ); ?>" aria-label="<?php echo esc_attr( $aria_label ); ?>">
337 <?php
338 Fns::get_product_image( $args['img_html'], $args['hover_img_html'] );
339 ?>
340 </a>
341 </figure>
342 <?php
343 } else {
344 echo '<figure class="rtsb-img-link">';
345 Fns::get_product_image( $args['img_html'], $args['hover_img_html'] );
346 echo '</figure>';
347 }
348 }
349
350 /**
351 * Modify WooCommerce query arguments for product retrieval.
352 *
353 * @param array $settings The settings array.
354 *
355 * @return void
356 */
357 public static function modify_wc_query_args( $settings ) {
358 if ( ( isset( $settings['tax_relation'] ) && 'OR' === $settings['tax_relation'] ) ||
359 ( isset( $settings['relation'] ) && 'OR' === $settings['relation'] ) ) {
360 add_filter( 'woocommerce_product_data_store_cpt_get_products_query', [ FilterHooks::class, 'extra_query_args_or' ], 10, 2 );
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 }
366
367 if ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) ) {
368 add_filter( 'woocommerce_product_data_store_cpt_get_products_query', [ FilterHooks::class, 'extra_query_args_outofstock' ] );
369 }
370 }
371
372 /**
373 * Reset WooCommerce query arguments for product retrieval.
374 *
375 * @param array $settings The settings array.
376 *
377 * @return void
378 */
379 public static function reset_wc_query_args( $settings ) {
380 if ( ( isset( $settings['tax_relation'] ) && 'OR' === $settings['tax_relation'] ) ||
381 ( isset( $settings['relation'] ) && 'OR' === $settings['relation'] ) ) {
382 remove_filter( 'woocommerce_product_data_store_cpt_get_products_query', [ FilterHooks::class, 'extra_query_args_or' ] );
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 }
388
389 if ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) ) {
390 remove_filter( 'woocommerce_product_data_store_cpt_get_products_query', [ FilterHooks::class, 'extra_query_args_outofstock' ] );
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();
547 }
548 }
549