Changeset 3390673
- Timestamp:
- 11/05/2025 07:12:31 PM (5 months ago)
- Location:
- inventory-presser/trunk
- Files:
-
- 15 edited
-
includes/addon/class-addon-updater.php (modified) (14 diffs)
-
includes/addon/class-addon.php (modified) (1 diff)
-
includes/integrations/class-classic-editor.php (modified) (1 diff)
-
inventory-presser.php (modified) (5 diffs)
-
languages/inventory-presser-en-GB.po (modified) (1 diff)
-
languages/inventory-presser-es-CL.po (modified) (1 diff)
-
languages/inventory-presser-es-CO.po (modified) (1 diff)
-
languages/inventory-presser-es-MX.po (modified) (1 diff)
-
languages/inventory-presser-es.po (modified) (1 diff)
-
languages/inventory-presser-nl.po (modified) (1 diff)
-
languages/inventory-presser-nl_NL.po (modified) (1 diff)
-
languages/inventory-presser.pot (modified) (1 diff)
-
package-lock.json (modified) (2 diffs)
-
package.json (modified) (1 diff)
-
readme.txt (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
inventory-presser/trunk/includes/addon/class-addon-updater.php
r3207679 r3390673 46 46 $this->wp_override = isset( $_api_data['wp_override'] ) ? (bool) $_api_data['wp_override'] : false; 47 47 $this->beta = ! empty( $this->api_data['beta'] ) ? true : false; 48 $this->cache_key = 'edd_sl_' . md5( serialize( $this->slug . $this->api_data['license'] . $this->beta ) );48 $this->cache_key = 'edd_sl_' . md5( wp_json_encode( $this->slug . $this->api_data['license'] . $this->beta ) ); 49 49 50 50 $edd_plugin_data[ $this->slug ] = $this->api_data; … … 87 87 88 88 /** 89 * Ensures updaters are initialized for all addon plugins in multisite, even if plugins aren't active on the main site. 90 * This is called via a static hook registered in Inventory_Presser_Addon. 91 * 92 * @param object $_transient_data Update array build by WordPress. 93 * @return object 94 */ 95 public static function ensure_addon_updaters_initialized( $_transient_data ) { 96 if ( ! is_multisite() ) { 97 return $_transient_data; 98 } 99 100 // Map of plugin slugs to their details 101 $addon_plugins = array( 102 'make-list-widget' => array( 103 'option_name' => 'make_list_widget_settings', 104 'item_id' => 607, 105 'class_name' => 'Make_List_Addon', 106 ), 107 'taxonomy-filters-widget' => array( 108 'option_name' => 'invp_filters_widget_settings', 109 'item_id' => 597, 110 'class_name' => 'Taxonomy_Filters_Addon', 111 ), 112 'taxonomy-drop-down-search-widget' => array( 113 'option_name' => 'invp_drop_down_widget_settings', 114 'item_id' => 599, 115 'class_name' => 'Dropdown_Search_Addon', 116 ), 117 ); 118 119 // Check if updaters are already initialized 120 global $edd_plugin_data; 121 if ( ! isset( $edd_plugin_data ) ) { 122 $edd_plugin_data = array(); 123 } 124 125 // Get all installed plugins 126 $all_plugins = get_plugins(); 127 128 foreach ( $addon_plugins as $slug => $plugin_info ) { 129 // Find the plugin file 130 $plugin_file = null; 131 foreach ( $all_plugins as $file => $plugin_data ) { 132 if ( strpos( $file, $slug ) !== false ) { 133 $plugin_file = $file; 134 break; 135 } 136 } 137 138 if ( ! $plugin_file ) { 139 continue; 140 } 141 142 // Check if updater is already initialized 143 if ( isset( $edd_plugin_data[ $slug ] ) ) { 144 continue; 145 } 146 147 // Try to get license key from any site, and remember which site it came from 148 $license_key = ''; 149 $license_site_url = ''; 150 $sites = get_sites( array( 'number' => 100 ) ); 151 foreach ( $sites as $site ) { 152 switch_to_blog( $site->blog_id ); 153 $options = get_option( $plugin_info['option_name'] ); 154 if ( ! empty( $options['license_key'] ) ) { 155 $license_key = $options['license_key']; 156 // Use the site URL where the license key was found 157 // This ensures the license validation matches the registered site 158 $license_site_url = home_url(); 159 restore_current_blog(); 160 break; 161 } 162 restore_current_blog(); 163 } 164 165 // If we found a license key, initialize the updater 166 if ( ! empty( $license_key ) && class_exists( 'Inventory_Presser_Addon_Updater' ) ) { 167 // Get plugin version from file 168 $plugin_path = WP_PLUGIN_DIR . '/' . $plugin_file; 169 if ( file_exists( $plugin_path ) ) { 170 $plugin_data = get_file_data( $plugin_path, array( 'Version' => 'Version' ) ); 171 $version = ! empty( $plugin_data['Version'] ) ? $plugin_data['Version'] : '1.0.0'; 172 173 // Use the site URL where the license key was found, or fall back to network URL 174 $site_url = ! empty( $license_site_url ) ? $license_site_url : network_home_url(); 175 176 $updater = new Inventory_Presser_Addon_Updater( 177 'https://inventorypresser.com', 178 $plugin_file, 179 array( 180 'version' => $version, 181 'license' => $license_key, 182 'item_id' => $plugin_info['item_id'], 183 'author' => 'Corey Salzano', 184 'url' => $site_url, 185 'beta' => false, 186 ) 187 ); 188 } 189 } 190 } 191 192 return $_transient_data; 193 } 194 195 /** 89 196 * Removes the core "There is a new version of {plugin} available" 90 197 * notice on the plugins list. We are adding our own. … … 122 229 if ( ! empty( $_transient_data->response ) && ! empty( $_transient_data->response[ $this->name ] ) && false === $this->wp_override ) { 123 230 return $_transient_data; 231 } 232 233 // In multisite, if license key is empty, try to retrieve it before checking for updates. 234 // This ensures updates work even when plugins aren't active on the main site. 235 if ( is_multisite() && empty( $this->api_data['license'] ) ) { 236 $option_name_map = array( 237 'make-list-widget' => 'make_list_widget_settings', 238 'taxonomy-filters-widget' => 'invp_filters_widget_settings', 239 'taxonomy-drop-down-search-widget' => 'invp_drop_down_widget_settings', 240 ); 241 242 if ( isset( $option_name_map[ $this->slug ] ) ) { 243 $option_name = $option_name_map[ $this->slug ]; 244 $current_blog_id = get_current_blog_id(); 245 246 // Try current site first. 247 $options = get_option( $option_name ); 248 if ( ! empty( $options['license_key'] ) ) { 249 $this->api_data['license'] = $options['license_key']; 250 } else { 251 // If not found, check all sites in the network. 252 $sites = get_sites( array( 'number' => 100 ) ); 253 foreach ( $sites as $site ) { 254 switch_to_blog( $site->blog_id ); 255 $options = get_option( $option_name ); 256 if ( ! empty( $options['license_key'] ) ) { 257 $this->api_data['license'] = $options['license_key']; 258 restore_current_blog(); 259 break; 260 } 261 restore_current_blog(); 262 } 263 } 264 } 124 265 } 125 266 … … 148 289 $version_info = $this->get_cached_version_info(); 149 290 291 // If cached version info has empty package URL but we have a license key, clear cache and retry. 292 // This fixes multisite issues where plugins initialize before site options are available. 293 if ( false !== $version_info && empty( $version_info->package ) && ! empty( $this->api_data['license'] ) ) { 294 // Clear the cache and retry. 295 delete_option( $this->cache_key ); 296 $version_info = false; 297 } 298 150 299 if ( false === $version_info ) { 300 // If license key is empty, try to retrieve it dynamically. 301 // This is a fallback for multisite where site options may not be available during initialization. 302 if ( empty( $this->api_data['license'] ) ) { 303 // Try to get license key from global plugin data registry. 304 global $edd_plugin_data; 305 if ( ! empty( $edd_plugin_data[ $this->slug ]['license'] ) ) { 306 $this->api_data['license'] = $edd_plugin_data[ $this->slug ]['license']; 307 } 308 309 // If still empty and we're in multisite, try to get license key from site options. 310 // Map known plugin slugs to their option names. 311 if ( empty( $this->api_data['license'] ) && is_multisite() ) { 312 $option_name_map = array( 313 'make-list-widget' => 'make_list_widget_settings', 314 'taxonomy-filters-widget' => 'invp_filters_widget_settings', 315 'taxonomy-drop-down-search-widget' => 'invp_drop_down_widget_settings', 316 ); 317 318 if ( isset( $option_name_map[ $this->slug ] ) ) { 319 $option_name = $option_name_map[ $this->slug ]; 320 $current_blog_id = get_current_blog_id(); 321 322 // Try current site first. 323 $options = get_option( $option_name ); 324 if ( ! empty( $options['license_key'] ) ) { 325 $this->api_data['license'] = $options['license_key']; 326 } else { 327 // If not found, check all sites in the network. 328 $sites = get_sites( array( 'number' => 100 ) ); 329 foreach ( $sites as $site ) { 330 switch_to_blog( $site->blog_id ); 331 $options = get_option( $option_name ); 332 if ( ! empty( $options['license_key'] ) ) { 333 $this->api_data['license'] = $options['license_key']; 334 restore_current_blog(); 335 break; 336 } 337 restore_current_blog(); 338 } 339 } 340 341 // Update global registry if we found a license key. 342 if ( ! empty( $this->api_data['license'] ) ) { 343 if ( ! isset( $edd_plugin_data ) ) { 344 $edd_plugin_data = array(); 345 } 346 if ( ! isset( $edd_plugin_data[ $this->slug ] ) ) { 347 $edd_plugin_data[ $this->slug ] = array(); 348 } 349 $edd_plugin_data[ $this->slug ]['license'] = $this->api_data['license']; 350 } 351 } 352 } 353 } 354 151 355 $version_info = $this->api_request( 152 356 'plugin_latest_version', … … 205 409 // Is the problem a missing license key? 206 410 if ( ! empty( $update_response->msg ) 207 && 'No license key has been provided.' == $update_response->msg208 && ! in_array( $update_response->slug, $handled_plugin_slugs )411 && 'No license key has been provided.' === $update_response->msg 412 && ! in_array( $update_response->slug, $handled_plugin_slugs, true ) 209 413 && ( ! is_multisite() || is_blog_admin() ) 210 414 ) { … … 219 423 ?><script type="text/javascript"><!-- 220 424 jQuery(document).ready(function(){ 221 jQuery('#<?php echo $update_response->slug; ?>-update .update-message p em').html( 'License key is missing at Vehicles → Options');425 jQuery('#<?php echo esc_js( $update_response->slug ); ?>-update .update-message p em').html( 'License key is missing at Vehicles → Options'); 222 426 }); 223 427 --></script> … … 318 522 // build a plugin list row, with update notification. 319 523 printf( 320 '<tr class="plugin-update-tr active" id="%1$s-update" data-slug="%1$s" data-plugin="%2$s">'524 '<tr class="plugin-update-tr" id="%1$s-update" data-slug="%1$s" data-plugin="%2$s">' 321 525 . '<td colspan="4" class="plugin-update colspanchange">' 322 526 . '<div class="update-message notice inline notice-warning notice-alt"><p>', … … 532 736 } 533 737 738 // Use the URL from api_data if set (this is the site URL where the license key was found) 739 // Otherwise fall back to home_url() for backward compatibility 740 $request_url = ! empty( $data['url'] ) ? $data['url'] : home_url(); 741 534 742 $api_params = array( 535 743 'edd_action' => 'get_version', … … 540 748 'slug' => $data['slug'], 541 749 'author' => $data['author'], 542 'url' => home_url(),750 'url' => $request_url, 543 751 'beta' => ! empty( $data['beta'] ), 544 752 ); … … 586 794 global $edd_plugin_data; 587 795 588 if ( empty( $_REQUEST['edd_sl_action'] ) || 'view_plugin_changelog' != $_REQUEST['edd_sl_action']) {796 if ( empty( $_REQUEST['edd_sl_action'] ) || 'view_plugin_changelog' !== sanitize_text_field( wp_unslash( $_REQUEST['edd_sl_action'] ) ) ) { 589 797 return; 590 798 } … … 602 810 } 603 811 604 $data = $edd_plugin_data[ $_REQUEST['slug'] ]; 812 $slug = sanitize_text_field( wp_unslash( $_REQUEST['slug'] ) ); 813 $data = isset( $edd_plugin_data[ $slug ] ) ? $edd_plugin_data[ $slug ] : null; 814 815 if ( empty( $data ) ) { 816 return; 817 } 818 605 819 $version_info = $this->get_cached_version_info(); 606 820 … … 610 824 'item_name' => isset( $data['item_name'] ) ? $data['item_name'] : false, 611 825 'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false, 612 'slug' => $ _REQUEST['slug'],826 'slug' => $slug, 613 827 'author' => $data['author'], 614 828 'url' => home_url(), … … 645 859 646 860 // Delete the unneeded option. 647 delete_option( md5( 'edd_plugin_' . sanitize_key( $_REQUEST['plugin'] ) . '_' . $this->beta . '_version_info' ) ); 861 $plugin = sanitize_text_field( wp_unslash( $_REQUEST['plugin'] ) ); 862 delete_option( md5( 'edd_plugin_' . sanitize_key( $plugin ) . '_' . $this->beta . '_version_info' ) ); 648 863 } 649 864 … … 703 918 704 919 update_option( $cache_key, $data, false ); 705 706 // Delete the duplicate option.707 delete_option( 'edd_api_request_' . md5( serialize( $this->slug . $this->api_data['license'] . $this->beta ) ) );708 920 } 709 921 -
inventory-presser/trunk/includes/addon/class-addon.php
r3175088 r3390673 43 43 ) 44 44 ); 45 } 46 47 /** 48 * Ensures updaters are initialized for addon plugins in multisite. 49 * This is called early in the update process to ensure updaters exist even when plugins aren't active on the main site. 50 * 51 * @return void 52 */ 53 public static function ensure_multisite_updaters() { 54 if ( ! is_multisite() ) { 55 return; 56 } 57 58 if ( ! class_exists( 'Inventory_Presser_Addon_Updater' ) ) { 59 return; 60 } 61 62 // Hook into the update process early to ensure updaters are initialized 63 // Use priority 5 to run before other update checks (which use default priority 10) 64 add_filter( 'pre_set_site_transient_update_plugins', array( 'Inventory_Presser_Addon_Updater', 'ensure_addon_updaters_initialized' ), 5, 1 ); 45 65 } 46 66 -
inventory-presser/trunk/includes/integrations/class-classic-editor.php
r3247185 r3390673 461 461 462 462 // Payment frequency is a drop-down. 463 $meta_key = apply_filters( 'invp_prefix_meta_key', 'payment_frequency' ); 463 464 printf( 464 465 '<tr><th scope="row"><label for="%1$s">Payment frequency</label></th>' -
inventory-presser/trunk/inventory-presser.php
r3387769 r3390673 13 13 * Plugin URI: https://inventorypresser.com 14 14 * Description: Car listings with photo sliders for automobile and powersports dealerships. 15 * Version: 15.2. 315 * Version: 15.2.4 16 16 * Author: Friday Systems 17 17 * Author URI: https://inventorypresser.com … … 22 22 * GitHub Plugin URI: https://github.com/fridaysystems/inventory-presser 23 23 * Primary Branch: main 24 * Download URI: https://downloads.wordpress.org/plugin/inventory-presser.15.2. 3.zip25 * Download URI: https://inventorypresser.com/wp-content/uploads/inventory-presser-v15.2. 3.zip24 * Download URI: https://downloads.wordpress.org/plugin/inventory-presser.15.2.4.zip 25 * Download URI: https://inventorypresser.com/wp-content/uploads/inventory-presser-v15.2.4.zip 26 26 */ 27 27 … … 33 33 } 34 34 if ( ! defined( 'INVP_PLUGIN_VERSION' ) ) { 35 define( 'INVP_PLUGIN_VERSION', '15.2. 3' );35 define( 'INVP_PLUGIN_VERSION', '15.2.4' ); 36 36 } 37 37 … … 632 632 $this->include_dependencies(); 633 633 634 // Ensure addon updaters are initialized in multisite. 635 if ( class_exists( 'Inventory_Presser_Addon' ) ) { 636 Inventory_Presser_Addon::ensure_multisite_updaters(); 637 } 638 634 639 // Prefix and unprefix meta keys with "inventory_presser_". 635 640 add_filter( 'invp_prefix_meta_key', array( 'INVP', 'translate_custom_field_names' ) ); … … 1019 1024 4 => __( 'Vehicle updated.', 'inventory-presser' ), 1020 1025 /* translators: 1. Formatted date timestamp of a post revision. */ 1021 5 => isset( $_GET['revision'] ) ? sprintf( __( 'Vehicle restored to revision from %s.', 'inventory-presser' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,1026 5 => isset( $_GET['revision'] ) ? sprintf( __( 'Vehicle restored to revision from %s.', 'inventory-presser' ), wp_post_revision_title( (int) wp_unslash( $_GET['revision'] ), false ) ) : false, 1022 1027 6 => __( 'Vehicle published. ', 'inventory-presser' ) . $view_link, 1023 1028 7 => __( 'Vehicle saved.', 'inventory-presser' ), -
inventory-presser/trunk/languages/inventory-presser-en-GB.po
r3387769 r3390673 1 1 msgid "" 2 2 msgstr "" 3 "Project-Id-Version: Inventory Presser 15.2. 3\n"3 "Project-Id-Version: Inventory Presser 15.2.4\n" 4 4 "Report-Msgid-Bugs-To: corey@friday.systems\n" 5 5 "Last-Translator: Corey Salzano <corey@friday.systems>\n" -
inventory-presser/trunk/languages/inventory-presser-es-CL.po
r3387769 r3390673 1 1 msgid "" 2 2 msgstr "" 3 "Project-Id-Version: Inventory Presser 15.2. 3\n"3 "Project-Id-Version: Inventory Presser 15.2.4\n" 4 4 "Report-Msgid-Bugs-To: corey@friday.systems\n" 5 5 "Last-Translator: Corey Salzano <corey@friday.systems>\n" -
inventory-presser/trunk/languages/inventory-presser-es-CO.po
r3387769 r3390673 1 1 msgid "" 2 2 msgstr "" 3 "Project-Id-Version: Inventory Presser 15.2. 3\n"3 "Project-Id-Version: Inventory Presser 15.2.4\n" 4 4 "Report-Msgid-Bugs-To: corey@friday.systems\n" 5 5 "Last-Translator: Corey Salzano <corey@friday.systems>\n" -
inventory-presser/trunk/languages/inventory-presser-es-MX.po
r3387769 r3390673 1 1 msgid "" 2 2 msgstr "" 3 "Project-Id-Version: Inventory Presser 15.2. 3\n"3 "Project-Id-Version: Inventory Presser 15.2.4\n" 4 4 "Report-Msgid-Bugs-To: corey@friday.systems\n" 5 5 "Last-Translator: Corey Salzano <corey@friday.systems>\n" -
inventory-presser/trunk/languages/inventory-presser-es.po
r3387769 r3390673 1 1 msgid "" 2 2 msgstr "" 3 "Project-Id-Version: Inventory Presser 15.2. 3\n"3 "Project-Id-Version: Inventory Presser 15.2.4\n" 4 4 "Report-Msgid-Bugs-To: corey@friday.systems\n" 5 5 "Last-Translator: Corey Salzano <corey@friday.systems>\n" -
inventory-presser/trunk/languages/inventory-presser-nl.po
r3387769 r3390673 1 1 msgid "" 2 2 msgstr "" 3 "Project-Id-Version: Inventory Presser 15.2. 3\n"3 "Project-Id-Version: Inventory Presser 15.2.4\n" 4 4 "Report-Msgid-Bugs-To: corey@friday.systems\n" 5 5 "Last-Translator: Corey Salzano <corey@friday.systems>\n" -
inventory-presser/trunk/languages/inventory-presser-nl_NL.po
r3387769 r3390673 3 3 msgid "" 4 4 msgstr "" 5 "Project-Id-Version: Inventory Presser 15.2. 3\n"5 "Project-Id-Version: Inventory Presser 15.2.4\n" 6 6 "Report-Msgid-Bugs-To: corey@friday.systems\n" 7 7 "Last-Translator: Corey Salzano <corey@friday.systems>\n" -
inventory-presser/trunk/languages/inventory-presser.pot
r3387769 r3390673 3 3 msgid "" 4 4 msgstr "" 5 "Project-Id-Version: Inventory Presser 15.2. 3\n"5 "Project-Id-Version: Inventory Presser 15.2.4\n" 6 6 "Report-Msgid-Bugs-To: corey@friday.systems\n" 7 7 "Last-Translator: Corey Salzano <corey@friday.systems>\n" -
inventory-presser/trunk/package-lock.json
r3387769 r3390673 1 1 { 2 2 "name": "inventory-presser", 3 "version": "15.2. 3",3 "version": "15.2.4", 4 4 "lockfileVersion": 3, 5 5 "requires": true, … … 7 7 "": { 8 8 "name": "inventory-presser", 9 "version": "15.2. 3",9 "version": "15.2.4", 10 10 "license": "GPL-2.0-only", 11 11 "devDependencies": { -
inventory-presser/trunk/package.json
r3387769 r3390673 1 1 { 2 2 "name": "inventory-presser", 3 "version": "15.2. 3",3 "version": "15.2.4", 4 4 "description": "Simple inventory listings & everything else", 5 5 "main": "build/index.js", -
inventory-presser/trunk/readme.txt
r3387769 r3390673 5 5 Tested up to: 6.8.3 6 6 Requires PHP: 7.0.0 7 Stable tag: 15.2. 37 Stable tag: 15.2.4 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 60 60 ### Downloads 61 61 62 * [https://downloads.wordpress.org/plugin/inventory-presser.15.2. 3.zip](https://downloads.wordpress.org/plugin/inventory-presser.15.2.3.zip)63 * [https://inventorypresser.com/wp-content/uploads/inventory-presser-v15.2. 3.zip](https://inventorypresser.com/wp-content/uploads/inventory-presser-v15.2.3.zip)62 * [https://downloads.wordpress.org/plugin/inventory-presser.15.2.4.zip](https://downloads.wordpress.org/plugin/inventory-presser.15.2.4.zip) 63 * [https://inventorypresser.com/wp-content/uploads/inventory-presser-v15.2.4.zip](https://inventorypresser.com/wp-content/uploads/inventory-presser-v15.2.4.zip) 64 64 65 65 … … 97 97 98 98 == Changelog == 99 100 = 15.2.4 = 101 * [Fixed] Fixes bugs when add-ons check for updates from multisite installations. 102 * [Fixed] Fixes a bug when saving payment and payment frequency in the Classic Editor. 103 * [Fixed] Fixes bugs around sanitizing and escaping data before using it. 99 104 100 105 = 15.2.3 = … … 323 328 == Upgrade Notice == 324 329 330 = 15.2.4 = 331 Fixes bugs when add-ons check for updates from multisite installations. Fixes a bug when saving payment and payment frequency in the Classic Editor. Fixes bugs around sanitizing and escaping data before using it. 332 325 333 = 15.2.3 = 326 334 Improves the Description block visibility by adding a placeholder "Enter vehicle description...". Adds a Description block to the editor when editing vehicles to help users locate where to put free-form vehicle content. Wraps the text "SOLD!" in a new filter `invp_sold_text` so that it can be changed. Prevent HTML encoding in single vehicle templates for sold and pending sale vehicles.
Note: See TracChangeset
for help on using the changeset viewer.