FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Feature: Cleanup plugin data on plugin uninstall by hbhalodia · Pull Request #692 · WordPress/ai · GitHub

/ ai Public

Feature: Cleanup plugin data on plugin uninstall - #692

Merged
dkotter merged 17 commits into
WordPress:developfrom
hbhalodia:feature/issue-690
Aug 11, 2026
Merged

Feature: Cleanup plugin data on plugin uninstall#692
dkotter merged 17 commits into
WordPress:developfrom
hbhalodia:feature/issue-690

Conversation

hbhalodia commented Jun 10, 2026
edited by github-actions Bot
Loading

Copy link
Copy Markdown
Contributor

What?

Closes #690

Why?

  • PR provides the way to cleanup the plugin data on uninstall. User's/Developers can opt it out using the filter.

How?

  • Adds uninstall.php file, Cleanup class to remove tables, options and cron schedules.

Use of AI Tools

  • Yes
  • Claude Code, Opus 4.8
  • Used for implementation. Implementation was reviewed and tested by me.

Testing Instructions

  1. Activate AI plugin.
  2. Go to Settings --> AI.
  3. Enable some settings.
  4. Uninstall the plugin via plugin list page.
  5. Open the database and check for wpai_* options or check for table wp_wpai_request_logs. This should not exists.

Screenshots or screencast

Screen.Recording.2026-06-10.at.12.26.58.PM.mov

Changelog Entry

Added - Cleanup plugin data on uninstall.


AI Summary

Summary

Implements full data cleanup when the plugin is deleted, addressing #690 (no uninstall.php, custom table and wpai_* options left behind). Cleanup is opt-out and destructive, It always runs when uninstall, user can opt out using the filter wpai_remove_data_on_uninstall . Deletion happens on uninstall only — never on deactivation.

