Plugin Directory

Changeset 3448463


Ignore:
Timestamp:
01/28/2026 08:24:45 AM (2 months ago)
Author:
ronyp
Message:

v7.11.0

Location:
woocommerce-jetpack/trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • woocommerce-jetpack/trunk/includes/admin/wcj-settings-dashboard.php

    r3426720 r3448463  
    1212}
    1313
    14 require WCJ_FREE_PLUGIN_PATH . '/includes/admin/wcj-settings-header.php'; ?>
     14require WCJ_FREE_PLUGIN_PATH . '/includes/admin/wcj-settings-header.php';
     15
     16// Handle preset application from hub cards.
     17if ( 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.
     37if ( isset( $GLOBALS['wcj_getting_started_hub'] ) ) {
     38    $GLOBALS['wcj_getting_started_hub']->render();
     39}
     40?>
    1541
    1642<div class="wcj-welcome-booster">
     
    4571    </div>
    4672</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
    4791<div class="wcj-dashboard-box">
    4892    <div class="wcj-container">
     
    5195                <div class="wcj-dash-sing-box">
    5296                    <h3><?php esc_html_e( 'Getting Started', 'woocommerce-jetpack' ); ?></h3>
    53                     <h6><?php esc_html_e( 'Lets 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>
    5498                    <div class="wcj-dash-sing-icn-list">
    5599                        <div class="wcj-dash-sing-part">
     
    198242                                    break;
    199243                                }
    200                                 $count++;
     244                                ++$count;
    201245
    202246                                echo '<li>';
  • woocommerce-jetpack/trunk/includes/admin/wcj-settings-plugins.php

    r3426720 r3448463  
    8484                        $section = ( isset( $_REQUEST['section'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['section'] ) ) : '' );
    8585
     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
    8693                        $pdf_header = '<div class="wcj-plugins-sing-acc-box-head">
    8794                            <div class="wcj-plugins-sing-head-lf">
  • woocommerce-jetpack/trunk/includes/class-wcj-multicurrency.php

    r3426720 r3448463  
    193193            add_filter( 'woocommerce_shipping_free_shipping_instance_option', array( $this, 'convert_free_shipping_min_amount' ), 10, 3 );
    194194            add_filter( 'woocommerce_shipping_free_shipping_option', array( $this, 'convert_free_shipping_min_amount' ), 10, 3 );
    195 
    196195        }
    197196
     
    315314        public function wc_tree_table_rate_shipping_compatibility() {
    316315            $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++ ) {
    318317                add_filter( 'option_woocommerce_tree_table_rate_' . $i . '_settings', array( $this, 'convert_wc_tree_table_rate_settings' ) );
    319318            }
     
    357356         * @since   4.9.0
    358357         *
    359          * @param array $array defines the array.
     358         * @param array $settings_array defines the array.
    360359         * @param null  $args defines the args.
    361360         *
    362361         * @return array
    363362         */
    364         public function recursively_convert_wc_tree_settings( $array, $args = null ) {
     363        public function recursively_convert_wc_tree_settings( $settings_array, $args = null ) {
    365364            $args          = wp_parse_args(
    366365                $args,
     
    372371            $change_keys   = $args['change_keys'];
    373372            $exchange_rate = $args['exchange_rate'];
    374             foreach ( $array as $key => $value ) {
     373            foreach ( $settings_array as $key => $value ) {
    375374                if ( in_array( $key, $change_keys, true ) ) {
    376375                    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'] &&
    380379                        ! empty( $value ) &&
    381380                        is_numeric( $value )
    382381                    ) {
    383                         $array[ $key ] = $value * $exchange_rate;
     382                        $settings_array[ $key ] = $value * $exchange_rate;
    384383                    } 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 &&
    388387                    ! empty( $value ) &&
    389388                    is_numeric( $value )
    390389                    ) {
    391                         $array->$key = $value * $exchange_rate;
     390                        $settings_array->$key = $value * $exchange_rate;
    392391                    }
    393392                }
     
    396395                }
    397396            }
    398             return $array;
     397            return $settings_array;
    399398        }
    400399
     
    438437         * @since   5.2.0
    439438         *
    440          * @param bool           $false defines the false.
     439         * @param bool           $is_false defines the false.
    441440         * @param string | array $data defines the data.
    442441         * @param string | array $coupon defines the coupon.
     
    444443         * @return mixed
    445444         */
    446         public function fix_wc_coupon_discount_amount( $false, $data, $coupon ) {
     445        public function fix_wc_coupon_discount_amount( $is_false, $data, $coupon ) {
    447446            $coupon_id = wc_get_coupon_id_by_code( $data );
    448447            if (
     
    452451            'fixed_cart' !== get_post_meta( $coupon_id, 'discount_type', true )
    453452            ) {
    454                 return $false;
     453                return $is_false;
    455454            }
    456455            $current_coupon_amount = get_post_meta( $coupon_id, 'coupon_amount', true );
     
    983982
    984983            $per_product_prices = array();
    985             for ( $i = 1; $i <= $total_number; $i ++ ) {
     984            for ( $i = 1; $i <= $total_number; $i++ ) {
    986985                $currency_code = empty( $currency_code_param ) ? wcj_get_option( 'wcj_multicurrency_currency_' . $i ) : $currency_code_param;
    987986                $exchange_rate = $this->get_currency_exchange_rate( $currency_code );
     
    10681067        public function get_default_currency() {
    10691068            $module_roles = wcj_get_option( 'wcj_multicurrency_role_defaults_roles', '' );
    1070             if ( ! empty( $module_roles ) ) {
     1069            if ( ! empty( $module_roles ) && is_array( $module_roles ) ) {
    10711070                $current_user_role = wcj_get_current_user_first_role();
    10721071                if ( in_array( $current_user_role, $module_roles, true ) ) {
     
    13291328            // Per product.
    13301329            $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();
    13311331            if ( 'yes' === wcj_get_option( 'wcj_multicurrency_per_product_enabled', 'yes' ) && null !== $_product ) {
    13321332                if (
     
    13421342                        $this->save_price( $price, $_product_id, $_current_filter );
    13431343                        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 ) ) {
    13451345                        if ( $_product->is_on_sale() ) {
    13461346                            $sale_price_per_product = get_post_meta( $_product_id, '_wcj_multicurrency_per_product_sale_price_' . $this->get_current_currency_code(), true );
     
    14001400            } else {
    14011401                $module_roles = wcj_get_option( 'wcj_multicurrency_role_defaults_roles', '' );
    1402                 if ( ! empty( $module_roles ) ) {
     1402                if ( ! empty( $module_roles ) && is_array( $module_roles ) ) {
    14031403                    $current_user_role = wcj_get_current_user_first_role();
    14041404                    if ( in_array( $current_user_role, $module_roles, true ) ) {
     
    14431443            return wcj_change_price_shipping_package_rates( $package_rates, $currency_exchange_rate );
    14441444        }
    1445 
    14461445    }
    14471446
  • woocommerce-jetpack/trunk/includes/class-wcj-order-quantities.php

    r3426720 r3448463  
    328328            $_product = wc_get_product();
    329329            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
    330338                $quantities_options = array(
    331339                    'reset_to_min'         => ( 'reset_to_min' === wcj_get_option( 'wcj_order_quantities_variable_variation_change', 'do_nothing' ) ),
     
    422430         * Set_quantity_input_max.
    423431         *
    424          * @version 3.2.2
     432         * @version 7.11.0
    425433         * @since   3.2.2
    426434         * @param int   $qty defines the qty.
     
    428436         */
    429437        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 ) {
    435441                return $qty;
    436442            }
     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;
    437459        }
    438460
  • woocommerce-jetpack/trunk/includes/classes/class-wcj-shortcodes.php

    r3426720 r3448463  
    401401                $before = wp_kses_post( $atts['before'] );
    402402                $after  = wp_kses_post( $atts['after'] );
    403                 $result = ( is_string( $result ) ? wp_kses_post( $result ) : $result );
    404403                return $before . apply_filters( 'wcj_shortcode_result', $result, $atts, $content, $shortcode ) . $after;
    405404            }
  • woocommerce-jetpack/trunk/includes/core/class-wcj-admin.php

    r3426720 r3448463  
    6262                new Booster_Onboarding();
    6363            }
     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();
    6475
    6576            if ( is_admin() ) {
     
    830841                }
    831842
    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                }
    833850
    834851                if ( in_array( $the_feature['id'], array( 'wcj_cart_abandonment_enabled', 'wcj_wishlist_enabled' ), true ) ) {
     
    840857
    841858                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 . '>
    843860                        <div class="wcj-plugins-sing-head-lf">
    844861                            <span class="wcj_admin_span">
     
    886903                    }
    887904
    888                     $total_modules++;
     905                    ++$total_modules;
    889906                    $url      = admin_url( 'admin.php?page=wcj-plugins&wcj-cat=' . sanitize_title( $cat_id ) . '&wcj-cat-nonce=' . wp_create_nonce( 'wcj-cat-nonce' ) . '&section=' . $id );
    890907                    $sub_desc = __( 'PDF Invoicing', 'woocommerce-jetpack' ) . ': ' . $label . ' ' . __( 'Settings', 'woocommerce-jetpack' );
     
    981998                    $custom_link_link = isset( $setting['link'] ) ? $setting['link'] : '';
    982999                    $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'] : '';
    9841001
    9851002                    if ( '' !== $desc_tip_str ) {
     
    12461263                                    $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
    12471264                                }
    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()
    12501266                                || 'yes' !== wcj_get_option( 'wcj_currency_exchange_rates_point_decimal_separator', 'no' )
    12511267                                ) {
     1268
    12521269                                    $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"' );
    12561272                            }
    12571273                            $custom_attributes_button = array();
  • woocommerce-jetpack/trunk/includes/settings/meta-box/wcj-settings-meta-box-order-quantities.php

    r3426720 r3448463  
    2121$products = array();
    2222if ( $_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        }
    2739    }
    2840} else {
  • woocommerce-jetpack/trunk/readme.txt

    r3426720 r3448463  
    66Tested up to: 6.9
    77Requires PHP: 7.2
    8 Stable tag: 7.10.0
     8Stable tag: 7.11.0
    99License: GNU General Public License v3.0
    1010License URI: http://www.gnu.org/licenses/gpl-3.0.html
     
    347347
    348348== 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
    349363
    350364= 7.10.0 - 24/12/2025 =
  • woocommerce-jetpack/trunk/version-details.json

    r3426720 r3448463  
    11{
    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"
    67}
  • woocommerce-jetpack/trunk/woocommerce-jetpack.php

    r3426720 r3448463  
    44 * Requires Plugins: woocommerce
    55 * 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.10.0
     6 * Description: Supercharge your WooCommerce site with these awesome powerful features.
     7 * Version: 7.11.0
    88 * Author: Pluggabl LLC
    99 * Author URI: https://booster.io
    1010 * Text Domain: woocommerce-jetpack
    1111 * Domain Path: /langs
    12  * Copyright: © 2020 Pluggabl LLC.
    1312 * WC tested up to: 10.4.3
    1413 * License: GNU General Public License v3.0
    15  * php version 7.2
    16  * License URI: http://www.gnu.org/licenses/gpl-3.0.html
    1714 *
    1815 * @package Booster_For_WooCommerce
    19  **/
     16 */
    2017
    2118if ( ! defined( 'ABSPATH' ) ) {
    22     exit; // Exit if accessed directly.
     19    exit;
    2320}
    2421
     
    3633    function () {
    3734        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            );
    3940        }
    4041    }
    4142);
    4243
    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.
     45if (
     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    )
    4953) {
    5054    return;
     
    5256
    5357if ( ! defined( 'WCJ_FREE_PLUGIN_FILE' ) ) {
    54     /**
    55      * WCJ_FREE_PLUGIN_FILE.
    56      *
    57      * @since 5.6.1
    58      */
    5958    define( 'WCJ_FREE_PLUGIN_FILE', __FILE__ );
    6059}
     
    6362
    6463    /**
    65      * Main WC_Jetpack Class
     64     * Main Booster for WooCommerce class.
    6665     *
    67      * @class   WC_Jetpack
    68      * @version 5.6.0
    69      * @since   1.0.0
     66     * @since 1.0.0
    7067     */
    7168    final class WC_Jetpack {
    7269
    7370        /**
    74          * Booster for WooCommerce version.
     71         * Plugin version.
    7572         *
    76          * @var   string
    77          * @since 2.4.7
     73         * @var string
    7874         */
    79         public $version = '7.9.0';
     75        public $version = '7.11.0';
    8076
    8177        /**
    82          * The single instance of the class
     78         * Singleton instance.
    8379         *
    84          * @var WC_Jetpack The single instance of the class
     80         * @var WC_Jetpack|null
    8581         */
    8682        protected static $instances = null;
    8783
    8884        /**
    89          * WC Jetpack
    90          *
    91          * @version 5.3.3
    92          * @since   5.3.3
     85         * Plugin options.
    9386         *
    9487         * @var array
     
    9790
    9891        /**
    99          * WC Jetpack
    100          *
    101          * @version 7.1.6
     92         * Registered shortcodes.
    10293         *
    10394         * @var array
     
    10697
    10798        /**
    108          * WC Jetpack
    109          *
    110          * @version 7.1.6
     99         * Active modules.
    111100         *
    112101         * @var array
     
    115104
    116105        /**
    117          * WC Jetpack
    118          *
    119          * @version 7.1.6
     106         * All available modules.
    120107         *
    121108         * @var array
     
    124111
    125112        /**
    126          * WC Jetpack
    127          *
    128          * @version 7.1.6
     113         * Module statuses.
    129114         *
    130115         * @var array
     
    133118
    134119        /**
    135          * Main WC_Jetpack Instance.
     120         * Get main instance (Singleton).
    136121         *
    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
    144123         */
    145124        public static function instance() {
     
    151130
    152131        /**
    153          * WC_Jetpack Constructor.
    154          *
    155          * @version 3.2.4
    156          * @since   1.0.0
    157          * @access  public
     132         * Class constructor.
    158133         */
    159134        public function __construct() {
     
    164139endif;
    165140
    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.
     142require_once __DIR__ . '/includes/wcj-free-functions.php';
     143
     144// Plugin usage tracking.
     145if ( ! class_exists( 'Plugin_Usage_Tracker' ) ) {
     146    include_once __DIR__ . '/tracking/class-plugin-usage-tracker.php';
    177147}
    178148
    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.
    238150add_action( 'plugins_loaded', 'w_c_j' );
    239 
    240 // Activation redirect - only on FIRST ever activation (not reactivations or updates).
     151register_uninstall_hook( __FILE__, 'wcj_delete_free_plugin_database_option' );
    241152register_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 transient
    247  * to trigger a redirect to the Getting Started page.
    248  * Only triggers on first-ever activation, not reactivations.
    249  *
    250  * @return void
    251  */
    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.
    267153add_action( 'admin_init', 'wcj_redirect_after_first_activation_free' );
    268154
    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.
     156woocommerce_jetpack_start_plugin_tracking();
Note: See TracChangeset for help on using the changeset viewer.