Plugin Directory

Changeset 3488708


Ignore:
Timestamp:
03/23/2026 08:48:07 AM (9 days ago)
Author:
flexcubed
Message:

Refactor script registration to include dependencies for admin and front-end scripts, and suppress session start errors in customization function.

Location:
pitchprint
Files:
20 edited
1 copied

Legend:

Unmodified
Added
Removed
  • pitchprint/tags/11.3.0/CHANGELOG.txt

    r3479889 r3488708  
     1== 11.3.0 =
     2Improved user identification for customization data isolation
     3Improved session handling reliability
     4Replaced deprecated wc_enqueue_js with wp_add_inline_script
     5
    16== 11.2.0 =
    27Fixed a vulnerability issue confined to uploads the plugin folder
  • pitchprint/tags/11.3.0/functions/admin/designs.php

    r3286188 r3488708  
    8989       
    9090        $credentials = \pitchprint\functions\general\fetch_credentials();
    91         wc_enqueue_js( PITCHPRINT_ADMIN_DEF . "
     91        $pp_inline_js = PITCHPRINT_ADMIN_DEF . "
    9292            PPADMIN.vars = {
    9393                credentials: { timestamp: '" . $credentials['timestamp'] . "', apiKey: '" . get_option('ppa_api_key') . "', signature: '" . $credentials['signature'] . "'},
     
    9696            PPADMIN.readyFncs.push('init', 'fetchDesigns');
    9797            if (typeof PPADMIN.start !== 'undefined') PPADMIN.start();
    98         ");
     98        ";
     99        wp_register_script('pitchprint-admin-designs', '', array('pitchprint_admin'), false, true);
     100        wp_enqueue_script('pitchprint-admin-designs');
     101        wp_add_inline_script('pitchprint-admin-designs', $pp_inline_js);
    99102
    100103    }
  • pitchprint/tags/11.3.0/functions/admin/orders.php

    r3391124 r3488708  
    2222        $cred = \pitchprint\functions\general\fetch_credentials();
    2323        wp_enqueue_script('pitchprint_admin', 'https://pitchprint.io/rsc/js/a.wp.js');
    24         wc_enqueue_js( "var PPADMIN = window.PPADMIN; if (typeof PPADMIN === 'undefined') window.PPADMIN = PPADMIN = { version: '9.0.0', readyFncs: [] };" . "
     24        $pp_inline_js = "var PPADMIN = window.PPADMIN; if (typeof PPADMIN === 'undefined') window.PPADMIN = PPADMIN = { version: '9.0.0', readyFncs: [] };" . "
    2525            PPADMIN.vars = {
    2626                credentials: { timestamp: '" . $cred['timestamp'] . "', apiKey: '" . get_option('ppa_api_key') . "', signature: '" . $cred['signature'] . "'}
     
    2828            PPADMIN.readyFncs.push('init');
    2929            if (typeof PPADMIN.start !== 'undefined') PPADMIN.start();
    30         ");
     30        ";
     31        wp_register_script('pitchprint-admin-order', '', array('pitchprint_admin'), false, true);
     32        wp_enqueue_script('pitchprint-admin-order');
     33        wp_add_inline_script('pitchprint-admin-order', $pp_inline_js);
    3134    }
    3235    function format_pitchprint_order_value($formatted_meta, $order_item) {
  • pitchprint/tags/11.3.0/functions/admin/settings.php

    r3404073 r3488708  
    4444        'ppa_settings_section'
    4545    );
     46    add_settings_field(
     47        'ppa_disable_session',
     48        __('Disable Session Backup', 'PitchPrint'),
     49        'pitchprint\\functions\\admin\\ppa_disable_session',
     50        'pitchprint',
     51        'ppa_settings_section'
     52    );
    4653
    4754    // Register settings with sanitization callbacks
     
    6067    ]);
    6168    register_setting('pitchprint', 'ppa_email_download_link', [
     69        'sanitize_callback' => 'sanitize_text_field'
     70    ]);
     71    register_setting('pitchprint', 'ppa_disable_session', [
    6272        'sanitize_callback' => 'sanitize_text_field'
    6373    ]);
     
    8696}
    8797
     98function ppa_disable_session() {
     99    $checked = checked(get_option('ppa_disable_session'), 'on', false);
     100    echo '<input id="ppa_disable_session" name="ppa_disable_session" type="checkbox" ' . $checked . ' />';
     101    echo '<label for="ppa_disable_session">' . __('Disable PHP session backup (enable this if your host uses Batcache or similar page caching)', 'PitchPrint') . '</label>';
     102}
     103
    88104function add_settings_link($links) {
    89105    $settings_link = [
  • pitchprint/tags/11.3.0/functions/front/accounts.php

    r3286188 r3488708  
    1313       
    1414        echo '<div id="pp_mydesigns_div"></div>';
    15         wc_enqueue_js("
     15        $pp_inline_js = "
    1616            ajaxsearch = undefined;
    1717            (function(_doc) {
     
    2828                    isCheckoutPage: " . (is_checkout() ? 'true' : 'false') . "
    2929                });
    30             })(document);");
     30            })(document);";
     31        wp_register_script('pitchprint-account-init', '', array('pitchprint_class'), false, true);
     32        wp_enqueue_script('pitchprint-account-init');
     33        wp_add_inline_script('pitchprint-account-init', $pp_inline_js);
    3134    }
    3235   
  • pitchprint/tags/11.3.0/functions/front/customize_button.php

    r3391124 r3488708  
    6969        $upload_path = file_exists(ABSPATH . 'pitchprint/uploader') ? 'pitchprint/uploader/' : 'wp-content/plugins/pitchprint/uploader/';
    7070
    71         wc_enqueue_js("
     71        $pp_inline_js = "
    7272            ajaxsearch = undefined;
    7373            (function(_doc) {
     
    100100                    ppValue: '{$now_value}',
    101101                });
    102             })(document);");
     102            })(document);";
     103        wp_register_script('pitchprint-product-init', '', array('pitchprint_class'), false, true);
     104        wp_enqueue_script('pitchprint-product-init');
     105        wp_add_inline_script('pitchprint-product-init', $pp_inline_js);
    103106
    104107        echo '<input type="hidden" id="_w2p_set_option" name="_w2p_set_option" value="' . $now_value . '" />
  • pitchprint/tags/11.3.0/functions/front/projects.php

    r3286188 r3488708  
    66
    77    function save_project_sess() {
    8 
     8       
    99        if (!isset($_POST['productId']) || empty($_POST['productId'])) {
    1010            wp_send_json_error('No product ID provided');
     
    3535
    3636    function reset_project_sess() {
     37
    3738        if (!isset($_POST['productId']) || empty($_POST['productId'])) {
    3839            wp_send_json_error('No product ID provided.');
  • pitchprint/tags/11.3.0/functions/general/customization.php

    r3296178 r3488708  
    33    namespace pitchprint\functions\general;
    44
    5     function get_user_token() {
    6         if (isset($_COOKIE[PITCHPRINT_CUSTOMIZATION_KEY]))
    7             return $_COOKIE[PITCHPRINT_CUSTOMIZATION_KEY];
    8    
    9         // Generate a random token for the user (guest or signed-in)
    10         if (!headers_sent()) {
    11             $token = bin2hex(random_bytes(16));
    12             $cookie_set = setcookie(PITCHPRINT_CUSTOMIZATION_KEY, $token, time() + PITCHPRINT_CUSTOMIZATION_DURATION, '/');
    13            
    14             if (!$cookie_set) {
    15                 // Handle error if cookie cannot be set
    16                 error_log('[PITCHPRINT] Failed to set cookie: ' . PRINT_APP_CUSTOMIZATION_KEY);
    17             } else {
    18                 return $token;
    19             }
     5    function use_session_backup() {
     6        return get_option('ppa_disable_session') !== 'on';
     7    }
     8
     9    function ensure_session() {
     10        if (use_session_backup() && session_status() === PHP_SESSION_NONE && !headers_sent()) {
     11            @session_start();
    2012        }
    2113    }
    2214
    23     // Sanitize and validate inputs for better security
     15    function get_user_token() {
     16        // For logged-in WordPress users, use their user ID as the token.
     17        // This ensures data isolation even if cookies are lost or shared.
     18        $user_id = get_current_user_id();
     19        if ($user_id > 0) {
     20            return 'user_' . $user_id;
     21        }
     22
     23        // For guests, use the cookie token managed by the JS client
     24        if (isset($_COOKIE[PITCHPRINT_CUSTOMIZATION_KEY]) && !empty($_COOKIE[PITCHPRINT_CUSTOMIZATION_KEY])) {
     25            return sanitize_text_field($_COOKIE[PITCHPRINT_CUSTOMIZATION_KEY]);
     26        }
     27
     28        return false;
     29    }
     30
    2431    function save_customization_data($product_id, $customization_data) {
    25         $product_id = absint($product_id); // Ensure product_id is an integer
    26         $customization_data = wp_unslash($customization_data); // Remove slashes from input
     32        $product_id = absint($product_id);
     33        $customization_data = wp_unslash($customization_data);
    2734       
    2835        $user_token = get_user_token();
    2936        if (!is_string($user_token) || empty($user_token)) {
    30             return false; // Invalid token
     37            return false;
    3138        }
    3239        $key = 'pitchprint_' . $user_token . '_' . $product_id;
    3340
    34         // Try saving to transient first
    3541        delete_transient($key);
    36         $transient_result = set_transient($key, $customization_data, PITCHPRINT_CUSTOMIZATION_DURATION);
     42        $result = set_transient($key, $customization_data, PITCHPRINT_CUSTOMIZATION_DURATION);
    3743
    38         // Also save to session as a backup
    39         if (!headers_sent() && session_status() === PHP_SESSION_NONE) {
    40             session_start();
     44        // Session backup for hosts that allow it
     45        ensure_session();
     46        if (session_status() === PHP_SESSION_ACTIVE) {
     47            $_SESSION[$key] = $customization_data;
    4148        }
    42         $_SESSION[$key] = $customization_data;
    4349
    44         // Return the key if transient save was successful, otherwise FALSE
    45         return $transient_result !== FALSE ? $key : FALSE;
     50        return $result !== FALSE ? $key : FALSE;
    4651    }
    4752
     
    4954        $user_token = get_user_token();
    5055        if (!is_string($user_token) || empty($user_token)) {
    51             return false; // Invalid token
     56            return false;
    5257        }
    5358        $key = 'pitchprint_' . $user_token . '_' . $product_id;
    5459
    55         // Try getting from transient first
    5660        $data = get_transient($key);
    57 
    5861        if ($data !== false) {
    5962            return $data;
    6063        }
    6164
    62         // If transient failed or expired, try getting from session
    63         if (!headers_sent() && session_status() === PHP_SESSION_NONE) {
    64             session_start();
    65         }
    66 
    67         if (isset($_SESSION[$key])) {
    68             // Optionally, restore the transient if found in session
     65        // Fall back to session if transient expired
     66        ensure_session();
     67        if (session_status() === PHP_SESSION_ACTIVE && isset($_SESSION[$key])) {
    6968            return $_SESSION[$key];
    7069        }
    7170
    72         return false; // Return false if not found in either
     71        return false;
    7372    }
    7473
     
    7675        $user_token = get_user_token();
    7776        if (!is_string($user_token) || empty($user_token)) {
    78             return false; // Invalid token
     77            return false;
    7978        }
    8079        $key = 'pitchprint_' . $user_token . '_' . $product_id;
    8180
    82         // Delete from transient
    8381        delete_transient($key);
    8482
    85         // Delete from session
    86         if (!headers_sent() && session_status() === PHP_SESSION_NONE) {
    87             session_start();
    88         }
    89         if (isset($_SESSION[$key])) {
     83        ensure_session();
     84        if (session_status() === PHP_SESSION_ACTIVE && isset($_SESSION[$key])) {
    9085            unset($_SESSION[$key]);
    9186        }
  • pitchprint/tags/11.3.0/pitchprint.php

    r3479889 r3488708  
    66*   Description:            A beautiful web based print customization app for your online store. Integrates with WooCommerce.
    77*   Author:                 PitchPrint, Inc.
    8 *   Version:                11.2.0
     8*   Version:                11.3.0
    99*   Author URI:             https://pitchprint.com
    1010*   Requires at least:      3.8
     
    4747             *  @var string
    4848            */
    49             public $version = '11.2.0';
     49            public $version = '11.3.0';
    5050
    5151            /**
  • pitchprint/tags/11.3.0/readme.txt

    r3479889 r3488708  
    44Requires at least: 3.8
    55Tested up to: 6.8
    6 Stable tag: 11.2.0
     6Stable tag: 11.3.0
    77License: GPLv2 or later
    88License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    172172
    173173== Changelog ==
     174
     175== 11.3.0 =
     176Improved user identification for customization data isolation
     177Improved session handling reliability
     178Replaced deprecated wc_enqueue_js with wp_add_inline_script
    174179
    175180== 11.2.0 =
  • pitchprint/trunk/CHANGELOG.txt

    r3479889 r3488708  
     1== 11.3.0 =
     2Improved user identification for customization data isolation
     3Improved session handling reliability
     4Replaced deprecated wc_enqueue_js with wp_add_inline_script
     5
    16== 11.2.0 =
    27Fixed a vulnerability issue confined to uploads the plugin folder
  • pitchprint/trunk/functions/admin/designs.php

    r3286188 r3488708  
    8989       
    9090        $credentials = \pitchprint\functions\general\fetch_credentials();
    91         wc_enqueue_js( PITCHPRINT_ADMIN_DEF . "
     91        $pp_inline_js = PITCHPRINT_ADMIN_DEF . "
    9292            PPADMIN.vars = {
    9393                credentials: { timestamp: '" . $credentials['timestamp'] . "', apiKey: '" . get_option('ppa_api_key') . "', signature: '" . $credentials['signature'] . "'},
     
    9696            PPADMIN.readyFncs.push('init', 'fetchDesigns');
    9797            if (typeof PPADMIN.start !== 'undefined') PPADMIN.start();
    98         ");
     98        ";
     99        wp_register_script('pitchprint-admin-designs', '', array('pitchprint_admin'), false, true);
     100        wp_enqueue_script('pitchprint-admin-designs');
     101        wp_add_inline_script('pitchprint-admin-designs', $pp_inline_js);
    99102
    100103    }
  • pitchprint/trunk/functions/admin/orders.php

    r3391124 r3488708  
    2222        $cred = \pitchprint\functions\general\fetch_credentials();
    2323        wp_enqueue_script('pitchprint_admin', 'https://pitchprint.io/rsc/js/a.wp.js');
    24         wc_enqueue_js( "var PPADMIN = window.PPADMIN; if (typeof PPADMIN === 'undefined') window.PPADMIN = PPADMIN = { version: '9.0.0', readyFncs: [] };" . "
     24        $pp_inline_js = "var PPADMIN = window.PPADMIN; if (typeof PPADMIN === 'undefined') window.PPADMIN = PPADMIN = { version: '9.0.0', readyFncs: [] };" . "
    2525            PPADMIN.vars = {
    2626                credentials: { timestamp: '" . $cred['timestamp'] . "', apiKey: '" . get_option('ppa_api_key') . "', signature: '" . $cred['signature'] . "'}
     
    2828            PPADMIN.readyFncs.push('init');
    2929            if (typeof PPADMIN.start !== 'undefined') PPADMIN.start();
    30         ");
     30        ";
     31        wp_register_script('pitchprint-admin-order', '', array('pitchprint_admin'), false, true);
     32        wp_enqueue_script('pitchprint-admin-order');
     33        wp_add_inline_script('pitchprint-admin-order', $pp_inline_js);
    3134    }
    3235    function format_pitchprint_order_value($formatted_meta, $order_item) {
  • pitchprint/trunk/functions/admin/settings.php

    r3404073 r3488708  
    4444        'ppa_settings_section'
    4545    );
     46    add_settings_field(
     47        'ppa_disable_session',
     48        __('Disable Session Backup', 'PitchPrint'),
     49        'pitchprint\\functions\\admin\\ppa_disable_session',
     50        'pitchprint',
     51        'ppa_settings_section'
     52    );
    4653
    4754    // Register settings with sanitization callbacks
     
    6067    ]);
    6168    register_setting('pitchprint', 'ppa_email_download_link', [
     69        'sanitize_callback' => 'sanitize_text_field'
     70    ]);
     71    register_setting('pitchprint', 'ppa_disable_session', [
    6272        'sanitize_callback' => 'sanitize_text_field'
    6373    ]);
     
    8696}
    8797
     98function ppa_disable_session() {
     99    $checked = checked(get_option('ppa_disable_session'), 'on', false);
     100    echo '<input id="ppa_disable_session" name="ppa_disable_session" type="checkbox" ' . $checked . ' />';
     101    echo '<label for="ppa_disable_session">' . __('Disable PHP session backup (enable this if your host uses Batcache or similar page caching)', 'PitchPrint') . '</label>';
     102}
     103
    88104function add_settings_link($links) {
    89105    $settings_link = [
  • pitchprint/trunk/functions/front/accounts.php

    r3286188 r3488708  
    1313       
    1414        echo '<div id="pp_mydesigns_div"></div>';
    15         wc_enqueue_js("
     15        $pp_inline_js = "
    1616            ajaxsearch = undefined;
    1717            (function(_doc) {
     
    2828                    isCheckoutPage: " . (is_checkout() ? 'true' : 'false') . "
    2929                });
    30             })(document);");
     30            })(document);";
     31        wp_register_script('pitchprint-account-init', '', array('pitchprint_class'), false, true);
     32        wp_enqueue_script('pitchprint-account-init');
     33        wp_add_inline_script('pitchprint-account-init', $pp_inline_js);
    3134    }
    3235   
  • pitchprint/trunk/functions/front/customize_button.php

    r3391124 r3488708  
    6969        $upload_path = file_exists(ABSPATH . 'pitchprint/uploader') ? 'pitchprint/uploader/' : 'wp-content/plugins/pitchprint/uploader/';
    7070
    71         wc_enqueue_js("
     71        $pp_inline_js = "
    7272            ajaxsearch = undefined;
    7373            (function(_doc) {
     
    100100                    ppValue: '{$now_value}',
    101101                });
    102             })(document);");
     102            })(document);";
     103        wp_register_script('pitchprint-product-init', '', array('pitchprint_class'), false, true);
     104        wp_enqueue_script('pitchprint-product-init');
     105        wp_add_inline_script('pitchprint-product-init', $pp_inline_js);
    103106
    104107        echo '<input type="hidden" id="_w2p_set_option" name="_w2p_set_option" value="' . $now_value . '" />
  • pitchprint/trunk/functions/front/projects.php

    r3286188 r3488708  
    66
    77    function save_project_sess() {
    8 
     8       
    99        if (!isset($_POST['productId']) || empty($_POST['productId'])) {
    1010            wp_send_json_error('No product ID provided');
     
    3535
    3636    function reset_project_sess() {
     37
    3738        if (!isset($_POST['productId']) || empty($_POST['productId'])) {
    3839            wp_send_json_error('No product ID provided.');
  • pitchprint/trunk/functions/general/customization.php

    r3296178 r3488708  
    33    namespace pitchprint\functions\general;
    44
    5     function get_user_token() {
    6         if (isset($_COOKIE[PITCHPRINT_CUSTOMIZATION_KEY]))
    7             return $_COOKIE[PITCHPRINT_CUSTOMIZATION_KEY];
    8    
    9         // Generate a random token for the user (guest or signed-in)
    10         if (!headers_sent()) {
    11             $token = bin2hex(random_bytes(16));
    12             $cookie_set = setcookie(PITCHPRINT_CUSTOMIZATION_KEY, $token, time() + PITCHPRINT_CUSTOMIZATION_DURATION, '/');
    13            
    14             if (!$cookie_set) {
    15                 // Handle error if cookie cannot be set
    16                 error_log('[PITCHPRINT] Failed to set cookie: ' . PRINT_APP_CUSTOMIZATION_KEY);
    17             } else {
    18                 return $token;
    19             }
     5    function use_session_backup() {
     6        return get_option('ppa_disable_session') !== 'on';
     7    }
     8
     9    function ensure_session() {
     10        if (use_session_backup() && session_status() === PHP_SESSION_NONE && !headers_sent()) {
     11            @session_start();
    2012        }
    2113    }
    2214
    23     // Sanitize and validate inputs for better security
     15    function get_user_token() {
     16        // For logged-in WordPress users, use their user ID as the token.
     17        // This ensures data isolation even if cookies are lost or shared.
     18        $user_id = get_current_user_id();
     19        if ($user_id > 0) {
     20            return 'user_' . $user_id;
     21        }
     22
     23        // For guests, use the cookie token managed by the JS client
     24        if (isset($_COOKIE[PITCHPRINT_CUSTOMIZATION_KEY]) && !empty($_COOKIE[PITCHPRINT_CUSTOMIZATION_KEY])) {
     25            return sanitize_text_field($_COOKIE[PITCHPRINT_CUSTOMIZATION_KEY]);
     26        }
     27
     28        return false;
     29    }
     30
    2431    function save_customization_data($product_id, $customization_data) {
    25         $product_id = absint($product_id); // Ensure product_id is an integer
    26         $customization_data = wp_unslash($customization_data); // Remove slashes from input
     32        $product_id = absint($product_id);
     33        $customization_data = wp_unslash($customization_data);
    2734       
    2835        $user_token = get_user_token();
    2936        if (!is_string($user_token) || empty($user_token)) {
    30             return false; // Invalid token
     37            return false;
    3138        }
    3239        $key = 'pitchprint_' . $user_token . '_' . $product_id;
    3340
    34         // Try saving to transient first
    3541        delete_transient($key);
    36         $transient_result = set_transient($key, $customization_data, PITCHPRINT_CUSTOMIZATION_DURATION);
     42        $result = set_transient($key, $customization_data, PITCHPRINT_CUSTOMIZATION_DURATION);
    3743
    38         // Also save to session as a backup
    39         if (!headers_sent() && session_status() === PHP_SESSION_NONE) {
    40             session_start();
     44        // Session backup for hosts that allow it
     45        ensure_session();
     46        if (session_status() === PHP_SESSION_ACTIVE) {
     47            $_SESSION[$key] = $customization_data;
    4148        }
    42         $_SESSION[$key] = $customization_data;
    4349
    44         // Return the key if transient save was successful, otherwise FALSE
    45         return $transient_result !== FALSE ? $key : FALSE;
     50        return $result !== FALSE ? $key : FALSE;
    4651    }
    4752
     
    4954        $user_token = get_user_token();
    5055        if (!is_string($user_token) || empty($user_token)) {
    51             return false; // Invalid token
     56            return false;
    5257        }
    5358        $key = 'pitchprint_' . $user_token . '_' . $product_id;
    5459
    55         // Try getting from transient first
    5660        $data = get_transient($key);
    57 
    5861        if ($data !== false) {
    5962            return $data;
    6063        }
    6164
    62         // If transient failed or expired, try getting from session
    63         if (!headers_sent() && session_status() === PHP_SESSION_NONE) {
    64             session_start();
    65         }
    66 
    67         if (isset($_SESSION[$key])) {
    68             // Optionally, restore the transient if found in session
     65        // Fall back to session if transient expired
     66        ensure_session();
     67        if (session_status() === PHP_SESSION_ACTIVE && isset($_SESSION[$key])) {
    6968            return $_SESSION[$key];
    7069        }
    7170
    72         return false; // Return false if not found in either
     71        return false;
    7372    }
    7473
     
    7675        $user_token = get_user_token();
    7776        if (!is_string($user_token) || empty($user_token)) {
    78             return false; // Invalid token
     77            return false;
    7978        }
    8079        $key = 'pitchprint_' . $user_token . '_' . $product_id;
    8180
    82         // Delete from transient
    8381        delete_transient($key);
    8482
    85         // Delete from session
    86         if (!headers_sent() && session_status() === PHP_SESSION_NONE) {
    87             session_start();
    88         }
    89         if (isset($_SESSION[$key])) {
     83        ensure_session();
     84        if (session_status() === PHP_SESSION_ACTIVE && isset($_SESSION[$key])) {
    9085            unset($_SESSION[$key]);
    9186        }
  • pitchprint/trunk/pitchprint.php

    r3479889 r3488708  
    66*   Description:            A beautiful web based print customization app for your online store. Integrates with WooCommerce.
    77*   Author:                 PitchPrint, Inc.
    8 *   Version:                11.2.0
     8*   Version:                11.3.0
    99*   Author URI:             https://pitchprint.com
    1010*   Requires at least:      3.8
     
    4747             *  @var string
    4848            */
    49             public $version = '11.2.0';
     49            public $version = '11.3.0';
    5050
    5151            /**
  • pitchprint/trunk/readme.txt

    r3479889 r3488708  
    44Requires at least: 3.8
    55Tested up to: 6.8
    6 Stable tag: 11.2.0
     6Stable tag: 11.3.0
    77License: GPLv2 or later
    88License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    172172
    173173== Changelog ==
     174
     175== 11.3.0 =
     176Improved user identification for customization data isolation
     177Improved session handling reliability
     178Replaced deprecated wc_enqueue_js with wp_add_inline_script
    174179
    175180== 11.2.0 =
Note: See TracChangeset for help on using the changeset viewer.