Skip to content

Commit

Permalink
Add auto-update suggestion
Browse files Browse the repository at this point in the history
  • Loading branch information
TorbenLundsgaard committed Oct 5, 2024
1 parent f76f669 commit d55a595
Show file tree
Hide file tree
Showing 13 changed files with 295 additions and 23 deletions.
2 changes: 1 addition & 1 deletion assets/admin/settings.asset.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array('lodash', 'react', 'react-dom', 'react-jsx-runtime', 'wp-api-fetch', 'wp-components', 'wp-element', 'wp-i18n', 'wp-plugins', 'wp-primitives'), 'version' => 'dc29ed09e43c1a3717ee');
<?php return array('dependencies' => array('lodash', 'react', 'react-dom', 'react-jsx-runtime', 'wp-api-fetch', 'wp-components', 'wp-element', 'wp-i18n', 'wp-plugins', 'wp-primitives'), 'version' => '6c0a99b8aca06ca33c76');
12 changes: 6 additions & 6 deletions assets/admin/settings.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion assets/admin/wizard.asset.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array('lodash', 'react', 'react-dom', 'react-jsx-runtime', 'wp-api-fetch', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => 'dbb3932ddfcb8fb8a6d5');
<?php return array('dependencies' => array('lodash', 'react', 'react-dom', 'react-jsx-runtime', 'wp-api-fetch', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => 'acf6e4eaedadb01491fd');
2 changes: 1 addition & 1 deletion assets/admin/wizard.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions inc/main.php
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ function gtmkit_admin_init(): void {

$notifications_handler = NotificationsHandler::get();

AutomaticUpdates::register();
Suggestions::register( $notifications_handler, $plugin_availability, $options, $util );
Analytics::register( $options, $util );
MetaBox::register( $options );
Expand Down
7 changes: 5 additions & 2 deletions src/Admin/AdminAPI.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,10 @@ public function set_notification_status(): void {
$notifications_handler->setup_current_notifications();
$notification = $notifications_handler->get_notification_by_id( $notification_id );

if ( $notification instanceof Notification ) {
if ( $action === 'remove' ) {
$notifications_handler->remove_notification_by_id( $notification_id );
wp_send_json_success( (object) $notifications_handler->get_notifications_array() );
} elseif ( $notification instanceof Notification ) {
switch ( $action ) {
case 'dismiss':
$notification_action = $notifications_handler->maybe_dismiss_notification( $notification );
Expand Down Expand Up @@ -197,7 +200,7 @@ public function set_notification_status(): void {
*/
private function validate_notification_input( ?array $input ): bool {
return isset( $input['notification-id'], $input['action'] )
&& in_array( $input['action'], [ 'dismiss', 'restore' ], true );
&& in_array( $input['action'], [ 'dismiss', 'restore', 'remove' ], true );
}

/**
Expand Down
41 changes: 41 additions & 0 deletions src/Admin/Suggestions.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,31 @@ public static function register( NotificationsHandler $notifications_handler, Pl
$page = new self( $notifications_handler, $plugin_availability, $options, $util );

add_action( 'admin_init', [ $page->plugin_availability, 'register' ] );
add_action( 'admin_init', [ $page, 'suggest_auto_update' ] );
add_action( 'admin_init', [ $page, 'suggest_premium' ] );
add_action( 'admin_init', [ $page, 'suggest_seo_plugin' ] );
add_action( 'admin_init', [ $page, 'detect_conflicting_plugins' ] );
add_action( 'admin_init', [ $page, 'suggest_grandfathered_wishlist' ] );
}

/**
* Suggest Auto-update.
*
* @return void
*/
public function suggest_auto_update(): void {

$notification_id = 'gtmkit-auto-update';

if ( $this->options->get( 'misc', 'auto_update' ) === true || ( defined( 'AUTOMATIC_UPDATER_DISABLED' ) && AUTOMATIC_UPDATER_DISABLED ) ) {
$this->notifications_handler->remove_notification_by_id( $notification_id );
return;
}

$notification = $this->get_suggest_auto_update_notification( $notification_id );
$this->notifications_handler->add_notification( $notification );
}

/**
* Suggest GTM Kit Woo Add-On.
*
Expand Down Expand Up @@ -344,6 +363,28 @@ protected function get_gf_wishlist_plugin_notification( string $notification_id
);
}

/**
* Build suggestion of auto-update notification.
*
* @param string $notification_id The id of the notification to be created.
*
* @return Notification The notification containing the suggested plugin.
*/
protected function get_suggest_auto_update_notification( string $notification_id ): Notification {

$message = __( 'New releases of GTM Kit may contain important updates to comply with changes in Google Tag Manager or analytics in general. We recommend enabling automatic plugin updates for GTM Kit to ensure it is always up to date.', 'gtm-kit' );

$url = $this->util->get_admin_page_url() . 'general#/misc';
$message .= ' <a href="' . $url . '" class="gtmkit-text-color-primary gtmkit hover:gtmkit-underline gtmkit-font-bold">';
$message .= __( 'Go to settings', 'gtm-kit' );
$message .= '</a>';

return $this->new_notification(
$notification_id,
$message,
__( 'Automatic Updates:', 'gtm-kit' )
);
}

/**
* New notification.
Expand Down
155 changes: 155 additions & 0 deletions src/Installation/AutomaticUpdates.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
<?php
/**
* GTM Kit plugin file.
*
* @package GTM Kit
*/

namespace TLA_Media\GTM_Kit\Installation;

use TLA_Media\GTM_Kit\Options;

/**
* Activation
*/
final class AutomaticUpdates {

/**
* Instance of this class
*
* @var null|self
*/
public static ?self $instance = null;

/**
* Register analytics
*/
public static function register(): void {
self::$instance = new self();

self::$instance->add_wp_hooks();

if ( doing_action( 'activate_' . GTMKIT_BASENAME ) ) {
self::$instance->activation_sync();
}
}

/**
* Get the singleton instance of this class.
*
* @return self
*/
public static function instance(): self {

if ( is_null( self::$instance ) ) {
self::$instance = new self();
}

return self::$instance;
}

/**
* Updates the GTM Kit setting when the WordPress auto_update_plugins option is updated.
*
* @param string $option The name of the option.
* @param array<int, string> $value The current value of the option.
* @param array<int, string> $old_value The previous value of the option.
*/
public function wp_option_updated( $option, $value, $old_value = [] ): void {
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && ! empty( $_POST['asset'] ) && ! empty( $_POST['state'] ) ) { // @phpcs:ignore WordPress.Security.NonceVerification.Missing
// Option is being updated by the ajax request performed when using the enable/disable auto-updates links on the plugins page.
$asset = sanitize_text_field( urldecode( $_POST['asset'] ) ); // @phpcs:ignore WordPress.Security.NonceVerification.Missing
if ( $asset !== GTMKIT_BASENAME ) {
return;
}

$is_enabled = $_POST['state'] === 'enable'; // @phpcs:ignore WordPress.Security.NonceVerification.Missing
} else {
// Option is being updated by some other means (e.g. CLI).
$is_enabled = in_array( GTMKIT_BASENAME, $value, true );
$was_enabled = in_array( GTMKIT_BASENAME, $old_value, true );

if ( $is_enabled === $was_enabled ) {
return;
}
}

$this->update_gtmkit_option( $is_enabled );
}

/**
* Updates the GTM Kit auto-update setting when the WordPress auto_update_plugins option is deleted.
*/
public function wp_option_deleted(): void {
$this->update_gtmkit_option( false );
}

/**
* Updates the GTM Kit option.
*
* @param bool $is_enabled Indicates if auto-updates are enabled.
*
* @return void
*/
public function update_gtmkit_option( bool $is_enabled ): void {
Options::init()->set_option( 'misc', 'auto_update', $is_enabled );
}

/**
* Activate auto-update of GTM Kit.
*
* Updates the WordPress auto_update_plugins option to enable or disable automatic updates for GTM Kit.
*
* @param bool $activate Activate or deactivate auto-updates.
*/
public function activate_auto_update( bool $activate ): void {
$auto_updates = (array) get_site_option( 'auto_update_plugins', [] );

if ( $activate ) {
$auto_updates[] = GTMKIT_BASENAME;
$auto_updates = array_unique( $auto_updates );
} else {
$auto_updates = array_diff( $auto_updates, [ GTMKIT_BASENAME ] );
}

$this->remove_wp_hooks();
update_site_option( 'auto_update_plugins', $auto_updates );
$this->add_wp_hooks();
}

/**
* Adds the action hooks for the auto_update_plugins option.
*
* @return void
*/
public function add_wp_hooks(): void {
add_action( 'add_site_option_auto_update_plugins', [ $this, 'wp_option_updated' ], 10, 2 );
add_action( 'update_site_option_auto_update_plugins', [ $this, 'wp_option_updated' ], 10, 3 );
add_action( 'delete_site_option_auto_update_plugins', [ $this, 'wp_option_deleted' ] );
}

/**
* Removes the action hooks for the auto_update_plugins option.
* @return void
*/
public function remove_wp_hooks(): void {
remove_action( 'add_site_option_auto_update_plugins', [ $this, 'wp_option_updated' ] );
remove_action( 'update_site_option_auto_update_plugins', [ $this, 'wp_option_updated' ] );
remove_action( 'delete_site_option_auto_update_plugins', [ $this, 'wp_option_deleted' ] );
}

/**
* Updates the WordPress auto_update_plugins option to match the GTM Kit setting.
*
* @return void
*/
public function activation_sync(): void {
$enabled = Options::init()->get( 'misc', 'auto_update' );
if ( ! $enabled ) {
return;
}

$this->activate_auto_update( $enabled );
}
}
17 changes: 17 additions & 0 deletions src/Installation/Upgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -179,4 +179,21 @@ protected function v2_upgrade(): void {
Options::init()->set( $values, false, false );
}
}

/**
* Upgrade routine for v2.2
*/
protected function v22_upgrade(): void {
$auto_update_plugins = (array) get_site_option( 'auto_update_plugins', array() );

$automatic_updates = in_array( 'gtm-kit/gtm-kit.php', $auto_update_plugins, true );

$values = [
'misc' => [
'auto_update' => $automatic_updates,
],
];

Options::init()->set( $values, false, false );
}
}
69 changes: 61 additions & 8 deletions src/Options.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

namespace TLA_Media\GTM_Kit;

use TLA_Media\GTM_Kit\Admin\NotificationsHandler;
use TLA_Media\GTM_Kit\Installation\AutomaticUpdates;

/**
* Options
*/
Expand Down Expand Up @@ -97,6 +100,12 @@ final class Options {
'type' => 'boolean',
],
],
'misc' => [
'auto_update' => [
'default' => false,
'type' => 'boolean',
],
],
];

/**
Expand Down Expand Up @@ -265,31 +274,63 @@ public function set( array $options, bool $first_install = false, bool $overwrit
$options = self::array_merge_recursive( $this->get_all_raw(), $options );
}

$options = $this->process_generic_options( $options );
$options = $this->process_options( $options );

// Whether to update existing options or to add these options only once if they don't exist yet.
if ( $first_install ) {
\add_option( self::OPTION_NAME, $options, '', true );
} elseif ( is_multisite() ) {
\update_blog_option( get_current_blog_id(), self::OPTION_NAME, $options );
\update_blog_option( get_current_blog_id(), self::OPTION_NAME, $options );
} else {
\update_option( self::OPTION_NAME, $options, true );
}

$this->clear_cache();
}

/**
* Set single option.
*
* @param string $group Option group.
* @param string $key Option key.
* @param mixed $value Option value.
*/
public function set_option( string $group, string $key, $value ): void {

$options = $this->get_all_raw();

$options[ $group ][ $key ] = $value;

if ( is_multisite() ) {
\update_blog_option( get_current_blog_id(), self::OPTION_NAME, $options );
} else {
\update_option( self::OPTION_NAME, $options, true );
}

// Now we need to re-cache values.
$this->clear_cache();
}

/**
* Clear the cache
*
* @return void
*/
private function clear_cache(): void {
wp_cache_delete( self::OPTION_NAME, 'options' );
wp_cache_delete( 'gtmkit_script_settings', 'gtmkit' );
$this->options = get_option( self::OPTION_NAME, [] );
}

/**
* Process the generic plugin options.
* Process the plugin options.
*
* @param array<string, mixed> $options The options array.
*
* @return array<string, mixed>
*/
private function process_generic_options( array $options ): array {
private function process_options( array $options ): array {

$old_options = $this->get_all_raw();

foreach ( $options as $group => $keys ) {
foreach ( $keys as $option_name => $option_value ) {
Expand All @@ -300,9 +341,11 @@ private function process_generic_options( array $options ): array {
}
break;

case 'debug_events':
if ( $option_name === 'email_debug' ) {
$options[ $group ][ $option_name ] = (bool) $option_value;
case 'misc':
if ( $option_name === 'auto_update' ) {
if ( $old_options[ $group ][ $option_name ] !== $option_value ) {
$this->auto_update_setting( $option_value );
}
}
}
}
Expand Down Expand Up @@ -374,4 +417,14 @@ public function get_all_raw(): array {

return $options;
}

/**
* Auto-update setting
*
* @param bool $activate Activate or deactivate auto-updates.
*/
private function auto_update_setting( bool $activate ): void {
AutomaticUpdates::instance()->activate_auto_update( $activate );
NotificationsHandler::get()->remove_notification_by_id( 'gtmkit-auto-update' );
}
}
Loading

0 comments on commit d55a595

Please sign in to comment.