com_joomlaupdater shares the minimum_stability variable in config.xml with com_installer minimum_stability viariable. This leads to incorrect update information for the Joomla updater
com_joomlaupdater should NOT prompt you to update to the (in this case) beta1 version as the Minimum Stability level for Joomla updater is set to Stable.
the other way around works okay, so when setting the com_joomlaupdater to development and the com_installer Minimum Extension Level to stable, there are not beta / dev / rc versions of extension listed,
| Labels |
Removed:
?
|
||
| Labels |
Added:
No Code Attached Yet
|
||
The logic described there goes beyond my English skills. but your comment (#46865 (comment)) is (I think) what I reported here.
The logic described there goes beyond my English skills. but your comment (#46865 (comment)) is (I think) what I reported here.
Ok, so found the root cause:
When listing the extensions that need an upgrade, Joomla File updates (this is Joomla Core) are excluded in administrator\components\com_installer\src\Model\UpdateModel::getListQuery() but in UpdateModel::findUpdates() it is NOT excluded, so when you check for updates in com_installer it finds updates for ALL (including Joomla File) with the stability level set to 'Minimal Extension Stability' and caches that result. This cache is shared with com_joomlaupdater > this will then notify you of the update for Joomla core.
The fix is to also exclude the Joomla File update site in com_installer UpdateModel, just like getListQuery() does.
in file: administrator\components\com_installer\src\Model\UpdateModel, replace the following function:
public function findUpdates($eid = 0, $cacheTimeout = 0, $minimumStability = Updater::STABILITY_STABLE)
{
if (!$eid) {
$db = $this->getDatabase();
$coreEid = ExtensionHelper::getExtensionRecord('joomla', 'file')->extension_id;
$query = $db->createQuery()
->select($db->quoteName('extension_id'))
->from($db->quoteName('#__extensions'))
->where($db->quoteName('extension_id') . ' != :eid')
->bind(':eid', $coreEid, ParameterType::INTEGER);
$db->setQuery($query);
$eid = $db->loadColumn();
}
Updater::getInstance()->findUpdates($eid, $cacheTimeout, $minimumStability);
return true;
}
As the results are cached, you need to clear cache / refetch the updates in both com_installer and com_joomlaupdater
@Ruud68 Query #__extensions table will result too many extension IDs and many of these extensions do not have update sites available. I guess it will be more efficient if we query #__update_sites_extensions instead
However, making the change like this will change the outcome of a public method and could result in backward incompatible changes, so unsafe. Look at the find method from UpdateController, I think it will be safe if we can find a way to exclude the $coreEid from two process:
Not sure how difficult it is yet, but I think it will be more safe than modify findUpdates method directly as you suggested.
@joomdonation , you are right. It is public so we must assume others are using it in their own code.
so the fix should then be in the UpdateController::find() and UpdateController::ajax() where we pass a computed list instead of a literal 0 for $eid.
For that computed list we create a UpdateModel::getExtensionIdsForUpdateCheck() that will return all extension IDs except Joomla File / Core.
in UpdateModel.php add:
/**
* Returns the IDs of all extensions that com_installer should check for updates, excluding the Joomla
* core "extension". Joomla core's own update site must only ever be refreshed by com_joomlaupdate using
* its own "minimum_stability" setting;
*
* @return int[]
*
* @since __DEPLOY_VERSION__
*/
public function getExtensionIdsForUpdateCheck()
{
$db = $this->getDatabase();
$coreEid = ExtensionHelper::getExtensionRecord('joomla', 'file')->extension_id;
$query = $db->createQuery()
->select($db->quoteName('extension_id'))
->from($db->quoteName('#__extensions'))
->where($db->quoteName('extension_id') . ' != :eid')
->bind(':eid', $coreEid, ParameterType::INTEGER);
$db->setQuery($query);
return $db->loadColumn();
}
in UpdateController.php change:
public function ajax()
$model->findUpdates($findEid, $cache_timeout, $minimum_stability);
to
$findEid = $eid ?: $model->getExtensionIdsForUpdateCheck();
$model->findUpdates($findEid, $cache_timeout, $minimum_stability);
and, public function find()
$model->findUpdates(0, $cache_timeout, $minimum_stability);
to
$model->findUpdates($model->getExtensionIdsForUpdateCheck(), $cache_timeout, $minimum_stability);
@joomdonation , you are right. It is public so we must assume others are using it in their own code.
so the fix should then be in the UpdateController::find() and UpdateController::ajax() where we pass a computed list instead of a literal 0 for $eid.
For that computed list we create a UpdateModel::getExtensionIdsForUpdateCheck() that will return all extension IDs except Joomla File / Core.
in UpdateModel.php add:
/**
* Returns the IDs of all extensions that com_installer should check for updates, excluding the Joomla
* core "extension". Joomla core's own update site must only ever be refreshed by com_joomlaupdate using
* its own "minimum_stability" setting;
*
* @return int[]
*
* @since __DEPLOY_VERSION__
*/
public function getExtensionIdsForUpdateCheck()
{
$db = $this->getDatabase();
$coreEid = ExtensionHelper::getExtensionRecord('joomla', 'file')->extension_id;
$query = $db->createQuery()
->select('DISTINCT ' . $db->quoteName('extension_id'))
->from($db->quoteName('#__update_sites_extensions'))
->where($db->quoteName('extension_id') . ' != :eid')
->bind(':eid', $coreEid, ParameterType::INTEGER);
$db->setQuery($query);
return $db->loadColumn();
}
in UpdateController.php change:
public function ajax()
$model->findUpdates($findEid, $cache_timeout, $minimum_stability);
to
$findEid = $eid ?: $model->getExtensionIdsForUpdateCheck();
$model->findUpdates($findEid, $cache_timeout, $minimum_stability);
and, public function find()
$model->findUpdates(0, $cache_timeout, $minimum_stability);
to
$model->findUpdates($model->getExtensionIdsForUpdateCheck(), $cache_timeout, $minimum_stability);
@joomdonation , you are right. It is public so we must assume others are using it in their own code.
so the fix should then be in the UpdateController::find() and UpdateController::ajax() where we pass a computed list instead of a literal 0 for $eid.
For that computed list we create a UpdateModel::getExtensionIdsForUpdateCheck() that will return all extension IDs except Joomla File / Core.
in UpdateModel.php add:
/**
* Returns the IDs of all extensions that com_installer should check for updates, excluding the Joomla
* core "extension". Joomla core's own update site must only ever be refreshed by com_joomlaupdate using
* its own "minimum_stability" setting;
*
* @return int[]
*
* @since __DEPLOY_VERSION__
*/
public function getExtensionIdsForUpdateCheck()
{
$db = $this->getDatabase();
$coreEid = ExtensionHelper::getExtensionRecord('joomla', 'file')->extension_id;
$query = $db->createQuery()
->select('DISTINCT ' . $db->quoteName('extension_id'))
->from($db->quoteName('#__update_sites_extensions'))
->where($db->quoteName('extension_id') . ' != :eid')
->bind(':eid', $coreEid, ParameterType::INTEGER);
$db->setQuery($query);
return $db->loadColumn();
}
and replace function purge() wit the code below:
public function purge()
{
$db = $this->getDatabase();
$coreEid = ExtensionHelper::getExtensionRecord('joomla', 'file')->extension_id;
try {
// Leave the Joomla core update cache alone; it is only ever managed by com_joomlaupdate
// using its own "minimum_stability" setting (see getExtensionIdsForUpdateCheck() above).
$query = $db->createQuery()
->delete($db->quoteName('#__updates'))
->where($db->quoteName('extension_id') . ' != :eid')
->bind(':eid', $coreEid, ParameterType::INTEGER);
$db->setQuery($query);
$db->execute();
} catch (ExecutionFailureException) {
$this->_message = Text::_('JLIB_INSTALLER_FAILED_TO_PURGE_UPDATES');
return false;
}
// Find the update site(s) belonging to Joomla core so their last check timestamp is left alone.
$query = $db->createQuery()
->select($db->quoteName('update_site_id'))
->from($db->quoteName('#__update_sites_extensions'))
->where($db->quoteName('extension_id') . ' = :eid')
->bind(':eid', $coreEid, ParameterType::INTEGER);
$db->setQuery($query);
$coreUpdateSiteIds = $db->loadColumn();
// Reset the last update check timestamp for every other update site
$query = $db->getQuery(true)
->update($db->quoteName('#__update_sites'))
->set($db->quoteName('last_check_timestamp') . ' = ' . $db->quote(0));
if (!empty($coreUpdateSiteIds)) {
$query->whereNotIn($db->quoteName('update_site_id'), $coreUpdateSiteIds);
}
$db->setQuery($query);
$db->execute();
// Clear the administrator cache
$this->cleanCache('_system');
$this->_message = Text::_('JLIB_INSTALLER_PURGED_UPDATES');
return true;
}
in UpdateController.php change:
public function ajax()
$model->findUpdates($findEid, $cache_timeout, $minimum_stability);
to
$findEid = $eid ?: $model->getExtensionIdsForUpdateCheck();
$model->findUpdates($findEid, $cache_timeout, $minimum_stability);
and, public function find()
$model->findUpdates(0, $cache_timeout, $minimum_stability);
to
$model->findUpdates($model->getExtensionIdsForUpdateCheck(), $cache_timeout, $minimum_stability);
for the CLI, change in .\libraries\src\Console\CheckUpdatesCommand.php in function doExecute()
$model->findUpdates();
to
$model->findUpdates($model->getExtensionIdsForUpdateCheck());
@Ruud68 I think it is right solution except that:
Updated the code in #48336 (comment)
The changing of the purge is IMO not related, if that needs improvement that should be handled separately
The changing of the purge is IMO not related, if that needs improvement that should be handled separately
It is actually related. Before, we also find update for Joomla core, so purge all updates are OK. Now, we do not find update for Joomla core anymore, so purge needs to exclude updates for Joomla core.
ok, done in #48336 (comment)
also did the CLI part as that was also 'ignorent' on the joomla core / extensions difference
Thanks @joomdonation for the help and keeping me 'focussed' :).
This is as far as my contributions go, so I hope somebody else can pick this up and do the PR.
Same problem as #46865 ?