From c27e3edb6cf9892db2867b436e0864961bef77bb Mon Sep 17 00:00:00 2001 From: Vova Feldman Date: Sun, 15 Jul 2018 20:12:53 +0300 Subject: [PATCH 1/7] [ms-network] [licensing] [premium-update] [bug-fix] Allow premium updates on a network level when the license is activated on a sub-site that is not the main one. --- includes/class-freemius.php | 58 ++++++++++++++++++++++++--- includes/class-fs-plugin-updater.php | 4 +- templates/forms/deactivation/form.php | 2 +- 3 files changed, 56 insertions(+), 8 deletions(-) diff --git a/includes/class-freemius.php b/includes/class-freemius.php index ace6f35d8..3c7a796d0 100755 --- a/includes/class-freemius.php +++ b/includes/class-freemius.php @@ -10574,7 +10574,7 @@ function _add_premium_version_upgrade_selection() { return; } - if ( ! $this->is_premium() || $this->has_active_valid_license() ) { + if ( ! $this->is_premium() || $this->has_any_active_valid_license() ) { // This is relevant only to the free versions and premium versions without an active license. return; } @@ -16288,14 +16288,62 @@ function has_active_license() { * @since 1.2.1 */ function has_active_valid_license() { + return self::is_active_valid_license( $this->_license ); + } + + /** + * Check if a given license is active & valid (not expired). + * + * @author Vova Feldman (@svovaf) + * @since 2.1.3 + * + * @param FS_Plugin_License $license + * + * @return bool + */ + private static function is_active_valid_license( $license ) { return ( - is_object( $this->_license ) && - is_numeric( $this->_license->id ) && - $this->_license->is_active() && - $this->_license->is_valid() + is_object( $license ) && + FS_Plugin_License::is_valid_id( $license->id ) && + $license->is_active() && + $license->is_valid() ); } + /** + * Checks if there's any site that is associated with an active & valid license. + * This logic is used to determine if the admin can download the premium code base from a network level admin. + * + * @author Vova Feldman (@svovaf) + * @since 2.1.3 + * + * @return bool + */ + function has_any_active_valid_license() { + if ( ! fs_is_network_admin() ) { + return $this->has_active_valid_license(); + } + + $installs = $this->get_blog_install_map(); + $all_plugin_licenses = self::get_all_licenses( $this->_module_id ); + + foreach ( $installs as $blog_id => $install ) { + if ( ! FS_Plugin_License::is_valid_id( $install->license_id ) ) { + continue; + } + + foreach ( $all_plugin_licenses as $license ) { + if ( $license->id == $install->license_id ) { + if ( self::is_active_valid_license( $license ) ) { + return true; + } + } + } + } + + return false; + } + /** * Check if site assigned with license with enabled features. * diff --git a/includes/class-fs-plugin-updater.php b/includes/class-fs-plugin-updater.php index af9eb263f..5aba1701f 100755 --- a/includes/class-fs-plugin-updater.php +++ b/includes/class-fs-plugin-updater.php @@ -82,7 +82,7 @@ private function filters() { $this->add_transient_filters(); - if ( ! $this->_fs->has_active_valid_license() ) { + if ( ! $this->_fs->has_any_active_valid_license() ) { /** * If user has the premium plugin's code but do NOT have an active license, * encourage him to upgrade by showing that there's a new release, but instead @@ -114,7 +114,7 @@ private function filters() { add_filter( 'upgrader_post_install', array( &$this, '_maybe_update_folder_name' ), 10, 3 ); } - if ( ! $this->_fs->has_active_valid_license() ) { + if ( ! $this->_fs->has_any_active_valid_license() ) { add_filter( 'wp_prepare_themes_for_js', array( &$this, 'change_theme_update_info_html' ), 10, 1 ); } } diff --git a/templates/forms/deactivation/form.php b/templates/forms/deactivation/form.php index 0e74617e9..93f08b32b 100755 --- a/templates/forms/deactivation/form.php +++ b/templates/forms/deactivation/form.php @@ -94,7 +94,7 @@ isAnonymous = , otherReasonID = , dontShareDataReasonID = , - deleteThemeUpdateData = is_theme() && $fs->is_premium() && ! $fs->has_active_valid_license() ? 'true' : 'false' ?>; + deleteThemeUpdateData = is_theme() && $fs->is_premium() && ! $fs->has_any_active_valid_license() ? 'true' : 'false' ?>; $modal.appendTo($('body')); From 4ae9a719f17ed501c7c9402123e11091f646ab09 Mon Sep 17 00:00:00 2001 From: Leo Fajardo Date: Sun, 19 Aug 2018 22:25:59 +0800 Subject: [PATCH 2/7] [install] [cron] Fixed the scheduling of the install sync cron. --- includes/class-freemius.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-freemius.php b/includes/class-freemius.php index 2775cfa2d..d5623b8d8 100755 --- a/includes/class-freemius.php +++ b/includes/class-freemius.php @@ -5987,7 +5987,7 @@ private function get_install_sync_cron_blog_id() { * @param int $except_blog_id Since 2.0.0 when running in a multisite network environment, the cron execution is consolidated. This param allows excluding excluded specified blog ID from being the cron executor. */ private function schedule_install_sync( $except_blog_id = 0 ) { - $this->schedule_cron( 'install_sync', 'install_sync', 'single', 0, false, $except_blog_id ); + $this->schedule_cron( 'install_sync', 'install_sync', 'single', WP_FS__SCRIPT_START_TIME, false, $except_blog_id ); } /** From 45f2798d82c85bb09f40d41e112f72341fb4f4db Mon Sep 17 00:00:00 2001 From: Leo Fajardo Date: Wed, 29 Aug 2018 21:46:53 +0800 Subject: [PATCH 3/7] [ms] [options] [migration] --- includes/class-freemius.php | 48 +++++++++++++++++++++++++++---------- templates/debug.php | 10 ++++++++ 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/includes/class-freemius.php b/includes/class-freemius.php index d5623b8d8..99f55ba18 100755 --- a/includes/class-freemius.php +++ b/includes/class-freemius.php @@ -2630,26 +2630,28 @@ private static function _load_required_static() { self::$_accounts = FS_Options::instance( WP_FS__ACCOUNTS_OPTION_NAME, true ); if ( is_multisite() ) { + $has_skipped_migration = ( + // 'id_slug_type_path_map' - was never stored on older versions, therefore, not exists on the site level. + null === self::$_accounts->get_option( 'id_slug_type_path_map', null, false ) && + // 'file_slug_map' stored on the site level, so it was running an SDK version before it was integrated with MS-network. + null !== self::$_accounts->get_option( 'file_slug_map', null, false ) + ); + /** - * If the id_slug_type_path_map exists on the site level but doesn't exist on the + * If the file_slug_map exists on the site level but doesn't exist on the * network level storage, it means that we need to process the storage with migration. * - * The code in this `if` scope will only be executed once and only for the first site that will execute it because once we migrate the storage data, id_slug_type_path_map will be already set in the network level storage. + * The code in this `if` scope will only be executed once and only for the first site that will execute it because once we migrate the storage data, file_slug_map will be already set in the network level storage. * * @author Vova Feldman (@svovaf) * @since 2.0.0 */ - if ( null === self::$_accounts->get_option( 'id_slug_type_path_map', null, true ) && - null !== self::$_accounts->get_option( 'id_slug_type_path_map', null, false ) + if ( + ( $has_skipped_migration && true !== self::$_accounts->get_option( 'ms_migration_complete', false, true ) ) || + ( null === self::$_accounts->get_option( 'file_slug_map', null, true ) && + null !== self::$_accounts->get_option( 'file_slug_map', null, false ) ) ) { - self::migrate_accounts_to_network(); - - // Migrate API options from site level to network level. - $api_network_options = FS_Option_Manager::get_manager( WP_FS__OPTIONS_OPTION_NAME, true, true ); - $api_network_options->migrate_to_network(); - - // Migrate API cache to network level storage. - FS_Cache_Manager::get_manager( WP_FS__API_CACHE_OPTION_NAME )->migrate_to_network(); + self::migrate_options_to_network(); } } @@ -2679,6 +2681,24 @@ private static function _load_required_static() { self::$_statics_loaded = true; } + /** + * @author Leo Fajardo (@leorw) + * + * @since 2.1.3 + */ + private static function migrate_options_to_network() { + self::migrate_accounts_to_network(); + + // Migrate API options from site level to network level. + $api_network_options = FS_Option_Manager::get_manager( WP_FS__OPTIONS_OPTION_NAME, true, true ); + $api_network_options->migrate_to_network(); + + // Migrate API cache to network level storage. + FS_Cache_Manager::get_manager( WP_FS__API_CACHE_OPTION_NAME )->migrate_to_network(); + + self::$_accounts->set_option( 'ms_migration_complete', true, true ); + } + #---------------------------------------------------------------------------------- #region Localization #---------------------------------------------------------------------------------- @@ -2905,6 +2925,10 @@ static function _debug_page_actions() { } fs_redirect( $download_url ); + } else if ( fs_request_is_action( 'migrate_options_to_network' ) ) { + check_admin_referer( 'migrate_options_to_network' ); + + self::migrate_options_to_network(); } } diff --git a/templates/debug.php b/templates/debug.php index 89ae7eb3b..0ee3ebf9c 100644 --- a/templates/debug.php +++ b/templates/debug.php @@ -86,6 +86,16 @@ + get_option( 'ms_migration_complete', false, true ) ) : ?> + + +
+ + + +
+ + From e4ff619ed53a48f986e4f20269cb0ef1ca83ba40 Mon Sep 17 00:00:00 2001 From: Vova Feldman Date: Sun, 2 Sep 2018 17:21:40 +0300 Subject: [PATCH 4/7] [install] [localhost] [enrich] Added kinsta's staging + stage.* as staging subdomains. --- includes/entities/class-fs-site.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/includes/entities/class-fs-site.php b/includes/entities/class-fs-site.php index c8954923b..c74bb55ba 100755 --- a/includes/entities/class-fs-site.php +++ b/includes/entities/class-fs-site.php @@ -150,6 +150,7 @@ static function is_localhost_by_address( $url ) { fs_starts_with( $subdomain, 'local.' ) || fs_starts_with( $subdomain, 'dev.' ) || fs_starts_with( $subdomain, 'test.' ) || + fs_starts_with( $subdomain, 'stage.' ) || fs_starts_with( $subdomain, 'staging.' ) || // Ends with. @@ -171,7 +172,9 @@ static function is_localhost_by_address( $url ) { ( fs_ends_with($subdomain, 'pantheonsite.io') && (fs_starts_with($subdomain, 'test-') || fs_starts_with($subdomain, 'dev-'))) || // Cloudways - fs_ends_with( $subdomain, '.cloudwaysapps.com' ) + fs_ends_with( $subdomain, '.cloudwaysapps.com' ) || + // Kinsta + (fs_ends_with($subdomain, '.kinsta.com') && fs_starts_with($subdomain, 'staging-')) ); } From 7a36d3cdf6d0655b6166487fdae88e027fe0b70a Mon Sep 17 00:00:00 2001 From: Vova Feldman Date: Sun, 2 Sep 2018 17:22:21 +0300 Subject: [PATCH 5/7] [plugin-info] [fix] The tag's "updated" column is no longer representing the last time the version was deployed since we added the download counter. --- includes/fs-plugin-info-dialog.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/fs-plugin-info-dialog.php b/includes/fs-plugin-info-dialog.php index 366ffa60e..489bb4c3e 100755 --- a/includes/fs-plugin-info-dialog.php +++ b/includes/fs-plugin-info-dialog.php @@ -203,7 +203,7 @@ function _get_addon_info_filter( $data, $action = '', $args = null ) { if ( is_object( $latest ) ) { $data->version = $latest->version; - $data->last_updated = ! is_null( $latest->updated ) ? $latest->updated : $latest->created; + $data->last_updated = $latest->created; $data->requires = $latest->requires_platform_version; $data->tested = $latest->tested_up_to_version; } else { From 8461ebf50b7392137b47aed608ad4e884cd3409e Mon Sep 17 00:00:00 2001 From: Vova Feldman Date: Sun, 2 Sep 2018 17:26:04 +0300 Subject: [PATCH 6/7] [download] [premium] [fix] The premium version should be downloadable if there's even a single valid license in the network. --- includes/class-freemius.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-freemius.php b/includes/class-freemius.php index 0ac94ad47..a8265372c 100755 --- a/includes/class-freemius.php +++ b/includes/class-freemius.php @@ -17362,7 +17362,7 @@ private function _is_addon_id( $plugin_id ) { * @return bool */ private function _can_download_premium() { - return $this->has_active_valid_license() || + return $this->has_any_active_valid_license() || ( $this->is_trial() && ! $this->get_trial_plan()->is_free() ); } From 64c4458323eecf5b903e0c28bfa043d8903ebdfd Mon Sep 17 00:00:00 2001 From: Vova Feldman Date: Sun, 2 Sep 2018 17:28:25 +0300 Subject: [PATCH 7/7] [version] --- start.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/start.php b/start.php index 68a7e2d82..dc7a50266 100644 --- a/start.php +++ b/start.php @@ -15,7 +15,7 @@ * * @var string */ - $this_sdk_version = '2.1.2'; + $this_sdk_version = '2.1.3'; #region SDK Selection Logic --------------------------------------------------------------------