3eb2562abd
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 18s
fix: pre-action backup fires for every extension, not one per 10 min Root cause of "pre-update backup only fires on the backup extension": a coarse 600s session throttle. Whenever ANY pre-action backup ran (including updating MokoSuiteBackup itself, or a core Joomla update), the key mokosuitebackup.preaction_backup_before_update was armed for 10 minutes. onBeforeCompileHead read it as `recentBackup` and DISABLED the client-side interceptor for all extensions, and runPreActionBackup was throttled by the same window. So after updating one extension, every other extension update silently skipped its backup for 10 minutes. Replace the time window with "one backup per Update action": - runPreActionBackup dedupes per-request (a batch update fires the event once per extension in a single request -> back up once) via instance flags, and consumes a ONE-SHOT session skip flag for the re-fired client update/uninstall (skip once, next distinct action backs up). - ajax.preupdateAck sets the one-shot flag for the SPECIFIC action (update|uninstall), passed from installer-backup.js via &msb_action and surfaced by Runbackup HtmlView -> CFG.action. A core update passes no action, so it never suppresses an extension backup. - onBeforeCompileHead drops the recentBackup time-suppression (the re-fire loop is already guarded client-side by window.__msbResuming). - The core Joomla update path uses its own key (mokosuitebackup.core_update_backed_up), decoupled from extensions. Claude-Session: https://claude.ai/code/session_01WbGBN9VyRK61zczYWcCQ2i @
94 lines
2.8 KiB
PHP
94 lines
2.8 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @package MokoSuiteBackup
|
|
* @subpackage com_mokosuitebackup
|
|
* @author Moko Consulting <hello@mokoconsulting.tech>
|
|
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
|
* @license GNU General Public License version 3 or later; see LICENSE
|
|
*/
|
|
|
|
namespace Joomla\Component\MokoSuiteBackup\Administrator\View\Runbackup;
|
|
|
|
defined('_JEXEC') or die;
|
|
|
|
use Joomla\CMS\Factory;
|
|
use Joomla\CMS\Language\Text;
|
|
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
|
use Joomla\CMS\Toolbar\ToolbarHelper;
|
|
|
|
/**
|
|
* Full-screen "run a backup" progress view.
|
|
*
|
|
* Auto-starts the stepped backup (ajax.init → loop ajax.step) and shows a
|
|
* full-page progress screen. Used both by the dashboard "Backup Now" action
|
|
* and — via the system plugin's pre-update redirect — as the interstitial
|
|
* between clicking Joomla's Update and the update actually running. When a
|
|
* `returnurl` is supplied the page redirects there once the backup completes
|
|
* (e.g. back to `com_joomlaupdate&task=update.install&is_backed_up=1`).
|
|
*/
|
|
class HtmlView extends BaseHtmlView
|
|
{
|
|
public int $profileId = 1;
|
|
|
|
public string $profileTitle = '';
|
|
|
|
public string $description = '';
|
|
|
|
/** Raw (possibly base64) return URL from the request; validated in the layout. */
|
|
public string $returnUrl = '';
|
|
|
|
public bool $autostart = true;
|
|
|
|
/** Which action the backup fronts ('update' | 'uninstall' | ''); drives the completion ack skip flag. */
|
|
public string $action = '';
|
|
|
|
public function display($tpl = null): void
|
|
{
|
|
$input = Factory::getApplication()->getInput();
|
|
|
|
$this->profileId = (int) $input->getInt('profile_id', $input->getInt('profileid', 1));
|
|
$this->description = $input->getString('description', '');
|
|
$this->returnUrl = $input->getRaw('returnurl', '');
|
|
$this->autostart = (bool) $input->getInt('autostart', 1);
|
|
$this->action = $input->getCmd('msb_action', '');
|
|
|
|
if ($this->profileId <= 0) {
|
|
$this->profileId = 1;
|
|
}
|
|
|
|
$this->profileTitle = $this->loadProfileTitle($this->profileId);
|
|
|
|
$this->addToolbar();
|
|
|
|
parent::display($tpl);
|
|
}
|
|
|
|
/**
|
|
* Look up the target profile's title for display (best-effort).
|
|
*/
|
|
private function loadProfileTitle(int $profileId): string
|
|
{
|
|
try {
|
|
$db = Factory::getContainer()->get(\Joomla\Database\DatabaseInterface::class);
|
|
$query = $db->getQuery(true)
|
|
->select($db->quoteName('title'))
|
|
->from($db->quoteName('#__mokosuitebackup_profiles'))
|
|
->where($db->quoteName('id') . ' = ' . (int) $profileId);
|
|
$db->setQuery($query);
|
|
|
|
return (string) ($db->loadResult() ?? '');
|
|
} catch (\Throwable $e) {
|
|
return '';
|
|
}
|
|
}
|
|
|
|
protected function addToolbar(): void
|
|
{
|
|
ToolbarHelper::title(
|
|
Text::_('COM_MOKOJOOMBACKUP_SHORT') . ': ' . Text::_('COM_MOKOJOOMBACKUP_RUNBACKUP_TITLE'),
|
|
'archive'
|
|
);
|
|
}
|
|
}
|