How to completely disable WordPress update checks for core, plugins, and themes
In WP, it is possible to completely disable update checks for everything (core, themes, plugins, and translations) at once. To do this, you need to specify true in the constant DISALLOW_FILE_MODS. However, there is no standard way to completely disable update checks only for core files or plugins/themes.
Do not confuse update checks and auto-updates. Disabling auto-updates is simple and not the same as update checks (for new versions). When disabling auto-updates, the check for new versions, notifications about them, and the ability to update remain.
Deactivating WordPress updates may be necessary when, for example, we want to manually update the WordPress core (or via composer), but at the same time we want to leave the ability to update plugins/themes through the admin panel.
See also:
Properly disable core WP update checks
Disable WP core updates, but leave core translation updates
/// Disable WP core updates, but leave core translation updates
add_filter( 'pre_set_site_transient_update_core', static function( $upinfo ) {
$upinfo->updates = [];
return $upinfo;
} );
In this case, WP will make an HTTP request to get new versions, but we reset them and as a result, only core translation update data will remain.
Disable WP core and core translation update checks
/// Disable WP core and core translation update checks
add_filter( 'pre_site_transient_update_core', static function( $value ) {
$upinfo = new stdClass();
$upinfo->updates = [];
$upinfo->version_checked = $GLOBALS['wp_version'];
$upinfo->last_checked = time();
return $upinfo;
} );
In this case, WP will not make an HTTP request to get new versions and, accordingly, there will be no updates.
See: wp_version_check().
Details
Now, if interested, let's delve into the details.
How does it work?
To find out if there are new versions, WordPress makes requests to the official updates server and saves the result in transient options:
update_core- for the WordPress core.update_plugins- for plugins.update_themes- for themes.
The value of each option can be changed using hooks:
pre_site_transient_{$option_name}- on receipt. Example:pre_site_transient_update_core.pre_set_site_transient_{$option_name}- for updates. Example:pre_set_site_transient_update_core.
Why did I decide to write about this?
On the Internet, you can often find a way to disable core updates like this:
add_filter( 'pre_site_transient_update_core', '__return_null' );
This code works, but incorrectly:
- Does not allow checking for updates for core WordPress translations.
- Does not disable the HTTP request to check for core updates.
- Creates PHP notices in the admin panel.
To fix this, we need to return not null, but a data object, only replace the data in it so that WP "thinks" that there are no updates.
The correct code that fixes these shortcomings can be found above.
What about translations?
If we look at the function wp_get_translation_updates(), we will see that to get data about translation updates, like in the function wp_version_check(), the data is taken from get_site_transient( 'update_core' ).
This data looks like this:
stdClass Object ( [updates] => Array ( [0] => stdClass Object ( [response] => latest [download] => https://downloads.wordpress.org/release/wordpress-6.3.1.zip [locale] => en_US [current] => 6.3.1 [version] => 6.3.1 [php_version] => 7.0.0 [mysql_version] => 5.0 ) ) [last_checked] => 1696017321 [version_checked] => 6.3.1 [translations] => Array ( [0] => Array ( [type] => core [slug] => default [language] => ru_RU [version] => 6.3.1 [updated] => 2023-09-27 08:44:56 [package] => https://downloads.wordpress.org/translation/core/6.3.1/ru_RU.zip [autoupdate] => 1 ) ) )
As we can see, the translations element contains data about the translation version. And if you completely disable the request or replace it with null, then there will be no data about new versions of translations.
Disable theme update checks
Disable checking (including sending an HTTP request to the update server):
add_filter( 'pre_site_transient_update_themes', static function( $value ) {
static $themes;
$themes || $themes = wp_get_themes();
$upinfo = new stdClass();
$upinfo->last_checked = time();
$upinfo->checked = [];
foreach ( $themes as $theme ) {
$upinfo->checked[ $theme->get_stylesheet() ] = $theme->get( 'Version' );
}
return $upinfo;
} );
See: wp_update_themes().
Disable plugin update checks
All plugins
Disable checking (including sending an HTTP request to the update server):
// update plugins check remove
add_filter( 'pre_site_transient_update_plugins', static function( $value ) {
static $plugins;
$plugins || $plugins = get_plugins();
$upinfo = new stdClass();
$upinfo->last_checked = time();
$upinfo->checked = [];
foreach ( $plugins as $file => $p ) {
$upinfo->checked[ $file ] = $p['Version'];
}
return $upinfo;
} );
Specified plugins
There are several ways to disable the update of a specific plugin.
Method 1: change the plugin version
During the check, the versions of the current plugin and the plugin in the WP directory are compared. If the version in the directory is higher, the plugin update is suggested. So, all you need to do is open the plugin and change its version to a deliberately higher one.
For example, if you have a plugin called "wp-super-cache" and you need to disable its updates, open the main plugin file "wp-cache.php". To do this, go to "Admin Panel > Plugins > Editor > Select plugin" and at the beginning, you will see these lines:
<?php /* Plugin Name: WP Super Cache Plugin URI: https://wordpress.org/plugins/wp-super-cache/ Description: Very fast caching plugin for WordPress. Version: 1.4.7 Author: Automattic Author URI: https://automattic.com/ License: GPL2+ Text Domain: wp-super-cache */
Replace the version, the line Version: 1.4.7 with Version: 99991.4.7 and save the changes.
Done! Now you have the highest version of the plugin, and WP will never update it to a lower version...
Method 2: insert code into the plugin
Insert the following code into the main plugin file and you're done!
add_filter( 'pre_site_transient_update_plugins', 'wpkama_disable_plugin_update' );
function wpkama_disable_plugin_update( $value ){
if( ! is_object( $value ) ){
return $value;
}
// Remove the current plugin from the list
unset( $value->response[ plugin_basename( __FILE__ ) ] );
return $value;
}
Method 2.1: code for functions.php
If inserting code into the plugin is not an option, you can use the previous code outside the plugin to cancel the update check. Inserting into the plugin is convenient because there we can dynamically get its base name, which is usually like this: plugin_folder_name/plugin_main_file.php.
Example for the Akismet plugin:
add_filter( 'pre_site_transient_update_plugins', static function( $value ) {
unset( $value->response['akismet/akismet.php'] );
return $value;
} );
See wp_update_plugins().