Behavior

  • Deleting the plugin removes:
    • The custom table {$wpdb->prefix}wpai_request_logs.
    • All wpai_* options.
    • All plugin transients (_transient_wpai_* / _transient_timeout_wpai_* and their site-transient equivalents).
    • The scheduled wpai_request_logs_cleanup cron event.
  • Multisite: cleanup runs per-site (get_sites() + switch_to_blog()), and the opt-in is evaluated per site so each site controls its own data.
  • Cleanup runs from uninstall.php (the WordPress-recommended approach) rather than register_uninstall_hook(), keeping the logic out of the normal runtime path.
  • Developers/Users can opt out for cleanup using the filter 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 on WP_UNINSTALL_PLUGIN, loads only the autoloader (deliberately not ai.php, to avoid bootstrapping Main), and calls Uninstall::uninstall().
  • includes/Admin/Uninstall.php (new) — the cleanup service:
    • uninstall() — multisite-aware orchestration (loops sites; single-site otherwise).
    • maybe_clean_current_site() — no-ops unless wpai_remove_data_on_uninstall is true for the current site.
    • Drops the request-logs table, deletes wpai_* options (via esc_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.
    • Flushes the object cache after uninstall() since the bulk DELETE runs via direct SQL (irrelevant during a real uninstall request, but the in-request alloptions cache would otherwise return stale values).

Implementation notes

  • Deactivation is untouched — only uninstall.php performs deletion, so deactivating remains fully reversible.
  • Option sweep uses LIKE 'wpai\_%' (escaped via esc_like) so dynamic per-feature options (wpai_feature_{id}_enabled, wpai_feature_{id}_field_developer, etc.) are covered without enumerating them.

Testing instructions

  1. Activate AI plugin.
  2. Go to Settings --> AI.
  3. Enable some settings.
  4. Uninstall the plugin via plugin list page.
  5. Open the database and check for wpai_* options or check for table wp_wpai_request_logs. This should not exists.
  6. Run the integration tests:
    npm run wp-env:test start
    npm run test:php tests/Integration/Includes/Admin/UninstallTest.php

hbhalodia marked this pull request as ready for review June 10, 2026 07:00

github-actions Bot commented Jun 10, 2026
edited
Loading

Copy link
Copy Markdown

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 props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: hbhalodia <hbhalodia@git.wordpress.org>
Co-authored-by: dkotter <dkotter@git.wordpress.org>
Co-authored-by: jeffpaul <jeffpaul@git.wordpress.org>
Co-authored-by: miyanialkesh7 <alkesh7@git.wordpress.org>
Co-authored-by: itsgajendraSingh <gajendrasingh@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

jeffpaul modified the milestones: 1.1.0, 1.0.2 Jun 10, 2026
jeffpaul modified the milestones: 1.1.0, 1.2.0 Jun 26, 2026
hbhalodia requested a review from a team July 13, 2026 04:33

codecov Bot commented Jul 13, 2026
edited
Loading

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 72.91667% with 26 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.31%. Comparing base (3f6944e) to head (f0dddcd).
⚠️ Report is 5 commits behind head on develop.

Files with missing lines Patch % Lines
includes/Admin/Uninstall.php 72.91% 26 Missing ⚠️
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     
Flag Coverage Δ
unit 80.31% <72.91%> (-0.11%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

hbhalodia requested review from dkotter and jeffpaul July 13, 2026 06:15
jeffpaul mentioned this pull request Jul 13, 2026
28 tasks

dkotter left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Left a few comments but otherwise looks good. Would be great to get the PR description updated as it still references an old approach

Comment thread includes/Admin/Uninstall.php Outdated

Copy link
Copy Markdown
Contributor Author

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 modified the milestones: 1.2.0, 1.3.0 Jul 14, 2026
hbhalodia changed the title Feature: Cleanup plugin data on uninstall via user opt in Feature: Cleanup plugin data on plugin uninstall Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

@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

Meta key Type How registered/written Location
ai_generated_summary string, show_in_rest register_meta('post', …) includes/Experiments/Summarization/Summarization.php:90
ai_generated integer, show_in_rest (attachment) register_post_meta('attachment', …) includes/Features/Image_Generation/Image_Generation.php:135
wpai_meta_description string, show_in_rest register_post_meta(<public types>, …) — only when no SEO plugin is active (FALLBACK_META_KEY) includes/Experiments/Meta_Description/Meta_Description.php:106, includes/Abilities/Meta_Description/SEO_Integration.php:29

✅ Comment meta — owned by the plugin

Meta key Type How registered/written Location
ai_note boolean, show_in_rest register_meta('comment', …) includes/Experiments/Editorial_Notes/Editorial_Notes.php:60
_wpai_toxicity_score update_comment_meta (not registered) const: includes/Experiments/Comment_Moderation/Comment_Moderation.php:39; write: includes/Abilities/Comment_Moderation/Comment_Analysis.php:141
_wpai_sentiment update_comment_meta const: Comment_Moderation.php:46; write: Comment_Analysis.php:142
_wpai_analysis_status update_comment_meta const: Comment_Moderation.php:53; write: Comment_Analysis.php:129/136/143
_wpai_analyzed_at update_comment_meta const: Comment_Moderation.php:60; write: Comment_Analysis.php:144

✅ User meta — owned by the plugin

Meta key How written Location
wpai_connector_approval_notice_dismissed update_user_meta includes/Connector_Approval/Admin_Notice.php:28

Term meta — none

The plugin registers/writes no term meta. It uses the wp_guideline_type taxonomy and assigns categories via wp_set_object_terms, but those are Gutenberg/core-owned taxonomy relationships, not plugin term meta.


❌ Meta the plugin touches but does NOT own — do not remove

Meta key(s) Owner Plugin's involvement
_wp_attachment_image_alt WordPress core Alt-text generation writes it (includes/CLI/Alt_Text_Command.php:364)
_yoast_wpseo_metadesc, rank_math_description, _aioseo_description, _seopress_titles_desc Respective SEO plugins Meta Description writes into the active SEO plugin's key (includes/Abilities/Meta_Description/SEO_Integration.php:41-54)
_guideline_copy, _guideline_images, _guideline_site, _guideline_additional, _guideline_block_* Gutenberg (wp_guideline CPT) Guidelines service only reads them (includes/Services/Guidelines.php:88-92, 200); never registered or written by this plugin

Note: Generated by claude code, Opus 4.8.

Thanks,

dkotter commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Here is the full plugin sweep to find all the metas that are owned and registered by the plugin

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 wpai_connector_approval_notice_dismissed. While it's unlikely any of that data will be needed/used after the AI plugin is removed, there may be scenarios where a site still wants it.

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!

Copy link
Copy Markdown
Contributor Author

Here is the full plugin sweep to find all the metas that are owned and registered by the plugin

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 wpai_connector_approval_notice_dismissed. While it's unlikely any of that data will be needed/used after the AI plugin is removed, there may be scenarios where a site still wants it.

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,

dkotter commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

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 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.

Copy link
Copy Markdown
Contributor Author

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 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. 😅

Copy link
Copy Markdown
Member

I concur with Darin, so @hbhalodia please proceed with any further changes needed here... thanks!

Copy link
Copy Markdown
Contributor Author

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.

Copy link
Copy Markdown
Member

Yes, let's see if community feedback wants to see more/less cleaned up and can iterate in a future release/PR as necessary

hbhalodia requested a review from dkotter August 10, 2026 15:37

Copy link
Copy Markdown
Contributor Author

Hi @jeffpaul @dkotter, This is now ready to be reviewed again. Updates,

  1. Removed post, comment meta from the cleanup process.
  2. Updated the test to ensure everything works as expected.

Thanks,

jeffpaul left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Will defer to @dkotter's review before merging

jeffpaul mentioned this pull request Aug 10, 2026
48 tasks
…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
dkotter merged commit a1df313 into WordPress:develop Aug 11, 2026
22 of 24 checks passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Plugin does not clean up database table and options on uninstall

4 participants


Back | FazBrowse Home | New Git URL