Incorrect update notifications in my WordPress plugin

I released an update for Members Only that fixes a small bug that caused WordPress to show an update available for Members Only, even when the latest version was already installed. This incorrect update notice was only shown for a short period of time (4 hours at most), and if you installed the same version again, it would fix the issue immediately. Let me explain the cause of the issue, and maybe you, and my future self, will avoid the same problem.

Self-hosted updates

Members Only is not listed on wordpress.org, therefore WordPress does not get its updates for Members Only from there. I host a custom update service on Primo Plugins that provides the latest update information in the format that WordPress expects. There are a few ways you can make a plugin do this, but the most common way is to hook into the update process so that WordPress uses the custom source.

Hooking into the plugin update process

There is more than one way to hook into the update process, but the most common one I’ve used myself is filtering the available updates data that WordPress saves to the database/cache and adding the self-hosted update data to it.

WordPress runs a filter called pre_set_site_transient_update_plugins right before it saves plugin update information it has collected. This is where I hook in and provide the custom data, which then gets saved for WordPress to use when it’s actually doing the updates.

The bug

When filtering the update information, one needs to do a version compare of the current version to the new version received from the custom update source, and only add the custom data if the new version is indeed newer than the current version. If you add your self-hosted data to this transient when there isn’t a newer version available, WordPress will think there is, even when the version numbers are the same.

This is what the version comparison with the bug looked like (snipped for brevity):

version_compare( MEMBERS_ONLY_VERSION, $update_info['new_version'], '<' )

The MEMBERS_ONLY_VERSION constant is defined in the main plugin file and is the current version represented as a string, e.g. ‘1.3.0’.

The bug is that MEMBERS_ONLY_VERSION is in memory, and has been there since the start of the process, and is still holding the old value from the version that was just upgraded. The new version that was just installed hasn’t been loaded into memory yet.

The reason this is a problem is that WordPress ends up triggering the hook we use to filter our custom data, so it runs again one more time with the in-memory version of Members Only, and thus the version compare doesn’t work as intended.

The fix

The fix is simple enough: instead of using MEMBERS_ONLY_VERSION to compare, get the version from the file on disk. This can be done with the WordPress function get_plugin_data(), which gets the plugin data from the file on disk, and returns an array of data contained within that new file. This causes the version compare to work as intended, and prevents the inaccurate update notification.

Thoughts

There are probably cleaner and better ways to do this, but the way I’m doing here (and the way many in the WP community do it too) is well understood and tested over many versions of WordPress over the span of many years. Have thoughts? Send me an email and let’s chat.