WP Code – plugin date audit
I found the need to want to check when plugins were last updated by the developer, in order to work out if any plugins needed replacing or not. Security is important and updates over the course of a year could have unintended consequences.
The following code can be inserted into a snippet to run in the admin area. It adds some extra detail so that at a glance you can see when the plugin was last updated. There is some colour coding for 6 months and 12 months to help with the visuals. Further explanation of the code is found in the commented code, as you should of course inspect any code before adding it to your own website. You can also make any changes too.
WPCode settings: Auto insert, Admin only
// snippet from https://timjefferson.net CC BY-NC-SA 4.0
// Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
add_filter('plugin_row_meta', 'pud_secure_display_last_updated', 10, 2);
function pud_secure_display_last_updated($plugin_meta, $plugin_file) {
// 1. PERFORMANCE: Only run in the admin plugins page
if (!is_admin()) return $plugin_meta;
$slug = dirname($plugin_file);
if ('.' === $slug || empty($slug)) return $plugin_meta;
// 2. CACHING: Check for existing data
$cache_key = 'pud_v4_' . md5($slug);
$last_updated_raw = get_transient($cache_key);
if (false === $last_updated_raw) {
include_once ABSPATH . 'wp-admin/includes/plugin-install.php';
// 3. PERFORMANCE: Explicitly set a 2-second timeout for this request
$timeout_func = function($args) {
$args['timeout'] = 2;
return $args;
};
add_filter('http_request_args', $timeout_func);
$api = plugins_api('plugin_information', array(
'slug' => $slug,
'fields' => array('last_updated' => true)
));
// Remove the filter so it doesn't affect other WP processes
remove_filter('http_request_args', $timeout_func);
// 4. ERROR HANDLING: Check for WP_Error or missing data
if (!is_wp_error($api) && isset($api->last_updated)) {
$last_updated_raw = $api->last_updated;
} else {
// Cache "non_repo" for 24 hours so we don't keep retrying failed lookups
$last_updated_raw = 'non_repo';
}
set_transient($cache_key, $last_updated_raw, DAY_IN_SECONDS);
}
// 5. SECURITY & DISPLAY LOGIC
if ($last_updated_raw !== 'non_repo') {
$updated_timestamp = strtotime($last_updated_raw);
$current_time = current_time('timestamp');
$diff = $current_time - $updated_timestamp;
$six_months = 15552000; // Seconds in 6 months
$one_year = 31104000; // Seconds in 1 year
$color = '#2271b1';
$icon = '';
if ($diff > $one_year) {
$color = '#d63638'; // Red
$icon = '⚠️ ';
} elseif ($diff > $six_months) {
$color = '#ffa500'; // Orange
$icon = '🕒 ';
}
$formatted_date = date_i18n(get_option('date_format'), $updated_timestamp);
$safe_style = sprintf('color: %s; font-weight: bold;', esc_attr($color));
$plugin_meta[] = sprintf(
'<span style="%s">%sRepo Update: %s</span>',
$safe_style,
$icon,
esc_html($formatted_date)
);
}
return $plugin_meta;
}
Here is a minified version:
// snippet from https://timjefferson.net CC BY-NC-SA 4.0
// Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
add_filter('plugin_row_meta', function($meta, $file) {
if (!is_admin() || !($slug = dirname($file)) || '.' === $slug) return $meta;
$cache_key = 'pud_v4_' . md5($slug);
if (false === ($val = get_transient($cache_key))) {
include_once ABSPATH . 'wp-admin/includes/plugin-install.php';
$to = function($a) { $a['timeout'] = 2; return $a; };
add_filter('http_request_args', $to);
$api = plugins_api('plugin_information', ['slug' => $slug, 'fields' => ['last_updated' => true]]);
remove_filter('http_request_args', $to);
$val = (!is_wp_error($api) && isset($api->last_updated)) ? $api->last_updated : 'none';
set_transient($cache_key, $val, DAY_IN_SECONDS);
}
if ($val !== 'none') {
$ts = strtotime($val);
$diff = current_time('timestamp') - $ts;
$color = ($diff > 31104000) ? '#d63638' : (($diff > 15552000) ? '#ffa500' : '#2271b1');
$icon = ($diff > 31104000) ? '⚠️ ' : (($diff > 15552000) ? '🕒 ' : '');
$date = date_i18n(get_option('date_format'), $ts);
$meta[] = sprintf('<span style="color:%s;font-weight:bold;">%sRepo: %s</span>', esc_attr($color), $icon, esc_html($date));
}
return $meta;
}, 10, 2);
These snippets were generated with assistance from Google Gemini Pro. The following information has been generated by AI to assist with further understanding.
This snippet enhances the WordPress Plugins dashboard by automatically retrieving and displaying the “Last Updated” date for every plugin hosted in the official WordPress.org repository. By leveraging the WordPress Plugins API, it calculates how long it has been since a developer last pushed an update and applies a visual “health status” using color-coded indicators: blue for recent updates, orange for plugins over six months old, and bold red with a warning icon for those untouched for over a year. Designed with performance and security in mind, the script utilizes transients to cache results for 24 hours—preventing dashboard slowdowns—and ensures all data is sanitized before display, providing site administrators with a critical, at-a-glance tool for identifying potentially abandoned or insecure software.
Key Features:
- Visual Health Checks: Instantly spot abandoned plugins via Red/Orange/Blue color coding.
- Performance Optimized: Uses the WordPress Transients API to ensure no impact on page load speed after the initial scan.
- Security First: Implements data escaping and API timeouts to maintain site stability.
- Zero Footprint: Works as a simple code snippet without the need for additional heavy plugin overhead.
Pro-Tips
1. Why does it say “N/A” for some plugins?
Not every plugin is hosted on the official WordPress.org repository. Premium plugins (like WP Rocket or ACF Pro) and custom-developed tools host their own update servers. Since this snippet queries the public WordPress API, it won’t find dates for “private” or “premium” software. This is actually a helpful way to distinguish between repo-hosted and third-party plugins!
2. How to “Force Refresh” the dates
If you’ve noticed a plugin was recently updated but your dashboard still shows the old date, it’s because of the 24-hour cache (transient). To force an update immediately, you can simply change the version number in the cache key within the code (e.g., change pud_v3 to pud_v4). This trick forces WordPress to ignore the old data and fetch fresh timestamps from the API.
3. Don’t panic over “Orange” dates
A plugin marked in orange (6+ months) isn’t necessarily “broken.” Some plugins are “feature-complete,” meaning the developer doesn’t need to add new code constantly. However, if a plugin is Red (over 1 year) and you see a “Warning: This plugin has not been tested with your current version of WordPress” message, it’s time to start looking for a modern alternative.
4. Performance Check
The very first time you load your plugin page after adding this snippet, it might take 2–5 seconds longer than usual. Don’t worry! This is just the script “meeting” the WordPress API for the first time. Once those dates are stored in your database (as transients), your dashboard will return to its normal lightning-fast speed.
🏥 The “Red Date” Audit Checklist
If your new snippet highlights a plugin as Red (over 1 year old), don’t panic—just follow these five steps to decide if it stays or goes.
- Check for Compatibility Warnings Does the plugin row show a “This plugin has not been tested with your current version of WordPress” message? If so, this is a strong sign the developer has moved on.
- Visit the Support Forum Click the “View Details” link and go to the Support tab. Are there dozens of unanswered questions from the last 6 months? If the developer isn’t responding, security patches are unlikely to happen.
- Assess the Complexity Is it a simple plugin (e.g., “Add a piece of code to the header”) or a complex one (e.g., a “Learning Management System” or “E-commerce tool”)? Simple plugins can often go years without needing an update, whereas complex ones break easily as WordPress evolves.
- Search for a “Modern” Alternative Go to Plugins > Add New and search for the main feature. Look for a replacement that has been updated within the last 3 months and has a high number of active installations.
- The “Deactivation Test” Deactivate the old plugin and check your site. Does everything still work? Sometimes we keep plugins active for features we don’t even use anymore. If you don’t miss it, delete it to reduce your attack surface.
Backup Before You Swap: If you decide to replace a “Red” plugin with a newer alternative, always take a full site backup first. Even though the new plugin is “healthier,” it might handle data differently than the old one!
If in any doubt, seek out a professional first. It’s always best to seek out a professional, especially if you’re relying on the plugin for your business.
