diff --git a/source/packages/com_mokosuitebackup/config.xml b/source/packages/com_mokosuitebackup/config.xml index 7cee4ac..5b93f7f 100644 --- a/source/packages/com_mokosuitebackup/config.xml +++ b/source/packages/com_mokosuitebackup/config.xml @@ -71,6 +71,31 @@ /> +
+ + + + + + + + +
+
'onAfterInitialise', - 'onAfterRoute' => 'onAfterRoute', + 'onAfterInitialise' => 'onAfterInitialise', + 'onAfterRoute' => 'onAfterRoute', + 'onExtensionBeforeUpdate' => 'onExtensionBeforeUpdate', + 'onExtensionBeforeUninstall' => 'onExtensionBeforeUninstall', ]; } @@ -199,6 +201,68 @@ final class MokoSuiteBackup extends CMSPlugin implements SubscriberInterface } } + /** + * Run a backup before any extension is updated. + */ + public function onExtensionBeforeUpdate(Event $event): void + { + $this->runPreActionBackup('backup_before_update', 'Pre-update backup'); + } + + /** + * Run a backup before any extension is uninstalled. + */ + public function onExtensionBeforeUninstall(Event $event): void + { + $this->runPreActionBackup('backup_before_uninstall', 'Pre-uninstall backup'); + } + + /** + * Run a pre-action backup if the option is enabled and not already + * done in this session (throttled to once per 10 minutes to avoid + * duplicate backups during batch updates). + */ + private function runPreActionBackup(string $paramName, string $description): void + { + $params = ComponentHelper::getParams('com_mokosuitebackup'); + + if (!(int) $params->get($paramName, 0)) { + return; + } + + // Throttle: only run once per 10 minutes to prevent duplicate + // backups when multiple extensions are updated in a batch + $session = Factory::getSession(); + $sessionKey = 'mokosuitebackup.preaction_' . $paramName; + $lastRun = $session->get($sessionKey, 0); + + if (time() - $lastRun < 600) { + return; + } + + $session->set($sessionKey, time()); + + $profileId = (int) $params->get('default_profile', 1); + + try { + $engine = new BackupEngine(); + $result = $engine->run($profileId, $description, 'preaction'); + + if (!$result['success']) { + Factory::getApplication()->enqueueMessage( + 'MokoSuiteBackup: ' . $description . ' failed — ' . $result['message'], + 'warning' + ); + } + } catch (\Exception $e) { + error_log('MokoSuiteBackup: ' . $description . ' failed: ' . $e->getMessage()); + Factory::getApplication()->enqueueMessage( + 'MokoSuiteBackup: ' . $description . ' failed — ' . $e->getMessage(), + 'warning' + ); + } + } + /** * Send a JSON response and terminate — used by web cron handler. */