WordPress plugin update hook – upgrader_process_complete

james zwadlo 190040

I had a situation recently when I wanted to let plugin users know of a change I’d made since the previous version. The best way, I think, is to use admin_notices and create a notice at the top of the admin page. But I wanted the message to appear only to users who had just updated the plugin, not to appear to users who had just installed the plugin.

It turns that there is a hook, upgrader_process_complete, that allows you to do exactly this. It fires when WordPress runs an upgrade / update for themes or plugins and provides us with data on which plugins or themes have been updated.

This means that you can add an action that will run when WordPress has processed an update and check which plugins have been updated. If yours is one of them, you can display a notice to your users.

To test this out, I made a short plugin that will display a notice to users when it’s installed then display a different notice when it’s updated.

<?php
/*Plugin Name: Upgrader Process Example
Plugin URI: https://pluginrepublic.com/wordpress-plugin-update-hook-upgrader_process_complete/
Description: Just an example of using upgrader_process_complete
Version: 1.0.0
Author: Catapult Themes
Author URI: https://pluginrepublic.com/
Text Domain: wp-upe
Domain Path: /languages*/

// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
 exit;
}

/**
 * This function runs when WordPress completes its upgrade process
 * It iterates through each plugin updated to see if ours is included
 * @param $upgrader_object Array
 * @param $options Array
 */
function wp_upe_upgrade_completed( $upgrader_object, $options ) {
 // The path to our plugin's main file
 $our_plugin = plugin_basename( __FILE__ );
 // If an update has taken place and the updated type is plugins and the plugins element exists
 if( $options['action'] == 'update' && $options['type'] == 'plugin' && isset( $options['plugins'] ) ) {
  // Iterate through the plugins being updated and check if ours is there
  foreach( $options['plugins'] as $plugin ) {
   if( $plugin == $our_plugin ) {
    // Set a transient to record that our plugin has just been updated
    set_transient( 'wp_upe_updated', 1 );
   }
  }
 }
}
add_action( 'upgrader_process_complete', 'wp_upe_upgrade_completed', 10, 2 );

/**
 * Show a notice to anyone who has just updated this plugin
 * This notice shouldn't display to anyone who has just installed the plugin for the first time
 */
function wp_upe_display_update_notice() {
 // Check the transient to see if we've just updated the plugin
 if( get_transient( 'wp_upe_updated' ) ) {
  echo '<div class="notice notice-success">' . __( 'Thanks for updating', 'wp-upe' ) . '</div>';
  delete_transient( 'wp_upe_updated' );
 }
}
add_action( 'admin_notices', 'wp_upe_display_update_notice' );

/**
 * Show a notice to anyone who has just installed the plugin for the first time
 * This notice shouldn't display to anyone who has just updated this plugin
 */
function wp_upe_display_install_notice() {
 // Check the transient to see if we've just activated the plugin
 if( get_transient( 'wp_upe_activated' ) ) {
  echo '<div class="notice notice-success">' . __( 'Thanks for installing', 'wp-upe' ) . '</div>';
  // Delete the transient so we don't keep displaying the activation message
 delete_transient( 'wp_upe_activated' );
 }
}
add_action( 'admin_notices', 'wp_upe_display_install_notice' );

/**
 * Run this on activation
 * Set a transient so that we know we've just activated the plugin
 */
function wp_upe_activate() {
 set_transient( 'wp_upe_activated', 1 );
}
register_activation_hook( __FILE__, 'wp_upe_activate' );

The function wp_upe_upgrade_completed hooks into upgrader_process_complete, running when the upgrade process has finished. The $options parameter is received from WordPress and contains information about what plugins have updated. It looks similar to this:

Array (
 [action] => update
 [type] => plugin
 [bulk] => 1
 [plugins] => Array (
 [0] => black-studio-tinymce-widget/black-studio-tinymce-widget.php
 )
)

If themes are being updated, the array looks like this:

Array (
 [action] => update
 [type] => theme
 [bulk] => 1
 [themes] => Array (
 [0] =>twentyfifteen
 )
)

So in our case where we’re looking at updating a plugin, we check the $options parameter to ensure that an update has taken place and which plugins have updated. We iterate through the array of plugins to find ours. If we find it, we set a transient variable.

We hook the wp_upe_display_update_notice function to admin_notices and just check for the existence of the transient we set previously. If it exists, we know our plugin has just been updated so we display a notice and delete the transient so that the notice doesn’t keep displaying.

The rest of the plugin follows a similar pattern for displaying a notice on plugin activation. We use register_activation_hook to detect activation and set another transient variable.

I hope you found this useful – it’s a great way to communicate with your users between plugin versions and I wish I’d known about it sooner.

Five comments

    • User image

      I have one question about this hook: when it triggers, the updated plugin is already running on the updated version right? or when this triggers the plugin still is on the older version?

        • User image

          I’ve tested it and it in fact runs from the old version of the plugin, not the updated one, which makes it fairy useless if you want to for example change table structure of your custom DB tables in the new version.

        • User image

          Use with caution: When you use the upgrader_process_complete action hook in your plugin and your plugin is the one which under upgrade, then this action will run the old version of your plugin.

          This was found in the Wordpress documentation.

Leave a Reply

Your email address will not be published. All fields are required.