Changeset 3448463
- Timestamp:
- 01/28/2026 08:24:45 AM (2 months ago)
- Location:
- woocommerce-jetpack/trunk
- Files:
-
- 10 edited
-
includes/admin/wcj-settings-dashboard.php (modified) (4 diffs)
-
includes/admin/wcj-settings-plugins.php (modified) (1 diff)
-
includes/class-wcj-multicurrency.php (modified) (14 diffs)
-
includes/class-wcj-order-quantities.php (modified) (3 diffs)
-
includes/classes/class-wcj-shortcodes.php (modified) (1 diff)
-
includes/core/class-wcj-admin.php (modified) (6 diffs)
-
includes/settings/meta-box/wcj-settings-meta-box-order-quantities.php (modified) (1 diff)
-
readme.txt (modified) (2 diffs)
-
version-details.json (modified) (1 diff)
-
woocommerce-jetpack.php (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
woocommerce-jetpack/trunk/includes/admin/wcj-settings-dashboard.php
r3426720 r3448463 12 12 } 13 13 14 require WCJ_FREE_PLUGIN_PATH . '/includes/admin/wcj-settings-header.php'; ?> 14 require WCJ_FREE_PLUGIN_PATH . '/includes/admin/wcj-settings-header.php'; 15 16 // Handle preset application from hub cards. 17 if ( isset( $_GET['apply_preset'] ) && ! empty( $_GET['apply_preset'] ) ) { 18 // Verify nonce. 19 if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_GET['_wpnonce'] ), 'wcj_apply_preset' ) ) { 20 wp_die( esc_html__( 'Security check failed.', 'woocommerce-jetpack' ) ); 21 } 22 // Verify capability. 23 // phpcs:ignore WordPress.WP.Capabilities.Unknown 24 if ( ! current_user_can( 'manage_woocommerce' ) ) { 25 wp_die( esc_html__( 'Permission denied.', 'woocommerce-jetpack' ) ); 26 } 27 $preset_id = sanitize_key( wp_unslash( $_GET['apply_preset'] ) ); 28 if ( class_exists( 'WCJ_Presets' ) ) { 29 WCJ_Presets::apply_preset( $preset_id ); 30 } 31 // Redirect to remove query params. 32 wp_safe_redirect( remove_query_arg( array( 'apply_preset', '_wpnonce' ) ) ); 33 exit; 34 } 35 36 // Render Getting Started Hub (P6) at top of dashboard. 37 if ( isset( $GLOBALS['wcj_getting_started_hub'] ) ) { 38 $GLOBALS['wcj_getting_started_hub']->render(); 39 } 40 ?> 15 41 16 42 <div class="wcj-welcome-booster"> … … 45 71 </div> 46 72 </div> 73 74 <!-- Quick Setup Presets Section --> 75 <div class="wcj-presets-section"> 76 <div class="wcj-container"> 77 <div class="wcj-row"> 78 <div class="wcj-presets-header"> 79 <h2><?php esc_html_e( 'Quick Setup', 'woocommerce-jetpack' ); ?></h2> 80 <p class="description"><?php esc_html_e( 'Get started quickly by applying a preset configuration for common use cases:', 'woocommerce-jetpack' ); ?></p> 81 </div> 82 <?php 83 if ( class_exists( 'WCJ_Presets' ) ) { 84 WCJ_Presets::render_preset_cards(); 85 } 86 ?> 87 </div> 88 </div> 89 </div> 90 47 91 <div class="wcj-dashboard-box"> 48 92 <div class="wcj-container"> … … 51 95 <div class="wcj-dash-sing-box"> 52 96 <h3><?php esc_html_e( 'Getting Started', 'woocommerce-jetpack' ); ?></h3> 53 <h6><?php esc_html_e( 'Let ’s get you set up with Booster', 'woocommerce-jetpack' ); ?></h6>97 <h6><?php esc_html_e( 'Let\'s get you set up with Booster', 'woocommerce-jetpack' ); ?></h6> 54 98 <div class="wcj-dash-sing-icn-list"> 55 99 <div class="wcj-dash-sing-part"> … … 198 242 break; 199 243 } 200 $count++;244 ++$count; 201 245 202 246 echo '<li>'; -
woocommerce-jetpack/trunk/includes/admin/wcj-settings-plugins.php
r3426720 r3448463 84 84 $section = ( isset( $_REQUEST['section'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['section'] ) ) : '' ); 85 85 86 // Render Module Filters (P7) above module list when showing all modules. 87 if ( '' === $section || 'active' === $section ) { 88 if ( isset( $GLOBALS['wcj_module_filters'] ) ) { 89 $GLOBALS['wcj_module_filters']->render_filter_buttons(); 90 } 91 } 92 86 93 $pdf_header = '<div class="wcj-plugins-sing-acc-box-head"> 87 94 <div class="wcj-plugins-sing-head-lf"> -
woocommerce-jetpack/trunk/includes/class-wcj-multicurrency.php
r3426720 r3448463 193 193 add_filter( 'woocommerce_shipping_free_shipping_instance_option', array( $this, 'convert_free_shipping_min_amount' ), 10, 3 ); 194 194 add_filter( 'woocommerce_shipping_free_shipping_option', array( $this, 'convert_free_shipping_min_amount' ), 10, 3 ); 195 196 195 } 197 196 … … 315 314 public function wc_tree_table_rate_shipping_compatibility() { 316 315 $shipping_instance_max = apply_filters( 'wcj_multicurrency_compatibility_wc_ttrs_instances', 90 ); 317 for ( $i = 1; $i <= $shipping_instance_max; $i ++ ) {316 for ( $i = 1; $i <= $shipping_instance_max; $i++ ) { 318 317 add_filter( 'option_woocommerce_tree_table_rate_' . $i . '_settings', array( $this, 'convert_wc_tree_table_rate_settings' ) ); 319 318 } … … 357 356 * @since 4.9.0 358 357 * 359 * @param array $ array defines the array.358 * @param array $settings_array defines the array. 360 359 * @param null $args defines the args. 361 360 * 362 361 * @return array 363 362 */ 364 public function recursively_convert_wc_tree_settings( $ array, $args = null ) {363 public function recursively_convert_wc_tree_settings( $settings_array, $args = null ) { 365 364 $args = wp_parse_args( 366 365 $args, … … 372 371 $change_keys = $args['change_keys']; 373 372 $exchange_rate = $args['exchange_rate']; 374 foreach ( $ array as $key => $value ) {373 foreach ( $settings_array as $key => $value ) { 375 374 if ( in_array( $key, $change_keys, true ) ) { 376 375 if ( 377 is_array( $ array ) &&378 isset( $ array['condition'] ) &&379 'price' === $ array['condition'] &&376 is_array( $settings_array ) && 377 isset( $settings_array['condition'] ) && 378 'price' === $settings_array['condition'] && 380 379 ! empty( $value ) && 381 380 is_numeric( $value ) 382 381 ) { 383 $ array[ $key ] = $value * $exchange_rate;382 $settings_array[ $key ] = $value * $exchange_rate; 384 383 } elseif ( 385 is_a( $ array, 'stdClass' ) &&386 property_exists( $ array, 'condition' ) &&387 'price' === $ array->condition &&384 is_a( $settings_array, 'stdClass' ) && 385 property_exists( $settings_array, 'condition' ) && 386 'price' === $settings_array->condition && 388 387 ! empty( $value ) && 389 388 is_numeric( $value ) 390 389 ) { 391 $ array->$key = $value * $exchange_rate;390 $settings_array->$key = $value * $exchange_rate; 392 391 } 393 392 } … … 396 395 } 397 396 } 398 return $ array;397 return $settings_array; 399 398 } 400 399 … … 438 437 * @since 5.2.0 439 438 * 440 * @param bool $ false defines the false.439 * @param bool $is_false defines the false. 441 440 * @param string | array $data defines the data. 442 441 * @param string | array $coupon defines the coupon. … … 444 443 * @return mixed 445 444 */ 446 public function fix_wc_coupon_discount_amount( $ false, $data, $coupon ) {445 public function fix_wc_coupon_discount_amount( $is_false, $data, $coupon ) { 447 446 $coupon_id = wc_get_coupon_id_by_code( $data ); 448 447 if ( … … 452 451 'fixed_cart' !== get_post_meta( $coupon_id, 'discount_type', true ) 453 452 ) { 454 return $ false;453 return $is_false; 455 454 } 456 455 $current_coupon_amount = get_post_meta( $coupon_id, 'coupon_amount', true ); … … 983 982 984 983 $per_product_prices = array(); 985 for ( $i = 1; $i <= $total_number; $i ++ ) {984 for ( $i = 1; $i <= $total_number; $i++ ) { 986 985 $currency_code = empty( $currency_code_param ) ? wcj_get_option( 'wcj_multicurrency_currency_' . $i ) : $currency_code_param; 987 986 $exchange_rate = $this->get_currency_exchange_rate( $currency_code ); … … 1068 1067 public function get_default_currency() { 1069 1068 $module_roles = wcj_get_option( 'wcj_multicurrency_role_defaults_roles', '' ); 1070 if ( ! empty( $module_roles ) ) {1069 if ( ! empty( $module_roles ) && is_array( $module_roles ) ) { 1071 1070 $current_user_role = wcj_get_current_user_first_role(); 1072 1071 if ( in_array( $current_user_role, $module_roles, true ) ) { … … 1329 1328 // Per product. 1330 1329 $regular_price_per_product = get_post_meta( $_product_id, '_wcj_multicurrency_per_product_regular_price_' . $this->get_current_currency_code(), true ); 1330 $additional_price_filters = is_array( $this->additional_price_filters ) ? $this->additional_price_filters : array(); 1331 1331 if ( 'yes' === wcj_get_option( 'wcj_multicurrency_per_product_enabled', 'yes' ) && null !== $_product ) { 1332 1332 if ( … … 1342 1342 $this->save_price( $price, $_product_id, $_current_filter ); 1343 1343 return $price; 1344 } elseif ( WCJ_PRODUCT_GET_PRICE_FILTER === $_current_filter || 'woocommerce_variation_prices_price' === $_current_filter || 'woocommerce_product_variation_get_price' === $_current_filter || in_array( $_current_filter, $ this->additional_price_filters, true ) ) {1344 } elseif ( WCJ_PRODUCT_GET_PRICE_FILTER === $_current_filter || 'woocommerce_variation_prices_price' === $_current_filter || 'woocommerce_product_variation_get_price' === $_current_filter || in_array( $_current_filter, $additional_price_filters, true ) ) { 1345 1345 if ( $_product->is_on_sale() ) { 1346 1346 $sale_price_per_product = get_post_meta( $_product_id, '_wcj_multicurrency_per_product_sale_price_' . $this->get_current_currency_code(), true ); … … 1400 1400 } else { 1401 1401 $module_roles = wcj_get_option( 'wcj_multicurrency_role_defaults_roles', '' ); 1402 if ( ! empty( $module_roles ) ) {1402 if ( ! empty( $module_roles ) && is_array( $module_roles ) ) { 1403 1403 $current_user_role = wcj_get_current_user_first_role(); 1404 1404 if ( in_array( $current_user_role, $module_roles, true ) ) { … … 1443 1443 return wcj_change_price_shipping_package_rates( $package_rates, $currency_exchange_rate ); 1444 1444 } 1445 1446 1445 } 1447 1446 -
woocommerce-jetpack/trunk/includes/class-wcj-order-quantities.php
r3426720 r3448463 328 328 $_product = wc_get_product(); 329 329 if ( $_product && $_product->is_type( 'variable' ) ) { 330 // Memory guard: skip loading variations for products with 100+ variations. 331 $variation_ids = $_product->get_children(); 332 $variation_count = count( $variation_ids ); 333 if ( $variation_count >= 100 ) { 334 // Too many variations - skip per-variation JS to prevent memory exhaustion. 335 return; 336 } 337 330 338 $quantities_options = array( 331 339 'reset_to_min' => ( 'reset_to_min' === wcj_get_option( 'wcj_order_quantities_variable_variation_change', 'do_nothing' ) ), … … 422 430 * Set_quantity_input_max. 423 431 * 424 * @version 3.2.2432 * @version 7.11.0 425 433 * @since 3.2.2 426 434 * @param int $qty defines the qty. … … 428 436 */ 429 437 public function set_quantity_input_max( $qty, $_product ) { 430 if ( ! $_product->is_type( 'variable' ) ) { 431 $max = $this->get_product_quantity( 'max', $_product, $qty ); 432 $_max = $_product->get_max_purchase_quantity(); 433 return ( -1 === $_max || $max < $_max ? $max : $_max ); 434 } else { 438 // Reentrancy guard to prevent infinite loops. 439 static $depth = 0; 440 if ( $depth > 0 ) { 435 441 return $qty; 436 442 } 443 444 $depth++; 445 446 // If product is variable, let WC handle it. 447 if ( $_product->is_type( 'variable' ) ) { 448 $depth--; 449 return $qty; 450 } 451 452 // Apply Booster logic. 453 $plugin_max = $this->get_product_quantity( 'max', $_product, $qty ); 454 $wc_max = $_product->get_max_purchase_quantity(); 455 $depth--; 456 457 // Return the more restrictive limit if applicable. 458 return ( -1 === $wc_max || $plugin_max < $wc_max ) ? $plugin_max : $wc_max; 437 459 } 438 460 -
woocommerce-jetpack/trunk/includes/classes/class-wcj-shortcodes.php
r3426720 r3448463 401 401 $before = wp_kses_post( $atts['before'] ); 402 402 $after = wp_kses_post( $atts['after'] ); 403 $result = ( is_string( $result ) ? wp_kses_post( $result ) : $result );404 403 return $before . apply_filters( 'wcj_shortcode_result', $result, $atts, $content, $shortcode ) . $after; 405 404 } -
woocommerce-jetpack/trunk/includes/core/class-wcj-admin.php
r3426720 r3448463 62 62 new Booster_Onboarding(); 63 63 } 64 65 // Load presets system for dashboard quick setup. 66 require_once WCJ_FREE_PLUGIN_PATH . '/includes/presets/class-wcj-presets.php'; 67 68 // Load Getting Started hub (P6). 69 require_once WCJ_FREE_PLUGIN_PATH . '/includes/admin/class-wcj-getting-started-hub.php'; 70 $GLOBALS['wcj_getting_started_hub'] = new WCJ_Getting_Started_Hub(); 71 72 // Load Module Filters (P7). 73 require_once WCJ_FREE_PLUGIN_PATH . '/includes/admin/class-wcj-module-filters.php'; 74 $GLOBALS['wcj_module_filters'] = new WCJ_Module_Filters(); 64 75 65 76 if ( is_admin() ) { … … 830 841 } 831 842 832 $total_modules++; 843 ++$total_modules; 844 845 // Get data attributes for module filters (P7). 846 $module_data_attrs = ''; 847 if ( isset( $GLOBALS['wcj_module_filters'] ) ) { 848 $module_data_attrs = $GLOBALS['wcj_module_filters']->get_module_data_attributes( $section ); 849 } 833 850 834 851 if ( in_array( $the_feature['id'], array( 'wcj_cart_abandonment_enabled', 'wcj_wishlist_enabled' ), true ) ) { … … 840 857 841 858 if ( 'pdf_invoicing' !== $cat_id ) { 842 $html .= '<div class="wcj-plugins-sing-acc-box-head" >859 $html .= '<div class="wcj-plugins-sing-acc-box-head"' . $module_data_attrs . '> 843 860 <div class="wcj-plugins-sing-head-lf"> 844 861 <span class="wcj_admin_span"> … … 886 903 } 887 904 888 $total_modules++;905 ++$total_modules; 889 906 $url = admin_url( 'admin.php?page=wcj-plugins&wcj-cat=' . sanitize_title( $cat_id ) . '&wcj-cat-nonce=' . wp_create_nonce( 'wcj-cat-nonce' ) . '§ion=' . $id ); 890 907 $sub_desc = __( 'PDF Invoicing', 'woocommerce-jetpack' ) . ': ' . $label . ' ' . __( 'Settings', 'woocommerce-jetpack' ); … … 981 998 $custom_link_link = isset( $setting['link'] ) ? $setting['link'] : ''; 982 999 $desc_tip_str = isset( $setting['desc_tip'] ) ? $setting['desc_tip'] : ''; 983 $help_text_str = isset( $setting['help_text'] ) ? $setting['help_text'] : '';1000 $help_text_str = isset( $setting['help_text'] ) ? $setting['help_text'] : ''; 984 1001 985 1002 if ( '' !== $desc_tip_str ) { … … 1246 1263 $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"'; 1247 1264 } 1248 } else { 1249 if ( ! w_c_j()->all_modules['currency_exchange_rates']->is_enabled() 1265 } elseif ( ! w_c_j()->all_modules['currency_exchange_rates']->is_enabled() 1250 1266 || 'yes' !== wcj_get_option( 'wcj_currency_exchange_rates_point_decimal_separator', 'no' ) 1251 1267 ) { 1268 1252 1269 $custom_attributes = array( 'step="' . sprintf( '%.12f', 1 / pow( 10, 12 ) ) . '"', 'min="0"' ); 1253 } else { 1254 $custom_attributes = array( 'step="0.00000001"', 'min="0"' ); 1255 } 1270 } else { 1271 $custom_attributes = array( 'step="0.00000001"', 'min="0"' ); 1256 1272 } 1257 1273 $custom_attributes_button = array(); -
woocommerce-jetpack/trunk/includes/settings/meta-box/wcj-settings-meta-box-order-quantities.php
r3426720 r3448463 21 21 $products = array(); 22 22 if ( $_product->is_type( 'variable' ) ) { 23 $available_variations = $_product->get_available_variations(); 24 foreach ( $available_variations as $variation ) { 25 $variation_product = wc_get_product( $variation['variation_id'] ); 26 $products[ $variation['variation_id'] ] = ' (' . wcj_get_product_formatted_variation( $variation_product, true ) . ')'; 23 // Memory guard: skip loading variations for products with 100+ variations. 24 $variation_ids = $_product->get_children(); 25 $variation_count = count( $variation_ids ); 26 if ( $variation_count >= 100 ) { 27 // Too many variations - use parent product only to prevent memory exhaustion. 28 $products[ $main_product_id ] = ' (' . sprintf( 29 /* translators: %d: variation count */ 30 __( 'All %d variations - per-variation settings disabled for performance', 'woocommerce-jetpack' ), 31 $variation_count 32 ) . ')'; 33 } else { 34 $available_variations = $_product->get_available_variations(); 35 foreach ( $available_variations as $variation ) { 36 $variation_product = wc_get_product( $variation['variation_id'] ); 37 $products[ $variation['variation_id'] ] = ' (' . wcj_get_product_formatted_variation( $variation_product, true ) . ')'; 38 } 27 39 } 28 40 } else { -
woocommerce-jetpack/trunk/readme.txt
r3426720 r3448463 6 6 Tested up to: 6.9 7 7 Requires PHP: 7.2 8 Stable tag: 7.1 0.08 Stable tag: 7.11.0 9 9 License: GNU General Public License v3.0 10 10 License URI: http://www.gnu.org/licenses/gpl-3.0.html … … 347 347 348 348 == Changelog == 349 350 = 7.11.0 - 28/01/2026 = 351 * **New - One-Click Presets**: Set up your store in seconds, not hours. Choose what you want to accomplish and we configure everything for you: 352 - **PDF Invoicing**: Start generating professional invoices immediately 353 - **Multicurrency**: Let customers shop in their local currency 354 - **Product Addons**: Add gift wrapping, engraving, and custom options to products 355 - **Checkout Customization**: Streamline your checkout experience 356 * **New - Getting Started Hub**: A friendly welcome panel on your dashboard pointing you to the most popular features 357 * **New - Smart Module Filters**: Find modules faster with All, Recommended, Active, and Recently Used filters 358 * Fixed - Multicurrency no longer shows PHP error when price filters are empty 359 * Fixed - Variable products with 100+ variations no longer cause memory issues with Order Quantities 360 * Improved - Better admin performance by only loading onboarding assets on Booster pages 361 * WooCommerce 10.4.3 Tested 362 * WordPress 6.9 Tested 349 363 350 364 = 7.10.0 - 24/12/2025 = -
woocommerce-jetpack/trunk/version-details.json
r3426720 r3448463 1 1 { 2 "0" : "= 7.10.0 24/12/2025 =", 3 "1": "* **Onboarding Phase 8 – UX & conversion improvements**. Enhanced onboarding flow with activation redirects, searchable goals, re-open onboarding controls, success feedback (celebrations, toasts), Quick Start presets, inline help tooltips, upgrade comparison blocks, and improved admin-page-only visibility.", 4 "2" : "* WooCommerce 10.4.3 Tested", 5 "3" : "* WordPress 6.9 Tested" 2 "0": "= 7.11.0 28/01/2026 =", 3 "1": "* **One-Click Presets & Onboarding**. Added one-click presets for PDF Invoicing, Multicurrency, Product Addons, and Checkout, along with a new Getting Started Hub and smart module filters.", 4 "2": "* **Bug Fixes & Performance Improvements**. Fixed Multicurrency price filter PHP errors, resolved memory issues with 100+ variations, and optimized admin asset loading.", 5 "3": "* WooCommerce 10.4.3 Tested", 6 "4": "* WordPress 6.9 Tested" 6 7 } -
woocommerce-jetpack/trunk/woocommerce-jetpack.php
r3426720 r3448463 4 4 * Requires Plugins: woocommerce 5 5 * Plugin URI: https://booster.io 6 * Description: Supercharge your WooCommerce site with these awesome powerful features. More than 100 modules.All in one WooCommerce plugin.7 * Version: 7.1 0.06 * Description: Supercharge your WooCommerce site with these awesome powerful features. 7 * Version: 7.11.0 8 8 * Author: Pluggabl LLC 9 9 * Author URI: https://booster.io 10 10 * Text Domain: woocommerce-jetpack 11 11 * Domain Path: /langs 12 * Copyright: © 2020 Pluggabl LLC.13 12 * WC tested up to: 10.4.3 14 13 * License: GNU General Public License v3.0 15 * php version 7.216 * License URI: http://www.gnu.org/licenses/gpl-3.0.html17 14 * 18 15 * @package Booster_For_WooCommerce 19 * */16 */ 20 17 21 18 if ( ! defined( 'ABSPATH' ) ) { 22 exit; // Exit if accessed directly.19 exit; 23 20 } 24 21 … … 36 33 function () { 37 34 if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) { 38 \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true ); 35 \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 36 'custom_order_tables', 37 __FILE__, 38 true 39 ); 39 40 } 40 41 } 41 42 ); 42 43 43 // Check if Plus is active. 44 if ( 'woocommerce-jetpack.php' === basename( __FILE__ ) && 45 ( wcj_is_plugin_activated( 'booster-plus-for-woocommerce', 'booster-plus-for-woocommerce.php' ) || 46 wcj_is_plugin_activated( 'booster-elite-for-woocommerce', 'booster-elite-for-woocommerce.php' ) || 47 wcj_is_plugin_activated( 'booster-basic-for-woocommerce', 'booster-basic-for-woocommerce.php' ) || 48 wcj_is_plugin_activated( 'booster-pro-for-woocommerce', 'booster-pro-for-woocommerce.php' ) ) 44 // Prevent loading if paid versions are active. 45 if ( 46 'woocommerce-jetpack.php' === basename( __FILE__ ) && 47 ( 48 wcj_is_plugin_activated( 'booster-plus-for-woocommerce', 'booster-plus-for-woocommerce.php' ) || 49 wcj_is_plugin_activated( 'booster-elite-for-woocommerce', 'booster-elite-for-woocommerce.php' ) || 50 wcj_is_plugin_activated( 'booster-basic-for-woocommerce', 'booster-basic-for-woocommerce.php' ) || 51 wcj_is_plugin_activated( 'booster-pro-for-woocommerce', 'booster-pro-for-woocommerce.php' ) 52 ) 49 53 ) { 50 54 return; … … 52 56 53 57 if ( ! defined( 'WCJ_FREE_PLUGIN_FILE' ) ) { 54 /**55 * WCJ_FREE_PLUGIN_FILE.56 *57 * @since 5.6.158 */59 58 define( 'WCJ_FREE_PLUGIN_FILE', __FILE__ ); 60 59 } … … 63 62 64 63 /** 65 * Main WC_Jetpack Class64 * Main Booster for WooCommerce class. 66 65 * 67 * @class WC_Jetpack 68 * @version 5.6.0 69 * @since 1.0.0 66 * @since 1.0.0 70 67 */ 71 68 final class WC_Jetpack { 72 69 73 70 /** 74 * Booster for WooCommerceversion.71 * Plugin version. 75 72 * 76 * @var string 77 * @since 2.4.7 73 * @var string 78 74 */ 79 public $version = '7. 9.0';75 public $version = '7.11.0'; 80 76 81 77 /** 82 * The single instance of the class78 * Singleton instance. 83 79 * 84 * @var WC_Jetpack The single instance of the class80 * @var WC_Jetpack|null 85 81 */ 86 82 protected static $instances = null; 87 83 88 84 /** 89 * WC Jetpack 90 * 91 * @version 5.3.3 92 * @since 5.3.3 85 * Plugin options. 93 86 * 94 87 * @var array … … 97 90 98 91 /** 99 * WC Jetpack 100 * 101 * @version 7.1.6 92 * Registered shortcodes. 102 93 * 103 94 * @var array … … 106 97 107 98 /** 108 * WC Jetpack 109 * 110 * @version 7.1.6 99 * Active modules. 111 100 * 112 101 * @var array … … 115 104 116 105 /** 117 * WC Jetpack 118 * 119 * @version 7.1.6 106 * All available modules. 120 107 * 121 108 * @var array … … 124 111 125 112 /** 126 * WC Jetpack 127 * 128 * @version 7.1.6 113 * Module statuses. 129 114 * 130 115 * @var array … … 133 118 134 119 /** 135 * Main WC_Jetpack Instance.120 * Get main instance (Singleton). 136 121 * 137 * Ensures only one instance of WC_Jetpack is loaded or can be loaded. 138 * 139 * @version 1.0.0 140 * @since 1.0.0 141 * @static 142 * @see w_c_j() 143 * @return WC_Jetpack - Main instance 122 * @return WC_Jetpack 144 123 */ 145 124 public static function instance() { … … 151 130 152 131 /** 153 * WC_Jetpack Constructor. 154 * 155 * @version 3.2.4 156 * @since 1.0.0 157 * @access public 132 * Class constructor. 158 133 */ 159 134 public function __construct() { … … 164 139 endif; 165 140 166 if ( ! function_exists( 'w_c_j' ) ) { 167 /** 168 * Returns the main instance of WC_Jetpack to prevent the need to use globals. 169 * 170 * @version 2.5.7 171 * @since 1.0.0 172 * @return WC_Jetpack 173 */ 174 function w_c_j() { 175 return WC_Jetpack::instance(); 176 } 141 // Load procedural functions. 142 require_once __DIR__ . '/includes/wcj-free-functions.php'; 143 144 // Plugin usage tracking. 145 if ( ! class_exists( 'Plugin_Usage_Tracker' ) ) { 146 include_once __DIR__ . '/tracking/class-plugin-usage-tracker.php'; 177 147 } 178 148 179 /** 180 * Wcj_delete_plugin_database_option 181 * 182 * @version 6.0.3 183 * @since 6.0.3 184 */ 185 function wcj_delete_free_plugin_database_option() { 186 global $wpdb; 187 188 $plugin_options = $wpdb->get_results( "SELECT option_name FROM $wpdb->options WHERE option_name LIKE 'wcj_%' OR option_name LIKE '_transient_timeout_wcj%' OR option_name LIKE '_transient_wcj%' OR option_name LIKE 'woocommerce_wcj_%' OR option_name LIKE 'widget_wcj_widget_%'" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 189 foreach ( $plugin_options as $option ) { 190 delete_option( $option->option_name ); 191 delete_site_option( $option->option_name ); 192 } 193 194 $plugin_meta = $wpdb->get_results( "SELECT * FROM $wpdb->postmeta WHERE meta_key LIKE '_wcj_%'" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 195 foreach ( $plugin_meta as $meta ) { 196 delete_post_meta( $meta->post_id, $meta->meta_key ); 197 } 198 } 199 200 register_uninstall_hook( __FILE__, 'wcj_delete_free_plugin_database_option' ); 201 202 203 /** 204 * Booster Pro 205 * 206 * @version 5.5.8 207 * @since 1.0.0 208 * @return Booster_Pro 209 */ 210 /** 211 * This function allows you to track usage of your plugin 212 * Place in your main plugin file 213 * Refer to https://wisdomplugin.com/support for help 214 */ 215 if ( ! class_exists( 'Plugin_Usage_Tracker' ) ) { 216 include_once dirname( __FILE__ ) . '/tracking/class-plugin-usage-tracker.php'; 217 } 218 if ( ! function_exists( 'woocommerce_jetpack_start_plugin_tracking' ) ) { 219 /** 220 * Woocommerce jetpack start plugin tracking 221 * 222 * @version 5.5.8 223 * @since 1.0.0 224 */ 225 function woocommerce_jetpack_start_plugin_tracking() { 226 $wisdom = new Plugin_Usage_Tracker( 227 __FILE__, 228 'https://boosterio.bigscoots-staging.com', 229 array(), 230 true, 231 true, 232 1 233 ); 234 } 235 woocommerce_jetpack_start_plugin_tracking(); 236 } 237 149 // Hooks. 238 150 add_action( 'plugins_loaded', 'w_c_j' ); 239 240 // Activation redirect - only on FIRST ever activation (not reactivations or updates). 151 register_uninstall_hook( __FILE__, 'wcj_delete_free_plugin_database_option' ); 241 152 register_activation_hook( __FILE__, 'wcj_set_activation_redirect_free' ); 242 243 /**244 * Set redirect flag after FIRST plugin activation only.245 *246 * This function runs on plugin activation and sets a transient247 * to trigger a redirect to the Getting Started page.248 * Only triggers on first-ever activation, not reactivations.249 *250 * @return void251 */252 function wcj_set_activation_redirect_free() {253 // Check if plugin was ever activated before.254 if ( get_option( 'wcj_plugin_activated_once', false ) ) {255 // This is a reactivation, do not redirect.256 return;257 }258 259 // Mark that plugin has been activated at least once.260 add_option( 'wcj_plugin_activated_once', true );261 262 // Set transient to trigger redirect (expires in 60 seconds as a safety measure).263 set_transient( 'wcj_activation_redirect', true, 60 );264 }265 266 // Redirect to Getting Started page after first plugin activation.267 153 add_action( 'admin_init', 'wcj_redirect_after_first_activation_free' ); 268 154 269 /** 270 * Redirects admin to the Getting Started page after first plugin activation. 271 * 272 * Checks for the `wcj_activation_redirect` transient set during activation. 273 * Prevents redirect in network admin or multi-site bulk activation cases. 274 * 275 * @return void 276 */ 277 function wcj_redirect_after_first_activation_free() { 278 // Check for the redirect transient. 279 if ( ! get_transient( 'wcj_activation_redirect' ) ) { 280 return; 281 } 282 283 // Delete the transient immediately (one-time only). 284 delete_transient( 'wcj_activation_redirect' ); 285 286 // Don't redirect in network admin or bulk activation. 287 if ( is_network_admin() || isset( $_GET['activate-multi'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended 288 return; 289 } 290 291 // Redirect to Getting Started page with modal param. 292 wp_safe_redirect( admin_url( 'admin.php?page=wcj-getting-started&modal=onboarding' ) ); 293 exit; 294 } 155 // Start tracking. 156 woocommerce_jetpack_start_plugin_tracking();
Note: See TracChangeset
for help on using the changeset viewer.