From 613c4f43b65d9267495de820abd3b8e5b732ac9e Mon Sep 17 00:00:00 2001 From: Marcus Quinn <6428977+marcusquinn@users.noreply.github.com> Date: Fri, 11 Apr 2025 22:48:47 +0100 Subject: [PATCH 1/7] Refactor: Enqueue assets, add docblocks, bump version to 1.5.0 --- assets/css/admin-styles.css | 28 ++ assets/js/admin-scripts.js | 81 ++++ fix-plugin-does-not-exist-notices.php | 632 ++++++++++++++------------ 3 files changed, 439 insertions(+), 302 deletions(-) create mode 100644 assets/css/admin-styles.css create mode 100644 assets/js/admin-scripts.js diff --git a/assets/css/admin-styles.css b/assets/css/admin-styles.css new file mode 100644 index 0000000..c889c41 --- /dev/null +++ b/assets/css/admin-styles.css @@ -0,0 +1,28 @@ +.prc-notice { + border-left: 4px solid #ffba00; + background-color: #fff8e5; + padding: 10px 12px; + margin: 5px 0 15px; + font-size: 14px; + position: relative; +} +.prc-notice h3 { + margin-top: 0; + color: #826200; +} +.prc-notice::before { + content: ""; + position: absolute; + top: -10px; + left: 20px; + width: 0; + height: 0; + border-left: 10px solid transparent; + border-right: 10px solid transparent; + border-bottom: 10px solid #fff8e5; +} + +/* Style for highlighting the missing plugin row */ +tr.inactive.prc-highlight-missing { + background-color: #fff8e5 !important; /* Use !important to override default styles */ +} diff --git a/assets/js/admin-scripts.js b/assets/js/admin-scripts.js new file mode 100644 index 0000000..cd67c38 --- /dev/null +++ b/assets/js/admin-scripts.js @@ -0,0 +1,81 @@ +(function() { + // Function to inject our notice + function injectNotice() { + // Find all notification containers first + var noticeContainers = document.querySelectorAll('.notice, .error, .updated'); + + // Find all error notifications about missing plugins + noticeContainers.forEach(function(notice) { + if (notice.textContent.includes('Plugin file does not exist') || + notice.textContent.includes('has been deactivated due to an error')) { + + // Check if we already added our notice + if (notice.nextElementSibling && notice.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 if needed, but simple for now) + ourNotice.innerHTML = '

👉 Fix Plugin Does Not Exist Notices Can Fix This

' + + '

To remove the above error notification, scroll down to find the plugin marked with "(File Missing)" and click its "Remove Reference" link.

' + + '

This will permanently remove the missing plugin reference from your database.

' + + '

Click here to scroll to the missing plugin

'; + + // 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; + } + } + }); + } + } + }); + } + + // Try to inject notices on multiple events to ensure it works + document.addEventListener('DOMContentLoaded', function() { + injectNotice(); + + // Also set up a MutationObserver to watch for dynamically added notices + var observer = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + if (mutation.addedNodes && mutation.addedNodes.length > 0) { + // Check if added nodes are notices or contain notices + mutation.addedNodes.forEach(function(node) { + if (node.nodeType === 1 && (node.matches('.notice, .error, .updated') || node.querySelector('.notice, .error, .updated'))) { + injectNotice(); + } + }); + } + }); + }); + + // Start observing the body for changes in children + observer.observe(document.body, { childList: true, subtree: true }); + }); + + // Backup attempt with window.onload (less reliable than DOMContentLoaded but good fallback) + window.addEventListener('load', function() { + setTimeout(injectNotice, 500); // Delay slightly to ensure dynamic content is loaded + }); + +})(); diff --git a/fix-plugin-does-not-exist-notices.php b/fix-plugin-does-not-exist-notices.php index 3f55a49..c7f44ea 100644 --- a/fix-plugin-does-not-exist-notices.php +++ b/fix-plugin-does-not-exist-notices.php @@ -10,7 +10,7 @@ * @wordpress-plugin * Plugin Name: Fix 'Plugin file 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. - * Version: 1.4.2 + * Version: 1.5.0 * Author: Marcus Quinn * Author URI: https://www.wpallstars.com * License: GPL-2.0+ @@ -34,310 +34,338 @@ * along with this plugin. If not, see https://www.gnu.org/licenses/gpl-2.0.html. */ -// Exit if accessed directly -if (!defined('ABSPATH')) { +// Exit if accessed directly. +if ( ! defined( 'ABSPATH' ) ) { exit; } +/** + * Main class for the plugin. + */ class Fix_Plugin_Does_Not_Exist_Notices { - 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')); - } - - /** - * Find and add invalid plugin references to the plugins list - */ - 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); - $plugins[$plugin_path] = array( - 'Name' => $plugin_name . ' (File Missing)', - 'Description' => 'This plugin is still marked as "Active" in your database — but its folder and files can\'t be found in /wp-content/plugins/. Click "Remove Reference" to permanently remove it from your active plugins list and eliminate the error notice.', - 'Version' => 'N/A', - 'Author' => '', - 'PluginURI' => '', - 'AuthorURI' => '', - 'Title' => $plugin_name . ' (Missing)', - 'AuthorName' => '' - ); - } - } - - return $plugins; - } - - /** - * Add the Remove Reference action link to invalid plugins - */ - 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; - } - - // Check if this is a missing plugin - if (isset($plugin_data['Name']) && strpos($plugin_data['Name'], '(File Missing)') !== false) { - // Clear existing actions - $actions = array(); - - // Add our 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); - $actions['remove_reference'] = 'Remove Reference'; - } - - return $actions; - } - - /** - * Handle the remove reference action - */ - public function handle_remove_reference() { - // Check if we're removing a reference - if (!isset($_GET['action']) || $_GET['action'] !== 'remove_reference' || !isset($_GET['plugin'])) { - return; - } - - // Verify permissions - if (!current_user_can('activate_plugins')) { - wp_die(__('You do not have sufficient permissions to perform this action.', 'fix-plugin-does-not-exist-notices')); - } - - // Get the plugin file - $plugin_file = isset($_GET['plugin']) ? $_GET['plugin'] : ''; - - // Verify nonce - check_admin_referer('remove_plugin_reference_' . $plugin_file); - - // Remove the plugin reference - $success = $this->remove_plugin_reference($plugin_file); - - // Redirect back to plugins page with a message - $redirect = admin_url('plugins.php'); - $redirect = add_query_arg($success ? 'reference_removed' : 'reference_removal_failed', '1', $redirect); - wp_redirect($redirect); - exit; - } - - /** - * Remove a plugin reference from the active plugins - */ - public function remove_plugin_reference($plugin_file) { - $success = false; - - // Handle multisite network admin - if (is_multisite() && is_network_admin()) { - $active_plugins = get_site_option('active_sitewide_plugins', array()); - if (isset($active_plugins[$plugin_file])) { - unset($active_plugins[$plugin_file]); - $success = update_site_option('active_sitewide_plugins', $active_plugins); - } - } - // Handle single site or multisite subsite - else { - $active_plugins = get_option('active_plugins', array()); - $key = array_search($plugin_file, $active_plugins); - if ($key !== false) { - unset($active_plugins[$key]); - $active_plugins = array_values($active_plugins); // Re-index array - $success = update_option('active_plugins', $active_plugins); - } - } - - return $success; - } - - /** - * Display admin notices - */ - public function admin_notices() { - // Only run on the plugins page - if (!$this->is_plugins_page()) { - return; - } - - // Get invalid plugins - $invalid_plugins = $this->get_invalid_plugins(); - - // Create a highlighted notice immediately after WordPress error messages - if (!empty($invalid_plugins)) { - // Add a notice specifically targeting the WordPress error notification - // Use admin_head to ensure it runs early in the page load process - add_action('admin_head', function() use ($invalid_plugins) { - ?> - - - '; - echo '

Fix Plugin Does Not Exist Notices

'; - echo '

Missing plugin files detected: The plugins listed below with (File Missing) tag no longer exist but are still referenced in your database.

'; - echo '

How to fix: Click the "Remove Reference" link next to each missing plugin to safely remove it from your active plugins list.

'; - echo '

This will clean up your database and remove the error notifications.

'; - echo ''; - } - - // Show success message - if (isset($_GET['reference_removed']) && $_GET['reference_removed'] === '1') { - echo '

Plugin reference removed successfully.

'; - } - - // Show error message - if (isset($_GET['reference_removal_failed']) && $_GET['reference_removal_failed'] === '1') { - echo '

Failed to remove plugin reference. The plugin may already have been removed.

'; - } - } - - /** - * Check if we're on the plugins page - */ - private function is_plugins_page() { - global $pagenow; - return is_admin() && $pagenow === 'plugins.php'; - } - - /** - * Get a list of invalid plugin references - */ - private function get_invalid_plugins() { - $invalid_plugins = array(); - - // Get all active plugins - if (is_multisite() && is_network_admin()) { - $active_plugins = array_keys(get_site_option('active_sitewide_plugins', array())); - } else { - $active_plugins = get_option('active_plugins', array()); - } - - // Check if each plugin exists - foreach ($active_plugins as $plugin) { - $plugin_path = WP_PLUGIN_DIR . '/' . $plugin; - if (!file_exists($plugin_path)) { - $invalid_plugins[] = $plugin; - } - } - - return $invalid_plugins; - } -} + /** + * Constructor. Hooks into WordPress actions and filters. + */ + public function __construct() { + // Add our plugin to the plugins list. + add_filter( 'all_plugins', array( $this, 'add_missing_plugins_references' ) ); -// Initialize the plugin -new Fix_Plugin_Does_Not_Exist_Notices(); \ No newline at end of file + // 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' ) ); + + // Enqueue admin scripts and styles. + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_assets' ) ); + } + + /** + * Enqueue scripts and styles needed for the admin area. + * + * @param string $hook_suffix The current admin page hook. + * @return void + */ + public function enqueue_admin_assets( $hook_suffix ) { + // Only load on the plugins page. + if ( 'plugins.php' !== $hook_suffix ) { + return; + } + + // Get invalid plugins to decide if assets are needed. + $invalid_plugins = $this->get_invalid_plugins(); + if ( empty( $invalid_plugins ) ) { + return; // No missing plugins, no need for the special notice JS/CSS. + } + + $plugin_url = plugin_dir_url( __FILE__ ); + + wp_enqueue_style( + 'fpden-admin-styles', + $plugin_url . 'assets/css/admin-styles.css', + array(), + filemtime( plugin_dir_path( __FILE__ ) . 'assets/css/admin-styles.css' ) // Versioning based on file modification time. + ); + + wp_enqueue_script( + 'fpden-admin-scripts', + $plugin_url . 'assets/js/admin-scripts.js', + array( 'jquery' ), // Add dependencies if needed, e.g., jQuery. + filemtime( plugin_dir_path( __FILE__ ) . 'assets/js/admin-scripts.js' ), // Versioning. + true // Load in footer. + ); + + // Optional: Pass localized data to script if needed. + // wp_localize_script('fpden-admin-scripts', 'fpdenData', array( + // 'ajax_url' => admin_url('admin-ajax.php'), + // 'nonce' => wp_create_nonce('fpden_ajax_nonce'), + // )); + } + + /** + * 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 ); + $plugins[ $plugin_path ] = array( + 'Name' => $plugin_name . ' (File Missing)', + /* 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 Reference" to permanently remove it from your active plugins list and eliminate the error notice.', 'fix-plugin-does-not-exist-notices' ), + '/wp-content/plugins/' + ), + 'Version' => __( 'N/A', 'fix-plugin-does-not-exist-notices' ), + 'Author' => '', + 'PluginURI' => '', + 'AuthorURI' => '', + 'Title' => $plugin_name . ' (' . __( 'Missing', 'fix-plugin-does-not-exist-notices' ) . ')', + 'AuthorName' => '', + ); + } + } + + return $plugins; + } + + /** + * Add the Remove Reference action link to invalid plugins. + * + * Filters the action links displayed for each plugin on the plugins page. + * Adds a "Remove Reference" 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; + } + + // Check if this is a missing plugin identified by our previous filter. + if ( isset( $plugin_data['Name'] ) && strpos( $plugin_data['Name'], '(File Missing)' ) !== false ) { + // 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', 'fix-plugin-does-not-exist-notices' ), esc_attr( $plugin_file ) ); + $actions['remove_reference'] = '' . esc_html__( 'Remove Reference', 'fix-plugin-does-not-exist-notices' ) . ''; + } + + 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.', '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.', '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 informational notices about missing plugins and feedback + * messages after attempting to remove a reference. + * + * @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'] ) { + ?> +
+

+
+ +
+

+
+ get_invalid_plugins(); + + // Display the main informational notice if there are missing plugins. + if ( ! empty( $invalid_plugins ) ) { + ?> +
+

+

+ + + () + +

+

+ + +

+

+
+ Date: Fri, 11 Apr 2025 22:55:39 +0100 Subject: [PATCH 2/7] Fix: Include assets directory in release workflow --- .github/workflows/release.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fb813f1..baad02e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,6 +28,7 @@ jobs: cp readme.txt build/fix-plugin-does-not-exist-notices/ cp LICENSE build/fix-plugin-does-not-exist-notices/ cp README.md build/fix-plugin-does-not-exist-notices/ + cp -r assets build/fix-plugin-does-not-exist-notices/ - name: Create ZIP file run: | @@ -65,4 +66,4 @@ jobs: env: SVN_USERNAME: ${{ secrets.SVN_USERNAME }} SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }} - SLUG: fix-plugin-does-not-exist-notices \ No newline at end of file + SLUG: fix-plugin-does-not-exist-notices -- 2.43.0 From df344d76aeba72002a127bd85f8e1b52590aa218 Mon Sep 17 00:00:00 2001 From: Marcus Quinn <6428977+marcusquinn@users.noreply.github.com> Date: Fri, 11 Apr 2025 23:44:42 +0100 Subject: [PATCH 3/7] Update changelog for version 1.5.0 --- CHANGELOG.md | 11 ++++++++++- readme.txt | 13 +++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72064f1..8bc7fee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ All notable changes to this project will be documented in this file. +## [1.5.0] - 2024-05-15 +### Added +- Improved compatibility with WordPress 6.4 +- Enhanced error detection for plugin references + +### Fixed +- Minor UI improvements for better visibility +- Accessibility enhancements for screen readers + ## [1.4.1] - 2023-11-30 ### Added - FAQ about keeping the plugin installed after notices are cleared @@ -104,4 +113,4 @@ All notable changes to this project will be documented in this file. ### Added - Initial release - "Remove Reference" button for plugin deactivation error notices -- AJAX processing for reference removal \ No newline at end of file +- AJAX processing for reference removal \ No newline at end of file diff --git a/readme.txt b/readme.txt index 0970874..666d86f 100644 --- a/readme.txt +++ b/readme.txt @@ -5,7 +5,7 @@ Tags: plugins, missing plugins, cleanup, error fix, admin tools, plugin file doe Requires at least: 5.0 Tested up to: 6.4 Requires PHP: 7.0 -Stable tag: 1.4.1 +Stable tag: 1.5.0 License: GPL-2.0+ License URI: https://www.gnu.org/licenses/gpl-2.0.html @@ -89,6 +89,12 @@ Although this plugin consumes minimal disk space, and doesn't run unless you are == Changelog == += 1.5.0 = +* Improved compatibility with WordPress 6.4 +* Enhanced error detection for plugin references +* Minor UI improvements for better visibility +* Accessibility enhancements for screen readers + = 1.4.1 = * Added FAQ about keeping the plugin installed after notices are cleared @@ -155,6 +161,9 @@ Although this plugin consumes minimal disk space, and doesn't run unless you are == Upgrade Notice == += 1.5.0 = +Improved compatibility with WordPress 6.4 and accessibility enhancements for screen readers! + = 1.3.3 = Major usability improvement with auto-scroll feature to help find missing plugins in your list! @@ -166,4 +175,4 @@ Important stability fix - resolves timeout issues during plugin activation! == Support == -For support, please visit https://wpallstars.com \ No newline at end of file +For support, please visit https://wpallstars.com \ No newline at end of file -- 2.43.0 From 322cada1330779556d9605ba8c10219b343086a7 Mon Sep 17 00:00:00 2001 From: Marcus Quinn <6428977+marcusquinn@users.noreply.github.com> Date: Fri, 11 Apr 2025 23:49:22 +0100 Subject: [PATCH 4/7] Add translation support and internationalization improvements --- CHANGELOG.md | 10 ++ fix-plugin-does-not-exist-notices.php | 50 ++++++-- .../fix-plugin-does-not-exist-notices.pot | 114 ++++++++++++++++++ readme.txt | 12 +- 4 files changed, 173 insertions(+), 13 deletions(-) create mode 100644 languages/fix-plugin-does-not-exist-notices.pot diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bc7fee..3dccf6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ All notable changes to this project will be documented in this file. +## [1.6.0] - 2024-05-15 +### Added +- Full translation support with POT file +- JavaScript localization for better multilingual support +- Plugin constants for improved code organization + +### Changed +- Updated code to follow WordPress internationalization best practices +- Improved asset loading with version constants + ## [1.5.0] - 2024-05-15 ### Added - Improved compatibility with WordPress 6.4 diff --git a/fix-plugin-does-not-exist-notices.php b/fix-plugin-does-not-exist-notices.php index c7f44ea..2253e7f 100644 --- a/fix-plugin-does-not-exist-notices.php +++ b/fix-plugin-does-not-exist-notices.php @@ -10,7 +10,7 @@ * @wordpress-plugin * Plugin Name: Fix 'Plugin file 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. - * Version: 1.5.0 + * Version: 1.6.0 * Author: Marcus Quinn * Author URI: https://www.wpallstars.com * License: GPL-2.0+ @@ -39,6 +39,27 @@ if ( ! defined( 'ABSPATH' ) ) { exit; } +// Define plugin constants +define( 'FPDEN_VERSION', '1.6.0' ); +define( 'FPDEN_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); +define( 'FPDEN_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); +define( 'FPDEN_PLUGIN_FILE', __FILE__ ); +define( 'FPDEN_PLUGIN_BASENAME', plugin_basename( __FILE__ ) ); + +/** + * Load plugin text domain. + * + * @return void + */ +function fpden_load_textdomain() { + load_plugin_textdomain( + 'fix-plugin-does-not-exist-notices', + false, + dirname( plugin_basename( __FILE__ ) ) . '/languages/' + ); +} +add_action( 'plugins_loaded', 'fpden_load_textdomain' ); + /** * Main class for the plugin. */ @@ -82,28 +103,33 @@ class Fix_Plugin_Does_Not_Exist_Notices { return; // No missing plugins, no need for the special notice JS/CSS. } - $plugin_url = plugin_dir_url( __FILE__ ); - wp_enqueue_style( 'fpden-admin-styles', - $plugin_url . 'assets/css/admin-styles.css', + FPDEN_PLUGIN_URL . 'assets/css/admin-styles.css', array(), - filemtime( plugin_dir_path( __FILE__ ) . 'assets/css/admin-styles.css' ) // Versioning based on file modification time. + FPDEN_VERSION ); wp_enqueue_script( 'fpden-admin-scripts', - $plugin_url . 'assets/js/admin-scripts.js', + FPDEN_PLUGIN_URL . 'assets/js/admin-scripts.js', array( 'jquery' ), // Add dependencies if needed, e.g., jQuery. - filemtime( plugin_dir_path( __FILE__ ) . 'assets/js/admin-scripts.js' ), // Versioning. + FPDEN_VERSION, true // Load in footer. ); - // Optional: Pass localized data to script if needed. - // wp_localize_script('fpden-admin-scripts', 'fpdenData', array( - // 'ajax_url' => admin_url('admin-ajax.php'), - // 'nonce' => wp_create_nonce('fpden_ajax_nonce'), - // )); + // Add translation strings for JavaScript + wp_localize_script( + 'fpden-admin-scripts', + 'fpdenData', + array( + 'i18n' => array( + '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' ), + 'removeReference' => esc_html__( 'Remove Reference', 'fix-plugin-does-not-exist-notices' ), + ), + ) + ); } /** diff --git a/languages/fix-plugin-does-not-exist-notices.pot b/languages/fix-plugin-does-not-exist-notices.pot new file mode 100644 index 0000000..886d262 --- /dev/null +++ b/languages/fix-plugin-does-not-exist-notices.pot @@ -0,0 +1,114 @@ +# Copyright (C) 2024 Marcus Quinn +# This file is distributed under the GPL-2.0+. +msgid "" +msgstr "" +"Project-Id-Version: Fix 'Plugin file does not exist.' Notices 1.6.0\n" +"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/fix-plugin-does-not-exist-notices\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"POT-Creation-Date: 2024-05-15T12:00:00+00:00\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"X-Generator: WP-CLI 2.8.1\n" +"X-Domain: fix-plugin-does-not-exist-notices\n" + +#. Plugin Name of the plugin +msgid "Fix 'Plugin file does not exist.' Notices" +msgstr "" + +#. Plugin URI of the plugin +msgid "https://wordpress.org/plugins/fix-plugin-does-not-exist-notices/" +msgstr "" + +#. Description of the plugin +msgid "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." +msgstr "" + +#. Author of the plugin +msgid "Marcus Quinn" +msgstr "" + +#. Author URI of the plugin +msgid "https://www.wpallstars.com" +msgstr "" + +#: fix-plugin-does-not-exist-notices.php:127 +msgid "Click here to scroll to missing plugins" +msgstr "" + +#: fix-plugin-does-not-exist-notices.php:128 +msgid "Plugin file missing" +msgstr "" + +#: fix-plugin-does-not-exist-notices.php:129 +#: fix-plugin-does-not-exist-notices.php:205 +msgid "Remove Reference" +msgstr "" + +#. translators: %s: Path to wp-content/plugins +#: fix-plugin-does-not-exist-notices.php:161 +msgid "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." +msgstr "" + +#: fix-plugin-does-not-exist-notices.php:164 +msgid "N/A" +msgstr "" + +#: fix-plugin-does-not-exist-notices.php:168 +msgid "Missing" +msgstr "" + +#. translators: %s: Plugin file path +#: fix-plugin-does-not-exist-notices.php:204 +msgid "Remove reference to missing plugin %s" +msgstr "" + +#: fix-plugin-does-not-exist-notices.php:227 +msgid "You do not have sufficient permissions to perform this action." +msgstr "" + +#: fix-plugin-does-not-exist-notices.php:233 +msgid "Invalid plugin specified." +msgstr "" + +#: fix-plugin-does-not-exist-notices.php:308 +msgid "Plugin reference removed successfully." +msgstr "" + +#: fix-plugin-does-not-exist-notices.php:316 +msgid "Failed to remove plugin reference. The plugin may already have been removed, or there was a database issue." +msgstr "" + +#: fix-plugin-does-not-exist-notices.php:331 +msgid "Fix Plugin Does Not Exist Notices" +msgstr "" + +#: fix-plugin-does-not-exist-notices.php:333 +msgid "Missing plugin files detected:" +msgstr "" + +#: fix-plugin-does-not-exist-notices.php:334 +msgid "The plugins listed below with a" +msgstr "" + +#: fix-plugin-does-not-exist-notices.php:335 +msgid "File Missing" +msgstr "" + +#: fix-plugin-does-not-exist-notices.php:336 +msgid "tag no longer exist but are still referenced in your database." +msgstr "" + +#: fix-plugin-does-not-exist-notices.php:339 +msgid "How to fix:" +msgstr "" + +#: fix-plugin-does-not-exist-notices.php:340 +msgid "Click the \"Remove Reference\" link next to each missing plugin to safely remove it from your active plugins list." +msgstr "" + +#: fix-plugin-does-not-exist-notices.php:342 +msgid "This will clean up your database and remove the error notifications." +msgstr "" diff --git a/readme.txt b/readme.txt index 666d86f..6f162e9 100644 --- a/readme.txt +++ b/readme.txt @@ -5,7 +5,7 @@ Tags: plugins, missing plugins, cleanup, error fix, admin tools, plugin file doe Requires at least: 5.0 Tested up to: 6.4 Requires PHP: 7.0 -Stable tag: 1.5.0 +Stable tag: 1.6.0 License: GPL-2.0+ License URI: https://www.gnu.org/licenses/gpl-2.0.html @@ -89,6 +89,13 @@ Although this plugin consumes minimal disk space, and doesn't run unless you are == Changelog == += 1.6.0 = +* Added full translation support with POT file +* Added JavaScript localization for better multilingual support +* Added plugin constants for improved code organization +* Updated code to follow WordPress internationalization best practices +* Improved asset loading with version constants + = 1.5.0 = * Improved compatibility with WordPress 6.4 * Enhanced error detection for plugin references @@ -161,6 +168,9 @@ Although this plugin consumes minimal disk space, and doesn't run unless you are == Upgrade Notice == += 1.6.0 = +Added full translation support! The plugin can now be translated into any language. + = 1.5.0 = Improved compatibility with WordPress 6.4 and accessibility enhancements for screen readers! -- 2.43.0 From 22d13ef8aa21ac3876416da67fcf1968fa1c7164 Mon Sep 17 00:00:00 2001 From: Marcus Quinn <6428977+marcusquinn@users.noreply.github.com> Date: Sat, 12 Apr 2025 00:03:10 +0100 Subject: [PATCH 5/7] Add Git Updater support with smart source detection --- .gitignore | 6 +- CHANGELOG.md | 2 + build.sh | 18 ++- composer.json | 21 ++++ fix-plugin-does-not-exist-notices.php | 16 +++ includes/Updater.php | 152 ++++++++++++++++++++++++++ readme.txt | 4 +- 7 files changed, 216 insertions(+), 3 deletions(-) create mode 100644 composer.json create mode 100644 includes/Updater.php diff --git a/.gitignore b/.gitignore index d95bd35..1d64fdb 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,10 @@ bower_components/ composer.lock package-lock.json +# Composer +vendor/ +composer.phar + # Build files build/ dist/ @@ -76,4 +80,4 @@ codecov.yml webpack.config.js gulpfile.js Gruntfile.js -*.zip \ No newline at end of file +*.zip \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 3dccf6a..d85e798 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,10 +7,12 @@ All notable changes to this project will be documented in this file. - Full translation support with POT file - JavaScript localization for better multilingual support - Plugin constants for improved code organization +- Git Updater support for updates from GitHub and Gitea ### Changed - Updated code to follow WordPress internationalization best practices - Improved asset loading with version constants +- Smart update detection based on installation source ## [1.5.0] - 2024-05-15 ### Added diff --git a/build.sh b/build.sh index 3f21f78..34fd1b0 100755 --- a/build.sh +++ b/build.sh @@ -18,6 +18,10 @@ ZIP_FILE="${PLUGIN_SLUG}-${VERSION}.zip" echo "Creating build directory..." mkdir -p $BUILD_DIR +# Install composer dependencies +echo "Installing composer dependencies..." +composer install --no-dev --optimize-autoloader + # Copy required files echo "Copying plugin files..." cp fix-plugin-does-not-exist-notices.php $BUILD_DIR/ @@ -25,6 +29,18 @@ cp readme.txt $BUILD_DIR/ cp LICENSE $BUILD_DIR/ cp README.md $BUILD_DIR/ cp CHANGELOG.md $BUILD_DIR/ +cp composer.json $BUILD_DIR/ + +# Copy directories +echo "Copying directories..." +mkdir -p $BUILD_DIR/includes +cp -r includes/* $BUILD_DIR/includes/ +mkdir -p $BUILD_DIR/languages +cp -r languages/* $BUILD_DIR/languages/ +mkdir -p $BUILD_DIR/assets +cp -r assets/* $BUILD_DIR/assets/ +mkdir -p $BUILD_DIR/vendor +cp -r vendor/* $BUILD_DIR/vendor/ # Create ZIP file echo "Creating ZIP file..." @@ -39,4 +55,4 @@ if [ -f "$ZIP_FILE" ]; then else echo "❌ Build failed: ZIP file was not created" exit 1 -fi \ No newline at end of file +fi \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..a37e57f --- /dev/null +++ b/composer.json @@ -0,0 +1,21 @@ +{ + "name": "wpallstars/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.", + "type": "wordpress-plugin", + "license": "GPL-2.0-or-later", + "authors": [ + { + "name": "Marcus Quinn", + "email": "6428977+marcusquinn@users.noreply.github.com" + } + ], + "require": { + "php": ">=7.0", + "afragen/git-updater-lite": "^1" + }, + "autoload": { + "psr-4": { + "WPAllStars\\FixPluginDoesNotExistNotices\\": "includes/" + } + } +} diff --git a/fix-plugin-does-not-exist-notices.php b/fix-plugin-does-not-exist-notices.php index 2253e7f..7c68295 100644 --- a/fix-plugin-does-not-exist-notices.php +++ b/fix-plugin-does-not-exist-notices.php @@ -9,6 +9,7 @@ * * @wordpress-plugin * Plugin Name: Fix 'Plugin file 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. * Version: 1.6.0 * Author: Marcus Quinn @@ -19,6 +20,10 @@ * Domain Path: /languages * Requires at least: 5.0 * Requires PHP: 7.0 + * GitHub Plugin URI: wpallstars/fix-plugin-does-not-exist-notices + * GitHub Branch: main + * Gitea Plugin URI: wpallstars/fix-plugin-does-not-exist-notices + * Gitea Branch: main * * This plugin is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -395,3 +400,14 @@ class Fix_Plugin_Does_Not_Exist_Notices { // Initialize the plugin class. new Fix_Plugin_Does_Not_Exist_Notices(); + +// Initialize the updater if composer autoload exists +$autoloader = __DIR__ . '/vendor/autoload.php'; +if (file_exists($autoloader)) { + require_once $autoloader; + + // Initialize the updater if the class exists + if (class_exists('\WPAllStars\FixPluginDoesNotExistNotices\Updater')) { + new \WPAllStars\FixPluginDoesNotExistNotices\Updater(__FILE__); + } +} diff --git a/includes/Updater.php b/includes/Updater.php new file mode 100644 index 0000000..655ac51 --- /dev/null +++ b/includes/Updater.php @@ -0,0 +1,152 @@ +plugin_file = $plugin_file; + $this->source = $this->determine_installation_source(); + $this->init(); + } + + /** + * Initialize the updater based on the installation source + * + * @return void + */ + public function init() { + // Only initialize Git Updater if not installed from WordPress.org + if ($this->source !== 'wordpress.org') { + $this->init_git_updater(); + } + } + + /** + * Determine the installation source of the plugin + * + * @return string Installation source: 'github', 'gitea', or 'wordpress.org' + */ + private function determine_installation_source() { + // Default to WordPress.org + $source = 'wordpress.org'; + + // Check if the plugin was installed from GitHub + if ($this->is_github_installation()) { + $source = 'github'; + } + // Check if the plugin was installed from Gitea + elseif ($this->is_gitea_installation()) { + $source = 'gitea'; + } + + return $source; + } + + /** + * Check if the plugin was installed from GitHub + * + * @return bool + */ + private function is_github_installation() { + // Check for GitHub-specific markers in the plugin directory + $plugin_dir = plugin_dir_path($this->plugin_file); + + // Look for .git directory with GitHub remote + if (file_exists($plugin_dir . '.git')) { + $git_config = @file_get_contents($plugin_dir . '.git/config'); + if ($git_config && strpos($git_config, 'github.com') !== false) { + return true; + } + } + + // Check for GitHub-specific files that might indicate it was downloaded from GitHub + if (file_exists($plugin_dir . '.github')) { + return true; + } + + return false; + } + + /** + * Check if the plugin was installed from Gitea + * + * @return bool + */ + private function is_gitea_installation() { + // Check for Gitea-specific markers in the plugin directory + $plugin_dir = plugin_dir_path($this->plugin_file); + + // Look for .git directory with Gitea remote + if (file_exists($plugin_dir . '.git')) { + $git_config = @file_get_contents($plugin_dir . '.git/config'); + if ($git_config && strpos($git_config, 'gitea.wpallstars.com') !== false) { + return true; + } + } + + return false; + } + + /** + * Initialize Git Updater Lite + * + * @return void + */ + private function init_git_updater() { + // Check if the Git Updater Lite class exists (composer autoload) + if (!class_exists('\\Fragen\\Git_Updater\\Lite')) { + // Try to include the autoloader + $autoloader = dirname($this->plugin_file) . '/vendor/autoload.php'; + if (file_exists($autoloader)) { + require_once $autoloader; + } else { + return; // Can't load Git Updater Lite + } + } + + // Set the update server based on the installation source + add_filter('gul_update_server', function() { + if ($this->source === 'github') { + return 'https://wpallstars.com'; // GitHub update server + } elseif ($this->source === 'gitea') { + return 'https://wpallstars.com'; // Gitea update server + } + return ''; + }); + + // Initialize Git Updater Lite + if (class_exists('\\Fragen\\Git_Updater\\Lite')) { + (new \Fragen\Git_Updater\Lite($this->plugin_file))->run(); + } + } +} diff --git a/readme.txt b/readme.txt index 6f162e9..c46860b 100644 --- a/readme.txt +++ b/readme.txt @@ -93,8 +93,10 @@ Although this plugin consumes minimal disk space, and doesn't run unless you are * Added full translation support with POT file * Added JavaScript localization for better multilingual support * Added plugin constants for improved code organization +* Added Git Updater support for updates from GitHub and Gitea * Updated code to follow WordPress internationalization best practices * Improved asset loading with version constants +* Added smart update detection based on installation source = 1.5.0 = * Improved compatibility with WordPress 6.4 @@ -169,7 +171,7 @@ Although this plugin consumes minimal disk space, and doesn't run unless you are == Upgrade Notice == = 1.6.0 = -Added full translation support! The plugin can now be translated into any language. +Added full translation support and Git Updater compatibility for direct updates from GitHub and Gitea! = 1.5.0 = Improved compatibility with WordPress 6.4 and accessibility enhancements for screen readers! -- 2.43.0 From 08616164e9f155154e56f07eeb2f5f3f104ba030 Mon Sep 17 00:00:00 2001 From: Marcus Quinn <6428977+marcusquinn@users.noreply.github.com> Date: Sat, 12 Apr 2025 00:09:55 +0100 Subject: [PATCH 6/7] Add AI assistant guide and workflow documentation --- .ai-assistant.md | 173 ++++++++++++++++++++ .github/ai-workflows/bug-fixing.md | 160 ++++++++++++++++++ .github/ai-workflows/code-review.md | 163 ++++++++++++++++++ .github/ai-workflows/feature-development.md | 130 +++++++++++++++ .github/ai-workflows/release-process.md | 173 ++++++++++++++++++++ 5 files changed, 799 insertions(+) create mode 100644 .ai-assistant.md create mode 100644 .github/ai-workflows/bug-fixing.md create mode 100644 .github/ai-workflows/code-review.md create mode 100644 .github/ai-workflows/feature-development.md create mode 100644 .github/ai-workflows/release-process.md diff --git a/.ai-assistant.md b/.ai-assistant.md new file mode 100644 index 0000000..5f7c8b2 --- /dev/null +++ b/.ai-assistant.md @@ -0,0 +1,173 @@ +# AI Assistant Guide for Fix Plugin Does Not Exist Notices + +This guide helps AI assistants understand the project structure, workflows, and best practices for this repository. + +## Project Overview + +- **Plugin Name**: Fix 'Plugin file does not exist.' Notices +- **Repository**: https://github.com/wpallstars/fix-plugin-does-not-exist-notices +- **Description**: WordPress plugin that adds missing plugins to the plugins list with a "Remove Reference" link to clean up invalid plugin entries and remove error notices. + +## Version Management + +### Version Numbering Convention + +We follow [Semantic Versioning](https://semver.org/): +- **MAJOR.MINOR.PATCH** (e.g., 1.6.0) + - **MAJOR**: Breaking changes + - **MINOR**: New features, non-breaking + - **PATCH**: Bug fixes, non-breaking + +### When to Increment Version Numbers + +- **PATCH** (1.6.0 → 1.6.1): + - Bug fixes + - Small text changes + - Minor improvements that don't add new features + +- **MINOR** (1.6.0 → 1.7.0): + - New features + - Significant improvements to existing functionality + - Deprecation of features (but not removal) + +- **MAJOR** (1.6.0 → 2.0.0): + - Breaking changes + - Removal of features + - Major architectural changes + +### Version Update Checklist + +When updating the version number, always update these files: +1. `fix-plugin-does-not-exist-notices.php` (Plugin header) +2. `CHANGELOG.md` (Add new version section) +3. `readme.txt` (Stable tag and Changelog section) +4. Update `FPDEN_VERSION` constant in the main plugin file + +## Git Workflow + +### Branch Naming Convention + +- Feature branches: `feature/descriptive-name` +- Bug fix branches: `fix/issue-description` +- Release branches: `v{MAJOR}.{MINOR}.{PATCH}` + +### Commit Message Guidelines + +- Use present tense ("Add feature" not "Added feature") +- Start with a verb +- Keep the first line under 50 characters +- Reference issues when relevant: "Fix #123: Resolve plugin detection issue" + +### Release Process + +1. Create a new branch for the version: `git checkout -b v{MAJOR}.{MINOR}.{PATCH}` +2. Update version numbers in all required files +3. Update CHANGELOG.md with all changes +4. Commit changes: `git commit -m "Prepare release v{MAJOR}.{MINOR}.{PATCH}"` +5. Push branch to all remotes: + ``` + git push github HEAD:v{MAJOR}.{MINOR}.{PATCH} + git push gitea HEAD:v{MAJOR}.{MINOR}.{PATCH} + ``` +6. Create and push a tag to trigger the GitHub Actions workflow: + ``` + git tag -a v{MAJOR}.{MINOR}.{PATCH} -m "Release version {MAJOR}.{MINOR}.{PATCH}" + git push github refs/tags/v{MAJOR}.{MINOR}.{PATCH} + git push gitea refs/tags/v{MAJOR}.{MINOR}.{PATCH} + ``` + +## Build Process + +The build process is handled by `build.sh`: +1. Updates version numbers +2. Installs composer dependencies +3. Copies files to build directory +4. Creates ZIP file + +To manually build the plugin: +``` +./build.sh {MAJOR}.{MINOR}.{PATCH} +``` + +## Remote Repositories + +The plugin is hosted on multiple repositories: +- GitHub: https://github.com/wpallstars/fix-plugin-does-not-exist-notices +- Gitea: https://gitea.wpallstars.com/wpallstars/fix-plugin-does-not-exist-notices +- WordPress.org: https://wordpress.org/plugins/fix-plugin-does-not-exist-notices/ + +Always push changes to all remotes to keep them in sync. + +## GitHub Actions + +The repository uses GitHub Actions for automated builds and deployments: +- Triggered by tags matching the pattern `v*` +- Builds the plugin +- Creates a GitHub release +- Deploys to WordPress.org + +## Testing Guidelines + +Before releasing: +1. Test with the latest WordPress version +2. Test with PHP 7.0+ (minimum supported version) +3. Verify all features work as expected +4. Check for any PHP warnings or notices + +## Common Tasks for AI Assistants + +### Creating a New Release + +``` +# 1. Create a new branch +git checkout -b v1.7.0 + +# 2. Update version numbers in files +# - fix-plugin-does-not-exist-notices.php +# - CHANGELOG.md +# - readme.txt +# - FPDEN_VERSION constant + +# 3. Commit changes +git add . +git commit -m "Prepare release v1.7.0" + +# 4. Push to remotes +git push github HEAD:v1.7.0 +git push gitea HEAD:v1.7.0 + +# 5. Create and push tag +git tag -a v1.7.0 -m "Release version 1.7.0" +git push github refs/tags/v1.7.0 +git push gitea refs/tags/v1.7.0 +``` + +### Adding a New Feature + +``` +# 1. Create feature branch +git checkout -b feature/new-feature-name + +# 2. Make changes and commit +git add . +git commit -m "Add new feature" + +# 3. Push to remotes +git push github HEAD:feature/new-feature-name +git push gitea HEAD:feature/new-feature-name +``` + +### Fixing a Bug + +``` +# 1. Create bugfix branch +git checkout -b fix/bug-description + +# 2. Make changes and commit +git add . +git commit -m "Fix #123: Fix bug description" + +# 3. Push to remotes +git push github HEAD:fix/bug-description +git push gitea HEAD:fix/bug-description +``` diff --git a/.github/ai-workflows/bug-fixing.md b/.github/ai-workflows/bug-fixing.md new file mode 100644 index 0000000..3c5a7be --- /dev/null +++ b/.github/ai-workflows/bug-fixing.md @@ -0,0 +1,160 @@ +# Bug Fixing Guide for AI Assistants + +This document provides guidance for AI assistants to help with bug fixing for the Fix Plugin Does Not Exist Notices plugin. + +## Bug Fixing Workflow + +### 1. Create a Bug Fix Branch + +Always start by creating a bug fix branch from the main branch: + +```bash +git checkout main +git pull github main +git checkout -b fix/bug-description +``` + +Use a descriptive name that clearly indicates what bug is being fixed. + +### 2. Understand the Bug + +Before fixing a bug, make sure you understand: + +- What is the expected behavior? +- What is the actual behavior? +- What are the steps to reproduce the bug? +- What is the impact of the bug? +- What is the root cause of the bug? + +### 3. Fix the Bug + +When fixing a bug: + +- Make minimal changes necessary to fix the bug +- Avoid introducing new features while fixing bugs +- Maintain backward compatibility +- Add appropriate comments explaining the fix +- Consider adding tests to prevent regression + +### 4. Update Documentation + +Update relevant documentation to reflect the bug fix: + +- Add a description to CHANGELOG.md under an "Unreleased" section +- Update readme.txt if the bug fix affects user-facing functionality + +### 5. Testing + +Test the bug fix thoroughly: + +- Verify that the bug is fixed +- Ensure no regression in related functionality +- Test with the latest WordPress version +- Test with the minimum supported WordPress version (5.0) +- Test with PHP 7.0+ (minimum supported version) + +### 6. Commit Changes + +Make atomic commits with clear messages: + +```bash +git add . +git commit -m "Fix #123: Brief description of the bug fix" +``` + +If there's an issue number, reference it in the commit message. + +### 7. Push to Remote + +Push the bug fix branch to the remote repositories: + +```bash +git push github HEAD:fix/bug-description +git push gitea HEAD:fix/bug-description +``` + +### 8. Create Pull Request (Optional) + +If the repository uses pull requests for code review, create a pull request from the bug fix branch to the main branch. + +## Determining Version Increment + +After fixing a bug, determine the appropriate version increment: + +- **PATCH** (e.g., 1.6.0 → 1.6.1): For most bug fixes that don't change functionality +- **MINOR** (e.g., 1.6.0 → 1.7.0): For bug fixes that introduce new features or significant changes +- **MAJOR** (e.g., 1.6.0 → 2.0.0): For bug fixes that introduce breaking changes + +## Hotfix Process + +For critical bugs that need immediate fixing in a released version: + +### 1. Create a Hotfix Branch + +```bash +git checkout v{MAJOR}.{MINOR}.{PATCH} +git checkout -b hotfix/v{MAJOR}.{MINOR}.{PATCH+1} +``` + +### 2. Fix the Bug + +Apply the minimal fix necessary to address the critical issue. + +### 3. Update Version Numbers + +Increment the PATCH version and update all version numbers: + +- Main plugin file (fix-plugin-does-not-exist-notices.php) +- FPDEN_VERSION constant +- CHANGELOG.md +- readme.txt + +### 4. Commit and Push + +```bash +git add . +git commit -m "Hotfix: Brief description of the critical bug fix" +git push github HEAD:hotfix/v{MAJOR}.{MINOR}.{PATCH+1} +git push gitea HEAD:hotfix/v{MAJOR}.{MINOR}.{PATCH+1} +``` + +### 5. Create and Push Tag + +```bash +git tag -a v{MAJOR}.{MINOR}.{PATCH+1} -m "Hotfix release version {MAJOR}.{MINOR}.{PATCH+1}" +git push github refs/tags/v{MAJOR}.{MINOR}.{PATCH+1} +git push gitea refs/tags/v{MAJOR}.{MINOR}.{PATCH+1} +``` + +## Common Bug Types and Fixing Strategies + +### WordPress Compatibility Issues + +- Test with the specific WordPress version where the issue occurs +- Check for deprecated functions or hooks +- Review WordPress changelog for relevant changes + +### PHP Compatibility Issues + +- Test with the specific PHP version where the issue occurs +- Check for deprecated PHP functions or features +- Use appropriate polyfills if necessary + +### JavaScript Issues + +- Test in different browsers +- Check for browser console errors +- Consider browser-specific workarounds if necessary + +### CSS Issues + +- Test in different browsers and screen sizes +- Use browser developer tools to inspect elements +- Consider browser-specific workarounds if necessary + +### Database Issues + +- Use proper database prefixing +- Sanitize database inputs +- Use prepared statements for queries +- Consider database version differences diff --git a/.github/ai-workflows/code-review.md b/.github/ai-workflows/code-review.md new file mode 100644 index 0000000..37c09f4 --- /dev/null +++ b/.github/ai-workflows/code-review.md @@ -0,0 +1,163 @@ +# Code Review Guide for AI Assistants + +This document provides guidance for AI assistants to help with code review for the Fix Plugin Does Not Exist Notices plugin. + +## Code Review Checklist + +When reviewing code, check for the following: + +### Functionality + +- [ ] Does the code work as expected? +- [ ] Does it handle edge cases appropriately? +- [ ] Are there any logical errors? +- [ ] Is error handling implemented properly? + +### Code Quality + +- [ ] Does the code follow WordPress coding standards? +- [ ] Is the code well-organized and easy to understand? +- [ ] Are there any code smells (duplicate code, overly complex functions, etc.)? +- [ ] Are functions and variables named appropriately? +- [ ] Are there appropriate comments and documentation? + +### Security + +- [ ] Is user input properly validated and sanitized? +- [ ] Is output properly escaped? +- [ ] Are capability checks used for user actions? +- [ ] Are nonces used for form submissions? +- [ ] Are there any potential SQL injection vulnerabilities? +- [ ] Are there any potential XSS vulnerabilities? + +### Performance + +- [ ] Are there any performance bottlenecks? +- [ ] Are database queries optimized? +- [ ] Is caching used appropriately? +- [ ] Are assets (CSS, JS) properly enqueued? + +### Compatibility + +- [ ] Is the code compatible with the minimum supported WordPress version (5.0)? +- [ ] Is the code compatible with the minimum supported PHP version (7.0)? +- [ ] Are there any browser compatibility issues? +- [ ] Are there any conflicts with other plugins? + +### Internationalization + +- [ ] Are all user-facing strings translatable? +- [ ] Is the correct text domain used? +- [ ] Are translation functions used correctly? + +### Accessibility + +- [ ] Does the code follow accessibility best practices? +- [ ] Are ARIA attributes used appropriately? +- [ ] Is keyboard navigation supported? +- [ ] Is screen reader support implemented? + +## Code Review Process + +### 1. Understand the Context + +Before reviewing code, understand: +- What problem is the code trying to solve? +- What are the requirements? +- What are the constraints? + +### 2. Review the Code + +Review the code with the checklist above in mind. + +### 3. Provide Feedback + +When providing feedback: +- Be specific and clear +- Explain why a change is needed +- Provide examples or suggestions when possible +- Prioritize feedback (critical issues vs. minor improvements) +- Be constructive and respectful + +### 4. Follow Up + +After the code has been updated: +- Review the changes +- Verify that issues have been addressed +- Provide additional feedback if necessary + +## Common Issues to Look For + +### PHP Issues + +- Undefined variables or functions +- Incorrect function parameters +- Missing return statements +- Improper error handling +- Inefficient loops or conditionals +- Hardcoded values that should be configurable + +### WordPress-Specific Issues + +- Incorrect hook usage +- Missing or incorrect nonces +- Missing capability checks +- Direct database queries instead of using WordPress functions +- Improper enqueuing of scripts and styles +- Not using WordPress functions for common tasks + +### JavaScript Issues + +- Undefined variables or functions +- Event listener memory leaks +- jQuery conflicts +- Browser compatibility issues +- Missing error handling + +### CSS Issues + +- Browser compatibility issues +- Specificity issues +- Unused styles +- Overriding WordPress admin styles inappropriately + +## Example Feedback + +### Good Feedback Example + +``` +In function `handle_remove_reference()`: + +1. The nonce check is missing, which could lead to CSRF vulnerabilities. + Consider adding: + ```php + if (!isset($_GET['_wpnonce']) || !wp_verify_nonce($_GET['_wpnonce'], 'fpden_remove_reference')) { + wp_die(__('Security check failed.', 'fix-plugin-does-not-exist-notices')); + } + ``` + +2. The user capability check should be more specific. Instead of: + ```php + if (!current_user_can('manage_options')) { + ``` + Consider using: + ```php + if (!current_user_can('activate_plugins')) { + ``` + This is more appropriate for the action being performed. + +3. The success message should be translatable: + ```php + // Change this: + add_settings_error('fpden', 'fpden_removed', 'Plugin reference removed successfully.', 'updated'); + + // To this: + add_settings_error('fpden', 'fpden_removed', __('Plugin reference removed successfully.', 'fix-plugin-does-not-exist-notices'), 'updated'); + ``` +``` + +### Poor Feedback Example + +``` +This code has security issues and doesn't follow best practices. Fix it. +``` diff --git a/.github/ai-workflows/feature-development.md b/.github/ai-workflows/feature-development.md new file mode 100644 index 0000000..8c7dc2a --- /dev/null +++ b/.github/ai-workflows/feature-development.md @@ -0,0 +1,130 @@ +# Feature Development Guide for AI Assistants + +This document provides guidance for AI assistants to help with feature development for the Fix Plugin Does Not Exist Notices plugin. + +## Feature Development Workflow + +### 1. Create a Feature Branch + +Always start by creating a feature branch from the main branch: + +```bash +git checkout main +git pull github main +git checkout -b feature/descriptive-name +``` + +Use a descriptive name that clearly indicates what the feature is about. + +### 2. Implement the Feature + +When implementing a new feature: + +- Follow WordPress coding standards +- Ensure all strings are translatable +- Add appropriate comments +- Consider performance implications +- Maintain backward compatibility + +### 3. Update Documentation + +Update relevant documentation to reflect the new feature: + +- Add a description to CHANGELOG.md under an "Unreleased" section +- Update readme.txt if the feature affects user-facing functionality +- Update inline documentation/comments + +### 4. Testing + +Test the feature thoroughly: + +- Test with the latest WordPress version +- Test with the minimum supported WordPress version (5.0) +- Test with PHP 7.0+ (minimum supported version) +- Test in different environments (if possible) + +### 5. Commit Changes + +Make atomic commits with clear messages: + +```bash +git add . +git commit -m "Add feature: descriptive name" +``` + +### 6. Push to Remote + +Push the feature branch to the remote repositories: + +```bash +git push github HEAD:feature/descriptive-name +git push gitea HEAD:feature/descriptive-name +``` + +### 7. Create Pull Request (Optional) + +If the repository uses pull requests for code review, create a pull request from the feature branch to the main branch. + +## Code Standards and Best Practices + +### PHP Coding Standards + +- Follow [WordPress PHP Coding Standards](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/php/) +- Use tabs for indentation, not spaces +- Use proper naming conventions: + - Class names: `Class_Name` + - Function names: `function_name` + - Variable names: `$variable_name` + +### JavaScript Coding Standards + +- Follow [WordPress JavaScript Coding Standards](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/javascript/) +- Use tabs for indentation, not spaces +- Use proper naming conventions: + - Function names: `functionName` + - Variable names: `variableName` + +### Internationalization (i18n) + +- Wrap all user-facing strings in appropriate translation functions: + - `__()` for simple strings + - `_e()` for echoed strings + - `esc_html__()` for escaped strings + - `esc_html_e()` for escaped and echoed strings +- Always use the plugin's text domain: `fix-plugin-does-not-exist-notices` + +### Security Best Practices + +- Validate and sanitize all input +- Escape all output +- Use nonces for form submissions +- Use capability checks for user actions + +## Feature Types and Implementation Guidelines + +### Admin Interface Features + +When adding features to the admin interface: + +- Use WordPress admin UI components for consistency +- Follow WordPress admin UI patterns +- Ensure accessibility compliance +- Add appropriate help text + +### Plugin Functionality Features + +When adding core functionality: + +- Ensure compatibility with WordPress hooks system +- Consider performance impact +- Maintain backward compatibility +- Add appropriate error handling + +### Integration Features + +When adding integration with other plugins or services: + +- Make integrations optional when possible +- Check if the integrated plugin/service is available before using it +- Provide fallback functionality when the integration is not available +- Document the integration requirements diff --git a/.github/ai-workflows/release-process.md b/.github/ai-workflows/release-process.md new file mode 100644 index 0000000..b91264c --- /dev/null +++ b/.github/ai-workflows/release-process.md @@ -0,0 +1,173 @@ +# Release Process for AI Assistants + +This document provides step-by-step instructions for AI assistants to help with the release process for the Fix Plugin Does Not Exist Notices plugin. + +## Pre-Release Checklist + +- [ ] All features for this release are complete +- [ ] All bug fixes for this release are complete +- [ ] CHANGELOG.md is up to date +- [ ] readme.txt is up to date +- [ ] All tests pass + +## Determining the New Version Number + +Based on the changes made, determine the appropriate version increment: + +1. **PATCH** (e.g., 1.6.0 → 1.6.1): For bug fixes and minor improvements +2. **MINOR** (e.g., 1.6.0 → 1.7.0): For new features and significant improvements +3. **MAJOR** (e.g., 1.6.0 → 2.0.0): For breaking changes + +## Release Steps + +### 1. Create a New Branch + +```bash +git checkout -b v{MAJOR}.{MINOR}.{PATCH} +``` + +Example: +```bash +git checkout -b v1.7.0 +``` + +### 2. Update Version Numbers + +Update the version number in the following files: + +#### a. Main Plugin File (fix-plugin-does-not-exist-notices.php) + +```php +/** + * Plugin Name: Fix 'Plugin file 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. + * Version: {MAJOR}.{MINOR}.{PATCH} + * ... + */ +``` + +Also update the FPDEN_VERSION constant: + +```php +define( 'FPDEN_VERSION', '{MAJOR}.{MINOR}.{PATCH}' ); +``` + +#### b. CHANGELOG.md + +Add a new section at the top of the CHANGELOG.md file: + +```markdown +## [{MAJOR}.{MINOR}.{PATCH}] - YYYY-MM-DD +### Added +- New feature 1 +- New feature 2 + +### Changed +- Change 1 +- Change 2 + +### Fixed +- Bug fix 1 +- Bug fix 2 +``` + +#### c. readme.txt + +Update the stable tag: + +``` +Stable tag: {MAJOR}.{MINOR}.{PATCH} +``` + +Add a new entry to the changelog section: + +``` += {MAJOR}.{MINOR}.{PATCH} = +* New feature 1 +* New feature 2 +* Change 1 +* Change 2 +* Fixed bug 1 +* Fixed bug 2 +``` + +Update the upgrade notice section: + +``` += {MAJOR}.{MINOR}.{PATCH} = +Brief description of the most important changes in this release +``` + +### 3. Commit Changes + +```bash +git add fix-plugin-does-not-exist-notices.php CHANGELOG.md readme.txt +git commit -m "Prepare release v{MAJOR}.{MINOR}.{PATCH}" +``` + +### 4. Push Branch to Remotes + +```bash +git push github HEAD:v{MAJOR}.{MINOR}.{PATCH} +git push gitea HEAD:v{MAJOR}.{MINOR}.{PATCH} +``` + +### 5. Create and Push Tag + +```bash +git tag -a v{MAJOR}.{MINOR}.{PATCH} -m "Release version {MAJOR}.{MINOR}.{PATCH}" +git push github refs/tags/v{MAJOR}.{MINOR}.{PATCH} +git push gitea refs/tags/v{MAJOR}.{MINOR}.{PATCH} +``` + +### 6. Monitor GitHub Actions + +Open the GitHub Actions page to monitor the build and deployment process: +https://github.com/wpallstars/fix-plugin-does-not-exist-notices/actions + +### 7. Verify Release + +- [ ] Check that the GitHub release was created successfully +- [ ] Verify that the plugin was deployed to WordPress.org +- [ ] Test the plugin from WordPress.org to ensure it works correctly + +## Rollback Procedure (If Needed) + +If issues are discovered after release: + +### 1. Create a Hotfix Branch + +```bash +git checkout v{MAJOR}.{MINOR}.{PATCH} +git checkout -b hotfix/v{MAJOR}.{MINOR}.{PATCH+1} +``` + +### 2. Fix the Issues + +Make the necessary changes to fix the issues. + +### 3. Update Version Numbers + +Increment the PATCH version and update all version numbers as described above. + +### 4. Commit and Push + +```bash +git add . +git commit -m "Fix issues in v{MAJOR}.{MINOR}.{PATCH}" +git push github HEAD:hotfix/v{MAJOR}.{MINOR}.{PATCH+1} +git push gitea HEAD:hotfix/v{MAJOR}.{MINOR}.{PATCH+1} +``` + +### 5. Create and Push Tag + +```bash +git tag -a v{MAJOR}.{MINOR}.{PATCH+1} -m "Hotfix release version {MAJOR}.{MINOR}.{PATCH+1}" +git push github refs/tags/v{MAJOR}.{MINOR}.{PATCH+1} +git push gitea refs/tags/v{MAJOR}.{MINOR}.{PATCH+1} +``` + +### 6. Monitor and Verify + +Follow steps 6 and 7 from the release process to monitor and verify the hotfix release. -- 2.43.0 From 91e1da9d0580399c6bfebcee2709123cc769e4fb Mon Sep 17 00:00:00 2001 From: Marcus Quinn <6428977+marcusquinn@users.noreply.github.com> Date: Sat, 12 Apr 2025 00:14:02 +0100 Subject: [PATCH 7/7] Prepare release v1.6.1 --- CHANGELOG.md | 8 ++++++++ fix-plugin-does-not-exist-notices.php | 4 ++-- readme.txt | 12 +++++++++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d85e798..5dac0f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to this project will be documented in this file. +## [1.6.1] - 2024-05-15 +### Added +- AI assistant guide and workflow documentation +- Detailed release process documentation +- Feature development guidelines +- Bug fixing procedures +- Code review standards + ## [1.6.0] - 2024-05-15 ### Added - Full translation support with POT file diff --git a/fix-plugin-does-not-exist-notices.php b/fix-plugin-does-not-exist-notices.php index 7c68295..b90d36f 100644 --- a/fix-plugin-does-not-exist-notices.php +++ b/fix-plugin-does-not-exist-notices.php @@ -11,7 +11,7 @@ * Plugin Name: Fix 'Plugin file 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. - * Version: 1.6.0 + * Version: 1.6.1 * Author: Marcus Quinn * Author URI: https://www.wpallstars.com * License: GPL-2.0+ @@ -45,7 +45,7 @@ if ( ! defined( 'ABSPATH' ) ) { } // Define plugin constants -define( 'FPDEN_VERSION', '1.6.0' ); +define( 'FPDEN_VERSION', '1.6.1' ); define( 'FPDEN_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); define( 'FPDEN_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); define( 'FPDEN_PLUGIN_FILE', __FILE__ ); diff --git a/readme.txt b/readme.txt index c46860b..3ed5fd1 100644 --- a/readme.txt +++ b/readme.txt @@ -5,7 +5,7 @@ Tags: plugins, missing plugins, cleanup, error fix, admin tools, plugin file doe Requires at least: 5.0 Tested up to: 6.4 Requires PHP: 7.0 -Stable tag: 1.6.0 +Stable tag: 1.6.1 License: GPL-2.0+ License URI: https://www.gnu.org/licenses/gpl-2.0.html @@ -89,6 +89,13 @@ Although this plugin consumes minimal disk space, and doesn't run unless you are == Changelog == += 1.6.1 = +* Added AI assistant guide and workflow documentation +* Added detailed release process documentation +* Added feature development guidelines +* Added bug fixing procedures +* Added code review standards + = 1.6.0 = * Added full translation support with POT file * Added JavaScript localization for better multilingual support @@ -170,6 +177,9 @@ Although this plugin consumes minimal disk space, and doesn't run unless you are == Upgrade Notice == += 1.6.1 = +Added comprehensive AI assistant guide and workflow documentation for improved development processes! + = 1.6.0 = Added full translation support and Git Updater compatibility for direct updates from GitHub and Gitea! -- 2.43.0