Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved the support for plugins with free and premium versions that … #727

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

fajardoleo
Copy link
Contributor

…can be activated in parallel.

@fajardoleo fajardoleo requested a review from swashata July 23, 2024 14:41
@fajardoleo fajardoleo self-assigned this Jul 23, 2024
@fajardoleo fajardoleo force-pushed the feature/free-premium-parallel-activation-support-enhancements branch from 3395977 to f49b565 Compare July 23, 2024 14:51
Copy link
Contributor

@swashata swashata left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see my suggestions, thanks.

! empty( $fs_active_plugins->newest->plugin_path ) &&
$fs_active_plugins->newest->plugin_path === $plugin_basename
) {
fs_fallback_to_newest_active_sdk();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fajardoleo Can't we always call the fs_fallback_to_newset_active_sdk? Will it harm anything? I find always calling it safer than relying on some uncontrolled data-structure.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@swashata It was actually supposed to reduce risks since it's called only when it's necessary. However, in the current code, we are always calling it anyway. I have reverted the changes.

*/
private function remove_sdk_reference() {
private function remove_sdk_reference( $plugin_basename = null ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can create a global function

function fs_remove_sdk_reference_by_basename( $basename )

and call that directly. This function will then be refactored to

private function remove_sdk_reference() {
  fs_remove_sdk_reference_by_basename( $this->_plugin_basename );
}

The reasons are

  1. $this->remove_sdk_reference better remove just its own reference instead of something else.
  2. We already have fs_fallback_to_newest_active_sdk, so having a complimentary fs_remove_sdk_reference_by_basename makes sense. They both work on $fs_active_plugins global.

Ideally, if we had a model class against the $fs_active_plugins it would've been better, but no need to refactor at this moment 😄

@@ -7407,6 +7407,11 @@ function _activate_plugin_event_hook() {
$this->apply_filters( 'deactivate_on_activation', true )
) {
deactivate_plugins( $other_version_basename );
} else if ( $is_premium_version_activation ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fajardoleo would it be good to always remove the sdk reference in case this is active?

if ( $is_premium_version_activation && is_plugin_active( $other_version_basename ) ) {
  fs_remove_sdk_reference_by_basename( $other_version_basename );
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now thinking about it again, perhaps we would want to also handle "Free plugin activation", for example user activates pro version, then deactivates free version on their own. Then notices the pro doesn't work without the Free, so they activate the Free version again. So instead of the else part here, we can do something like (pseudo code)

// If both free and premium version are active, then remove SDK from the Free version to avoid having it load the configuration.
if (is_plugin_active( $other_version_basename ) ) {
  fs_remove_sdk_reference_by_basename( $this->_free_plugin_basename );
}

But please double check me.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@swashata In that use case, when the premium version is activated, the latest SDK is already set to the SDK that comes with the premium version (when using the code in this PR). When the free version is deactivated and reactivated, it will not have any effect on the latest SDK information. Please let me know if I missed something :) Thanks!

@fajardoleo fajardoleo force-pushed the feature/free-premium-parallel-activation-support-enhancements branch from f49b565 to 3b639fd Compare August 18, 2024 05:05
if ( ! function_exists( 'fs_remove_sdk_reference_by_basename' ) ) {
/**
* @author Leo Fajardo (@leorw)
* @since 2.7.4
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@since 2.8.0 or 2.7.3.6. I don't think there will be a 2.7.0 version.

@fajardoleo fajardoleo force-pushed the feature/free-premium-parallel-activation-support-enhancements branch 2 times, most recently from ed9d106 to 2293c14 Compare August 19, 2024 17:10
@fajardoleo fajardoleo force-pushed the feature/free-premium-parallel-activation-support-enhancements branch from 2293c14 to a281bef Compare August 19, 2024 17:11
* @param string $plugin
* @param bool $network_wide
*/
function _activated_plugin( $plugin, $network_wide ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for the sake of properly handling bulk activation, can we also do this?

if ( $plugin !== $this->premium_plugin_basename() || $plugin !== $this->_free_plugin_basename ) {
  return;
}

$this->move_free_plugin_to_end_of_active_plugins();

*/
function _activated_plugin( $plugin, $network_wide ) {
// We cannot rely on fs_remove_sdk_reference_by_basename() for reordering, as the latest SDK reference might be associated with a different product, leading to the reordering of that product instead of the intended one.
$this->move_free_plugin_to_end_of_active_plugins( $this->_free_plugin_basename );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest not to pass the $this->_free_plugin_basename as the function can already get it from the instance. (Just for code readability)

/**
* To avoid placing the free version at the start of the active plugins option when the SDK is loaded from it, remove the SDK reference linked to the free version if it is the newest.
*/
fs_remove_sdk_reference_by_basename( $this->_free_plugin_basename );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will it hurt us even if the SDK reference from the free version is at top? I don't mind doing this "just in case", but just asking for my understanding.

*
* @param string $plugin
*/
private function move_free_plugin_to_end_of_active_plugins( $plugin ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the $plugin parameter and rely solely on $this->_free_plugin_basename. If that's not set, just bail early.

if ( empty( $this->_free_plugin_basename ) ) {
  return;
}


// Move the free version to the last position in the active plugins option.
if ( false !== ( $key = array_search( $plugin, $active_plugins ) ) ) {
unset( $active_plugins[ $key ] );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's either use array_splice or right after unset, let's reindex the array with $active_plugins = array_values( $active_plugins ).

*
* @param string $plugin
*/
private function move_free_plugin_to_end_of_active_plugins( $plugin ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we want to handle network wide activation too?

CleanShot 2024-08-20 at 11 35 31@2x

Maybe it will be difficult to support network wide. Since I see the wp_get_active_network_plugins function does a sort when being called. If that's the case then please add some comment here.

* @param string $plugin
* @param bool $network_wide
*/
function _activated_plugin( $plugin, $network_wide ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Proposing to rename this function to _handle_free_and_premium_parallel_activation or something like that, just for readability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants