Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

My plugin not updating properly (issue with upgrader_process_complete)

Tags:

php

wordpress

I have users who have installed my plugin (we'll call it v6).

V6 version of my plugin does not register a handler for upgrader_process_complete.

In my new version, I have upgrader_process_complete registered to do some upgrades to my database table.

However, it seems that when the user upgrades from the Plugins page using the update now link, the handler of my new version is not invoked.

Could anyone shed some light on this issue?

like image 726
Gezim Avatar asked Oct 30 '22 20:10

Gezim


1 Answers

The upgrader_process_complete hook is running in the current version while updating the plugin.


Let say that you are running plugin v 6.0.
And then you are just updated to 6.1 which contain upgrader_process_complete hook in this version.
The upgrader hook will not be called until next scenario.

Now you have running plugin v 6.1 which contain upgrader_process_complete hook since v 6.1.
And you are just updated to 6.2 which contain the code that write ABC.txt file.
The upgrader hook for 6.1 will be called, NOT 6.2. So, it means that the ABC.txt file will not be created.

If you are running plugin v 6.1 and want to run the newly updated code from 6.2 that just updated, you have to add something like transient to get notice that the update from new version of code is need.
And here is from my plugin. You can use as you need under MIT license.


<?php

class Upgrader
{


        /**
         * Display link or maybe redirect to manual update page.
         * 
         * To understand more about new version of code, please read more on `updateProcessComplete()` method.
         * 
         * @link https://codex.wordpress.org/Plugin_API/Action_Reference/admin_notices Reference.
         */
        public function redirectToUpdatePlugin()
        {
            if (get_transient('myplugin_updated') && current_user_can('update_plugins')) {
                // if there is updated transient
                // any background update process can be run here.
                // write your new version of code that will be run after updated the plugin here.
            }// endif;
        }// redirectToUpdatePlugin


        /**
         * {@inheritDoc}
         */
        public function registerHooks()
        {
            // on update/upgrade plugin completed. set transient and let `redirectToUpdatePlugin()` work.
            add_action('upgrader_process_complete', [$this, 'updateProcessComplete'], 10, 2);
            // on plugins loaded, background update the plugin with new version.
            add_action('plugins_loaded', [$this, 'redirectToUpdatePlugin']);
        }// registerHooks


        /**
         * After update plugin completed.
         * 
         * This method will be called while running the current version of this plugin, not the new one that just updated.
         * For example: You are running 1.0 and just updated to 2.0. The 2.0 version will not working here yet but 1.0 is working.
         * So, any code here will not work as the new version. Please be aware!
         * 
         * This method will add the transient to work again and will be called in `redirectToUpdatePlugin()` method.
         * 
         * @link https://developer.wordpress.org/reference/hooks/upgrader_process_complete/ Reference.
         * @link https://codex.wordpress.org/Plugin_API/Action_Reference/upgrader_process_complete Reference.
         * @param \WP_Upgrader $upgrader
         * @param array $hook_extra
         */
        public function updateProcessComplete(\WP_Upgrader $upgrader, array $hook_extra)
        {
            if (is_array($hook_extra) && array_key_exists('action', $hook_extra) && array_key_exists('type', $hook_extra) && array_key_exists('plugins', $hook_extra)) {
                if ($hook_extra['action'] == 'update' && $hook_extra['type'] == 'plugin' && is_array($hook_extra['plugins']) && !empty($hook_extra['plugins'])) {
                    $this_plugin = plugin_basename(MYPLUGIN_FILE);// MYPLUGIN_FILE is come from __FILE__ of the main plugin file.
                    foreach ($hook_extra['plugins'] as $key => $plugin) {
                        if ($this_plugin == $plugin) {
                            // if this plugin is in the updated plugins.
                            // set transient to let it run later. this transient will be called and run in `redirectToUpdatePlugin()` method.
                            set_transient('myplugin_updated', 1);
                            break;
                        }
                    }// endforeach;
                    unset($key, $plugin, $this_plugin);
                }// endif update plugin and plugins not empty.
            }// endif; $hook_extra
        }// updateProcessComplete


    }

Please carefully read and modify the code above.
In your plugin file, call to Upgrader->registerHooks() method.
And write your code inside redirectToUpdatePlugin() method to work as background update process.


From my code, the procedure will be like this...
Running plugin v 6.0 -> update to 6.1 -> The code in 6.0 set transient that it is just updated.
Reload the page or click to anywhere in admin pages. -> Now v 6.1 is running. -> On the plugin loaded hook, it can detected that this plugin is just updated. -> Call to redirectToUpdatePlugin() method and background process start working here.

like image 162
vee Avatar answered Nov 09 '22 13:11

vee