-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit b0a7f4c
Showing
3 changed files
with
204 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"name": "wp-forge/wp-upgrade-handler", | ||
"description": "A drop-in library for handling upgrade routines in WordPress plugins and themes.", | ||
"type": "library", | ||
"license": "GPL-2.0-or-later", | ||
"authors": [ | ||
{ | ||
"name": "Micah Wood", | ||
"email": "[email protected]" | ||
} | ||
], | ||
"autoload": { | ||
"psr-4": { | ||
"WP_Forge\\UpgradeHandler\\": "includes" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
<?php | ||
|
||
namespace WP_Forge\UpgradeHandler; | ||
|
||
/** | ||
* Class UpgradeHandler | ||
* | ||
* @package WP_Forge\UpgradeHandler | ||
*/ | ||
class UpgradeHandler { | ||
|
||
/** | ||
* The previous version. | ||
* | ||
* @var string | ||
*/ | ||
protected $old_version; | ||
|
||
/** | ||
* The current version. | ||
* | ||
* @var string | ||
*/ | ||
protected $new_version; | ||
|
||
/** | ||
* The directory containing upgrade routines. | ||
* | ||
* @var string | ||
*/ | ||
protected $upgrade_dir; | ||
|
||
/** | ||
* Class constructor. | ||
* | ||
* @param string $upgrade_dir The directory containing upgrade routines. | ||
* @param string $old_version The previous version. | ||
* @param string $new_version The current version. | ||
*/ | ||
public function __construct( $upgrade_dir, $old_version, $new_version ) { | ||
$this->upgrade_dir = $upgrade_dir; | ||
$this->old_version = $old_version; | ||
$this->new_version = $new_version; | ||
} | ||
|
||
/** | ||
* Detect when an upgrade is necessary and run the updates. | ||
* | ||
* @return bool Whether or not an upgrade routine ran. | ||
*/ | ||
public function maybe_upgrade() { | ||
$should_upgrade = $this->should_upgrade(); | ||
if ( $should_upgrade ) { | ||
$available_routines = $this->get_available_upgrade_routines(); | ||
$required_routines = $this->get_required_upgrade_routines( $available_routines ); | ||
$this->run_upgrade_routines( $required_routines ); | ||
} | ||
|
||
return $should_upgrade; | ||
} | ||
|
||
/** | ||
* Check if we should upgrade. | ||
* | ||
* @return bool | ||
*/ | ||
public function should_upgrade() { | ||
return $this->old_version !== $this->new_version; | ||
} | ||
|
||
/** | ||
* Get a collection of available upgrade routines. | ||
* | ||
* @return array A collection of filepaths indexed by versions. | ||
*/ | ||
public function get_available_upgrade_routines() { | ||
$routines = array(); | ||
$filepaths = glob( rtrim( $this->upgrade_dir, '/' ) . '/*.php' ); | ||
if ( $filepaths ) { | ||
$versions = str_replace( '.php', '', array_map( 'basename', $filepaths ) ); | ||
$routines = array_combine( $versions, $filepaths ); | ||
} | ||
|
||
return $routines; | ||
} | ||
|
||
/** | ||
* Get a collection of the required upgrade routines. | ||
* | ||
* @param array $available_routines A collection of available upgrade routines. | ||
* | ||
* @return array A collection of filepaths indexed by versions. | ||
*/ | ||
public function get_required_upgrade_routines( array $available_routines ) { | ||
$routines = array(); | ||
$required = array_filter( array_keys( $available_routines ), array( $this, 'filter_upgrade_routines' ) ); | ||
if ( $required ) { | ||
$routines = array_intersect_key( $available_routines, array_combine( $required, $required ) ); | ||
} | ||
|
||
return $routines; | ||
} | ||
|
||
/** | ||
* Run an ordered set of upgrade routines. | ||
* | ||
* @param array $routines A collection of filepaths indexed by versions. | ||
*/ | ||
public function run_upgrade_routines( array $routines ) { | ||
foreach ( $routines as $file ) { | ||
if ( file_exists( $file ) ) { | ||
require $file; | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Filter to find the versions for which we need to run an upgrade routine. | ||
* | ||
* @param string $version The current version. | ||
* | ||
* @return bool Whether or not to keep the routine. | ||
*/ | ||
protected function filter_upgrade_routines( $version ) { | ||
return version_compare( $this->old_version, $version, '<' ) && version_compare( $this->new_version, $version, '>=' ); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# WordPress Upgrade Handler | ||
|
||
A drop-in library for handling upgrade routines in WordPress plugins and themes. | ||
|
||
## Installation | ||
|
||
- Run `composer require wp-forge/wp-upgrade-handler` | ||
- Make sure you require the `vendor/autoload.php` file in your project. | ||
|
||
## Usage | ||
|
||
Here is an example of how to use this library in a WordPress plugin or theme: | ||
|
||
```php | ||
<?php | ||
|
||
use WP_Forge\UpgradeHandler\UpgradeHandler; | ||
|
||
// Define the current plugin version in the code | ||
define( 'MY_PLUGIN_VERSION', '1.4.1' ); | ||
|
||
// Only handle upgrades in the admin | ||
if ( is_admin() ) { | ||
|
||
// Handle plugin upgrades | ||
$upgrade_handler = new UpgradeHandler( | ||
__DIR__ . '/upgrades', // Directory where upgrade routines live | ||
get_option( 'my_plugin_version' ), // Old plugin version (from database) | ||
MY_PLUGIN_VERSION // New plugin version (from code) | ||
); | ||
|
||
// Returns true if the old version doesn't match the new version | ||
$did_upgrade = $upgrade_handler->maybe_upgrade(); | ||
|
||
if ( $did_upgrade ) { | ||
// If an upgrade occurred, update the new version in the database to prevent running the routine(s) again. | ||
update_option( 'my_plugin_version', MY_PLUGIN_VERSION, true ); | ||
} | ||
} | ||
``` | ||
|
||
If you just released version `1.4.1` of your plugin, but created upgrade routines for `1.4.1` and `1.3.9`, anyone upgrading from version `1.3.8` or earlier would have both of those upgrade routines run automatically. If someone is upgrading from version `1.3.9` or greater, then only the `1.4.1` upgrade routine would be run. | ||
|
||
### Creating an Upgrade Routine | ||
As an example, let's assume I just released version `1.4.1` of my plugin. The upgrade routine needs to change an option name in the database. All I need to do after adding the previous code from above is to create a file named `1.4.1.php` in my `upgrades` directory. | ||
|
||
The following would be the contents of that file: | ||
|
||
```php | ||
<?php | ||
|
||
// Rename 'old_option' to 'new_option', if necessary. | ||
$old_option = get_option( 'old_option' ); | ||
if( $old_option ) { | ||
update_option( 'new_option', get_option( 'old_option' ) ); | ||
delete_option( 'old_option' ); | ||
} | ||
|
||
``` |