Refactor plugin to use OOP best practices with proper namespaces and class structure
This commit is contained in:
619
includes/Core.php
Normal file
619
includes/Core.php
Normal file
@ -0,0 +1,619 @@
|
||||
<?php
|
||||
/**
|
||||
* Core Functionality
|
||||
*
|
||||
* @package WPALLSTARS\FixPluginDoesNotExistNotices
|
||||
*/
|
||||
|
||||
namespace WPALLSTARS\FixPluginDoesNotExistNotices;
|
||||
|
||||
/**
|
||||
* Core Class
|
||||
*
|
||||
* Handles the core functionality of finding and fixing invalid plugin references.
|
||||
*/
|
||||
class Core {
|
||||
|
||||
/**
|
||||
* Stores a list of invalid plugins found in the active_plugins option.
|
||||
*
|
||||
* @var array|null
|
||||
*/
|
||||
private $invalid_plugins = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
// Add our plugin to the plugins list
|
||||
add_filter('all_plugins', array($this, 'add_missing_plugins_references'));
|
||||
|
||||
// Add our action link to the plugins list
|
||||
add_filter('plugin_action_links', array($this, 'add_remove_reference_action'), 20, 4);
|
||||
|
||||
// Handle the remove reference action
|
||||
add_action('admin_init', array($this, 'handle_remove_reference'));
|
||||
|
||||
// Add admin notices for operation feedback
|
||||
add_action('admin_notices', array($this, 'admin_notices'));
|
||||
|
||||
// Filter the plugin API to fix version display in plugin details popup
|
||||
add_filter('plugins_api', array($this, 'filter_plugin_details'), 10, 3);
|
||||
|
||||
// Prevent WordPress from caching our plugin API responses
|
||||
add_filter('plugins_api_result', array($this, 'prevent_plugins_api_caching'), 10, 3);
|
||||
|
||||
// Clear plugin API transients on plugin activation and when viewing plugins page
|
||||
add_action('admin_init', array($this, 'maybe_clear_plugin_api_cache'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of invalid plugins (plugins that are active but don't exist).
|
||||
*
|
||||
* @return array An array of plugin file paths that don't exist.
|
||||
*/
|
||||
public function get_invalid_plugins() {
|
||||
// Return cached result if available
|
||||
if (is_array($this->invalid_plugins)) {
|
||||
return $this->invalid_plugins;
|
||||
}
|
||||
|
||||
// Initialize empty array
|
||||
$invalid_plugins = array();
|
||||
|
||||
// Handle multisite network admin context
|
||||
if (is_multisite() && is_network_admin()) {
|
||||
$active_plugins = get_site_option('active_sitewide_plugins', array());
|
||||
// Network active plugins are stored as key => timestamp
|
||||
$active_plugins = array_keys($active_plugins);
|
||||
} else {
|
||||
// Single site or non-network admin context
|
||||
$active_plugins = get_option('active_plugins', array());
|
||||
}
|
||||
|
||||
// Check each active plugin
|
||||
foreach ($active_plugins as $plugin_file) {
|
||||
$plugin_path = WP_PLUGIN_DIR . '/' . $plugin_file;
|
||||
if (!file_exists($plugin_path)) {
|
||||
$invalid_plugins[] = $plugin_file;
|
||||
}
|
||||
}
|
||||
|
||||
// Cache the result
|
||||
$this->invalid_plugins = $invalid_plugins;
|
||||
|
||||
return $invalid_plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current page is the plugins page.
|
||||
*
|
||||
* @return bool True if on the plugins page, false otherwise.
|
||||
*/
|
||||
public function is_plugins_page() {
|
||||
global $pagenow;
|
||||
return is_admin() && 'plugins.php' === $pagenow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find and add invalid plugin references to the plugins list.
|
||||
*
|
||||
* Filters the list of plugins displayed on the plugins page to include
|
||||
* entries for active plugins whose files are missing.
|
||||
*
|
||||
* @param array $plugins An array of plugin data.
|
||||
* @return array The potentially modified array of plugin data.
|
||||
*/
|
||||
public function add_missing_plugins_references($plugins) {
|
||||
// Only run on the plugins page
|
||||
if (!$this->is_plugins_page()) {
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
// Get active plugins that don't exist
|
||||
$invalid_plugins = $this->get_invalid_plugins();
|
||||
|
||||
// Add each invalid plugin to the plugin list
|
||||
foreach ($invalid_plugins as $plugin_path) {
|
||||
if (!isset($plugins[$plugin_path])) {
|
||||
$plugin_name = basename($plugin_path);
|
||||
$plugin_slug = dirname($plugin_path);
|
||||
if ('.' === $plugin_slug) {
|
||||
$plugin_slug = basename($plugin_path, '.php');
|
||||
}
|
||||
|
||||
// Create a basic plugin data array
|
||||
$plugins[$plugin_path] = array(
|
||||
'Name' => $plugin_name . ' <span class="error">(File Missing)</span>',
|
||||
/* translators: %s: Path to wp-content/plugins */
|
||||
'Description' => sprintf(
|
||||
__('This plugin is still marked as "Active" in your database — but its folder and files can\'t be found in %s. Click "Remove Notice" to permanently remove it from your active plugins list and eliminate the error notice.', 'wp-fix-plugin-does-not-exist-notices'),
|
||||
'<code>/wp-content/plugins/</code>'
|
||||
),
|
||||
'Version' => FPDEN_VERSION, // Use our plugin version instead of 'N/A'
|
||||
'Author' => 'Marcus Quinn & WPALLSTARS',
|
||||
'PluginURI' => 'https://www.wpallstars.com',
|
||||
'AuthorURI' => 'https://www.wpallstars.com',
|
||||
'Title' => $plugin_name . ' (' . __('Missing', 'wp-fix-plugin-does-not-exist-notices') . ')',
|
||||
'AuthorName' => 'Marcus Quinn & WPALLSTARS',
|
||||
);
|
||||
|
||||
// Add the data needed for the "View details" link
|
||||
$plugins[$plugin_path]['slug'] = $plugin_slug;
|
||||
$plugins[$plugin_path]['plugin'] = $plugin_path;
|
||||
$plugins[$plugin_path]['type'] = 'plugin';
|
||||
|
||||
// Add Git Updater fields
|
||||
$plugins[$plugin_path]['GitHub Plugin URI'] = 'wpallstars/wp-fix-plugin-does-not-exist-notices';
|
||||
$plugins[$plugin_path]['GitHub Branch'] = 'main';
|
||||
$plugins[$plugin_path]['TextDomain'] = 'wp-fix-plugin-does-not-exist-notices';
|
||||
}
|
||||
}
|
||||
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the Remove Notice action link to invalid plugins.
|
||||
*
|
||||
* Filters the action links displayed for each plugin on the plugins page.
|
||||
* Adds a "Remove Notice" link for plugins identified as missing.
|
||||
*
|
||||
* @param array $actions An array of plugin action links.
|
||||
* @param string $plugin_file Path to the plugin file relative to the plugins directory.
|
||||
* @param array $plugin_data An array of plugin data.
|
||||
* @param string $context The plugin context (e.g., 'all', 'active', 'inactive').
|
||||
* @return array The potentially modified array of plugin action links.
|
||||
*/
|
||||
public function add_remove_reference_action($actions, $plugin_file, $plugin_data, $context) {
|
||||
// Only run on the plugins page
|
||||
if (!$this->is_plugins_page()) {
|
||||
return $actions;
|
||||
}
|
||||
|
||||
// Get our list of invalid plugins
|
||||
$invalid_plugins = $this->get_invalid_plugins();
|
||||
|
||||
// Check if this plugin file is in our list of invalid plugins
|
||||
if (in_array($plugin_file, $invalid_plugins, true)) {
|
||||
// Clear existing actions like "Activate", "Deactivate", "Edit"
|
||||
$actions = array();
|
||||
|
||||
// Add our custom action
|
||||
$nonce = wp_create_nonce('remove_plugin_reference_' . $plugin_file);
|
||||
$remove_url = admin_url('plugins.php?action=remove_reference&plugin=' . urlencode($plugin_file) . '&_wpnonce=' . $nonce);
|
||||
/* translators: %s: Plugin file path */
|
||||
$aria_label = sprintf(__('Remove reference to missing plugin %s', 'wp-fix-plugin-does-not-exist-notices'), esc_attr($plugin_file));
|
||||
$actions['remove_reference'] = '<a href="' . esc_url($remove_url) . '" class="delete" aria-label="' . $aria_label . '">' . esc_html__('Remove Notice', 'wp-fix-plugin-does-not-exist-notices') . '</a>';
|
||||
}
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the remove reference action triggered by the link.
|
||||
*
|
||||
* Checks for the correct action, verifies nonce and permissions,
|
||||
* calls the removal function, and redirects back to the plugins page.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle_remove_reference() {
|
||||
// Check if our specific action is being performed
|
||||
if (!isset($_GET['action']) || 'remove_reference' !== $_GET['action'] || !isset($_GET['plugin'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify user permissions
|
||||
if (!current_user_can('activate_plugins')) {
|
||||
wp_die(esc_html__('You do not have sufficient permissions to perform this action.', 'wp-fix-plugin-does-not-exist-notices'));
|
||||
}
|
||||
|
||||
// Sanitize and get the plugin file path
|
||||
$plugin_file = isset($_GET['plugin']) ? sanitize_text_field(wp_unslash($_GET['plugin'])) : '';
|
||||
if (empty($plugin_file)) {
|
||||
wp_die(esc_html__('Invalid plugin specified.', 'wp-fix-plugin-does-not-exist-notices'));
|
||||
}
|
||||
|
||||
// Verify nonce for security
|
||||
check_admin_referer('remove_plugin_reference_' . $plugin_file);
|
||||
|
||||
// Attempt to remove the plugin reference
|
||||
$success = $this->remove_plugin_reference($plugin_file);
|
||||
|
||||
// Prepare redirect URL with feedback query args
|
||||
$redirect_url = admin_url('plugins.php');
|
||||
$redirect_url = add_query_arg($success ? 'reference_removed' : 'reference_removal_failed', '1', $redirect_url);
|
||||
|
||||
// Redirect and exit
|
||||
wp_safe_redirect($redirect_url);
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a plugin reference from the active plugins list in the database.
|
||||
*
|
||||
* Handles both single site and multisite network activated plugins.
|
||||
*
|
||||
* @param string $plugin_file The plugin file path to remove.
|
||||
* @return bool True on success, false on failure or if the plugin wasn't found.
|
||||
*/
|
||||
public function remove_plugin_reference($plugin_file) {
|
||||
$success = false;
|
||||
|
||||
// Ensure plugin file path is provided
|
||||
if (empty($plugin_file)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Handle multisite network admin context
|
||||
if (is_multisite() && is_network_admin()) {
|
||||
$active_plugins = get_site_option('active_sitewide_plugins', array());
|
||||
// Network active plugins are stored as key => timestamp
|
||||
if (isset($active_plugins[$plugin_file])) {
|
||||
unset($active_plugins[$plugin_file]);
|
||||
$success = update_site_option('active_sitewide_plugins', $active_plugins);
|
||||
}
|
||||
} else { // Handle single site or non-network admin context
|
||||
$active_plugins = get_option('active_plugins', array());
|
||||
// Single site active plugins are stored as an indexed array
|
||||
$key = array_search($plugin_file, $active_plugins, true); // Use strict comparison
|
||||
if (false !== $key) {
|
||||
unset($active_plugins[$key]);
|
||||
// Re-index the array numerically
|
||||
$active_plugins = array_values($active_plugins);
|
||||
$success = update_option('active_plugins', $active_plugins);
|
||||
}
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display admin notices on the plugins page.
|
||||
*
|
||||
* Shows feedback messages after attempting to remove a reference.
|
||||
* The main informational notice is handled by JavaScript to position it
|
||||
* directly below the WordPress error message.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function admin_notices() {
|
||||
// Only run on the plugins page
|
||||
if (!$this->is_plugins_page()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for feedback messages from the remove action
|
||||
if (isset($_GET['reference_removed']) && '1' === $_GET['reference_removed']) {
|
||||
?>
|
||||
<div class="notice notice-success is-dismissible">
|
||||
<p><?php esc_html_e('Plugin reference removed successfully.', 'wp-fix-plugin-does-not-exist-notices'); ?></p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
if (isset($_GET['reference_removal_failed']) && '1' === $_GET['reference_removal_failed']) {
|
||||
?>
|
||||
<div class="notice notice-error is-dismissible">
|
||||
<p><?php esc_html_e('Failed to remove plugin reference. The plugin may already have been removed, or there was a database issue.', 'wp-fix-plugin-does-not-exist-notices'); ?></p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter plugin details API response to provide custom data for our plugin.
|
||||
*
|
||||
* @param object|WP_Error $result The result object or WP_Error.
|
||||
* @param string $action The type of information being requested.
|
||||
* @param object $args Plugin API arguments.
|
||||
* @return object|WP_Error The result object or WP_Error.
|
||||
*/
|
||||
public function filter_plugin_details($result, $action, $args) {
|
||||
// Only modify plugin_information requests
|
||||
if ('plugin_information' !== $action) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Check if we have a slug to work with
|
||||
if (empty($args->slug)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Get our list of invalid plugins
|
||||
$invalid_plugins = $this->get_invalid_plugins();
|
||||
|
||||
// Check if this is our plugin or a missing plugin
|
||||
$our_plugin = in_array($args->slug, array('wp-fix-plugin-does-not-exist-notices', 'fix-plugin-does-not-exist-notices'), true);
|
||||
$is_missing_plugin = $this->is_missing_plugin($args->slug, $invalid_plugins);
|
||||
|
||||
// Only modify the result if this is our plugin or a missing plugin
|
||||
if ($our_plugin || $is_missing_plugin) {
|
||||
// Create a new result object
|
||||
$new_result = new \stdClass();
|
||||
|
||||
// Set all the properties we need
|
||||
$new_result->name = $our_plugin ? 'Fix \'Plugin file does not exist\' Notices' : (isset($result->name) ? $result->name : $args->slug);
|
||||
$new_result->slug = $args->slug;
|
||||
$new_result->version = FPDEN_VERSION;
|
||||
$new_result->author = '<a href="https://www.wpallstars.com">Marcus Quinn & WPALLSTARS</a>';
|
||||
$new_result->author_profile = 'https://www.wpallstars.com';
|
||||
$new_result->requires = '5.0';
|
||||
$new_result->tested = '6.7.2'; // Updated to match readme.txt
|
||||
$new_result->requires_php = '7.0';
|
||||
$new_result->last_updated = date('Y-m-d H:i:s');
|
||||
|
||||
// Add a cache buster timestamp
|
||||
$new_result->cache_buster = time();
|
||||
|
||||
// Get full readme content for our plugin
|
||||
$readme_file = FPDEN_PLUGIN_DIR . 'readme.txt';
|
||||
$readme_content = '';
|
||||
$description = '';
|
||||
$changelog = '';
|
||||
$faq = '';
|
||||
$installation = '';
|
||||
$screenshots = '';
|
||||
|
||||
if (file_exists($readme_file) && $our_plugin) {
|
||||
$readme_content = file_get_contents($readme_file);
|
||||
|
||||
// Extract description
|
||||
if (preg_match('/== Description ==(.+?)(?:==|$)/s', $readme_content, $matches)) {
|
||||
$description = trim($matches[1]);
|
||||
}
|
||||
|
||||
// Extract changelog
|
||||
if (preg_match('/== Changelog ==(.+?)(?:==|$)/s', $readme_content, $matches)) {
|
||||
$changelog = trim($matches[1]);
|
||||
}
|
||||
|
||||
// Extract FAQ
|
||||
if (preg_match('/== Frequently Asked Questions ==(.+?)(?:==|$)/s', $readme_content, $matches)) {
|
||||
$faq = trim($matches[1]);
|
||||
}
|
||||
|
||||
// Extract installation
|
||||
if (preg_match('/== Installation ==(.+?)(?:==|$)/s', $readme_content, $matches)) {
|
||||
$installation = trim($matches[1]);
|
||||
}
|
||||
|
||||
// Extract screenshots
|
||||
if (preg_match('/== Screenshots ==(.+?)(?:==|$)/s', $readme_content, $matches)) {
|
||||
$screenshots = trim($matches[1]);
|
||||
}
|
||||
} else {
|
||||
// Fallback content if readme.txt doesn't exist or for missing plugins
|
||||
$changelog = '<h2>' . FPDEN_VERSION . '</h2><ul><li>Fixed: Plugin details popup version display issue with Git Updater integration</li><li>Added: JavaScript-based solution to ensure correct version display in plugin details</li><li>Improved: Version consistency across all plugin views</li><li>Enhanced: Cache busting for plugin information API</li></ul>';
|
||||
}
|
||||
|
||||
// Set description based on whether this is our plugin or a missing plugin
|
||||
if ($our_plugin) {
|
||||
$description = !empty($description) ? wpautop($description) : 'Adds missing plugins to your plugins list with a "Remove Notice" action link, allowing you to safely clean up invalid plugin references.';
|
||||
} else {
|
||||
$description = sprintf(
|
||||
__('This plugin is still marked as "Active" in your database — but its folder and files can\'t be found in %s. Use the "Remove Notice" link on the plugins page to permanently remove it from your active plugins list and eliminate the error notice.', 'wp-fix-plugin-does-not-exist-notices'),
|
||||
'<code>/wp-content/plugins/</code>'
|
||||
);
|
||||
}
|
||||
|
||||
// Prepare sections
|
||||
$new_result->sections = array(
|
||||
'description' => $description,
|
||||
'changelog' => !empty($changelog) ? wpautop($changelog) : $changelog,
|
||||
'faq' => !empty($faq) ? wpautop($faq) : '<h3>Is it safe to remove plugin references?</h3><p>Yes, this plugin only removes entries from the WordPress active_plugins option, which is safe to modify when a plugin no longer exists.</p>',
|
||||
);
|
||||
|
||||
// Add installation section if available
|
||||
if (!empty($installation)) {
|
||||
$new_result->sections['installation'] = wpautop($installation);
|
||||
}
|
||||
|
||||
// Add screenshots section if available
|
||||
if (!empty($screenshots)) {
|
||||
$new_result->sections['screenshots'] = wpautop($screenshots);
|
||||
}
|
||||
|
||||
// Add contributors information
|
||||
$new_result->contributors = array(
|
||||
'marcusquinn' => array(
|
||||
'profile' => 'https://profiles.wordpress.org/marcusquinn/',
|
||||
'avatar' => 'https://secure.gravatar.com/avatar/',
|
||||
'display_name' => 'Marcus Quinn'
|
||||
),
|
||||
'wpallstars' => array(
|
||||
'profile' => 'https://profiles.wordpress.org/wpallstars/',
|
||||
'avatar' => 'https://secure.gravatar.com/avatar/',
|
||||
'display_name' => 'WPALLSTARS'
|
||||
)
|
||||
);
|
||||
|
||||
// Add a random number and timestamp to force cache refresh
|
||||
$new_result->download_link = 'https://www.wpallstars.com/plugins/wp-fix-plugin-does-not-exist-notices.zip?v=' . FPDEN_VERSION . '&cb=' . mt_rand(1000000, 9999999) . '&t=' . time();
|
||||
|
||||
// Add active installations count
|
||||
$new_result->active_installs = 1000;
|
||||
|
||||
// Add rating information
|
||||
$new_result->rating = 100;
|
||||
$new_result->num_ratings = 5;
|
||||
$new_result->ratings = array(
|
||||
5 => 5,
|
||||
4 => 0,
|
||||
3 => 0,
|
||||
2 => 0,
|
||||
1 => 0
|
||||
);
|
||||
|
||||
// Add homepage and download link
|
||||
$new_result->homepage = 'https://www.wpallstars.com';
|
||||
|
||||
// Set no caching
|
||||
$new_result->cache_time = 0;
|
||||
|
||||
// Return our completely new result object
|
||||
return $new_result;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a slug matches one of our missing plugins.
|
||||
*
|
||||
* @param string $slug The plugin slug to check.
|
||||
* @param array $invalid_plugins List of invalid plugin paths.
|
||||
* @return bool True if the slug matches a missing plugin.
|
||||
*/
|
||||
private function is_missing_plugin($slug, $invalid_plugins) {
|
||||
foreach ($invalid_plugins as $plugin_file) {
|
||||
// Extract the plugin slug from the plugin file path
|
||||
$plugin_slug = dirname($plugin_file);
|
||||
if ('.' === $plugin_slug) {
|
||||
$plugin_slug = basename($plugin_file, '.php');
|
||||
}
|
||||
|
||||
if ($slug === $plugin_slug) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent WordPress from caching our plugin API responses.
|
||||
*
|
||||
* @param object|WP_Error $result The result object or WP_Error.
|
||||
* @param string $action The type of information being requested.
|
||||
* @param object $args Plugin API arguments.
|
||||
* @return object|WP_Error The result object or WP_Error.
|
||||
*/
|
||||
public function prevent_plugins_api_caching($result, $action, $args) {
|
||||
// Only modify plugin_information requests
|
||||
if ('plugin_information' !== $action) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Check if we have a slug to work with
|
||||
if (empty($args->slug)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Get our list of invalid plugins
|
||||
$invalid_plugins = $this->get_invalid_plugins();
|
||||
|
||||
// Check if the requested plugin is one of our missing plugins
|
||||
foreach ($invalid_plugins as $plugin_file) {
|
||||
// Extract the plugin slug from the plugin file path
|
||||
$plugin_slug = dirname($plugin_file);
|
||||
if ('.' === $plugin_slug) {
|
||||
$plugin_slug = basename($plugin_file, '.php');
|
||||
}
|
||||
|
||||
// If this is one of our missing plugins, prevent caching
|
||||
if ($args->slug === $plugin_slug) {
|
||||
// Add a filter to prevent caching of this response
|
||||
add_filter('plugins_api_result_' . $args->slug, '__return_false');
|
||||
|
||||
// Add a timestamp to force cache busting
|
||||
if (is_object($result)) {
|
||||
$result->last_updated = current_time('mysql');
|
||||
$result->cache_time = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear plugin API cache when viewing the plugins page.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function maybe_clear_plugin_api_cache() {
|
||||
// Only run on the plugins page
|
||||
if (!$this->is_plugins_page()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get our list of invalid plugins
|
||||
$invalid_plugins = $this->get_invalid_plugins();
|
||||
|
||||
// Clear transients for each invalid plugin
|
||||
foreach ($invalid_plugins as $plugin_file) {
|
||||
// Extract the plugin slug from the plugin file path
|
||||
$plugin_slug = dirname($plugin_file);
|
||||
if ('.' === $plugin_slug) {
|
||||
$plugin_slug = basename($plugin_file, '.php');
|
||||
}
|
||||
|
||||
// Delete all possible transients for this plugin
|
||||
delete_transient('plugins_api_' . $plugin_slug);
|
||||
delete_site_transient('plugins_api_' . $plugin_slug);
|
||||
delete_transient('plugin_information_' . $plugin_slug);
|
||||
delete_site_transient('plugin_information_' . $plugin_slug);
|
||||
|
||||
// Clear any other transients that might be caching plugin info
|
||||
$this->clear_all_plugin_transients();
|
||||
}
|
||||
|
||||
// Also clear our own plugin's cache
|
||||
$this->clear_own_plugin_cache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all plugin-related transients that might be caching information.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function clear_all_plugin_transients() {
|
||||
// Clear update cache
|
||||
delete_site_transient('update_plugins');
|
||||
delete_site_transient('update_themes');
|
||||
delete_site_transient('update_core');
|
||||
|
||||
// Clear plugins API cache
|
||||
delete_site_transient('plugin_information');
|
||||
|
||||
// Clear plugin update counts
|
||||
delete_transient('plugin_updates_count');
|
||||
delete_site_transient('plugin_updates_count');
|
||||
|
||||
// Clear plugin slugs cache
|
||||
delete_transient('plugin_slugs');
|
||||
delete_site_transient('plugin_slugs');
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear cache specifically for our own plugin.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function clear_own_plugin_cache() {
|
||||
// Clear our own plugin's cache (both old and new slugs)
|
||||
$our_slugs = array('wp-fix-plugin-does-not-exist-notices', 'fix-plugin-does-not-exist-notices');
|
||||
|
||||
foreach ($our_slugs as $slug) {
|
||||
delete_transient('plugins_api_' . $slug);
|
||||
delete_site_transient('plugins_api_' . $slug);
|
||||
delete_transient('plugin_information_' . $slug);
|
||||
delete_site_transient('plugin_information_' . $slug);
|
||||
}
|
||||
|
||||
// Clear plugin update transients
|
||||
delete_site_transient('update_plugins');
|
||||
delete_site_transient('plugin_information');
|
||||
|
||||
// Force refresh of plugin update information if function exists
|
||||
if (function_exists('wp_clean_plugins_cache')) {
|
||||
wp_clean_plugins_cache(true);
|
||||
}
|
||||
|
||||
// Clear object cache if function exists
|
||||
if (function_exists('wp_cache_flush')) {
|
||||
wp_cache_flush();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user