Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ The Joomla! 5.0 branch is under heavy development and not all links in this docu

Build Status
---------------------
| Drone-CI | AppVeyor | PHP | Node | npm |
|------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------| ------------- | ------------- |
| [![Build Status](https://ci.joomla.org/api/badges/joomla/joomla-cms/status.svg?branch=5.0-dev)](https://ci.joomla.org/joomla/joomla-cms) | [![Build status](https://ci.appveyor.com/api/projects/status/ru6sxal8jmfckvjc/branch/5.0-dev?svg=true)](https://ci.appveyor.com/project/release-joomla/joomla-cms) | [![PHP](https://img.shields.io/badge/PHP-V8.1.0-green)](https://www.php.net/) | [![node-lts](https://img.shields.io/badge/Node-V16.0-green)](https://nodejs.org/en/) | [![npm](https://img.shields.io/badge/npm-v8.6.0-green)](https://nodejs.org/en/) |
| Drone-CI | AppVeyor | PHP | Node | npm |
|------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------|--------------------------------------------------------------------------------------|---------------------------------------------------------------------------------|
| [![Build Status](https://ci.joomla.org/api/badges/joomla/joomla-cms/status.svg?branch=5.0-dev)](https://ci.joomla.org/joomla/joomla-cms) | [![Build status](https://ci.appveyor.com/api/projects/status/ru6sxal8jmfckvjc/branch/5.0-dev?svg=true)](https://ci.appveyor.com/project/release-joomla/joomla-cms) | [![PHP](https://img.shields.io/badge/PHP-V8.1.0-green)](https://www.php.net/) | [![node-lts](https://img.shields.io/badge/Node-V18.0-green)](https://nodejs.org/en/) | [![npm](https://img.shields.io/badge/npm-v9.6.7-green)](https://nodejs.org/en/) |

Overview
---------------------
Expand Down
128 changes: 101 additions & 27 deletions administrator/components/com_admin/script.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,50 @@ class JoomlaInstallerScript
*/
protected $fromVersion = null;

/**
* Callback for collecting errors. Like function(string $context, \Throwable $error){};
*
* @var callable
*
* @since __DEPLOY_VERSION__
*/
protected $errorCollector;

/**
* Set the callback for collecting errors.
*
* @param callable $callback The callback Like function(string $context, \Throwable $error){};
*
* @return void
*
* @since __DEPLOY_VERSION__
*/
public function setErrorCollector(callable $callback)
{
$this->errorCollector = $callback;
}

/**
* Collect errors.
*
* @param string $context A context/place where error happened
* @param \Throwable $error The error that occurred
*
* @return void
*
* @since __DEPLOY_VERSION__
*/
protected function collectError(string $context, \Throwable $error)
{
// The errorCollector are required
// However when someone already running the script manually the code may fail.
if ($this->errorCollector) {
call_user_func($this->errorCollector, $context, $error);
} else {
Log::add($error->getMessage(), Log::ERROR, 'Update');
}
}

/**
* Function to act prior to installation process begins
*
Expand Down Expand Up @@ -82,27 +126,46 @@ public function preflight($action, $installer)
*/
public function update($installer)
{
$options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}';
$options['text_file'] = 'joomla_update.php';

Log::addLogger($options, Log::INFO, ['Update', 'databasequery', 'jerror']);

// Uninstall plugins before removing their files and folders
try {
Log::add(Text::_('COM_JOOMLAUPDATE_UPDATE_LOG_DELETE_FILES'), Log::INFO, 'Update');
} catch (RuntimeException $exception) {
// Informational log only
}

// Uninstall extensions before removing their files and folders
$this->uninstallExtensions();

// This needs to stay for 2.5 update compatibility
$this->deleteUnexistingFiles();
$this->updateManifestCaches();
$this->updateDatabase();
$this->updateAssets($installer);
$this->clearStatsCache();
$this->cleanJoomlaCache();
try {
Log::add(Text::_('COM_JOOMLAUPDATE_UPDATE_LOG_UNINSTALL_EXTENSIONS'), Log::INFO, 'Update');
$this->uninstallExtensions();
} catch (\Throwable $e) {
$this->collectError('uninstallExtensions', $e);
}

// Remove old files
try {
Log::add(Text::_('COM_JOOMLAUPDATE_UPDATE_LOG_DELETE_FILES'), Log::INFO, 'Update');
$this->deleteUnexistingFiles();
} catch (\Throwable $e) {
$this->collectError('deleteUnexistingFiles', $e);
}

// Further update
try {
$this->updateManifestCaches();
$this->updateDatabase();
$this->updateAssets($installer);
$this->clearStatsCache();
} catch (\Throwable $e) {
$this->collectError('Further update', $e);
}

// Clean cache
try {
$this->cleanJoomlaCache();
} catch (\Throwable $e) {
$this->collectError('cleanJoomlaCache', $e);
}

}

/**
Expand All @@ -127,7 +190,7 @@ protected function clearStatsCache()
->where($db->quoteName('element') . ' = ' . $db->quote('stats'))
)->loadResult();
} catch (Exception $e) {
echo Text::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()) . '<br>';
$this->collectError(__METHOD__, $e);

return;
}
Expand All @@ -151,7 +214,7 @@ protected function clearStatsCache()
try {
$db->setQuery($query)->execute();
} catch (Exception $e) {
echo Text::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()) . '<br>';
$this->collectError(__METHOD__, $e);

return;
}
Expand Down Expand Up @@ -183,7 +246,7 @@ protected function updateDatabaseMysql()
try {
$results = $db->loadObjectList();
} catch (Exception $e) {
echo Text::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()) . '<br>';
$this->collectError(__METHOD__, $e);

return;
}
Expand All @@ -198,7 +261,7 @@ protected function updateDatabaseMysql()
try {
$db->execute();
} catch (Exception $e) {
echo Text::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()) . '<br>';
$this->collectError(__METHOD__, $e);

return;
}
Expand All @@ -207,6 +270,7 @@ protected function updateDatabaseMysql()
}
}


/**
* Uninstall extensions and optionally migrate their parameters when
* updating from a version older than 5.0.1.
Expand All @@ -233,12 +297,12 @@ protected function uninstallExtensions()
* 'pre_function' => Name of an optional migration function to be called before
* uninstalling, `null` if not used.
*/
['type' => 'plugin', 'element' => 'demotasks', 'folder' => 'task', 'client_id' => 0, 'pre_function' => null],
['type' => 'plugin', 'element' => 'compat', 'folder' => 'system', 'client_id' => 0, 'pre_function' => 'migrateCompatPlugin'],
['type' => 'plugin', 'element' => 'logrotation', 'folder' => 'system', 'client_id' => 0, 'pre_function' => 'migrateLogRotationPlugin'],
['type' => 'plugin', 'element' => 'recaptcha', 'folder' => 'captcha', 'client_id' => 0, 'pre_function' => null],
['type' => 'plugin', 'element' => 'sessiongc', 'folder' => 'system', 'client_id' => 0, 'pre_function' => 'migrateSessionGCPlugin'],
['type' => 'plugin', 'element' => 'updatenotification', 'folder' => 'system', 'client_id' => 0, 'pre_function' => 'migrateUpdatenotificationPlugin'],
['type' => 'plugin', 'element' => 'demotasks', 'folder' => 'task', 'client_id' => 0, 'pre_function' => null],
['type' => 'plugin', 'element' => 'compat', 'folder' => 'system', 'client_id' => 0, 'pre_function' => 'migrateCompatPlugin'],
['type' => 'plugin', 'element' => 'logrotation', 'folder' => 'system', 'client_id' => 0, 'pre_function' => 'migrateLogRotationPlugin'],
['type' => 'plugin', 'element' => 'recaptcha', 'folder' => 'captcha', 'client_id' => 0, 'pre_function' => null],
['type' => 'plugin', 'element' => 'sessiongc', 'folder' => 'system', 'client_id' => 0, 'pre_function' => 'migrateSessionGCPlugin'],
['type' => 'plugin', 'element' => 'updatenotification', 'folder' => 'system', 'client_id' => 0, 'pre_function' => 'migrateUpdatenotificationPlugin'],
];

$db = Factory::getDbo();
Expand Down Expand Up @@ -477,7 +541,7 @@ protected function updateManifestCaches()
try {
$extensions = $db->loadObjectList();
} catch (Exception $e) {
echo Text::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()) . '<br>';
$this->collectError(__METHOD__, $e);

return;
}
Expand All @@ -487,7 +551,10 @@ protected function updateManifestCaches()

foreach ($extensions as $extension) {
if (!$installer->refreshManifestCache($extension->extension_id)) {
echo Text::sprintf('FILES_JOOMLA_ERROR_MANIFEST', $extension->type, $extension->element, $extension->name, $extension->client_id) . '<br>';
$this->collectError(
__METHOD__,
new \Exception(Text::sprintf('FILES_JOOMLA_ERROR_MANIFEST', $extension->type, $extension->element, $extension->name, $extension->client_id))
);
}
}
}
Expand Down Expand Up @@ -2346,6 +2413,8 @@ public function updateAssets($installer)
$asset->setLocation(1, 'last-child');

