CRM_Utils_Hook::upgrade('enqueue', $queue);
+ // dev/core#1618 When Extension Upgrades are run reconcile log tables
+ $task = new CRM_Queue_Task(
+ [__CLASS__, 'upgradeLogTables'],
+ [],
+ ts('Update log tables')
+ );
+ // Set weight low so that it will be run last.
+ $queue->createItem($task, -2);
+
return $queue;
}
+ /**
+ * Update log tables following execution of extension upgrades
+ */
+ public static function upgradeLogTables() {
+ $logging = new CRM_Logging_Schema();
+ $logging->fixSchemaDifferences();
+ return TRUE;
+ }
+
/**
* @return array
* Array(string $extKey => CRM_Extension_Upgrader_Interface $upgrader)
}
/**
+ * Sorts active extensions according to their dependencies
+ *
* @param string[] $keys
+ * Names of all active modules
*
* @return string[]
* @throws \CRM_Extension_Exception
protected static function sortKeys($keys) {
$infos = CRM_Extension_System::singleton()->getMapper()->getAllInfos();
- // Start with our inputs in a normalized form.
+ // Ensure a stable starting order.
$todoKeys = array_unique($keys);
sort($todoKeys);
- // Goal: Add all active items to $sorter and flag $doneKeys['org.example.foobar']=1.
- $doneKeys = [];
$sorter = new \MJS\TopSort\Implementations\FixedArraySort();
- while (!empty($todoKeys)) {
- $key = array_shift($todoKeys);
- if (isset($doneKeys[$key])) {
- continue;
- }
- $doneKeys[$key] = 1;
-
+ foreach ($todoKeys as $key) {
/** @var CRM_Extension_Info $info */
- $info = @$infos[$key];
+ $info = $infos[$key] ?? NULL;
- if ($info && $info->requires) {
- $sorter->add($key, $info->requires);
- $todoKeys = array_merge($todoKeys, $info->requires);
+ // Add dependencies
+ if ($info) {
+ // Filter out missing dependencies; missing modules cannot be upgraded
+ $requires = array_intersect($info->requires ?? [], $keys);
+ $sorter->add($key, $requires);
}
+ // This shouldn't ever happen if this function is being passed a list of active extensions.
else {
- $sorter->add($key, []);
+ throw new CRM_Extension_Exception('Invalid extension key: "' . $key . '"');
}
}
return $sorter->sort();