Files
MokoSuiteBackup/CHANGELOG.md
T
jmiller 8cfa46d985
Universal: PR Check / Wiki Update Reminder (pull_request) Has been skipped
Universal: PR Check / Require Docs Update (pull_request) Has been skipped
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Universal: PR Check / Secret Scan (pull_request) Successful in 7s
Generic: Project CI / Lint & Validate (pull_request) Successful in 12s
Universal: PR Check / Validate PR (pull_request) Failing after 13s
Joomla: Metadata Validation / Validate Joomla Metadata (pull_request) Successful in 49s
Generic: Project CI / Tests (pull_request) Has been cancelled
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Universal: PR Check / Report Issues (pull_request) Has been cancelled
feat: full-screen backup screen for pre-update + Backup Now (Akeeba-style)
Replace the popup-modal pre-update approach with a dedicated full-page
backup screen, modelled on Akeeba Backup-on-Update, and fix the white
screen caused by running a backup synchronously inside the update request.

- New view=runbackup (View/Runbackup + tmpl/runbackup): full-screen
  progress page that auto-starts the stepped backup (ajax.init -> loop
  ajax.step), then redirects to a validated returnurl on completion or
  shows a completion/retry panel. Auto-resolved by MVCFactory.
- System plugin: on com_joomlaupdate task=update.install (when
  backup_before_update is on), redirect to the full-screen backup screen
  with returnurl back to update.install&is_backed_up=1; on return, arm the
  throttle so onExtensionBeforeUpdate does not run a duplicate backup. No
  synchronous backup in the update request.
- Dashboard 'Backup Now' navigates to the full-screen screen instead of
  the inline modal; the inline modal + stepped JS are removed.
- Retire the popup modal: delete media/js/update-backup.js, remove the
  plugin <media> element and the preupdate_auto_intercept param.
- Dashboard: warn when Global Config live_site is empty (CLI/scheduled
  backup naming + URL generation depend on it).

Refs #196

Claude-Session: https://claude.ai/code/session_01WbGBN9VyRK61zczYWcCQ2i
2026-07-05 22:55:28 -05:00

7.9 KiB

Changelog

[Unreleased]

