options, array(), array('wpcbr_tick_lock_', '_transient_wpcbr_', '_transient_timeout_wpcbr_'), 'out:uninstall_bookkeeping'); // docs/recovery-design-v3.md 7章 G: how the restore record reads decides everything below. // - unreadable: nothing of a restore is deleted (kept copies, inventory, wpcbrb_ tables, the // database's record, the watcher) — a person decides (HOW-TO-RECOVER.txt); // - preparing: dropped with its work (it holds an extracted copy of the database); // - committing: settled (put back, or finished); // - committed: kept (the watcher goes on; "Everything is fine" or 7 days) — with "delete // everything" it is the person's "Everything is fine" (checked first; the watcher // finishes the deleting through WP-Cron); // - any later state: kept, the watcher goes on; // - no record, but this site's database copy of an earlier restore (D3): kept with its // record and the watcher (a person decides on the KiraBackup screen); // - a 1.1 roll-back under way (wpcbr-tmp/legacy-undo.json): kept. $wpcbr_state = WPCBR_Recovery::read_state(); if ('valid' === $wpcbr_state['read']) { WPCBR_Recovery::settle(null, true); $wpcbr_journal = WPCBR_Recovery::read(); if (null !== $wpcbr_journal && 'preparing' === $wpcbr_journal['state']) { WPCBR_Recovery::abandon(); $wpcbr_journal = WPCBR_Recovery::read(); } if (null !== $wpcbr_journal && in_array($wpcbr_journal['state'], array('committed', 'requested_keep'), true) && $wpcbr_delete_data) { WPCBR_Recovery::confirm(10, 'uninstall'); } } $wpcbr_pending = WPCBR_Recovery::exists() || null !== WPCBR_Recovery::orphan_record() || WPCBR_Recovery::legacy_pending(); if (! $wpcbr_pending) { WPCBR_Recovery::remove_watcher(); // What versions before 1.2 left in wpcbr-tmp, then the empty work folders only: a set-aside // copy (journal.foreign.json) and the leftover-… folders are a person's to delete (Codex 4・7章 E). wpcbr_uninstall_clean_dir(WPCBR_Recovery::root(), array('wpcbr-restore-*', 'trash-*'), '9c:uninstall'); WPCBR_Recovery::remove_empty_base(); } // Imported tables that never went live (行9c: the ones this site's record names — never by // the shape of a name, QA 2026-10-09 N1). The tables of a 1.1 // restore point only when everything is to be deleted (行16) — never another site's in the // same database, never the kept tables of a record of this version. require_once __DIR__ . '/includes/class-wpcbr-migration-helper.php'; require_once __DIR__ . '/includes/class-wpcbr-backup-service.php'; require_once __DIR__ . '/includes/class-wpcbr-restore-service.php'; $wpcbr_restore = new WPCBR_Restore_Service(); if (! $wpcbr_pending) { $wpcbr_restore->cleanup_orphan_tables(); // While a record is there, its tables are decided by it. } $wpcbr_legacy_gone = false; if (! $wpcbr_pending && $wpcbr_delete_data) { $wpcbr_legacy_gone = $wpcbr_restore->drop_own_point_tables(); } if (! $wpcbr_delete_data) { return; } // Backups, upload staging. What the owner put into the imports folder (a ZIP by FTP, whatever // its name) is never deleted: only KiraBackup's own staged copies, upload parts and protection // files go; the folder stays while anything else is in it (QA 2026-10-09 L3). $wpcbr_backup_dir = defined('WPCBR_BACKUP_DIR') && '' !== (string) WPCBR_BACKUP_DIR ? untrailingslashit((string) WPCBR_BACKUP_DIR) : WPCBR_Recovery_Gate::wp_dir('content') . '/' . (string) get_option('wpcbr_backup_dir_name', 'wpcbr-backups'); $wpcbr_own_files = array('wpcbr-backup-*', 'tmp-*', 'index.php', '.htaccess', 'web.config'); $wpcbr_staged = array('staged-????????????????.zip', 'staged-????????????????.ref', 'parts-*', 'index.php', 'web.config', '.htaccess'); if (WPCBR_Backup_Service::shared_backup_dir()) { // A folder set with WPCBR_BACKUP_DIR may be shared with other sites: their backups, running // work and staged restores have the same shapes of names. Only what this site's record names // goes (QA 2026-10-09 N1); its backups stay in that folder (the settings tab says so). ( new WPCBR_Backup_Service() )->cleanup_unfinished(); } else { wpcbr_uninstall_clean_dir($wpcbr_backup_dir . '/imports', $wpcbr_staged); wpcbr_uninstall_clean_dir($wpcbr_backup_dir, $wpcbr_own_files); } // The 1.1 folders in this site's wp-content — unless the shared folder is one of them (Codex 9回目). $wpcbr_shared_real = WPCBR_Backup_Service::shared_backup_dir() ? realpath($wpcbr_backup_dir) : false; foreach (array('/wpcbr-backups' => $wpcbr_own_files, '/wpcbr-imports' => $wpcbr_staged) as $wpcbr_legacy => $wpcbr_patterns) { $wpcbr_legacy_real = realpath(WPCBR_Recovery_Gate::wp_dir('content') . $wpcbr_legacy); if (false !== $wpcbr_legacy_real && false !== $wpcbr_shared_real && 0 === strpos(wp_normalize_path($wpcbr_shared_real) . '/', wp_normalize_path($wpcbr_legacy_real) . '/')) { continue; } wpcbr_uninstall_clean_dir(WPCBR_Recovery_Gate::wp_dir('content') . $wpcbr_legacy, $wpcbr_patterns); } // The database's record only when it is of version 1.1 and its tables are gone (a record of // this version stays with its tables — D3). // It is under 1.1's name (this plugin's own, 18回目〜, is wpcbr_kb_point). if (! $wpcbr_pending && $wpcbr_legacy_gone && ! WPCBR_Recovery::is_v3_record(WPCBR_Recovery::db_record()) && null !== WPCBR_Recovery::legacy_record()) { WPCBR_Recovery_Gate::write_legacy_record(null, '16:uninstall'); } delete_option('wpcbr_backup_dir_name');