diff --git a/administrator/components/com_joomlaupdate/extract.php b/administrator/components/com_joomlaupdate/extract.php index c59dc7b01625f..9328a57beea0c 100644 --- a/administrator/components/com_joomlaupdate/extract.php +++ b/administrator/components/com_joomlaupdate/extract.php @@ -1942,8 +1942,44 @@ function getConfiguration(): ?array $configuration = getConfiguration(); $enabled = !empty($configuration); +/** + * Sets the PHP timeout to 3600 seconds + * + * @return void + * @since __DEPLOY_VERSION__ + */ +function setLongTimeout() +{ + if (!function_exists('ini_set')) + { + return; + } + + ini_set('max_execution_time', 3600); +} + +/** + * Sets the memory limit to 1GiB + * + * @return void + * @since __DEPLOY_VERSION__ + */ +function setHugeMemoryLimit() +{ + if (!function_exists('ini_set')) + { + return; + } + + ini_set('memory_limit', 1073741824); +} + if ($enabled) { + // Try to set a very large memory and timeout limit + setLongTimeout(); + setHugeMemoryLimit(); + $sourcePath = $configuration['setup.sourcepath'] ?? ''; $sourceFile = $configuration['setup.sourcefile'] ?? ''; $destDir = ($configuration['setup.destdir'] ?? null) ?: __DIR__; diff --git a/administrator/components/com_joomlaupdate/tmpl/update/default.php b/administrator/components/com_joomlaupdate/tmpl/update/default.php index 9c2ac08fa6b6e..ff76166341672 100644 --- a/administrator/components/com_joomlaupdate/tmpl/update/default.php +++ b/administrator/components/com_joomlaupdate/tmpl/update/default.php @@ -12,6 +12,7 @@ use Joomla\CMS\Factory; use Joomla\CMS\Help\Help; use Joomla\CMS\Language\Text; +use Joomla\CMS\Router\Route; use Joomla\CMS\Uri\Uri; /** @var Joomla\CMS\WebAsset\WebAssetManager $wa */ @@ -56,36 +57,7 @@ $helpUrl = Help::createUrl('JHELP_COMPONENTS_JOOMLA_UPDATE', false); ?> - - -
+

@@ -116,9 +88,47 @@ class="btn btn-info">
-
- +
+ + +
+
+

+
+
+
+
diff --git a/administrator/language/en-GB/com_joomlaupdate.ini b/administrator/language/en-GB/com_joomlaupdate.ini index 25685034d05d5..adfa68698301f 100644 --- a/administrator/language/en-GB/com_joomlaupdate.ini +++ b/administrator/language/en-GB/com_joomlaupdate.ini @@ -27,6 +27,8 @@ COM_JOOMLAUPDATE_ERRORMODAL_HEAD_FORBIDDEN="Access forbidden" COM_JOOMLAUPDATE_ERRORMODAL_HEAD_GENERIC="An error occurred" COM_JOOMLAUPDATE_ERRORMODAL_HEAD_SERVERERROR="Server error" COM_JOOMLAUPDATE_ERRORMODAL_BTN_HELP="Get help with this error" +COM_JOOMLAUPDATE_ERRORSTATE_BTN_RETRY="Resume Update" +COM_JOOMLAUPDATE_ERRORSTATE_BTN_RESTART="Restart Update" COM_JOOMLAUPDATE_FAILED_TO_CHECK_UPDATES="Failed to check for updates." COM_JOOMLAUPDATE_MINIMUM_STABILITY_ALPHA="Alpha" COM_JOOMLAUPDATE_MINIMUM_STABILITY_BETA="Beta" diff --git a/build/media_source/com_joomlaupdate/js/admin-update-default.es6.js b/build/media_source/com_joomlaupdate/js/admin-update-default.es6.js index 4de020089a4c4..ebf02cb9a9e47 100644 --- a/build/media_source/com_joomlaupdate/js/admin-update-default.es6.js +++ b/build/media_source/com_joomlaupdate/js/admin-update-default.es6.js @@ -16,18 +16,12 @@ Joomla.Update = window.Joomla.Update || { totalsize: 0, ajax_url: null, return_url: null, + cached_instance: null, genericErrorMessage: (message) => { const headerDiv = document.getElementById('errorDialogLabel'); const messageDiv = document.getElementById('errorDialogMessage'); - const progressDiv = document.getElementById('progress-bar'); - const titleDiv = document.getElementById('update-title'); - const helpDiv = document.getElementById('update-help'); - - progressDiv.classList.add('bg-danger'); - progressDiv.classList.remove('bg-success'); - titleDiv.innerHTML = Joomla.Text._('COM_JOOMLAUPDATE_UPDATING_FAIL'); - helpDiv.classList.remove('d-none'); - helpDiv.classList.add('d-grid'); + const progressDiv = document.getElementById('joomlaupdate-progress'); + const errorDiv = document.getElementById('joomlaupdate-error'); headerDiv.innerHTML = Joomla.Text._('COM_JOOMLAUPDATE_ERRORMODAL_HEAD_GENERIC'); messageDiv.innerHTML = message; @@ -36,25 +30,16 @@ Joomla.Update = window.Joomla.Update || { messageDiv.innerHTML = Joomla.Text._('COM_JOOMLAUPDATE_ERRORMODAL_BODY_INVALIDLOGIN'); } - const myModal = new bootstrap.Modal(document.getElementById('errorDialog'), { - keyboard: true, - backdrop: true, - }); - myModal.show(); + progressDiv.classList.add('d-none'); + errorDiv.classList.remove('d-none'); }, handleErrorResponse: (xhr) => { const isForbidden = xhr.status === 403; const headerDiv = document.getElementById('errorDialogLabel'); const messageDiv = document.getElementById('errorDialogMessage'); - const progressDiv = document.getElementById('progress-bar'); - const titleDiv = document.getElementById('update-title'); - const helpDiv = document.getElementById('update-help'); - progressDiv.classList.add('bg-danger'); - progressDiv.classList.remove('bg-success'); - titleDiv.innerHTML = Joomla.Text._('COM_JOOMLAUPDATE_UPDATING_FAIL'); - helpDiv.classList.remove('d-none'); - helpDiv.classList.add('d-grid'); + const progressDiv = document.getElementById('joomlaupdate-progress'); + const errorDiv = document.getElementById('joomlaupdate-error'); if (isForbidden) { headerDiv.innerHTML = Joomla.Text._('COM_JOOMLAUPDATE_ERRORMODAL_HEAD_FORBIDDEN'); @@ -64,17 +49,15 @@ Joomla.Update = window.Joomla.Update || { messageDiv.innerHTML = Joomla.Text._('COM_JOOMLAUPDATE_ERRORMODAL_BODY_SERVERERROR'); } - const myModal = new bootstrap.Modal(document.getElementById('errorDialog'), { - keyboard: true, - backdrop: true, - }); - myModal.show(); + progressDiv.classList.add('d-none'); + errorDiv.classList.remove('d-none'); }, startExtract: () => { // Reset variables Joomla.Update.stat_files = 0; Joomla.Update.stat_inbytes = 0; Joomla.Update.stat_outbytes = 0; + Joomla.Update.cached_instance = null; document.getElementById('extbytesin').innerText = Joomla.Update.formatBytes(Joomla.Update.stat_inbytes); document.getElementById('extbytesout').innerText = Joomla.Update.formatBytes(Joomla.Update.stat_outbytes); @@ -158,6 +141,8 @@ Joomla.Update = window.Joomla.Update || { }, 50); }, delayedStepExtract: (instance) => { + Joomla.Update.cached_instance = instance; + const postData = new FormData(); postData.append('task', 'stepExtract'); postData.append('password', Joomla.Update.password); @@ -218,8 +203,41 @@ Joomla.Update = window.Joomla.Update || { return `${parseFloat((bytes / (k ** i)).toFixed(dm))} ${sizes[i]}`; }, + resumeButtonHandler: (e) => { + e.preventDefault(); + + document.getElementById('joomlaupdate-progress').classList.remove('d-none'); + document.getElementById('joomlaupdate-error').classList.add('d-none'); + + if (Joomla.Update.cached_instance === false) { + Joomla.Update.startExtract(); + } else { + Joomla.Update.delayedStepExtract(Joomla.Update.cached_instance); + } + }, + restartButtonHandler: (e) => { + e.preventDefault(); + + document.getElementById('joomlaupdate-progress').classList.remove('d-none'); + document.getElementById('joomlaupdate-error').classList.add('d-none'); + + Joomla.Update.startExtract(); + }, }; +// Add click handlers for the Resume and Restart Update buttons in the error pane. +const elResume = document.getElementById('joomlaupdate-resume'); +const elRestart = document.getElementById('joomlaupdate-restart'); + +if (elResume) { + elResume.addEventListener('click', Joomla.Update.resumeButtonHandler); +} + +if (elRestart) { + elRestart.addEventListener('click', Joomla.Update.restartButtonHandler); +} + +// Start the update const JoomlaUpdateOptions = Joomla.getOptions('joomlaupdate'); if (JoomlaUpdateOptions && Object.keys(JoomlaUpdateOptions).length) {