Added

  • Full-screen backup screen (view=runbackup) for both pre-update and manual backups, modelled on Akeeba's Backup-on-Update — replaces the earlier popup-modal approach. Clicking Joomla's Install the update now redirects (server-side, Akeeba-style) to a dedicated full-page backup screen that runs the stepped backup with a real progress bar and then automatically continues the update via a validated returnurl (flagged is_backed_up=1 so the backup isn't repeated). Crucially, no backup runs synchronously inside the update request — which is what white-screened large sites. The dashboard Backup Now now opens the same full-screen screen instead of an inline modal. (#196)
  • Retention now prunes remote copies too: when a backup is pruned by age/count, its archive is deleted from every enabled remote destination (SFTP / FTP / S3 / Google Drive), not just the local copy. Each uploader gained an idempotent delete() method (already-absent file = success), and removal is best-effort — a failing destination is logged but never blocks local pruning. The shared standalone restore.php is intentionally left in place (every backup overwrites it, so newer backups still depend on it). (#229)

Changed

  • Consolidated backup plumbing into shared helpers (#230):
    • New RemoteUploaderFactory replaces the createUploaderFromParams() copy that was duplicated in BackupEngine and SteppedBackupEngine.
    • RetentionManager is now the single retention authority — it takes the global max_age_days/max_backups fallback and gained pruneOrphans(); the system plugin's hourly cleanup delegates to it and its duplicate deleteBackupRecord() logic is removed.
    • The backend controller, Web Services API controller, and legacy cli/mokosuitebackup.php now run backups through the shared BackupRunner (gaining the normalized complete/warning/fail status) instead of instantiating BackupEngine directly.

Fixed

  • Pre-update/uninstall backup no longer white-screens the update on large sites. The synchronous backup that runs inside the extension update/uninstall request now raises max_execution_time/memory_limit (and ignore_user_abort) like the web-cron path, so it can't exhaust the request's default limits mid-backup. (Core Joomla updates additionally get a full-screen backup screen — see below.)
  • Archive names for CLI/console-triggered backups no longer come out as joomla.invalid_…. The [HOST] placeholder took $_SERVER['HTTP_HOST'] verbatim, but Joomla's console fills that with the reserved sentinel host joomla.invalid; the resolver now treats that (like empty/localhost) as unusable and falls back to the configured live_site host, then the system hostname. (Set the site's live_site to get the exact domain in CLI-built names.)
  • Standalone restore script generation no longer aborts backups with str_replace() expects at least 3 arguments, 2 given. MokoRestore::generateStandaloneScript() had a str_replace() call (the "Backup Archive" pre-check rewrite) that was missing its $php subject argument, so every standalone-mode backup fatally errored while "Generating standalone restore.php…" — the archive still finalized and uploaded, but no restore.php was ever produced (the true root cause behind #226). (#226)
  • Remote upload: the standalone restore script upload is no longer silent — its result is now checked and logged, and a failed restore-script upload marks the backup as warning (previously the result was discarded, so a missing restore script on the remote went unreported while the archive still showed success). (#226)

[02.58.00] --- 2026-07-06

Added

  • SFTP destinations: upload an SSH private key file in the Add/Edit Destination modal instead of pasting it (reads the file into the key field client-side; pasting still works).

Changed

  • Add/Edit Destination modal: wrap the content in a Bootstrap .container-fluid and give it a 1rem padding frame via the WAM stylesheet (Bootstrap's .modal-content has no padding of its own).

Fixed

  • Pre-update backup now shows an admin notification on every outcome (success / warning / failure) — previously a successful pre-update backup fired nothing, so it looked like the notification wasn't working. (#192)

Changed

  • Component admin CSS now loads via the Joomla Web Asset Manager (media/com_mokosuitebackup/ + joomla.asset.json) instead of an inline <style> block.
  • "Keep local copy" is configured per remote destination (in the Add/Edit Destination modal); the redundant profile-level field and its "Remote" tab are removed.
  • Add/Edit Destination modal: cleaned up the cramped padding/margins.

Fixed

  • Admin menu / duplicate-component fallout: (a) the orphaned com_component-mokosuitebackup is now removed in preflight too, so its "Backup" menu no longer collides on install ("The alias backup is already being used"); (b) ensureSubmenuItems() recreates the top-level "Backup" menu if it was deleted, instead of giving up — so Backup no longer disappears from the admin menu (and the cPanel module / MokoSuiteClient can find it again); (c) the component menu label now uses the short constant COM_MOKOJOOMBACKUP_SHORT. (#213 fallout)
  • Installer no longer aborts on MySQL 8 with "This command is not supported in the prepared statement protocol yet" (error 1295). The legacy remote-column purge migration (02.56.01.sql) used PREPARE/EXECUTE/DEALLOCATE, which Joomla's installer rejects; the drop now runs in the package installer script via an INFORMATION_SCHEMA-gated plain ALTER (portable across MariaDB and MySQL 8). (#213 update path)

[02.57.00] --- 2026-07-05

Added

  • BackupRunner service — a single synchronous entry point for backups that unifies final status and notification gating across the pre-update, web-cron, pre-install, scheduled-task and CLI triggers (delegates to BackupEngine; no double-notify). Returns a normalized result including the real complete/warning/fail status. Dashboard "Backup Now" (AJAX) unchanged; installer progress popup deferred to #196. (#214)

Fixed

  • Release automation: the changelog-promote step is now idempotent — it only inserts a ## [version] header when that version isn't already present, preventing the empty, duplicated version headers that repeated/same-version builds were producing. (workflow)

[02.56.11] --- 2026-07-05

Fixed

  • Package postflight now removes the orphaned com_component-mokosuitebackup registration (stray extension record, admin menu items, schema rows, and administrator/ folder) left behind by the old "Type - Name" component <name> — self-healing on update so affected sites reconcile to the real com_mokosuitebackup. (#213 follow-up)

[02.56.08] --- 2026-07-05

Fixed

  • Component manifest <name> reverted to the element-safe MokoSuiteBackup. The "Type - Name" convention derived element com_component-mokosuitebackup, registering a duplicate component and leaving the real com_mokosuitebackup orphaned on the old version. (#213)

[02.56.07] --- 2026-07-05

Security

  • Mask the FTP password in AjaxController::maskSecrets()/mergeExistingSecrets() — stored FTP remotes no longer leak their password via listRemotes. (#169)
  • Stop the API single-item view (Backups/JsonapiView) leaking the server absolute_path. (#187)
  • SFTP uploader uses StrictHostKeyChecking=accept-new instead of no. (#182)

Fixed

  • DatabaseDumper writes a real newline after DROP TABLE (was a literal \n). (#179)
  • Profile-picker forms order by id instead of the dropped ordering column. (#180)
  • uninstall.mysql.sql now drops the snapshots table. (#181)
  • CLI snapshot delete uses the data_file column (was non-existent file_path). (#184)
  • Remove the duplicate pre-update backup (content plugin no longer subscribes to onExtensionBeforeUpdate). (#186)
  • DatabaseImporter collects non-fatal statement errors (getErrors()/hasErrors()). (#188)