How does WordPress collect and display plugin updates?
The presentation of plugin updates is the result of several independent processes.
Retrieving plugin update information
Plugins are checked for updates by the function wp_update_plugins() defined in wp_includes/update.php. wp_update_plugins() is called in many ways for example by scheduling.
As it processes, wp_update_plugins() calls set_site_transient() with an argument of ‘update_plugins’. As it begins, this function runs the filter pre_set_site_transient_update_plugins. This is filter added in the lsl_sl_plugin_updater class in this file. The filter implementation in the lsl_sl_plugin_updater class attempts to retrieve update information from the vendor site.
If plugin information can be retrieved, the filter checks the returned version number and, if greater than version of the uninstalled plugin, the updated information contained in the response from the vendor is added to the ‘response’ array of the transient data passed to the filter which is keyed by the plugins file name (technically the result of a call to the WordPress function plugin_basename()).
When the filter returns to the set_site_transient() function the transient data, which now contains information for any updated plugin, is saved as an option with the option_name _set_site_transient_update_plugins.
Displaying plugin updates
Available plugins are displayed by the table WP_Plugins_List_Table which is defined in class-wp-plugins-list-table.php. It can be seen from the prepare() and display() methods that the content for the table are the entries in the global $plugins variable.
The display function of the table class calls the single_row() function render each row. This function in turn runs the action ‘after_plugin_row_$plugin_file’ where $plugin_file contains the file name (again, technically the result of a call to the WordPress function plugin_basename()). So the action run will be something like:
It’s clear that the action name is plugin specific but plugins don’t usually include an action with this name so where are these actions defined?
The answer is the function wp_plugin_update_rows() which is defined in wp-admin\includes\update.php. This function is called by an action attached to ‘admin_init’.
This function retrieves the ‘_set_site_transient_update_plugins’ options record, deserializes the value and sets up an action for every entry in the deserialized object which has an entry in the ‘response’ array. This is the array updated by the pre_set_site_transient_update_plugins filter of the lsl_sl_plugin_updater class when it is determined that the plugin version number has changed.
Plugin update information is collected based on several events and any change information is stored as a site transient option.
An action is setup for every entry in the transient that holds plugin change information.
The action is used by the single_row() function of the WP_Plugins_List_Table class to render a notice about the respective plugin change.
Is this perfect?
No probably not. A point of potential cause for confusion when creating a plugin that is updateable arises because action which runs to add the actions which will render change information executes *before* the call is made to request update information. As a result, any changes do not appear when the plugins are first displayed. Instead they appear the second time the list of plugin is displayed. To the end user this does not matter. They will not expect a plugin they’ve just installed to have been updated. However the plugin developer who is testing to confirm updating does work may be confused if the fact of a change does not appear immediately.
This could be resolved by calling wp_update_plugins() before wp_plugin_update_rows() is called. However deferring the use of wp_update_plugins() means the set_site_transient() function can be used. The benefit of using the transient function means their inherent expiration feature can be exploited to prevent update information being requested every time plugins are listed which would be very intrusive.