PluginProbe
TablePress – Tables in WordPress made easy / 3.4
TablePress – Tables in WordPress made easy v3.4
3.4 3.3.4 3.3.3 3.3.2 3.3.1 trunk 1.12 1.14 1.9.2 2.0.4 2.1.7 2.1.8 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3 2.3.1 2.3.2 2.4 2.4.1 2.4.2 2.4.3 All 45 releases
← 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