Skip to content

Instantly share code, notes, and snippets.

@EarthmanWeb
Last active January 17, 2024 16:38
Show Gist options
  • Save EarthmanWeb/5db7b5d14ee5b67e772df9c1341de8f4 to your computer and use it in GitHub Desktop.
Save EarthmanWeb/5db7b5d14ee5b67e772df9c1341de8f4 to your computer and use it in GitHub Desktop.
Add a copy/pasteable plugin update list with quick links to changelogs in wp-admin
<?php
/**
* Plugin Name: Plugin Versions
* Description: Adds a Plugin Versions menu in WordPress Admin under Plugins.
* Author: Terrance Orletsky - Earthman Media
* Author URI: https://earthmanmedia.com
* Version: 1.0.4
*/
// Hook to add submenu under Network Admin > Plugins
// if this is a network, add to network, otherwise, add to plugins
if ( is_multisite() ) {
add_action( 'network_admin_menu', 'em_add_plugin_versions_menu' );
} else {
add_action( 'admin_menu', 'em_add_plugin_versions_menu' );
}
// Function to add submenu
function em_add_plugin_versions_menu() {
// if this is a network, add to network, otherwise, add to plugins
if ( is_multisite() ) {
$add_plugin_versions_menu_caps = 'manage_network_options';
} else {
$add_plugin_versions_menu_caps = 'manage_options';
}
add_submenu_page(
'plugins.php',
'Plugin Versions',
'Plugin Versions',
$add_plugin_versions_menu_caps,
'plugin-versions',
'em_display_plugin_versions'
);
}
// Function to display plugin versions
function em_display_plugin_versions() {
// Fetch all installed plugins
$all_plugins = get_plugins();
if ( isset( $_ENV['PANTHEON_ENVIRONMENT'] ) && in_array( $_ENV['PANTHEON_ENVIRONMENT'], array( 'test', 'live' ), true ) && ( php_sapi_name() !== 'cli' ) ) {
// Re-Enable Plugin Updates.
add_action( 'load-update-core.php', 'wp_update_plugins' );
remove_filter( 'pre_site_transient_update_plugins', '_pantheon_disable_wp_updates' );
}
// if this is a network, add to network, otherwise, add to plugins
if ( is_multisite() ) {
$add_plugin_versions_network_path = 'network/';
} else {
$add_plugin_versions_network_path = '';
}
// Trigger update check for plugins
do_action( 'wp_update_plugins' );
// Fetch transient data for plugin updates
$plugin_updates = get_site_transient( 'update_plugins' );
// Counter to keep track of plugins needing updates
$update_count = 0;
$counter = 0;
$row_output = '';
// Loop through each plugin and output versions
foreach ( $all_plugins as $plugin_path => $plugin_data ) {
$counter++;
$current_version = $plugin_data['Version'];
$plugin_name = $plugin_data['Name'];
// parse the path to get the folder name
$plugin_slug = explode( '/', $plugin_path );
$plugin_slug = $plugin_slug[0];
$plugin_url = '/wp-admin/' . $add_plugin_versions_network_path . 'plugin-install.php?tab=plugin-information&plugin=' . $plugin_slug . '&section=changelog';
$available_version = '-';
$row_style = 'margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline;';
$td_style = 'border-top-color:rgb(221, 221, 221);border-top-style:solid;border-top-width:0.555556px;';
// Check for updates
if ( isset( $plugin_updates->response[ $plugin_path ] ) ) {
$update_data = $plugin_updates->response[ $plugin_path ];
$available_version = $update_data->new_version;
$update_count++;
$td_style .= ' background-color: #faefb3;';
}
// Output each plugin row
$row_output .= "<tr style='{$row_style}'>";
$row_output .= "<td style='{$td_style}'><a href='{$plugin_url}' target='_blank' style='text-decoration: none; color: #000;'>{$plugin_name}</a></td>";
$row_output .= "<td style='{$td_style}'>{$current_version}</td>";
$row_output .= "<td style='{$td_style}'>{$available_version}</td>";
$row_output .= '</tr>';
}
if ( isset( $_ENV['PANTHEON_ENVIRONMENT'] ) && in_array( $_ENV['PANTHEON_ENVIRONMENT'], array( 'test', 'live' ), true ) && ( php_sapi_name() !== 'cli' ) ) {
// Re-Disable Plugin Updates.
remove_action( 'load-update-core.php', 'wp_update_plugins' );
add_filter( 'pre_site_transient_update_plugins', '_pantheon_disable_wp_updates' );
}
// table output
echo '<hr><h4>Plugins Update Status: <small> ' . $update_count . ' plugins to be updated.</small></h4><table style="margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline;"><thead style="margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline;"><tr style="margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline;"><th style="margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline;text-align:left;font-weight: bold;">Plugin Name / Link</th><th style="margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline;text-align:left;font-weight: bold;">Current Version</th><th style="margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline;text-align:left;font-weight: bold;">Update Available</th></tr></thead><tbody style="margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline;">' . $row_output . '</tbody></table><br><br><hr>';
}
add_filter( 'map_meta_cap', 'em_allow_plugin_information_access', 10, 4 );
/**
* Allow access to plugin information page.
*
* @param array $caps The user's actual capabilities.
* @param string $cap Capability name.
* @param int $user_id The user ID.
* @param array $args Adds the context to the cap. Typically the object ID.
*
* @return array Modified capabilities.
*/
function em_allow_plugin_information_access( $caps, $cap, $user_id, $args ) {
if ( 'install_plugins' === $cap && defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS ) {
$script = basename( $_SERVER['PHP_SELF'] );
if ( 'plugin-install.php' === $script && isset( $_GET['tab'] ) && 'plugin-information' === $_GET['tab'] ) {
$caps = array( 'read' );
}
}
return $caps;
}
add_action( 'admin_head-plugin-install.php', 'em_customize_plugin_info_style' );
/**
* Add custom CSS to the plugin information page in WP Admin.
*/
function em_customize_plugin_info_style() {
// Check if we're on the correct tab of the plugin install page
if ( isset( $_GET['tab'] ) && 'plugin-information' === $_GET['tab'] ) {
echo '<style id="em_customize_plugin_info_style">
#plugin-information-content {
padding: 30px !important; /* Adjust padding as needed */
}
</style>';
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment