Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
7ac72fd3c0 | |||
0a394fa671 |
19
CHANGELOG.md
19
CHANGELOG.md
@ -2,6 +2,25 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [1.2.4] - 2023-10-05
|
||||||
|
### Fixed
|
||||||
|
- Compatibility with more WordPress admin UI variations
|
||||||
|
- Specific targeting for admin notices in various themes
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Advanced DOM traversal using TreeWalker API
|
||||||
|
- Multiple fallback approaches to ensure button appears
|
||||||
|
- Enhanced console logging for troubleshooting
|
||||||
|
|
||||||
|
## [1.2.3] - 2023-10-05
|
||||||
|
### Fixed
|
||||||
|
- Button not appearing in some WordPress admin themes
|
||||||
|
- Error message detection for greater theme compatibility
|
||||||
|
|
||||||
|
### Improved
|
||||||
|
- DOM traversal to find notification elements in various themes
|
||||||
|
- Added console logging for troubleshooting
|
||||||
|
|
||||||
## [1.2.2] - 2023-10-05
|
## [1.2.2] - 2023-10-05
|
||||||
### Fixed
|
### Fixed
|
||||||
- Timeout issue during plugin activation
|
- Timeout issue during plugin activation
|
||||||
|
13
README.md
13
README.md
@ -1,7 +1,7 @@
|
|||||||
# Plugin Reference Cleaner
|
# Plugin Reference Cleaner
|
||||||
Author: Marcus Quinn
|
Author: Marcus Quinn
|
||||||
Author URI: https://www.wpallstars.com
|
Author URI: https://www.wpallstars.com
|
||||||
Version: 1.2.2
|
Version: 1.2.4
|
||||||
License: GPL-2.0+
|
License: GPL-2.0+
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
@ -47,6 +47,17 @@ If you don't have this notification perpetually showing on your /wp-admin/plugin
|
|||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
### 1.2.4
|
||||||
|
* Fixed compatibility with more WordPress admin themes
|
||||||
|
* Added advanced DOM traversal to find error messages
|
||||||
|
* Implemented fallback mechanisms to ensure button appears
|
||||||
|
* Added detailed console logging for troubleshooting
|
||||||
|
|
||||||
|
### 1.2.3
|
||||||
|
* Fixed button not appearing in some WordPress admin themes
|
||||||
|
* Improved error message detection for greater compatibility
|
||||||
|
* Enhanced DOM traversal to find notification elements
|
||||||
|
|
||||||
### 1.2.2
|
### 1.2.2
|
||||||
* Fixed timeout issue during plugin activation
|
* Fixed timeout issue during plugin activation
|
||||||
* Improved hook management to prevent potential infinite recursion
|
* Improved hook management to prevent potential infinite recursion
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
/*
|
/*
|
||||||
* Plugin Name: Plugin Reference Cleaner
|
* Plugin Name: Plugin Reference Cleaner
|
||||||
* Description: Adds a "Remove Reference" button to plugin deactivation error notices, allowing users to clean up invalid plugin entries.
|
* Description: Adds a "Remove Reference" button to plugin deactivation error notices, allowing users to clean up invalid plugin entries.
|
||||||
* Version: 1.2.2
|
* Version: 1.2.4
|
||||||
* Author: Marcus Quinn
|
* Author: Marcus Quinn
|
||||||
* Author URI: https://www.wpallstars.com
|
* Author URI: https://www.wpallstars.com
|
||||||
* License: GPL-2.0+
|
* License: GPL-2.0+
|
||||||
@ -37,8 +37,10 @@ class Plugin_Reference_Cleaner {
|
|||||||
|
|
||||||
if (!empty($notices)) {
|
if (!empty($notices)) {
|
||||||
foreach ($notices as $notice) {
|
foreach ($notices as $notice) {
|
||||||
if (strpos($notice, 'has been deactivated due to an error: Plugin file does not exist') !== false) {
|
// Look for both variations of the error message
|
||||||
// Extract plugin file from notice
|
if (strpos($notice, 'has been deactivated due to an error: Plugin file does not exist') !== false ||
|
||||||
|
strpos($notice, 'deactivated due to an error: Plugin file does not exist') !== false) {
|
||||||
|
// Extract plugin file from notice using various patterns
|
||||||
if (preg_match('/The plugin ([^ ]+)/', $notice, $match)) {
|
if (preg_match('/The plugin ([^ ]+)/', $notice, $match)) {
|
||||||
$plugin_files[] = $match[1];
|
$plugin_files[] = $match[1];
|
||||||
$has_error_notice = true;
|
$has_error_notice = true;
|
||||||
@ -57,25 +59,123 @@ class Plugin_Reference_Cleaner {
|
|||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
var pluginFiles = <?php echo wp_json_encode($plugin_files); ?>;
|
var pluginFiles = <?php echo wp_json_encode($plugin_files); ?>;
|
||||||
var notices = document.querySelectorAll('.notice-error p');
|
console.log('Plugin Reference Cleaner: Detected plugin files:', pluginFiles);
|
||||||
|
|
||||||
if (notices.length === 0) {
|
// Get all notifications directly in the plugins page
|
||||||
|
var pluginsPage = document.querySelector('.wrap');
|
||||||
|
if (!pluginsPage) {
|
||||||
|
console.log('Plugin Reference Cleaner: Could not find the plugins page wrapper');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
notices.forEach(function(notice) {
|
// Look specifically for elements containing the error message
|
||||||
|
// Use direct DOM traversal to find all text nodes
|
||||||
|
function findTextNodesWithText(element, searchText) {
|
||||||
|
var result = [];
|
||||||
|
var walk = document.createTreeWalker(element, NodeFilter.SHOW_TEXT, null, false);
|
||||||
|
var node;
|
||||||
|
|
||||||
|
while (node = walk.nextNode()) {
|
||||||
|
if (node.nodeValue.indexOf(searchText) > -1) {
|
||||||
|
result.push(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find paragraphs containing error messages
|
||||||
|
var errorTexts = findTextNodesWithText(pluginsPage, 'Plugin file does not exist');
|
||||||
|
console.log('Plugin Reference Cleaner: Found error nodes:', errorTexts.length);
|
||||||
|
|
||||||
|
if (errorTexts.length === 0) {
|
||||||
|
// Try another approach - find direct error messages
|
||||||
|
var allElements = pluginsPage.querySelectorAll('*');
|
||||||
|
for (var i = 0; i < allElements.length; i++) {
|
||||||
|
var el = allElements[i];
|
||||||
|
var text = el.textContent;
|
||||||
|
if (text && text.includes('has been deactivated due to an error: Plugin file does not exist')) {
|
||||||
|
errorTexts.push(el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle each error message
|
||||||
|
errorTexts.forEach(function(textNode) {
|
||||||
|
console.log('Plugin Reference Cleaner: Processing error node:', textNode);
|
||||||
|
|
||||||
|
// Get the parent element of the text node
|
||||||
|
var errorElement = textNode.parentNode || textNode;
|
||||||
|
|
||||||
|
// Check if a button already exists to avoid duplicates
|
||||||
|
if (errorElement.querySelector('.remove-plugin-ref')) {
|
||||||
|
console.log('Plugin Reference Cleaner: Button already exists for this element');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find which plugin file this error refers to
|
||||||
|
var matchingPluginFile = null;
|
||||||
pluginFiles.forEach(function(pluginFile) {
|
pluginFiles.forEach(function(pluginFile) {
|
||||||
if (notice.textContent.includes('The plugin ' + pluginFile)) {
|
if (textNode.nodeValue && textNode.nodeValue.includes(pluginFile) ||
|
||||||
|
(textNode.textContent && textNode.textContent.includes(pluginFile))) {
|
||||||
|
matchingPluginFile = pluginFile;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// If we couldn't match a specific plugin, use the first one as fallback
|
||||||
|
if (!matchingPluginFile && pluginFiles.length > 0) {
|
||||||
|
matchingPluginFile = pluginFiles[0];
|
||||||
|
console.log('Plugin Reference Cleaner: Using fallback plugin file:', matchingPluginFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matchingPluginFile) {
|
||||||
|
// Create button
|
||||||
|
var button = document.createElement('button');
|
||||||
|
button.textContent = 'Remove Reference';
|
||||||
|
button.className = 'button button-secondary remove-plugin-ref';
|
||||||
|
button.dataset.plugin = matchingPluginFile;
|
||||||
|
button.style.marginLeft = '10px';
|
||||||
|
|
||||||
|
// Append the button to the error message
|
||||||
|
errorElement.appendChild(button);
|
||||||
|
console.log('Plugin Reference Cleaner: Added button for ' + matchingPluginFile + ' to', errorElement);
|
||||||
|
} else {
|
||||||
|
console.log('Plugin Reference Cleaner: Could not determine plugin file for this error');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Inject a more direct approach if the above fails
|
||||||
|
if (errorTexts.length === 0) {
|
||||||
|
// Target the specific format in the screenshot
|
||||||
|
var errorMessages = document.querySelectorAll('.wrap > .notice, .wrap > div > .notice');
|
||||||
|
console.log('Plugin Reference Cleaner: Trying direct approach, found notices:', errorMessages.length);
|
||||||
|
|
||||||
|
errorMessages.forEach(function(notice) {
|
||||||
|
var text = notice.textContent;
|
||||||
|
if (text && text.includes('Plugin file does not exist')) {
|
||||||
|
// Extract the plugin path
|
||||||
|
var pluginMatch = /The plugin ([^ ]+) has been deactivated/.exec(text);
|
||||||
|
var pluginFile = pluginMatch ? pluginMatch[1] : (pluginFiles.length > 0 ? pluginFiles[0] : null);
|
||||||
|
|
||||||
|
if (pluginFile) {
|
||||||
|
// Get container to add button
|
||||||
|
var container = notice.querySelector('p') || notice;
|
||||||
|
|
||||||
|
if (!container.querySelector('.remove-plugin-ref')) {
|
||||||
var button = document.createElement('button');
|
var button = document.createElement('button');
|
||||||
button.textContent = 'Remove Reference';
|
button.textContent = 'Remove Reference';
|
||||||
button.className = 'button button-secondary remove-plugin-ref';
|
button.className = 'button button-secondary remove-plugin-ref';
|
||||||
button.dataset.plugin = pluginFile;
|
button.dataset.plugin = pluginFile;
|
||||||
button.style.marginLeft = '10px';
|
button.style.marginLeft = '10px';
|
||||||
notice.appendChild(button);
|
container.appendChild(button);
|
||||||
|
console.log('Plugin Reference Cleaner: Direct approach - added button for ' + pluginFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
// Add click event listeners to all created buttons
|
||||||
document.querySelectorAll('.remove-plugin-ref').forEach(function(button) {
|
document.querySelectorAll('.remove-plugin-ref').forEach(function(button) {
|
||||||
button.addEventListener('click', function(e) {
|
button.addEventListener('click', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
13
readme.txt
13
readme.txt
@ -1,7 +1,7 @@
|
|||||||
=== Plugin Reference Cleaner ===
|
=== Plugin Reference Cleaner ===
|
||||||
Author: Marcus Quinn
|
Author: Marcus Quinn
|
||||||
Author URI: https://www.wpallstars.com
|
Author URI: https://www.wpallstars.com
|
||||||
Version: 1.2.2
|
Version: 1.2.4
|
||||||
License: GPL-2.0+
|
License: GPL-2.0+
|
||||||
|
|
||||||
== Description ==
|
== Description ==
|
||||||
@ -47,6 +47,17 @@ If you don't have this notification perpetually showing on your /wp-admin/plugin
|
|||||||
|
|
||||||
== Changelog ==
|
== Changelog ==
|
||||||
|
|
||||||
|
= 1.2.4 =
|
||||||
|
* Fixed compatibility with more WordPress admin themes
|
||||||
|
* Added advanced DOM traversal to find error messages
|
||||||
|
* Implemented fallback mechanisms to ensure button appears
|
||||||
|
* Added detailed console logging for troubleshooting
|
||||||
|
|
||||||
|
= 1.2.3 =
|
||||||
|
* Fixed button not appearing in some WordPress admin themes
|
||||||
|
* Improved error message detection for greater compatibility
|
||||||
|
* Enhanced DOM traversal to find notification elements
|
||||||
|
|
||||||
= 1.2.2 =
|
= 1.2.2 =
|
||||||
* Fixed timeout issue during plugin activation
|
* Fixed timeout issue during plugin activation
|
||||||
* Improved hook management to prevent potential infinite recursion
|
* Improved hook management to prevent potential infinite recursion
|
||||||
|
Reference in New Issue
Block a user