Skip to content
Merged
Changes from all 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
82 changes: 82 additions & 0 deletions administrator/components/com_admin/script.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ public function update($installer)
// 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();
Expand Down Expand Up @@ -201,6 +204,85 @@ protected function updateDatabaseMysql()
}
}

/**
* Uninstall extensions and optionally migrate their parameters when
* updating from a version older than 5.0.1.
*
* @return void
*
* @since __DEPLOY_VERSION__
*/
protected function uninstallExtensions()
{
// Don't uninstall extensions when not updating from a version older than 5.0.1
if (empty($this->fromVersion) || version_compare($this->fromVersion, '5.0.1', 'ge')) {
return true;
}

$extensions = [
/**
* Define here the extensions to be uninstalled and optionally migrated on update.
* For each extension, specify an associative array with following elements (key => value):
* 'type' => Field `type` in the `#__extensions` table
* 'element' => Field `element` in the `#__extensions` table
* 'folder' => Field `folder` in the `#__extensions` table
* 'client_id' => Field `client_id` in the `#__extensions` table
* 'pre_function' => Name of an optional migration function to be called before
* uninstalling, `null` if not used.
*/
];

$db = Factory::getDbo();

foreach ($extensions as $extension) {
$row = $db->setQuery(
$db->getQuery(true)
->select($db->quoteName('extension_id'))
->select($db->quoteName('params'))
->from($db->quoteName('#__extensions'))
->where($db->quoteName('type') . ' = ' . $db->quote($extension['type']))
->where($db->quoteName('element') . ' = ' . $db->quote($extension['element']))
->where($db->quoteName('folder') . ' = ' . $db->quote($extension['folder']))
->where($db->quoteName('client_id') . ' = ' . $db->quote($extension['client_id']))
)->loadObject();

// Skip migrating and uninstalling if the extension doesn't exist
if (!$row) {
continue;
}

// If there is a function for migration to be called before uninstalling, call it
if ($extension['pre_function'] && method_exists($this, $extension['pre_function'])) {
$this->{$extension['pre_function']}($row);
}

try {
$db->transactionStart();

// Unlock and unprotect the plugin so we can uninstall it
$db->setQuery(
$db->getQuery(true)
->update($db->quoteName('#__extensions'))
->set($db->quoteName('locked') . ' = 0')
->set($db->quoteName('protected') . ' = 0')
->where($db->quoteName('extension_id') . ' = :extension_id')
->bind(':extension_id', $row->extension_id, ParameterType::INTEGER)
)->execute();

// Uninstall the plugin
$installer = new Installer();
$installer->setDatabase($db);
$installer->uninstall($extension['type'], $row->extension_id);

$db->transactionCommit();
} catch (\Exception $e) {
$db->transactionRollback();
echo Text::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()) . '<br>';
throw $e;
}
}
}

/**
* Update the manifest caches
*
Expand Down