Feature: Cleanup plugin data on plugin uninstall - #692
Conversation
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #692 +/- ##
=============================================
- Coverage 80.41% 80.31% -0.11%
- Complexity 2565 2591 +26
=============================================
Files 110 111 +1
Lines 10437 10536 +99
=============================================
+ Hits 8393 8462 +69
- Misses 2044 2074 +30
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
dkotter
left a comment
There was a problem hiding this comment.
Left a few comments but otherwise looks good. Would be great to get the PR description updated as it still references an old approach
Sure would update that and will check the feedbacks! |
|
@dkotter, Here is the full plugin sweep to find all the metas that are owned and registered by the plugin. A complete audit of all meta the AI plugin registers or writes, grouped by object type, so we can decide what to remove on uninstall and what to leave alone. ✅ Post meta — owned by the plugin
✅ Comment meta — owned by the plugin
✅ User meta — owned by the plugin
Term meta — noneThe plugin registers/writes no term meta. It uses the ❌ Meta the plugin touches but does NOT own — do not remove
Note: Generated by claude code, Opus 4.8. Thanks, |
Thanks @hbhalodia for pulling this together, this is super helpful! The more I think about it, especially after looking through that list, I think likely fine to just leave all of that meta behind, other than maybe deleting And as you mention, all of that is associated with other objects that we aren't deleting (posts, attachments, comments) so seems like best to just leave that behind. And most of these are all fairly minimal amount of data so shouldn't cause any sort of database bloat if left. But let me know if you feel differently or have opinions based on what you've seen other plugins do, whether they leave meta behind or not. Thanks again for all the work here! |
Thanks for the update here! While it's hard to say what other plugins do, I feel like all the plugins have different scenarios to cover and they do differently. There is no any exact source of truth what needs to be done. Its the plugins choice what to do with there data, i.e., to either keep, to either delete, or to delete some part and keep some. I have a strong opinion here that, since we are not deleting the objects like for example a generated comment, or a generated image, deleting there meta would not be beneficial and may loose some key sources for identification, but still all those meta are part of AI plugin and removing them should not cause any disturbance to those objects, that would function as is. The above statement does not sounds a complete favour on either remove or keep. I am thinking to get an opinion here from more team members on what they feel should be good choice for uninstall, that is to remove the meta that are added by plugin or keep them as is. @jeffpaul @justlevine Also thinking to at least go with any one thing for now and we can iterate it on future based on the feedbacks we receive. Thanks, |
I would say let's just leave that meta behind and as you mention, can always update that in the future to be deleted if we get requests for that. But definitely open to second opinions here. |
Sure, I will wait for the 2nd Opinion before moving forward to remove the meta removal from the PR. It would be great if we have that earliest. 😅 |
|
I concur with Darin, so @hbhalodia please proceed with any further changes needed here... thanks! |
|
Thanks @jeffpaul, I would update the PR as needed. To confirm, we would be leaving the post,comment etc meta's behind and would only remove the options as a cleanup part as per discussions. |
|
Yes, let's see if community feedback wants to see more/less cleaned up and can iterate in a future release/PR as necessary |
…nd after deletion
…o clear the entire site cache. Ensure network transients are cleared properly. Ensure we delete our own secret values and only delete the master key if no other plugin is using it
What?
Closes #690
Why?
How?
Use of AI Tools
Testing Instructions
wpai_*options or check for tablewp_wpai_request_logs. This should not exists.Screenshots or screencast
Screen.Recording.2026-06-10.at.12.26.58.PM.mov
Changelog Entry
AI Summary
Summary
Implements full data cleanup when the plugin is deleted, addressing #690 (no
uninstall.php, custom table andwpai_*options left behind). Cleanup is opt-out and destructive, It always runs when uninstall, user can opt out using the filterwpai_remove_data_on_uninstall. Deletion happens on uninstall only — never on deactivation.Behavior
{$wpdb->prefix}wpai_request_logs.wpai_*options._transient_wpai_*/_transient_timeout_wpai_*and their site-transient equivalents).wpai_request_logs_cleanupcron event.get_sites()+switch_to_blog()), and the opt-in is evaluated per site so each site controls its own data.uninstall.php(the WordPress-recommended approach) rather thanregister_uninstall_hook(), keeping the logic out of the normal runtime path.wpai_remove_data_on_uninstall. If the filter returns false, the cleanup would not happen on deletion.Changes
Backend (PHP)
uninstall.php(new) — plugin-root uninstall entry point. Guards onWP_UNINSTALL_PLUGIN, loads only the autoloader (deliberately notai.php, to avoid bootstrappingMain), and callsUninstall::uninstall().includes/Admin/Uninstall.php(new) — the cleanup service:uninstall()— multisite-aware orchestration (loops sites; single-site otherwise).maybe_clean_current_site()— no-ops unlesswpai_remove_data_on_uninstallistruefor the current site.wpai_*options (viaesc_like+LIKE), deletes plugin transients, and clears the request-log cleanup cron.Tests
tests/Integration/Includes/Admin/UninstallTest.php(new):test_uninstall_removes_data_by_default— seeds the table +wpai_*options + a scheduled event, opts in, asserts all are removed and a non-wpai_option is preserved.test_uninstall_preserves_data_when_filtered_out— asserts data is untouched when the opt-out is enabled by filter.uninstall()since the bulkDELETEruns via direct SQL (irrelevant during a real uninstall request, but the in-requestalloptionscache would otherwise return stale values).Implementation notes
uninstall.phpperforms deletion, so deactivating remains fully reversible.LIKE 'wpai\_%'(escaped viaesc_like) so dynamic per-feature options (wpai_feature_{id}_enabled,wpai_feature_{id}_field_developer, etc.) are covered without enumerating them.Testing instructions
wpai_*options or check for tablewp_wpai_request_logs. This should not exists.