← All changes
|
libraries/freemius/includes/class-fs-plugin-updater.php
+80
-42
2.2
→
3.4
View file →
| @@ -36,8 +36,10 @@ | ||
| 36 | 36 | private $_translation_updates; |
| 37 | 37 | |
| 38 | 38 | private static $_upgrade_basename = null; |
| 39 | 39 | |
| 40 | + const UPDATES_CHECK_CACHE_EXPIRATION = ( WP_FS__TIME_24_HOURS_IN_SEC / 24 ); | |
| 41 | + | |
| 40 | 42 | #-------------------------------------------------------------------------------- |
| 41 | 43 | #region Singleton |
| 42 | 44 | #-------------------------------------------------------------------------------- |
| 43 | 45 | |
| @@ -103,8 +105,10 @@ | ||
| 103 | 105 | ), 11, 2 ); |
| 104 | 106 | |
| 105 | 107 | if ( ! $this->_fs->has_any_active_valid_license() ) { |
| 106 | 108 | add_action( 'admin_head', array( &$this, 'catch_plugin_information_dialog_contents' ) ); |
| 109 | + } else { | |
| 110 | + add_action( 'admin_footer', array( &$this, '_add_fs_allow_updater_and_dialog_request_param' ) ); | |
| 107 | 111 | } |
| 108 | 112 | |
| 109 | 113 | if ( ! WP_FS__IS_PRODUCTION_MODE ) { |
| 110 | 114 | add_filter( 'http_request_host_is_external', array( |
| @@ -128,15 +132,48 @@ | ||
| 128 | 132 | } |
| 129 | 133 | |
| 130 | 134 | /** |
| 131 | 135 | * @author Leo Fajardo (@leorw) |
| 136 | + * @since 2.7.4 | |
| 137 | + */ | |
| 138 | + function _add_fs_allow_updater_and_dialog_request_param() { | |
| 139 | + if ( ! $this->is_plugin_information_dialog_for_plugin() ) { | |
| 140 | + return; | |
| 141 | + } | |
| 142 | + ?> | |
| 143 | + <script type="text/javascript"> | |
| 144 | + if ( typeof jQuery !== 'undefined' ) { | |
| 145 | + jQuery( document ).on( 'wp-plugin-updating', function( event, args ) { | |
| 146 | + if ( typeof args === 'object' && args.slug && typeof args.slug === 'string' ) { | |
| 147 | + if ( <?php echo json_encode( $this->_fs->get_slug() ) ?> === args.slug ) { | |
| 148 | + args.fs_allow_updater_and_dialog = true; | |
| 149 | + } | |
| 150 | + } | |
| 151 | + } ); | |
| 152 | + } | |
| 153 | + </script> | |
| 154 | + <?php | |
| 155 | + } | |
| 156 | + | |
| 157 | + /** | |
| 158 | + * @author Leo Fajardo (@leorw) | |
| 159 | + * @since 2.7.4 | |
| 160 | + * | |
| 161 | + * @return bool | |
| 162 | + */ | |
| 163 | + private function is_plugin_information_dialog_for_plugin() { | |
| 164 | + return ( | |
| 165 | + 'plugin-information' === fs_request_get( 'tab', false ) && | |
| 166 | + $this->_fs->get_slug() === fs_request_get_raw( 'plugin', false ) | |
| 167 | + ); | |
| 168 | + } | |
| 169 | + | |
| 170 | + /** | |
| 171 | + * @author Leo Fajardo (@leorw) | |
| 132 | 172 | * @since 2.1.4 |
| 133 | 173 | */ |
| 134 | 174 | function catch_plugin_information_dialog_contents() { |
| 135 | - if ( | |
| 136 | - 'plugin-information' !== fs_request_get( 'tab', false ) || | |
| 137 | - $this->_fs->get_slug() !== fs_request_get_raw( 'plugin', false ) | |
| 138 | - ) { | |
| 175 | + if ( ! $this->is_plugin_information_dialog_for_plugin() ) { | |
| 139 | 176 | return; |
| 140 | 177 | } |
| 141 | 178 | |
| 142 | 179 | add_action( 'admin_footer', array( &$this, 'edit_and_echo_plugin_information_dialog_contents' ), 0, 1 ); |
| @@ -502,38 +539,40 @@ | ||
| 502 | 539 | ) { |
| 503 | 540 | return $transient_data; |
| 504 | 541 | } |
| 505 | 542 | |
| 543 | + // Alias. | |
| 544 | + $basename = $this->_fs->premium_plugin_basename(); | |
| 545 | + | |
| 506 | 546 | global $wp_current_filter; |
| 507 | 547 | |
| 508 | - $current_plugin_version = $this->_fs->get_plugin_version(); | |
| 509 | - | |
| 510 | - if ( ! empty( $wp_current_filter ) && 'upgrader_process_complete' === $wp_current_filter[0] ) { | |
| 511 | - if ( | |
| 512 | - is_null( $this->_update_details ) || | |
| 513 | - ( is_object( $this->_update_details ) && $this->_update_details->new_version !== $current_plugin_version ) | |
| 514 | - ) { | |
| 548 | + /** | |
| 549 | + * During bulk updates, avoid re-injecting update data for the plugin itself once it has already been updated. | |
| 550 | + * | |
| 551 | + * If the custom package is re-added to the transient after the plugin update, WordPress may detect the package again and incorrectly report "The plugin is at the latest version" for a pending update, since the custom package version matches the currently installed version. | |
| 552 | + * | |
| 553 | + * Behavior differs depending on how the bulk update is triggered. Please refer to the inline comments for each flow below for details. | |
| 554 | + */ | |
| 555 | + if ( | |
| 556 | + ! empty( $wp_current_filter ) && ( | |
| 515 | 557 | /** |
| 516 | - * After an update, clear the stored update details and reparse the plugin's main file in order to get | |
| 517 | - * the updated version's information and prevent the previous update information from showing up on the | |
| 518 | - * updates page. | |
| 519 | - * | |
| 520 | - * @author Leo Fajardo (@leorw) | |
| 521 | - * @since 2.3.1 | |
| 558 | + * update-core.php and other upgrader pages: | |
| 559 | + * The `upgrader_process_complete` action fires only once after all updates have finished. In this case, it is the current action (`$wp_current_filter[0]`), while `self::$_upgrade_basename` may contain any plugin basename. | |
| 522 | 560 | */ |
| 523 | - $this->_update_details = null; | |
| 524 | - $current_plugin_version = $this->_fs->get_plugin_version( true ); | |
| 525 | - } | |
| 561 | + 'upgrader_process_complete' === $wp_current_filter[0] || | |
| 562 | + /** | |
| 563 | + * AJAX bulk updates (e.g., from the Plugins page): | |
| 564 | + * The `upgrader_process_complete` action fires multiple times — once for each plugin after it finishes updating. In this flow, it is not the current action (`$wp_current_filter[0]`) because it is triggered from another action. Instead, we compare `self::$_upgrade_basename` with the basename of the plugin currently being updated, since the `upgrader_process_complete` action runs separately for each plugin. | |
| 565 | + */ | |
| 566 | + ( in_array( 'upgrader_process_complete', $wp_current_filter ) && self::$_upgrade_basename === $basename ) | |
| 567 | + ) | |
| 568 | + ) { | |
| 569 | + return $transient_data; | |
| 526 | 570 | } |
| 527 | 571 | |
| 528 | 572 | if ( ! isset( $this->_update_details ) ) { |
| 529 | 573 | // Get plugin's newest update. |
| 530 | - $new_version = $this->_fs->get_update( | |
| 531 | - false, | |
| 532 | - fs_request_get_bool( 'force-check' ), | |
| 533 | - WP_FS__TIME_24_HOURS_IN_SEC / 24, | |
| 534 | - $current_plugin_version | |
| 535 | - ); | |
| 574 | + $new_version = $this->_fs->get_update( false, fs_request_get_bool( 'force-check' ) ); | |
| 536 | 575 | |
| 537 | 576 | $this->_update_details = false; |
| 538 | 577 | |
| 539 | 578 | if ( is_object( $new_version ) && $this->is_new_version_premium( $new_version ) ) { |
| @@ -549,11 +588,8 @@ | ||
| 549 | 588 | $this->_update_details = $this->get_update_details( $new_version ); |
| 550 | 589 | } |
| 551 | 590 | } |
| 552 | 591 | |
| 553 | - // Alias. | |
| 554 | - $basename = $this->_fs->premium_plugin_basename(); | |
| 555 | - | |
| 556 | 592 | if ( is_object( $this->_update_details ) ) { |
| 557 | 593 | if ( isset( $transient_data->no_update ) ) { |
| 558 | 594 | unset( $transient_data->no_update[ $basename ] ); |
| 559 | 595 | } |
| @@ -613,9 +649,9 @@ | ||
| 613 | 649 | } |
| 614 | 650 | |
| 615 | 651 | $slug = $this->_fs->get_slug(); |
| 616 | 652 | |
| 617 | - if ( $this->_fs->is_org_repo_compliant() && $this->_fs->is_freemium() ) { | |
| 653 | + if ( $this->can_fetch_data_from_wp_org() ) { | |
| 618 | 654 | if ( ! isset( $this->_translation_updates ) ) { |
| 619 | 655 | $this->_translation_updates = array(); |
| 620 | 656 | |
| 621 | 657 | $translation_updates = $this->fetch_wp_org_module_translation_updates( $module_type, $slug ); |
| @@ -682,18 +718,10 @@ | ||
| 682 | 718 | 'default' => $icon, |
| 683 | 719 | ); |
| 684 | 720 | } |
| 685 | 721 | |
| 686 | - if ( $this->_fs->is_premium() ) { | |
| 687 | - $latest_tag = $this->_fs->_fetch_latest_version( $this->_fs->get_id(), false ); | |
| 688 | - | |
| 689 | - if ( | |
| 690 | - isset( $latest_tag->readme ) && | |
| 691 | - isset( $latest_tag->readme->upgrade_notice ) && | |
| 692 | - ! empty( $latest_tag->readme->upgrade_notice ) | |
| 693 | - ) { | |
| 694 | - $update->upgrade_notice = $latest_tag->readme->upgrade_notice; | |
| 695 | - } | |
| 722 | + if ( $this->_fs->is_premium() && ! empty( $new_version->upgrade_notice ) ) { | |
| 723 | + $update->upgrade_notice = $new_version->upgrade_notice; | |
| 696 | 724 | } |
| 697 | 725 | |
| 698 | 726 | $update->{$this->_fs->get_module_type()} = $this->_fs->get_plugin_basename(); |
| 699 | 727 | |
| @@ -871,8 +899,18 @@ | ||
| 871 | 899 | return $res; |
| 872 | 900 | } |
| 873 | 901 | |
| 874 | 902 | /** |
| 903 | + * Returns true if the product can fetch data from WordPress.org. | |
| 904 | + * | |
| 905 | + * @author Leo Fajardo (@leorw) | |
| 906 | + * @since 2.7.4 | |
| 907 | + */ | |
| 908 | + private function can_fetch_data_from_wp_org() { | |
| 909 | + return ( $this->_fs->is_org_repo_compliant() && $this->_fs->is_freemium() ); | |
| 910 | + } | |
| 911 | + | |
| 912 | + /** | |
| 875 | 913 | * Fetches module translation updates from wordpress.org. |
| 876 | 914 | * |
| 877 | 915 | * @author Leo Fajardo (@leorw) |
| 878 | 916 | * @since 2.1.2 |
| @@ -1054,9 +1092,9 @@ | ||
| 1054 | 1092 | $is_addon = true; |
| 1055 | 1093 | } |
| 1056 | 1094 | |
| 1057 | 1095 | $plugin_in_repo = false; |
| 1058 | - if ( ! $is_addon ) { | |
| 1096 | + if ( ! $is_addon && $this->can_fetch_data_from_wp_org() ) { | |
| 1059 | 1097 | // Try to fetch info from .org repository. |
| 1060 | 1098 | $data = self::_fetch_plugin_info_from_repository( $action, $args ); |
| 1061 | 1099 | |
| 1062 | 1100 | $plugin_in_repo = ( false !== $data ); |
| @@ -1187,9 +1225,9 @@ | ||
| 1187 | 1225 | * |
| 1188 | 1226 | * @return object |
| 1189 | 1227 | */ |
| 1190 | 1228 | private function get_latest_download_details( $addon_id = false, $newer_than = false, $fetch_readme = true ) { |
| 1191 | - return $this->_fs->_fetch_latest_version( $addon_id, true, WP_FS__TIME_24_HOURS_IN_SEC, $newer_than, $fetch_readme ); | |
| 1229 | + return $this->_fs->_fetch_latest_version( $addon_id, true, FS_Plugin_Updater::UPDATES_CHECK_CACHE_EXPIRATION, $newer_than, $fetch_readme ); | |
| 1192 | 1230 | } |
| 1193 | 1231 | |
| 1194 | 1232 | /** |
| 1195 | 1233 | * Checks if a given basename has a matching folder name |