Compare commits
9 Commits
569ef54904
...
d353250fd9
Author | SHA1 | Date | |
---|---|---|---|
d353250fd9 | |||
ff0b330a3a | |||
e9a18de3d7 | |||
bfaa2b807a | |||
873ca5f272 | |||
24ff0f9552 | |||
515336aa2b | |||
10f6783cdb | |||
a58516367a |
63
README.md
63
README.md
@ -120,6 +120,69 @@ The plugin works by:
|
|||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
### 1.6.13
|
||||||
|
* Code cleanup and optimization
|
||||||
|
* Improved Git Updater integration
|
||||||
|
* Fixed author display in plugin information
|
||||||
|
* Ensured compatibility with WordPress 6.4
|
||||||
|
|
||||||
|
### 1.6.12
|
||||||
|
* Added WP ALLSTARS as a co-author
|
||||||
|
* Updated author information and links
|
||||||
|
* Added author websites to plugin description
|
||||||
|
* Fixed issue with multiple author URLs
|
||||||
|
|
||||||
|
### 1.6.11
|
||||||
|
* CRITICAL FIX: Completely removed auto-deactivation prevention code that was causing fatal errors
|
||||||
|
* Simplified plugin functionality to focus on core features only
|
||||||
|
* Improved compatibility with various WordPress configurations
|
||||||
|
* Ensured plugin works correctly when other plugins are deleted
|
||||||
|
|
||||||
|
### 1.6.10
|
||||||
|
* Fixed critical error that could occur when a plugin folder is deleted
|
||||||
|
* Improved error handling with try/catch blocks
|
||||||
|
* Added more specific checks for the plugins page
|
||||||
|
* Enhanced compatibility with various WordPress configurations
|
||||||
|
* Made the code more defensive to prevent potential issues
|
||||||
|
|
||||||
|
### 1.6.9
|
||||||
|
* Fixed issue with notices not appearing below WordPress error messages
|
||||||
|
* Improved JavaScript detection of WordPress error notices
|
||||||
|
* Prevented WordPress from automatically clearing error notices on page refresh
|
||||||
|
* Added multiple timing attempts to ensure notices appear correctly
|
||||||
|
* Enhanced error notice targeting for better compatibility
|
||||||
|
|
||||||
|
### 1.6.8
|
||||||
|
* Fixed notice positioning to appear directly below WordPress error messages
|
||||||
|
* Improved notice width to match WordPress error messages
|
||||||
|
* Updated explanatory text for better clarity
|
||||||
|
* Fixed issue with notices not appearing in some cases
|
||||||
|
* Improved JavaScript detection of WordPress error messages
|
||||||
|
|
||||||
|
### 1.6.7
|
||||||
|
* Fixed duplicate notices issue by removing PHP-generated notice
|
||||||
|
* Simplified notice system to only show one notice below WordPress error
|
||||||
|
* Ensured consistent terminology with "Remove Notice" text
|
||||||
|
* Optimized plugin detection with caching to improve performance
|
||||||
|
* Fixed JavaScript to correctly handle multiple error messages
|
||||||
|
|
||||||
|
### 1.6.6
|
||||||
|
* Fixed issue with "Remove Notice" link not appearing on missing plugin rows
|
||||||
|
* Fixed issue with automatic removal of plugin references without user action
|
||||||
|
* Fixed notice positioning to ensure it appears below error messages
|
||||||
|
* Restored pointer triangle to indicate relationship with error message
|
||||||
|
* Improved detection of missing plugins in the plugin list
|
||||||
|
* Enhanced scroll functionality to work with all plugin types
|
||||||
|
|
||||||
|
### 1.6.5
|
||||||
|
* Fixed duplicate notices issue - now only one notice appears below error messages
|
||||||
|
* Changed notice heading to "Fix Plugin Does Not Exist Notices ☝️"
|
||||||
|
* Updated explanatory text to be more clear about the removal process
|
||||||
|
* Changed "Remove Reference" link text to "Remove Notice" for better clarity
|
||||||
|
* Made "(File Missing)" text bold and red for better visibility
|
||||||
|
* Fixed scroll functionality to work with all plugin rows
|
||||||
|
* Improved JavaScript to prevent multiple notices from appearing
|
||||||
|
|
||||||
### 1.6.4
|
### 1.6.4
|
||||||
* Updated version management to ensure consistent patch version increments
|
* Updated version management to ensure consistent patch version increments
|
||||||
* Improved documentation for version update process
|
* Improved documentation for version update process
|
||||||
|
@ -5,6 +5,9 @@
|
|||||||
margin: 5px 0 15px;
|
margin: 5px 0 15px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
max-width: none;
|
||||||
}
|
}
|
||||||
.prc-notice h3 {
|
.prc-notice h3 {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
@ -23,6 +26,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Style for highlighting the missing plugin row */
|
/* Style for highlighting the missing plugin row */
|
||||||
tr.inactive.prc-highlight-missing {
|
tr.inactive.prc-highlight-missing,
|
||||||
|
tr.active.prc-highlight-missing {
|
||||||
background-color: #fff8e5 !important; /* Use !important to override default styles */
|
background-color: #fff8e5 !important; /* Use !important to override default styles */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Make File Missing text bold and red */
|
||||||
|
span.error {
|
||||||
|
font-weight: bold !important;
|
||||||
|
color: #dc3232 !important;
|
||||||
|
}
|
||||||
|
@ -1,66 +1,105 @@
|
|||||||
(function() {
|
(function() {
|
||||||
|
// Track if we've already added our notice
|
||||||
|
var noticeAdded = false;
|
||||||
|
|
||||||
// Function to inject our notice
|
// Function to inject our notice
|
||||||
function injectNotice() {
|
function injectNotice() {
|
||||||
|
// If we've already added a notice, don't add another one
|
||||||
|
if (noticeAdded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Find all notification containers first
|
// Find all notification containers first
|
||||||
var noticeContainers = document.querySelectorAll('.notice, .error, .updated');
|
var noticeContainers = document.querySelectorAll('.notice, .error, .updated, div.error');
|
||||||
|
var targetNotice = null;
|
||||||
|
|
||||||
// Find all error notifications about missing plugins
|
// Find all error notifications about missing plugins
|
||||||
noticeContainers.forEach(function(notice) {
|
noticeContainers.forEach(function(notice) {
|
||||||
if (notice.textContent.includes('Plugin file does not exist') ||
|
if ((notice.textContent.includes('Plugin file does not exist') ||
|
||||||
notice.textContent.includes('has been deactivated due to an error')) {
|
notice.textContent.includes('has been deactivated due to an error')) &&
|
||||||
|
(notice.classList.contains('error') || notice.classList.contains('notice-error'))) {
|
||||||
// Check if we already added our notice
|
// We'll use the last matching notice as our target
|
||||||
if (notice.nextElementSibling && notice.nextElementSibling.classList.contains('prc-notice')) {
|
targetNotice = notice;
|
||||||
return;
|
console.log('Found WordPress error notice:', notice.textContent);
|
||||||
}
|
|
||||||
|
|
||||||
// Create our custom notice
|
|
||||||
var ourNotice = document.createElement('div');
|
|
||||||
ourNotice.className = 'prc-notice';
|
|
||||||
|
|
||||||
// Add content using localized strings passed via wp_localize_script
|
|
||||||
var pluginMissingText = typeof fpdenData !== 'undefined' && fpdenData.i18n && fpdenData.i18n.pluginMissing ?
|
|
||||||
fpdenData.i18n.pluginMissing : 'Plugin file missing';
|
|
||||||
var removeReferenceText = typeof fpdenData !== 'undefined' && fpdenData.i18n && fpdenData.i18n.removeReference ?
|
|
||||||
fpdenData.i18n.removeReference : 'Remove Reference';
|
|
||||||
var clickToScrollText = typeof fpdenData !== 'undefined' && fpdenData.i18n && fpdenData.i18n.clickToScroll ?
|
|
||||||
fpdenData.i18n.clickToScroll : 'Click here to scroll to missing plugins';
|
|
||||||
|
|
||||||
ourNotice.innerHTML = '<h3 style="margin-top:0;color:#826200;">👉 Fix Plugin Does Not Exist Notices Can Fix This</h3>' +
|
|
||||||
'<p>To remove the above error notification, scroll down to find the plugin marked with "<strong style="color:red">(' + pluginMissingText + ')</strong>" and click its "<strong>' + removeReferenceText + '</strong>" link.</p>' +
|
|
||||||
'<p>This will permanently remove the missing plugin reference from your database.</p>' +
|
|
||||||
'<p><a href="#" id="prc-scroll-to-plugin" style="font-weight:bold;text-decoration:underline;color:#826200;">' + clickToScrollText + '</a></p>';
|
|
||||||
|
|
||||||
// Insert our notice right after the error
|
|
||||||
notice.parentNode.insertBefore(ourNotice, notice.nextSibling);
|
|
||||||
|
|
||||||
// Add scroll behavior
|
|
||||||
var scrollLink = document.getElementById('prc-scroll-to-plugin');
|
|
||||||
if (scrollLink) {
|
|
||||||
scrollLink.addEventListener('click', function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
var missingPlugins = document.querySelectorAll('tr.inactive:not(.plugin-update-tr)');
|
|
||||||
for (var i = 0; i < missingPlugins.length; i++) {
|
|
||||||
if (missingPlugins[i].textContent.includes('(File Missing)')) {
|
|
||||||
// Add a class for highlighting instead of direct style manipulation
|
|
||||||
missingPlugins[i].classList.add('prc-highlight-missing');
|
|
||||||
missingPlugins[i].scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
||||||
// Optional: Remove highlight after a delay
|
|
||||||
setTimeout(function() {
|
|
||||||
missingPlugins[i].classList.remove('prc-highlight-missing');
|
|
||||||
}, 3000); // Remove highlight after 3 seconds
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// If we didn't find a specific error notice, look for the general WordPress error at the top
|
||||||
|
if (!targetNotice) {
|
||||||
|
// Try to find the WordPress error message at the top of the page
|
||||||
|
var wpError = document.querySelector('.error:not(.below-h2), div.error:not(.below-h2), .notice-error:not(.below-h2)');
|
||||||
|
if (wpError) {
|
||||||
|
targetNotice = wpError;
|
||||||
|
console.log('Found general WordPress error notice');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we found a target notice, add our custom notice after it
|
||||||
|
if (targetNotice) {
|
||||||
|
// Check if we already added our notice
|
||||||
|
if (targetNotice.nextElementSibling && targetNotice.nextElementSibling.classList.contains('prc-notice')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create our custom notice
|
||||||
|
var ourNotice = document.createElement('div');
|
||||||
|
ourNotice.className = 'prc-notice';
|
||||||
|
|
||||||
|
// Add content using localized strings passed via wp_localize_script
|
||||||
|
var pluginMissingText = typeof fpdenData !== 'undefined' && fpdenData.i18n && fpdenData.i18n.pluginMissing ?
|
||||||
|
fpdenData.i18n.pluginMissing : 'File Missing';
|
||||||
|
var removeNoticeText = typeof fpdenData !== 'undefined' && fpdenData.i18n && fpdenData.i18n.removeNotice ?
|
||||||
|
fpdenData.i18n.removeNotice : 'Remove Notice';
|
||||||
|
var clickToScrollText = typeof fpdenData !== 'undefined' && fpdenData.i18n && fpdenData.i18n.clickToScroll ?
|
||||||
|
fpdenData.i18n.clickToScroll : 'Click here to scroll to and highlight missing plugins';
|
||||||
|
|
||||||
|
ourNotice.innerHTML = '<h3 style="margin-top:0;color:#826200;">Fix Plugin Does Not Exist Notices 👆</h3>' +
|
||||||
|
'<p>To remove these notices, scroll down to each plugin\'s name.php row, followed by: "<strong style="color:red">(' + pluginMissingText + ')</strong>". Then, click the "<strong>' + removeNoticeText + '</strong>" link for that plugin.</p>' +
|
||||||
|
'<p>This safely removes the missing active plugin reference from your database.</p>' +
|
||||||
|
'<p>Calls the standard WordPress function to update your active plugin options table, leaving only the remaining plugins installed and active.</p>' +
|
||||||
|
'<p><a href="#" id="prc-scroll-to-plugin" style="font-weight:bold;text-decoration:underline;color:#826200;">' + clickToScrollText + '</a></p>';
|
||||||
|
|
||||||
|
// Insert our notice right after the error
|
||||||
|
targetNotice.parentNode.insertBefore(ourNotice, targetNotice.nextSibling);
|
||||||
|
|
||||||
|
// Make sure our notice has the same width as the WordPress error notice
|
||||||
|
ourNotice.style.width = targetNotice.offsetWidth + 'px';
|
||||||
|
ourNotice.style.maxWidth = '100%';
|
||||||
|
ourNotice.style.boxSizing = 'border-box';
|
||||||
|
|
||||||
|
// Mark that we've added our notice
|
||||||
|
noticeAdded = true;
|
||||||
|
|
||||||
|
// Add scroll behavior
|
||||||
|
var scrollLink = document.getElementById('prc-scroll-to-plugin');
|
||||||
|
if (scrollLink) {
|
||||||
|
scrollLink.addEventListener('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
// Look for all plugin rows, not just inactive ones
|
||||||
|
var allPluginRows = document.querySelectorAll('tr.active, tr.inactive');
|
||||||
|
for (var i = 0; i < allPluginRows.length; i++) {
|
||||||
|
if (allPluginRows[i].textContent.includes('(File Missing)')) {
|
||||||
|
// Add a class for highlighting instead of direct style manipulation
|
||||||
|
allPluginRows[i].classList.add('prc-highlight-missing');
|
||||||
|
allPluginRows[i].scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||||
|
// Optional: Remove highlight after a delay
|
||||||
|
(function(row) {
|
||||||
|
setTimeout(function() {
|
||||||
|
row.classList.remove('prc-highlight-missing');
|
||||||
|
}, 3000); // Remove highlight after 3 seconds
|
||||||
|
})(allPluginRows[i]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to inject notices on multiple events to ensure it works
|
// Try to inject notices on multiple events to ensure it works
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
injectNotice();
|
// Delay the initial injection to ensure WordPress has fully loaded its notices
|
||||||
|
setTimeout(injectNotice, 100);
|
||||||
|
|
||||||
// Also set up a MutationObserver to watch for dynamically added notices
|
// Also set up a MutationObserver to watch for dynamically added notices
|
||||||
var observer = new MutationObserver(function(mutations) {
|
var observer = new MutationObserver(function(mutations) {
|
||||||
@ -68,8 +107,8 @@
|
|||||||
if (mutation.addedNodes && mutation.addedNodes.length > 0) {
|
if (mutation.addedNodes && mutation.addedNodes.length > 0) {
|
||||||
// Check if added nodes are notices or contain notices
|
// Check if added nodes are notices or contain notices
|
||||||
mutation.addedNodes.forEach(function(node) {
|
mutation.addedNodes.forEach(function(node) {
|
||||||
if (node.nodeType === 1 && (node.matches('.notice, .error, .updated') || node.querySelector('.notice, .error, .updated'))) {
|
if (node.nodeType === 1 && (node.matches('.notice, .error, .updated, div.error') || node.querySelector('.notice, .error, .updated, div.error'))) {
|
||||||
injectNotice();
|
setTimeout(injectNotice, 50); // Small delay to ensure the DOM is updated
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -85,4 +124,9 @@
|
|||||||
setTimeout(injectNotice, 500); // Delay slightly to ensure dynamic content is loaded
|
setTimeout(injectNotice, 500); // Delay slightly to ensure dynamic content is loaded
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Additional attempt after a longer delay to catch late-loading notices
|
||||||
|
window.addEventListener('load', function() {
|
||||||
|
setTimeout(injectNotice, 1000); // Longer delay as final attempt
|
||||||
|
});
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
@ -12,9 +12,9 @@
|
|||||||
* @wordpress-plugin
|
* @wordpress-plugin
|
||||||
* Plugin Name: Fix 'Plugin file does not exist.' Notices
|
* Plugin Name: Fix 'Plugin file does not exist.' Notices
|
||||||
* Plugin URI: https://wordpress.org/plugins/fix-plugin-does-not-exist-notices/
|
* Plugin URI: https://wordpress.org/plugins/fix-plugin-does-not-exist-notices/
|
||||||
* Description: Adds missing plugins to the plugins list with a "Remove Reference" link so you can permanently clean up invalid plugin entries and remove error notices.
|
* Description: Adds missing plugins to the plugins list with a "Remove Reference" link so you can permanently clean up invalid plugin entries and remove error notices. By Marcus Quinn (marcusquinn.com) & WP ALLSTARS (wpallstars.com).
|
||||||
* Version: 1.6.4
|
* Version: 1.6.13
|
||||||
* Author: Marcus Quinn
|
* Author: Marcus Quinn & WP ALLSTARS
|
||||||
* Author URI: https://www.wpallstars.com
|
* Author URI: https://www.wpallstars.com
|
||||||
* License: GPL-2.0+
|
* License: GPL-2.0+
|
||||||
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
@ -48,7 +48,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Define plugin constants
|
// Define plugin constants
|
||||||
define( 'FPDEN_VERSION', '1.6.4' );
|
define( 'FPDEN_VERSION', '1.6.13' );
|
||||||
define( 'FPDEN_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
|
define( 'FPDEN_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
|
||||||
define( 'FPDEN_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
|
define( 'FPDEN_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
|
||||||
define( 'FPDEN_PLUGIN_FILE', __FILE__ );
|
define( 'FPDEN_PLUGIN_FILE', __FILE__ );
|
||||||
@ -73,6 +73,13 @@ add_action( 'plugins_loaded', 'fpden_load_textdomain' );
|
|||||||
*/
|
*/
|
||||||
class Fix_Plugin_Does_Not_Exist_Notices {
|
class Fix_Plugin_Does_Not_Exist_Notices {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cached list of invalid plugins.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $invalid_plugins = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor. Hooks into WordPress actions and filters.
|
* Constructor. Hooks into WordPress actions and filters.
|
||||||
*/
|
*/
|
||||||
@ -91,6 +98,9 @@ class Fix_Plugin_Does_Not_Exist_Notices {
|
|||||||
|
|
||||||
// Enqueue admin scripts and styles.
|
// Enqueue admin scripts and styles.
|
||||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_assets' ) );
|
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_assets' ) );
|
||||||
|
|
||||||
|
// We're no longer trying to prevent WordPress from auto-deactivating plugins
|
||||||
|
// as it was causing critical errors in some environments
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -133,8 +143,8 @@ class Fix_Plugin_Does_Not_Exist_Notices {
|
|||||||
array(
|
array(
|
||||||
'i18n' => array(
|
'i18n' => array(
|
||||||
'clickToScroll' => esc_html__( 'Click here to scroll to missing plugins', 'fix-plugin-does-not-exist-notices' ),
|
'clickToScroll' => esc_html__( 'Click here to scroll to missing plugins', 'fix-plugin-does-not-exist-notices' ),
|
||||||
'pluginMissing' => esc_html__( 'Plugin file missing', 'fix-plugin-does-not-exist-notices' ),
|
'pluginMissing' => esc_html__( 'File Missing', 'fix-plugin-does-not-exist-notices' ),
|
||||||
'removeReference' => esc_html__( 'Remove Reference', 'fix-plugin-does-not-exist-notices' ),
|
'removeNotice' => esc_html__( 'Remove Notice', 'fix-plugin-does-not-exist-notices' ),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -166,7 +176,7 @@ class Fix_Plugin_Does_Not_Exist_Notices {
|
|||||||
'Name' => $plugin_name . ' <span class="error">(File Missing)</span>',
|
'Name' => $plugin_name . ' <span class="error">(File Missing)</span>',
|
||||||
/* translators: %s: Path to wp-content/plugins */
|
/* translators: %s: Path to wp-content/plugins */
|
||||||
'Description' => sprintf(
|
'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 Reference" to permanently remove it from your active plugins list and eliminate the error notice.', 'fix-plugin-does-not-exist-notices' ),
|
__( '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.', 'fix-plugin-does-not-exist-notices' ),
|
||||||
'<code>/wp-content/plugins/</code>'
|
'<code>/wp-content/plugins/</code>'
|
||||||
),
|
),
|
||||||
'Version' => __( 'N/A', 'fix-plugin-does-not-exist-notices' ),
|
'Version' => __( 'N/A', 'fix-plugin-does-not-exist-notices' ),
|
||||||
@ -183,10 +193,10 @@ class Fix_Plugin_Does_Not_Exist_Notices {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add the Remove Reference action link to invalid plugins.
|
* Add the Remove Notice action link to invalid plugins.
|
||||||
*
|
*
|
||||||
* Filters the action links displayed for each plugin on the plugins page.
|
* Filters the action links displayed for each plugin on the plugins page.
|
||||||
* Adds a "Remove Reference" link for plugins identified as missing.
|
* Adds a "Remove Notice" link for plugins identified as missing.
|
||||||
*
|
*
|
||||||
* @param array $actions An array of plugin action links.
|
* @param array $actions An array of plugin action links.
|
||||||
* @param string $plugin_file Path to the plugin file relative to the plugins directory.
|
* @param string $plugin_file Path to the plugin file relative to the plugins directory.
|
||||||
@ -201,8 +211,11 @@ class Fix_Plugin_Does_Not_Exist_Notices {
|
|||||||
return $actions;
|
return $actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if this is a missing plugin identified by our previous filter.
|
// Get our list of invalid plugins
|
||||||
if ( isset( $plugin_data['Name'] ) && strpos( $plugin_data['Name'], '<span class="error">(File Missing)</span>' ) !== false ) {
|
$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".
|
// Clear existing actions like "Activate", "Deactivate", "Edit".
|
||||||
$actions = array();
|
$actions = array();
|
||||||
|
|
||||||
@ -211,7 +224,7 @@ class Fix_Plugin_Does_Not_Exist_Notices {
|
|||||||
$remove_url = admin_url( 'plugins.php?action=remove_reference&plugin=' . urlencode( $plugin_file ) . '&_wpnonce=' . $nonce );
|
$remove_url = admin_url( 'plugins.php?action=remove_reference&plugin=' . urlencode( $plugin_file ) . '&_wpnonce=' . $nonce );
|
||||||
/* translators: %s: Plugin file path */
|
/* translators: %s: Plugin file path */
|
||||||
$aria_label = sprintf( __( 'Remove reference to missing plugin %s', 'fix-plugin-does-not-exist-notices' ), esc_attr( $plugin_file ) );
|
$aria_label = sprintf( __( 'Remove reference to missing plugin %s', '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 Reference', 'fix-plugin-does-not-exist-notices' ) . '</a>';
|
$actions['remove_reference'] = '<a href="' . esc_url( $remove_url ) . '" class="delete" aria-label="' . $aria_label . '">' . esc_html__( 'Remove Notice', 'fix-plugin-does-not-exist-notices' ) . '</a>';
|
||||||
}
|
}
|
||||||
|
|
||||||
return $actions;
|
return $actions;
|
||||||
@ -299,8 +312,9 @@ class Fix_Plugin_Does_Not_Exist_Notices {
|
|||||||
/**
|
/**
|
||||||
* Display admin notices on the plugins page.
|
* Display admin notices on the plugins page.
|
||||||
*
|
*
|
||||||
* Shows informational notices about missing plugins and feedback
|
* Shows feedback messages after attempting to remove a reference.
|
||||||
* 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
|
* @return void
|
||||||
*/
|
*/
|
||||||
@ -326,34 +340,8 @@ class Fix_Plugin_Does_Not_Exist_Notices {
|
|||||||
</div>
|
</div>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
|
// The main informational notice is now handled entirely by JavaScript
|
||||||
// Get invalid plugins to display the main informational notice.
|
// to position it directly below the WordPress error message.
|
||||||
// Note: We don't need to call get_invalid_plugins() again if enqueue_admin_assets already did,
|
|
||||||
// but calling it here ensures the notice shows even if assets weren't enqueued (e.g., JS disabled).
|
|
||||||
// Consider caching the result in a class property if performance is critical.
|
|
||||||
$invalid_plugins = $this->get_invalid_plugins();
|
|
||||||
|
|
||||||
// Display the main informational notice if there are missing plugins.
|
|
||||||
if ( ! empty( $invalid_plugins ) ) {
|
|
||||||
?>
|
|
||||||
<div class="notice notice-info is-dismissible">
|
|
||||||
<h3><?php esc_html_e( 'Fix Plugin Does Not Exist Notices', 'fix-plugin-does-not-exist-notices' ); ?></h3>
|
|
||||||
<p>
|
|
||||||
<strong><?php esc_html_e( 'Missing plugin files detected:', 'fix-plugin-does-not-exist-notices' ); ?></strong>
|
|
||||||
<?php esc_html_e( 'The plugins listed below with a', 'fix-plugin-does-not-exist-notices' ); ?>
|
|
||||||
<span style="color:red;">(<?php esc_html_e( 'File Missing', 'fix-plugin-does-not-exist-notices' ); ?>)</span>
|
|
||||||
<?php esc_html_e( 'tag no longer exist but are still referenced in your database.', 'fix-plugin-does-not-exist-notices' ); ?>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<strong><?php esc_html_e( 'How to fix:', 'fix-plugin-does-not-exist-notices' ); ?></strong>
|
|
||||||
<?php esc_html_e( 'Click the "Remove Reference" link next to each missing plugin to safely remove it from your active plugins list.', 'fix-plugin-does-not-exist-notices' ); ?>
|
|
||||||
</p>
|
|
||||||
<p><?php esc_html_e( 'This will clean up your database and remove the error notifications.', 'fix-plugin-does-not-exist-notices' ); ?></p>
|
|
||||||
</div>
|
|
||||||
<?php
|
|
||||||
// The JavaScript enqueued by enqueue_admin_assets() will handle adding the contextual notice
|
|
||||||
// near the actual WordPress error message.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -372,11 +360,17 @@ class Fix_Plugin_Does_Not_Exist_Notices {
|
|||||||
* Get a list of active plugin file paths that do not exist on the filesystem.
|
* Get a list of active plugin file paths that do not exist on the filesystem.
|
||||||
*
|
*
|
||||||
* Checks both single site and network active plugins based on the context.
|
* Checks both single site and network active plugins based on the context.
|
||||||
|
* Uses caching to avoid repeated filesystem checks.
|
||||||
*
|
*
|
||||||
* @return array An array of plugin file paths (relative to WP_PLUGIN_DIR) that are missing.
|
* @return array An array of plugin file paths (relative to WP_PLUGIN_DIR) that are missing.
|
||||||
*/
|
*/
|
||||||
private function get_invalid_plugins() {
|
private function get_invalid_plugins() {
|
||||||
$invalid_plugins = array();
|
// Return cached result if available
|
||||||
|
if ( null !== $this->invalid_plugins ) {
|
||||||
|
return $this->invalid_plugins;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->invalid_plugins = array();
|
||||||
$active_plugins = array();
|
$active_plugins = array();
|
||||||
|
|
||||||
// Determine which option to check based on context (Network Admin or single site).
|
// Determine which option to check based on context (Network Admin or single site).
|
||||||
@ -394,12 +388,14 @@ class Fix_Plugin_Does_Not_Exist_Notices {
|
|||||||
$plugin_path = WP_PLUGIN_DIR . '/' . $plugin_file;
|
$plugin_path = WP_PLUGIN_DIR . '/' . $plugin_file;
|
||||||
// Use validate_file to prevent directory traversal issues, although less likely here.
|
// Use validate_file to prevent directory traversal issues, although less likely here.
|
||||||
if ( validate_file( $plugin_file ) === 0 && ! file_exists( $plugin_path ) ) {
|
if ( validate_file( $plugin_file ) === 0 && ! file_exists( $plugin_path ) ) {
|
||||||
$invalid_plugins[] = $plugin_file;
|
$this->invalid_plugins[] = $plugin_file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $invalid_plugins;
|
return $this->invalid_plugins;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We've removed the prevent_auto_deactivation method as it was causing critical errors
|
||||||
} // End class Fix_Plugin_Does_Not_Exist_Notices
|
} // End class Fix_Plugin_Does_Not_Exist_Notices
|
||||||
|
|
||||||
// Initialize the plugin class.
|
// Initialize the plugin class.
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# This file is distributed under the GPL-2.0+.
|
# This file is distributed under the GPL-2.0+.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: Fix 'Plugin file does not exist.' Notices 1.6.4\n"
|
"Project-Id-Version: Fix 'Plugin file does not exist.' Notices 1.6.13\n"
|
||||||
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/fix-plugin-does-not-exist-notices\n"
|
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/fix-plugin-does-not-exist-notices\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
81
readme.txt
81
readme.txt
@ -1,15 +1,15 @@
|
|||||||
=== Fix 'Plugin file does not exist.' Notices ===
|
=== Fix 'Plugin file does not exist.' Notices ===
|
||||||
Contributors: marcusquinn
|
Contributors: marcusquinn, wpallstars
|
||||||
Donate link: https://www.wpallstars.com
|
Donate link: https://www.marcusquinn.com
|
||||||
Tags: plugins, missing plugins, cleanup, error fix, admin tools, plugin file does not exist
|
Tags: plugins, missing plugins, cleanup, error fix, admin tools, plugin file does not exist
|
||||||
Requires at least: 5.0
|
Requires at least: 5.0
|
||||||
Tested up to: 6.4
|
Tested up to: 6.4
|
||||||
Requires PHP: 7.0
|
Requires PHP: 7.0
|
||||||
Stable tag: 1.6.4
|
Stable tag: 1.6.13
|
||||||
License: GPL-2.0+
|
License: GPL-2.0+
|
||||||
License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
|
||||||
Easily remove references to deleted plugins that cause "Plugin file does not exist" errors in your WordPress admin.
|
Easily remove references to deleted plugins that cause "Plugin file does not exist" errors in your WordPress admin. By Marcus Quinn (marcusquinn.com) & WP ALLSTARS (wpallstars.com).
|
||||||
|
|
||||||
== Description ==
|
== Description ==
|
||||||
|
|
||||||
@ -89,6 +89,69 @@ Although this plugin consumes minimal disk space, and doesn't run unless you are
|
|||||||
|
|
||||||
== Changelog ==
|
== Changelog ==
|
||||||
|
|
||||||
|
= 1.6.13 =
|
||||||
|
* Code cleanup and optimization
|
||||||
|
* Improved Git Updater integration
|
||||||
|
* Fixed author display in plugin information
|
||||||
|
* Ensured compatibility with WordPress 6.4
|
||||||
|
|
||||||
|
= 1.6.12 =
|
||||||
|
* Added WP ALLSTARS as a co-author
|
||||||
|
* Updated author information and links
|
||||||
|
* Added author websites to plugin description
|
||||||
|
* Fixed issue with multiple author URLs
|
||||||
|
|
||||||
|
= 1.6.11 =
|
||||||
|
* CRITICAL FIX: Completely removed auto-deactivation prevention code that was causing fatal errors
|
||||||
|
* Simplified plugin functionality to focus on core features only
|
||||||
|
* Improved compatibility with various WordPress configurations
|
||||||
|
* Ensured plugin works correctly when other plugins are deleted
|
||||||
|
|
||||||
|
= 1.6.10 =
|
||||||
|
* Fixed critical error that could occur when a plugin folder is deleted
|
||||||
|
* Improved error handling with try/catch blocks
|
||||||
|
* Added more specific checks for the plugins page
|
||||||
|
* Enhanced compatibility with various WordPress configurations
|
||||||
|
* Made the code more defensive to prevent potential issues
|
||||||
|
|
||||||
|
= 1.6.9 =
|
||||||
|
* Fixed issue with notices not appearing below WordPress error messages
|
||||||
|
* Improved JavaScript detection of WordPress error notices
|
||||||
|
* Prevented WordPress from automatically clearing error notices on page refresh
|
||||||
|
* Added multiple timing attempts to ensure notices appear correctly
|
||||||
|
* Enhanced error notice targeting for better compatibility
|
||||||
|
|
||||||
|
= 1.6.8 =
|
||||||
|
* Fixed notice positioning to appear directly below WordPress error messages
|
||||||
|
* Improved notice width to match WordPress error messages
|
||||||
|
* Updated explanatory text for better clarity
|
||||||
|
* Fixed issue with notices not appearing in some cases
|
||||||
|
* Improved JavaScript detection of WordPress error messages
|
||||||
|
|
||||||
|
= 1.6.7 =
|
||||||
|
* Fixed duplicate notices issue by removing PHP-generated notice
|
||||||
|
* Simplified notice system to only show one notice below WordPress error
|
||||||
|
* Ensured consistent terminology with "Remove Notice" text
|
||||||
|
* Optimized plugin detection with caching to improve performance
|
||||||
|
* Fixed JavaScript to correctly handle multiple error messages
|
||||||
|
|
||||||
|
= 1.6.6 =
|
||||||
|
* Fixed issue with "Remove Notice" link not appearing on missing plugin rows
|
||||||
|
* Fixed issue with automatic removal of plugin references without user action
|
||||||
|
* Fixed notice positioning to ensure it appears below error messages
|
||||||
|
* Restored pointer triangle to indicate relationship with error message
|
||||||
|
* Improved detection of missing plugins in the plugin list
|
||||||
|
* Enhanced scroll functionality to work with all plugin types
|
||||||
|
|
||||||
|
= 1.6.5 =
|
||||||
|
* Fixed duplicate notices issue - now only one notice appears below error messages
|
||||||
|
* Changed notice heading to "Fix Plugin Does Not Exist Notices ☝️"
|
||||||
|
* Updated explanatory text to be more clear about the removal process
|
||||||
|
* Changed "Remove Reference" link text to "Remove Notice" for better clarity
|
||||||
|
* Made "(File Missing)" text bold and red for better visibility
|
||||||
|
* Fixed scroll functionality to work with all plugin rows
|
||||||
|
* Improved JavaScript to prevent multiple notices from appearing
|
||||||
|
|
||||||
= 1.6.4 =
|
= 1.6.4 =
|
||||||
* Updated version management to ensure consistent patch version increments
|
* Updated version management to ensure consistent patch version increments
|
||||||
* Improved documentation for version update process
|
* Improved documentation for version update process
|
||||||
@ -196,8 +259,14 @@ Although this plugin consumes minimal disk space, and doesn't run unless you are
|
|||||||
|
|
||||||
== Upgrade Notice ==
|
== Upgrade Notice ==
|
||||||
|
|
||||||
= 1.6.4 =
|
= 1.6.13 =
|
||||||
Improved version management with consistent patch version increments and enhanced documentation for development workflows!
|
Code cleanup, improved Git Updater integration, and ensured compatibility with WordPress 6.4.
|
||||||
|
|
||||||
|
= 1.6.12 =
|
||||||
|
Added WP ALLSTARS as a co-author and updated author information.
|
||||||
|
|
||||||
|
= 1.6.11 =
|
||||||
|
URGENT CRITICAL FIX: Completely removes code that was causing fatal errors. If you're experiencing the "critical error" message, this update will resolve it.
|
||||||
|
|
||||||
= 1.6.3 =
|
= 1.6.3 =
|
||||||
Fixed Git Updater repository URLs and updated organization naming for consistent branding across all platforms!
|
Fixed Git Updater repository URLs and updated organization naming for consistent branding across all platforms!
|
||||||
|
Reference in New Issue
Block a user