From 49463eb74723149bd52cc438b77ce6078dd9cf51 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Sun, 5 Jul 2026 22:33:43 -0500 Subject: [PATCH] fix: raise resource limits for synchronous pre-update backup (WSOD) The pre-update/uninstall backup runs synchronously inside the extension update request. Without raising limits, a large site exceeds max_execution_time/memory_limit mid-backup and the update page white-screens. Raise set_time_limit(0)/memory_limit/ignore_user_abort like the web-cron path. Claude-Session: https://claude.ai/code/session_01WbGBN9VyRK61zczYWcCQ2i --- CHANGELOG.md | 1 + .../src/Extension/MokoSuiteBackup.php | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8209fef5..57002893 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - 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) diff --git a/source/packages/plg_system_mokosuitebackup/src/Extension/MokoSuiteBackup.php b/source/packages/plg_system_mokosuitebackup/src/Extension/MokoSuiteBackup.php index 07146b69..b2399603 100644 --- a/source/packages/plg_system_mokosuitebackup/src/Extension/MokoSuiteBackup.php +++ b/source/packages/plg_system_mokosuitebackup/src/Extension/MokoSuiteBackup.php @@ -386,6 +386,16 @@ final class MokoSuiteBackup extends CMSPlugin implements SubscriberInterface $profileId = (int) $params->get('default_profile', 1); + /* This backup runs synchronously inside the extension update/uninstall + request. Without raising these limits a large site blows past + max_execution_time / memory_limit mid-backup and the update page + white-screens. Mirror the web-cron path. (Core Joomla updates are + handled by the full-screen redirect instead — see onAfterRoute.) */ + @set_time_limit(0); + @ini_set('max_execution_time', '0'); + @ini_set('memory_limit', '512M'); + @ignore_user_abort(true); + try { $result = (new BackupRunner())->run($profileId, $description, 'preaction'); $app = Factory::getApplication();