Skip to content

Privacy: Schedule _wp_personal_data_cleanup_requests() on WP-Cron and fix timezone bug in expiry query#11444

Open
masteradhoc wants to merge 3 commits intoWordPress:trunkfrom
masteradhoc:44498-wp_personal_data_cleanup_requests-cron
Open

Privacy: Schedule _wp_personal_data_cleanup_requests() on WP-Cron and fix timezone bug in expiry query#11444
masteradhoc wants to merge 3 commits intoWordPress:trunkfrom
masteradhoc:44498-wp_personal_data_cleanup_requests-cron

Conversation

@masteradhoc
Copy link
Copy Markdown

@masteradhoc masteradhoc commented Apr 5, 2026

Trac ticket: https://core.trac.wordpress.org/ticket/44498

What

Adds a WP-Cron schedule for _wp_personal_data_cleanup_requests() so
that expired, unconfirmed privacy requests are cleaned up automatically
— not only when an admin visits the Export or Erase Personal Data pages.

Also fixes a pre-existing timezone bug in the expiry query that caused
requests to fail immediately on sites in UTC+ timezones.

Changes

wp-includes/functions.php

  • wp_schedule_personal_data_cleanup_requests() — registers an hourly
    cron event, matching the pattern of
    wp_schedule_delete_old_privacy_export_files().
  • wp_cron_personal_data_cleanup_requests() — cron callback that
    requires wp-admin/includes/privacy-tools.php before calling
    _wp_personal_data_cleanup_requests(), since that file is not loaded
    in a cron request context.

wp-includes/default-filters.php

  • Hooks both new functions into init and the cron event, following
    the same pattern as the existing export-file cleanup hooks.

wp-admin/includes/privacy-tools.php

  • Changes the date_query column from post_modified_gmt to
    post_modified. WP_Date_Query::build_mysql_datetime() resolves
    relative strings like "86400 seconds ago" using the site's local
    timezone and returns a local-time string. Comparing that against
    post_modified_gmt (UTC) produced the wrong threshold for any site
    not on UTC — immediate failure on UTC+ sites, over-long expiry on
    UTC- sites. Using post_modified (local time) makes both sides of
    the comparison consistent.

Backward compatibility

The direct calls to _wp_personal_data_cleanup_requests() in
export-personal-data.php and erase-personal-data.php are unchanged
and continue to serve as a synchronous fallback on admin page visits.

Trac ticket: https://core.trac.wordpress.org/ticket/44498

Use of AI Tools

AI assistance: Yes
Tool(s): Claude
Model(s): Sonnet 4.6
Used for: Code review and manual test suggestions to test extensively; final implementation were reviewed and fully tested by me.


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 5, 2026

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.

Core Committers: Use this line as a base for the props when committing in SVN:

Props masteradhoc.

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

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 5, 2026

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

}

if ( ! wp_next_scheduled( 'wp_privacy_personal_data_cleanup_requests' ) ) {
wp_schedule_event( time(), 'hourly', 'wp_privacy_personal_data_cleanup_requests' );
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.

What is intention for running the cron every hours?

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.

2 participants