}
/**
- * Get the list of local extensions and format them as a table with
+ * Get the list of remote extensions and format them as a table with
* status and action data.
*
* @param array $localExtensionRows
// build list of available downloads
$remoteExtensionRows = array();
+ $compat = CRM_Extension_System::getCompatibilityInfo();
+
foreach ($remoteExtensions as $info) {
+ if (!empty($compat[$info->key]['obsolete'])) {
+ continue;
+ }
$row = (array) $info;
$row['id'] = $info->key;
$action = CRM_Core_Action::UPDATE;
}
}
elseif ($attr === 'requires') {
- $this->requires = array();
- foreach ($val->ext as $ext) {
- $this->requires[] = (string) $ext;
- }
+ $this->requires = $this->filterRequirements($val);
}
else {
$this->$attr = CRM_Utils_XML::xmlObjToArray($val);
}
}
+ /**
+ * Filter out invalid requirements, e.g. extensions that have been moved to core.
+ *
+ * @param SimpleXMLElement $requirements
+ * @return array
+ */
+ public function filterRequirements($requirements) {
+ $filtered = [];
+ $compatInfo = CRM_Extension_System::getCompatibilityInfo();
+ foreach ($requirements->ext as $ext) {
+ $ext = (string) $ext;
+ if (empty($compatInfo[$ext]['obsolete'])) {
+ $filtered[] = $ext;
+ }
+ }
+ return $filtered;
+ }
+
}
return $this->_repoUrl;
}
+ /**
+ * Returns a list keyed by extension key
+ *
+ * @return array
+ */
+ public static function getCompatibilityInfo() {
+ if (!isset(Civi::$statics[__CLASS__]['compatibility'])) {
+ Civi::$statics[__CLASS__]['compatibility'] = json_decode(file_get_contents(Civi::paths()->getPath('[civicrm.root]/extension-compatibility.json')), TRUE);
+ }
+ return Civi::$statics[__CLASS__]['compatibility'];
+ }
+
/**
* Take an extension's raw XML info and add information about the
* extension's status on the local system.
);
$queue->createItem($task);
+ $task = new CRM_Queue_Task(
+ array('CRM_Upgrade_Form', 'disableOldExtensions'),
+ array($postUpgradeMessageFile),
+ "Checking extensions"
+ );
+ $queue->createItem($task);
+
$revisions = $upgrade->getRevisionSequence();
foreach ($revisions as $rev) {
// proceed only if $currentVer < $rev
return TRUE;
}
+ /**
+ * Disable any extensions not compatible with this new version.
+ *
+ * @param \CRM_Queue_TaskContext $ctx
+ * @param string $postUpgradeMessageFile
+ * @return bool
+ */
+ public static function disableOldExtensions(CRM_Queue_TaskContext $ctx, $postUpgradeMessageFile) {
+ $compatInfo = CRM_Extension_System::getCompatibilityInfo();
+ $disabled = [];
+ $manager = CRM_Extension_System::singleton()->getManager();
+ foreach ($compatInfo as $key => $ext) {
+ if (!empty($ext['obsolete']) && $manager->getStatus($key) == $manager::STATUS_INSTALLED) {
+ $disabled[$key] = sprintf("<li>%s</li>", ts('The extension %1 is now obsolete and has been disabled.', [1 => $key]));
+ }
+ }
+ if ($disabled) {
+ $manager->disable(array_keys($disabled));
+ file_put_contents($postUpgradeMessageFile,
+ '<br/><br/><ul>' . implode("\n", $disabled) . '</ul>',
+ FILE_APPEND
+ );
+ }
+
+ return TRUE;
+ }
+
/**
* Perform an incremental version update.
*
done
dm_install_files "$repo" "$to" {agpl-3.0,agpl-3.0.exception,gpl,CONTRIBUTORS}.txt
- dm_install_files "$repo" "$to" composer.json composer.lock bower.json package.json Civi.php README.md release-notes.md
+ dm_install_files "$repo" "$to" composer.json composer.lock bower.json package.json Civi.php README.md release-notes.md extension-compatibility.json
mkdir -p "$to/sql"
pushd "$repo" >> /dev/null
--- /dev/null
+{
+ "com.ixiam.modules.quicksearch": {
+ "obsolete": "5.8"
+ }
+}
$this->assertTrue(is_object($exc));
}
+ public function test_requirements() {
+ // Quicksearch requirement should get filtered out per extension-compatibility.json
+ $data = "<extension key='test.foo' type='module'><file>foo</file><requires><ext>example.test</ext><ext>com.ixiam.modules.quicksearch</ext></requires></extension>";
+
+ $info = CRM_Extension_Info::loadFromString($data);
+ $this->assertEquals(['example.test'], $info->requires);
+ }
+
}