if (!$asset->store()) {
$this->collectError(__METHOD__, new \Exception($asset->getError(true)));

// Install failed, roll back changes
$installer->abort(Text::sprintf('JLIB_INSTALLER_ABORT_COMP_INSTALL_ROLLBACK', $asset->getError(true)));

Expand Down Expand Up @@ -2552,9 +2621,13 @@ private function migratePrivacyconsentConfiguration(): bool
return false;
}

// Refresh versionable assets cache.
Factory::getApplication()->flushAssets();

return true;
}


/**
* Migrate TinyMCE editor plugin configuration
*
Expand Down Expand Up @@ -2670,7 +2743,7 @@ private function setGuidedToursUid()
{
/** @var \Joomla\Component\Cache\Administrator\Model\CacheModel $model */
$model = Factory::getApplication()->bootComponent('com_guidedtours')->getMVCFactory()
->createModel('Tours', 'Administrator', ['ignore_request' => true]);
->createModel('Tours', 'Administrator', ['ignore_request' => true]);

$items = $model->getItems();

Expand Down Expand Up @@ -2779,4 +2852,5 @@ protected function fixFilenameCasing()
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ public function display($cachable = false, $urlparams = false)
$view->setModel($warningsModel, false);
}

// Check for update result
if ($lName === 'complete') {
$state = $model->getState();
$state->set('update_finished_with_error', $this->app->getUserState('com_joomlaupdate.update_finished_with_error'));
$state->set('update_errors', (array) $this->app->getUserState('com_joomlaupdate.update_errors', []));
$state->set('installer_message', $this->app->getUserState('com_joomlaupdate.installer_message'));
$state->set('log_file', $this->app->get('log_path') . '/joomla_update.php');
}

// Perform update source preference check and refresh update information.
$model->applyUpdateSite();
$model->refreshUpdates();
Expand Down
Loading