7a0636606e
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 18s
Extend the full-screen backup screen beyond core Joomla updates: - Extension updates/uninstalls (com_installer): update.update and manage.remove are POST + checkToken with a checked cid[] list, so a server-side GET redirect can't resume them. New client-side interceptor (installer-backup.js, injected via onBeforeCompileHead on the update and manage views) wraps Joomla.submitbutton, stores the selection, sends the browser to view=runbackup, and on return restores the selection and re-submits the real POST form. Gated by backup_before_update / backup_before_uninstall, super-user only, skipped within the throttle window. - runbackup: on manual 'Backup Now' completion, show a 'View backup record' button (links to view=backup&id=<record_id>); not shown for the pre-update/uninstall flow (which hands back to Joomla). SteppedBackup Engine now returns record_id in its step result. - runbackup arms the pre-action throttles on success (ajax.preupdateAck, now arming both update+uninstall keys) so the following server-side onExtensionBefore(Update|Uninstall) backup is skipped (no duplicate). - Plugin manifest re-registers media/js. NOTE: untested end-to-end (no dev build available this session) — verify the com_installer resume flow on a dev build before relying on it. Claude-Session: https://claude.ai/code/session_01WbGBN9VyRK61zczYWcCQ2i
10 KiB
10 KiB
Changelog
[Unreleased]
Added
- Full-screen backup now also fronts extension updates and uninstalls (Extensions → Update / Manage), not just core Joomla updates. Because
com_installer'supdate.update/manage.removeare POST actions (CSRF token + a checkedcid[]list) that a server-side redirect can't cleanly resume, this is done client-side: the toolbar Update/Uninstall click is intercepted, the selection is captured, the full-screen backup runs, and on return the original selection is restored and the real POST form is re-submitted. Gated bybackup_before_update/backup_before_uninstall, super-user only, and skipped if a backup already ran this session. - Manual "Backup Now" completion now offers a View backup record button (links straight to the record that was just created). It appears only for manual backups — the pre-update / pre-uninstall flow hands control back to Joomla instead.
- 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 validatedreturnurl(flaggedis_backed_up=1so 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 standalonerestore.phpis 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
RemoteUploaderFactoryreplaces thecreateUploaderFromParams()copy that was duplicated inBackupEngineandSteppedBackupEngine. RetentionManageris now the single retention authority — it takes the globalmax_age_days/max_backupsfallback and gainedpruneOrphans(); the system plugin's hourly cleanup delegates to it and its duplicatedeleteBackupRecord()logic is removed.- The backend controller, Web Services API controller, and legacy
cli/mokosuitebackup.phpnow run backups through the sharedBackupRunner(gaining the normalized complete/warning/fail status) instead of instantiatingBackupEnginedirectly.
- New
Fixed
- Package installer is now honest about success: the postflight no longer prints "installed successfully" / next-steps when the install actually failed or only partially completed. Joomla logs a failed child extension but still runs the package postflight, so the postflight now (a) verifies every bundled child declared in the manifest actually registered in
#__extensions(matched by element + type, and folder/group for plugins) and (b) verifies the component's schema tables — derived dynamically from the installedinstall.mysql.sql— actually exist. If anything is missing it enqueues an error listing what's missing and stops before the success message. Fail-open: any manifest/DB/IO glitch is treated as "nothing missing" so a transient error never turns a good install into a false failure. Unconditional housekeeping (e.g. download-key restore) still runs regardless. - Pre-update full-screen backup screen now actually triggers on Joomla 6 (and 4/5). The redirect matched only the legacy
update.installtask, which Joomla 4/5/6 don't use — they server-side-redirect to the updating pageview=update, which then extracts the downloaded package from JavaScript. The plugin now intercepts theview=updatepage load (the last point before any files change) and returns the browser there flaggedis_backed_up=1so the extraction proceeds after the backup. (update.finaliseis intentionally not intercepted — by then the files are already extracted.) - 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(andignore_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 hostjoomla.invalid; the resolver now treats that (like empty/localhost) as unusable and falls back to the configuredlive_sitehost, 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 astr_replace()call (the "Backup Archive" pre-check rewrite) that was missing its$phpsubject argument, so every standalone-mode backup fatally errored while "Generating standalone restore.php…" — the archive still finalized and uploaded, but norestore.phpwas 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-fluidand give it a 1rem padding frame via the WAM stylesheet (Bootstrap's.modal-contenthas 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-mokosuitebackupis 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 constantCOM_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) usedPREPARE/EXECUTE/DEALLOCATE, which Joomla's installer rejects; the drop now runs in the package installer script via an INFORMATION_SCHEMA-gated plainALTER(portable across MariaDB and MySQL 8). (#213 update path)
[02.57.00] --- 2026-07-05
Added
BackupRunnerservice — 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 toBackupEngine; 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
postflightnow removes the orphanedcom_component-mokosuitebackupregistration (stray extension record, admin menu items, schema rows, andadministrator/folder) left behind by the old "Type - Name" component<name>— self-healing on update so affected sites reconcile to the realcom_mokosuitebackup. (#213 follow-up)
[02.56.08] --- 2026-07-05
Fixed
- Component manifest
<name>reverted to the element-safeMokoSuiteBackup. The "Type - Name" convention derived elementcom_component-mokosuitebackup, registering a duplicate component and leaving the realcom_mokosuitebackuporphaned 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 vialistRemotes. (#169) - Stop the API single-item view (
Backups/JsonapiView) leaking the serverabsolute_path. (#187) - SFTP uploader uses
StrictHostKeyChecking=accept-newinstead ofno. (#182)
Fixed
DatabaseDumperwrites a real newline afterDROP TABLE(was a literal\n). (#179)- Profile-picker forms order by
idinstead of the droppedorderingcolumn. (#180) uninstall.mysql.sqlnow drops the snapshots table. (#181)- CLI snapshot delete uses the
data_filecolumn (was non-existentfile_path). (#184) - Remove the duplicate pre-update backup (content plugin no longer subscribes to
onExtensionBeforeUpdate). (#186) DatabaseImportercollects non-fatal statement errors (getErrors()/hasErrors()). (#188)