| 1 |
<?php |
| 2 |
/** |
| 3 |
* Handles any routines or migrations necessary when upgrading to a new version of the plugin. |
| 4 |
* |
| 5 |
* @package WordPress\AI\Admin |
| 6 |
* @since 0.6.0 |
| 7 |
*/ |
| 8 |
|
| 9 |
declare( strict_types=1 ); |
| 10 |
|
| 11 |
namespace WordPress\AI\Admin; |
| 12 |
|
| 13 |
use WordPress\AI\Admin\Upgrades\V0_5_0; |
| 14 |
use WordPress\AI\Admin\Upgrades\V0_6_0; |
| 15 |
use WordPress\AI\Admin\Upgrades\V1_0_0; |
| 16 |
use WordPress\AI\Admin\Upgrades\V1_3_0; |
| 17 |
|
| 18 |
// Exit if accessed directly. |
| 19 |
defined( 'ABSPATH' ) || exit; |
| 20 |
|
| 21 |
/** |
| 22 |
* Class - Upgrades. |
| 23 |
* |
| 24 |
* @internal |
| 25 |
* |
| 26 |
* @since 0.6.0 |
| 27 |
*/ |
| 28 |
final class Upgrades { |
| 29 |
/** |
| 30 |
* The key to store the version. |
| 31 |
* |
| 32 |
* @since 0.6.0 |
| 33 |
*/ |
| 34 |
private const VERSION_OPTION_KEY = 'wpai_version'; |
| 35 |
|
| 36 |
/** |
| 37 |
* The key to store failed upgrade information for the admin notice. |
| 38 |
* |
| 39 |
* @since 0.6.0 |
| 40 |
*/ |
| 41 |
private const FAILED_UPGRADE_OPTION_KEY = 'wpai_failed_upgrade_message'; |
| 42 |
|
| 43 |
/** |
| 44 |
* Upgrade classes. |
| 45 |
* |
| 46 |
* New upgrade routine classes should be added here, in order of oldest to newest. |
| 47 |
* |
| 48 |
* @since 0.6.0 |
| 49 |
* |
| 50 |
* @var class-string<\WordPress\AI\Admin\Upgrades\Abstract_Upgrade>[] |
| 51 |
*/ |
| 52 |
private const UPGRADE_CLASSES = array( // phpcs:ignore SlevomatCodingStandard.Classes.DisallowMultiConstantDefinition -- This is used as a single const. |
| 53 |
V0_5_0::class, |
| 54 |
V0_6_0::class, |
| 55 |
V1_0_0::class, |
| 56 |
V1_3_0::class, |
| 57 |
); |
| 58 |
|
| 59 |
/** |
| 60 |
* Initialize the class. |
| 61 |
* |
| 62 |
* @since 0.6.0 |
| 63 |
*/ |
| 64 |
public function init(): void { |
| 65 |
// Runs as a fallback, in case the activation hook is missed. |
| 66 |
add_action( 'admin_init', array( $this, 'do_upgrades' ) ); |
| 67 |
|
| 68 |
add_action( 'admin_notices', array( $this, 'failed_upgrade_notice' ) ); |
| 69 |
} |
| 70 |
|
| 71 |
/** |
| 72 |
* Checks for and runs any pending upgrades. |
| 73 |
* |
| 74 |
* @since 0.6.0 |
| 75 |
*/ |
| 76 |
public static function do_upgrades(): void { |
| 77 |
$db_version = get_option( self::VERSION_OPTION_KEY, '' ); |
| 78 |
|
| 79 |
foreach ( self::UPGRADE_CLASSES as $upgrade_class ) { |
| 80 |
/** |
| 81 |
* Skip upgrades for newer versions. |
| 82 |
* @todo Remove the !empty() check once we no long need to support < v0.5.0 and '' means a new install. |
| 83 |
*/ |
| 84 |
if ( ! empty( $db_version ) && version_compare( $db_version, $upgrade_class::$version, '>=' ) ) { |
| 85 |
continue; |
| 86 |
} |
| 87 |
|
| 88 |
$upgrade = new $upgrade_class( $db_version ); |
| 89 |
$result = $upgrade->run(); |
| 90 |
|
| 91 |
// Store the error message and stop if the upgrade failed. |
| 92 |
if ( is_wp_error( $result ) ) { |
| 93 |
update_option( |
| 94 |
self::FAILED_UPGRADE_OPTION_KEY, |
| 95 |
array( |
| 96 |
'version' => $upgrade_class::$version, |
| 97 |
'error' => $result->get_error_message(), |
| 98 |
) |
| 99 |
); |
| 100 |
return; |
| 101 |
} |
| 102 |
|
| 103 |
$db_version = $upgrade_class::$version; |
| 104 |
} |
| 105 |
|
| 106 |
// If all upgrades completed successfully, the plugin was successfully upgraded to the latest version. |
| 107 |
delete_option( self::FAILED_UPGRADE_OPTION_KEY ); |
| 108 |
update_option( self::VERSION_OPTION_KEY, WPAI_VERSION ); |
| 109 |
} |
| 110 |
|
| 111 |
/** |
| 112 |
* Displays an admin notice if a plugin upgrade failed, with the error message. |
| 113 |
* |
| 114 |
* @since 0.6.0 |
| 115 |
*/ |
| 116 |
public function failed_upgrade_notice(): void { |
| 117 |
// Skip if there's no failures. |
| 118 |
$failed_upgrade = get_option( self::FAILED_UPGRADE_OPTION_KEY, false ); |
| 119 |
if ( ! $failed_upgrade ) { |
| 120 |
return; |
| 121 |
} |
| 122 |
|
| 123 |
// If the error is set but empty, clean it up. |
| 124 |
if ( empty( $failed_upgrade['version'] ) || empty( $failed_upgrade['error'] ) ) { |
| 125 |
delete_option( self::FAILED_UPGRADE_OPTION_KEY ); |
| 126 |
return; |
| 127 |
} |
| 128 |
|
| 129 |
// Display the error message. |
| 130 |
wp_admin_notice( |
| 131 |
sprintf( |
| 132 |
/* translators: 1. The version the upgrade failed on, 2. The error message. */ |
| 133 |
esc_html__( 'WordPress AI failed to upgrade to %1$s. Migration version %2$s failed with the following error: %3$s. Please deactivate and reactivate the plugin to try again.', 'ai' ), |
| 134 |
WPAI_VERSION, |
| 135 |
esc_html( $failed_upgrade['version'] ), |
| 136 |
esc_html( $failed_upgrade['error'] ) |
| 137 |
), |
| 138 |
array( |
| 139 |
'type' => 'error', |
| 140 |
'dismissible' => false, |
| 141 |
) |
| 142 |
); |
| 143 |
} |
| 144 |
} |
| 145 |
|