Skip to content

Instantly share code, notes, and snippets.

@zaus
Last active October 2, 2020 17:10
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save zaus/c08288c68b7f487193d1 to your computer and use it in GitHub Desktop.
Save zaus/c08288c68b7f487193d1 to your computer and use it in GitHub Desktop.
Wordpress Activation/Upgrade Hook Helper
<?php
if(!class_exists('WpPluginUpgradeBase')) :
abstract class WpPluginUpgradeBase {
function __construct() {
add_action( 'admin_init', array(&$this, 'load_plugin') );
}
/**
* Namespace the given key
* @param string $key the key to namespace
* @return the namespaced key
*/
public function N($key = false) {
// nothing provided, return namespace
if( ! $key || empty($key) ) { return get_class($this); }
return sprintf('%s_%s', get_class($this), $key);
}
const HOOK_ACTIVATED = 'activated';
const HOOK_LOADED = 'loaded';
public function loaded_hook_name() { return $this->N(self::HOOK_LOADED); }
public function activated_hook_name() { return $this->N(self::HOOK_ACTIVATED); }
public function register($original_file) {
register_activation_hook( $original_file, array( &$this, 'activate' ) );
}
public function activate() {
// delay doing anything until plugins are actually ready
// see http://codex.wordpress.org/Function_Reference/register_activation_hook#Process_Flow
add_option( $this->N(), $this->N() );
/* other non-plugin-dependent activation code here */
do_action( $this->activated_hook_name(), 'activated' );
}
public function load_plugin() {
if ( is_admin() && get_option( $this->N() ) == $this->N() ) {
// clear the 'run once' flag
delete_option( $this->N() );
/* do stuff once right after activation */
do_action( $this->loaded_hook_name(), 'loaded' );
}
}
}//--- class WpPluginUpgradeBase
endif; // class_exists
<?php
// the main plugin file
// header....etc...then...
// handle plugin upgrades
// http://codex.wordpress.org/Function_Reference/register_activation_hook#Examples
include_once dirname( __FILE__ ) . '/WpPluginUpgradeBase.php'; // core helper
include_once dirname( __FILE__ ) . '/YourPluginUpgrader.php'; // your custom code
$ugrader = new YourPluginUpgrader();
$ugrader->register(__FILE__);
class YourPlugin {
const pluginVersion = '1.6.0'; // to make it easier to compare in upgrade check, rather than calling `get_plugin_data` http://codex.wordpress.org/Function_Reference/get_plugin_data
// other plugin code
}
<?php
class YourPluginUpgrader extends WpPluginUpgradeBase {
function __construct() {
parent::__construct();
add_action($this->loaded_hook_name(), array(&$this, 'loaded'));
//add_action($this->activated_hook_name(), array(&$this, 'test'));
}
public function test($action) {
// just prove it was called
error_log(print_r(array(__FILE__, __CLASS__, __FUNCTION__, $action), true));
}
public function loaded($action) {
// check current plugin version
// compare against prev version and do stuff
}
}
<?php
// an example that goes through upgrade steps depending on how out-of-date
class YourPluginUpgradeSteps extends WpPluginUpgradeBase {
function __construct() {
parent::__construct();
add_action($this->loaded_hook_name(), array(&$this, 'loaded'));
## just to show that each hook was hit
## add_action($this->loaded_hook_name(), array(&$this, 'test'));
## add_action($this->activated_hook_name(), array(&$this, 'test'));
}
public function test($action) {
// just prove it was called
error_log(print_r(array(__FILE__, __CLASS__, __FUNCTION__, $action), true));
}
/**
* List of important upgrade steps
*/
var $upgrades = array(
self::VERSION_FEATURE_A_ADDED,
self::VERSION_WHEN_THIS_HAPPENED,
self::VERSION_WHEN_THAT_HAPPENED
);
const VERSION_FEATURE_A_ADDED = '1.2.0';
const VERSION_WHEN_THIS_HAPPENED = '1.2.2';
const VERSION_WHEN_THAT_HAPPENED = '1.5';
public function loaded($action) {
// check current plugin version
$current = YourPlugin::pluginVersion;
// compare against prev version and do stuff
$prev = get_option( 'YourPlugin_version' );
// special case: we've never set the version before; not all plugins will need to upgrade in that case
if(empty($prev) || version_compare($prev, $current) < 0) {
// are there upgrade steps depending on how out-of-date?
foreach($this->upgrades as $next_version) {
if(version_compare($prev, $next_version) < 0) $this->do_upgrade($prev, $next_version);
$prev = $next_version;
}
}
// update stored plugin version for next time
update_option('YourPlugin_version', $current);
}
function do_upgrade($prev, $next) {
## error_log('upgrade from ' . $prev . ' to ' . $next);
switch($next) {
case self::VERSION_FEATURE_A_ADDED:
## error_log('doing feature A upgrade...');
break;
case self::VERSION_WHEN_THIS_HAPPENED:
## error_log('doing feature B upgrade...');
break;
case self::VERSION_WHEN_THAT_HAPPENED:
## error_log('doing feature C upgrade...');
break;
}
}
}
@zaus
Copy link
Author

zaus commented Aug 8, 2016

You could probably replace register_activation_hook with hooking to plugins_loaded only when is_admin per discussions at http://wordpress.stackexchange.com/questions/144870/wordpress-update-plugin-hook-action-since-3-9/160749#160749

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment