Skip to content

Commit

Permalink
Merge pull request #2128 from the-events-calendar/tweak/TEC-5110-noti…
Browse files Browse the repository at this point in the history
…ces-split-messages

Abstract for handling merge logic.
  • Loading branch information
stratease authored Jul 1, 2024
2 parents 5f0b943 + e3f4969 commit 09d1edd
Show file tree
Hide file tree
Showing 2 changed files with 339 additions and 1 deletion.
338 changes: 338 additions & 0 deletions src/Common/Integrations/Plugin_Merge_Provider_Abstract.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,338 @@
<?php
/**
* Abstract for Plugin Merge operations.
*
* @since TBD
*
* @package TEC\Common\Integrations
*/

namespace TEC\Common\Integrations;

use TEC\Common\Contracts\Service_Provider;
use TEC\Common\lucatume\DI52\Container;
use Tribe__Admin__Notices;
use Tribe__Settings_Manager;

/**
* Class Plugin_Merge_Provider_Abstract
*
* @since TBD
*
* @package TEC\Common\Integrations
*/
abstract class Plugin_Merge_Provider_Abstract extends Service_Provider {
/**
* If the plugin was updated from a version that is less than the merged plugin version.
*
* @var bool
*/
protected bool $updated_to_merge_version = false;

/**
* Get the plugins version where the merge was applied.
*
* @since TBD
*
* @return string
*/
abstract public function get_merged_version(): string;

/**
* Get version key for the last version option.
*
* @since TBD
*
* @return string
*/
abstract public function get_last_version_option_key(): string;

/**
* Get the key of the plugin file, e.g. path/file.php.
*
* @return string
*/
abstract public function get_plugin_file_key(): string;

/**
* Get the slug of the notice to display with various notices.
*
* @return string
*/
abstract public function get_merge_notice_slug(): string;

/**
* Get the message to display when the parent plugin is being updated but the child plugin is not active.
*
* @return string
*/
abstract public function get_updated_notice_message(): string;

/**
* Get the message to display when the parent plugin is being updated to the merge.
*
* @return string
*/
abstract public function get_updated_merge_notice_message(): string;

/**
* Get the message to display when the child plugin is being activated.
*
* @return string
*/
abstract public function get_activating_merge_notice_message(): string;

/**
* Run initialization of container and plugin version comparison.
*
* @since TBD
*
* @param Container $container The container instance for DI.
*/
public function __construct( Container $container ) {
parent::__construct( $container );
// Was updated from a version that is less than the merged version?
$this->updated_to_merge_version = $this->did_update_to_merge_version();
}

/**
* Binds and sets up implementations.
*
* @since TBD
*/
public function register(): void {
$this->init();
}

/**
* Check if the plugin was updated from a version that is less than the merged plugin version.
*
* @since TBD
*
* @return bool
*/
protected function did_update_to_merge_version(): bool {
return version_compare( Tribe__Settings_Manager::get_option( $this->get_last_version_option_key() ), $this->get_merged_version(), '<' );
}

/**
* Is the child plugin active?
*
* @since TBD
*/
protected function is_child_plugin_active(): bool {
return is_plugin_active( $this->get_plugin_file_key() );
}

/**
* Initializes the merged compatibility checks.
*
* @since TBD
*/
public function init(): void {
// Load our is_plugin_activated function.
if ( ! function_exists( 'is_plugin_activated' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}

if ( $this->updated_to_merge_version && ! $this->is_child_plugin_active() ) {
// Leave a notice of the recent update.
$this->send_updated_notice();
$this->init_merged_plugin();
return;
}

// If the Event Ticket Wallet Plus plugin is active, we need to deactivate it before continuing to avoid a fatal.
if ( $this->is_child_plugin_active() ) {
$this->deactivate_plugin();

// Leave a notice of the forced deactivation.
$this->send_updated_merge_notice();
return;
}

// If the action is to activate the plugin, we should not continue to avoid a fatal.
if ( $this->is_activating_plugin() ) {
add_action( 'activated_plugin', [ $this, 'deactivate_plugin' ] );

// Remove "Plugin activated" notice from redirect.
add_action( 'activate_plugin', [ $this, 'remove_activated_from_redirect' ] );
// Leave a notice of the forced deactivation.
$this->send_activating_merge_notice();
return;
}

// If the plugin is not active and the action is not to activate it, we can proceed with the merge.
$this->init_merged_plugin();
}

/**
* If any initialization is necessary for the merged plugin to work after child plugin deactivation is resolved.
*
* @since TBD
*/
public function init_merged_plugin(): void {
// Implement the merged plugin initialization.
}

/**
* Deactivates the merged plugin.
*
* @since TBD
*/
public function deactivate_plugin(): void {
deactivate_plugins( $this->get_plugin_file_key(), true, is_multisite() && is_plugin_active_for_network( $this->get_plugin_file_key() ) );
}

/**
* Adds the hook to remove the "Plugin activated" notice from the redirect.
*
* @since TBD
*
* @param string $plugin The plugin file path.
*/
public function remove_activated_from_redirect( $plugin ): void {
if ( basename( $plugin ) === basename( $this->get_plugin_file_key() ) ) {
add_filter( 'wp_redirect', [ $this, 'filter_remove_activated_from_redirect' ] );
}
}

/**
* Filter the redirect location to remove the "activate" query arg.
*
* @since TBD
*
* @param string $location The redirect location.
*
* @return string The redirect location without the "activate" query arg.
*/
public function filter_remove_activated_from_redirect( $location ): string {
return remove_query_arg( 'activate', $location );
}

/**
* Send admin notice about the updates of Tickets Plus.
*
* @since TBD
*/
public function send_updated_notice(): void {
// Remove dismissed flag since we want to show the notice everytime this is triggered.
Tribe__Admin__Notices::instance()->undismiss( $this->get_merge_notice_slug() );

$message = $this->get_updated_notice_message();
tribe_transient_notice(
$this->get_merge_notice_slug(),
sprintf( '<p>%s</p>', $message ),
[
'type' => 'success',
'dismiss' => true,
'action' => 'admin_notices',
'priority' => 1,
'active_callback' => __CLASS__ . '::should_show_merge_notice',
],
YEAR_IN_SECONDS
);
}

/**
* Send admin notice about the merge of the Event Tickets Wallet Plus plugin into Tickets Plus.
* This notice is for after updating Tickets Plus to the merged version.
*
* @since TBD
*/
public function send_updated_merge_notice(): void {
// Remove dismissed flag since we want to show the notice everytime this is triggered.
Tribe__Admin__Notices::instance()->undismiss( $this->get_merge_notice_slug() );

$message = $this->get_updated_merge_notice_message();
tribe_transient_notice(
$this->get_merge_notice_slug(),
sprintf( '<p>%s</p>', $message ),
[
'type' => 'success',
'dismiss' => true,
'action' => 'admin_notices',
'priority' => 1,
'active_callback' => __CLASS__ . '::should_show_merge_notice',
],
YEAR_IN_SECONDS
);
}

/**
* Send admin notice about the merge of the Event Tickets Wallet Plus plugin into Tickets Plus.
* This notice is for after activating the deprecated Wallet Plus plugin.
*
* @since TBD
*/
public function send_activating_merge_notice(): void {
// Remove dismissed flag since we want to show the notice everytime this is triggered.
Tribe__Admin__Notices::instance()->undismiss( $this->get_merge_notice_slug() );

$message = $this->get_activating_merge_notice_message();
tribe_transient_notice(
$this->get_merge_notice_slug(),
sprintf( '<p>%s</p>', $message ),
[
'type' => 'warning',
'dismiss' => true,
'action' => 'admin_notices',
'priority' => 1,
'active_callback' => __CLASS__ . '::should_show_merge_notice',
],
YEAR_IN_SECONDS
);
}

/**
* Check if the merge notice should be shown.
*
* @since TBD
*
* @return bool
*/
public static function should_show_merge_notice(): bool {
return tribe( \Tribe__Admin__Helpers::class )->is_screen() || tribe( \Tribe__Admin__Helpers::class )->is_screen( 'plugins' );
}

/**
* Implements Runner's private method cmd_starts_with.
*
* @since TBD
*
* @param array $looking_for The array of strings to look for.
* @param mixed $args The arguments to search in.
*
* @return bool
*/
protected function cli_args_start_with( array $looking_for, $args ): bool {
if ( empty( $args ) || ! is_array( $args ) ) {
return false;
}

return array_slice( $args, 0, count( $looking_for ) ) === $looking_for;
}

/**
* Checks if the current request is activating the VE plugin.
*
* @since TBD
*
* @return bool
*/
protected function is_activating_plugin(): bool {
if ( defined( 'WP_CLI' ) && WP_CLI ) {
// Taking advantage of Runner's __get method to access private properties.
$args = \WP_CLI::get_runner()->arguments;
return $this->cli_args_start_with( [ 'plugin', 'activate' ], $args ) || $this->cli_args_start_with( [ 'plugin', 'install' ], $args );
}

// phpcs:ignore
$is_activating = isset( $_GET['action'] ) && $_GET['action'] === 'activate';
// phpcs:ignore
$is_child_plugin = isset( $_GET['plugin'] ) && basename( $_GET['plugin'] ) === basename( $this->get_plugin_file_key() );
$user_can_activate = current_user_can( 'activate_plugins' ) && is_admin();

return $is_child_plugin && $is_activating && $user_can_activate;
}
}
2 changes: 1 addition & 1 deletion tests/wpunit/Tribe/functions/templateTags/generalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ static function () {
$output = tribe_asset_print_group( 'test-group', false );

$expected_tmpl = <<< TAG
<script src='{{ common_url }}/js/test-script-1.js?ver=1.0.0' id='tribe-test-js-js'></script>
<script src="{{ common_url }}/js/test-script-1.js?ver=1.0.0" id="tribe-test-js-js"></script>
<link rel='stylesheet' id='tribe-test-css-css' href='{{ common_url }}/css/test-style-1.css?ver=1.0.0' media='all' />
TAG;
Expand Down

0 comments on commit 09d1edd

Please sign in to comment.