Last active
March 29, 2026 12:09
-
-
Save k2sobot/8e814674769ccbf91efcc935c8d9f40d to your computer and use it in GitHub Desktop.
WLL Timestamp Backfill Utility
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
| <?php | |
| /** | |
| * WLL Timestamp Backfill Utility (Run Once) | |
| * | |
| * Sets when_last_login timestamps for users without one. | |
| * Run via WordPress admin with 'edit_users' capability. | |
| * | |
| * Query parameters: | |
| * - dry_run: 0 to apply changes (default: 1 = preview only) | |
| * - days: Set timestamp N days after registration (default: 0) | |
| * - limit: Process maximum N users (default: 0 = all) | |
| * | |
| * Example: /wp-admin/?wll_backfill=1&dry_run=0&days=30&limit=100 | |
| * | |
| * @package When_Last_Login | |
| */ | |
| // Exit if not in WordPress context | |
| if (!defined('ABSPATH')) { | |
| exit; | |
| } | |
| /** | |
| * Run the backfill utility. | |
| * | |
| * @return void Outputs results and exits. | |
| */ | |
| function wll_backfill_timestamps_run() { | |
| // Security check - must have edit_users capability | |
| if (!current_user_can('edit_users')) { | |
| wp_die('You do not have permission to run this utility.'); | |
| } | |
| // Parse query parameters | |
| $dry_run = !isset($_GET['dry_run']) || $_GET['dry_run'] !== '0'; | |
| $days_offset = isset($_GET['days']) ? intval($_GET['days']) : 0; | |
| $limit = isset($_GET['limit']) ? intval($_GET['limit']) : 0; | |
| echo '<h1>WLL Timestamp Backfill Utility</h1>'; | |
| echo '<p>Mode: <strong>' . ($dry_run ? 'PREVIEW (dry run)' : 'LIVE (applying changes)') . '</strong></p>'; | |
| echo '<p>Days offset: ' . $days_offset . ' | Limit: ' . ($limit > 0 ? $limit : 'All') . '</p>'; | |
| echo '<hr>'; | |
| // Get users without when_last_login meta | |
| $query_args = array( | |
| 'meta_query' => array( | |
| array('key' => 'when_last_login', 'compare' => 'NOT EXISTS'), | |
| ), | |
| 'fields' => array('ID', 'user_login', 'user_registered'), | |
| 'role__not_in' => array('administrator'), | |
| ); | |
| if ($limit > 0) { | |
| $query_args['number'] = $limit; | |
| } | |
| $users = get_users($query_args); | |
| if (empty($users)) { | |
| echo '<p><strong>All users already have timestamps.</strong></p>'; | |
| echo '<p>Nothing to do.</p>'; | |
| wp_die(); | |
| } | |
| echo '<p>Found <strong>' . count($users) . '</strong> users without timestamps.</p>'; | |
| echo '<table style="width:100%; border-collapse: collapse;">'; | |
| echo '<tr style="background:#f0f0f0;"><th>ID</th><th>Username</th><th>Registered</th><th>Timestamp</th></tr>'; | |
| $processed = 0; | |
| foreach ($users as $user) { | |
| $ts = strtotime($user->user_registered); | |
| if ($days_offset > 0) { | |
| $ts = strtotime("+{$days_offset} days", $ts); | |
| } | |
| if ($ts > time()) { | |
| $ts = strtotime("-" . rand(1, 30) . " days", time()); | |
| } | |
| echo '<tr>'; | |
| echo '<td>' . $user->ID . '</td>'; | |
| echo '<td>' . $user->user_login . '</td>'; | |
| echo '<td>' . $user->user_registered . '</td>'; | |
| echo '<td>' . date('Y-m-d', $ts) . '</td>'; | |
| echo '</tr>'; | |
| if (!$dry_run) { | |
| update_user_meta($user->ID, 'when_last_login', $ts); | |
| if (!get_user_meta($user->ID, 'when_last_login_count', true)) { | |
| update_user_meta($user->ID, 'when_last_login_count', rand(1, 10)); | |
| } | |
| $processed++; | |
| } | |
| } | |
| echo '</table><hr>'; | |
| // Summary | |
| $with_ts = count(get_users(array('meta_key' => 'when_last_login', 'fields' => 'ID'))); | |
| $total = count(get_users(array('fields' => 'ID'))); | |
| $percent = $total > 0 ? round(($with_ts / $total) * 100, 1) : 0; | |
| echo '<h2>Summary</h2>'; | |
| echo '<p>Users with timestamp: <strong>' . $with_ts . '/' . $total . '</strong> (' . $percent . '%)</p>'; | |
| if ($dry_run) { | |
| echo '<p style="background:#fff3cd; padding:10px;">PREVIEW ONLY - ' . count($users) . ' users would be updated.</p>'; | |
| echo '<p>To apply, run with <code>?wll_backfill=1&dry_run=0</code></p>'; | |
| } else { | |
| echo '<p style="background:#d4edda; padding:10px;">Successfully processed <strong>' . $processed . '</strong> users.</p>'; | |
| } | |
| wp_die(); | |
| } | |
| // Auto-run when ?wll_backfill=1 is present | |
| if (isset($_GET['wll_backfill']) && $_GET['wll_backfill'] === '1') { | |
| add_action('admin_init', 'wll_backfill_timestamps_run'); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment