/** * Returns a list of available updates for installed packages. * * @param boolean $removeRequirements * @return array */ public static function getAvailableUpdates($removeRequirements = true) { $updates = array(); // get update server data $updateServers = UpdateServer::getActiveUpdateServers(); $packageUpdateServerIDs = implode(',', array_keys($updateServers)); if (empty($packageUpdateServerIDs)) { return $updates; } // get existing packages and their versions $existingPackages = array(); $sql = "SELECT\tpackageID, package, instanceNo, packageDescription,\n\t\t\t\tpackageVersion, packageDate, author, authorURL, standalone,\n\t\t\t\tCASE WHEN instanceName <> '' THEN instanceName ELSE packageName END AS packageName\n\t\t\tFROM\twcf" . WCF_N . "_package"; $result = WCF::getDB()->sendQuery($sql); while ($row = WCF::getDB()->fetchArray($result)) { $existingPackages[$row['package']][] = $row; } $existingPackageIdentifiers = implode("','", array_keys($existingPackages)); if (empty($existingPackageIdentifiers)) { return $updates; } // get all update versions $sql = "SELECT\t\tpu.packageUpdateID, pu.packageUpdateServerID, pu.package,\n\t\t\t\t\tpuv.packageUpdateVersionID, puv.updateType, puv.timestamp, puv.file, puv.packageVersion\n\t\t\tFROM\t\twcf" . WCF_N . "_package_update pu\n\t\t\tLEFT JOIN\twcf" . WCF_N . "_package_update_version puv\n\t\t\tON\t\t(puv.packageUpdateID = pu.packageUpdateID)\n\t\t\tWHERE\t\tpu.packageUpdateServerID IN (" . $packageUpdateServerIDs . ")\n\t\t\t\t\tAND package IN (\n\t\t\t\t\t\tSELECT\tDISTINCT package\n\t\t\t\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\t\t\t)"; $result = WCF::getDB()->sendQuery($sql); while ($row = WCF::getDB()->fetchArray($result)) { // test version foreach ($existingPackages[$row['package']] as $existingVersion) { if (Package::compareVersion($existingVersion['packageVersion'], $row['packageVersion'], '<')) { // package data if (!isset($updates[$existingVersion['packageID']])) { $existingVersion['versions'] = array(); $updates[$existingVersion['packageID']] = $existingVersion; } // version data if (!isset($updates[$existingVersion['packageID']]['versions'][$row['packageVersion']])) { $updates[$existingVersion['packageID']]['versions'][$row['packageVersion']] = array('updateType' => $row['updateType'], 'timestamp' => $row['timestamp'], 'packageVersion' => $row['packageVersion'], 'servers' => array()); } // server data $updates[$existingVersion['packageID']]['versions'][$row['packageVersion']]['servers'][] = array('packageUpdateID' => $row['packageUpdateID'], 'packageUpdateServerID' => $row['packageUpdateServerID'], 'packageUpdateVersionID' => $row['packageUpdateVersionID'], 'file' => $row['file']); } } } // sort package versions // and remove old versions foreach ($updates as $packageID => $data) { uksort($updates[$packageID]['versions'], array('Package', 'compareVersion')); $updates[$packageID]['version'] = end($updates[$packageID]['versions']); } // remove requirements of standalone packages if ($removeRequirements) { foreach ($existingPackages as $identifier => $instances) { foreach ($instances as $instance) { if ($instance['standalone'] && isset($updates[$instance['packageID']])) { $updates = self::removeUpdateRequirements($updates, $updates[$instance['packageID']]['version']['servers'][0]['packageUpdateVersionID']); } } } } return $updates; }
/** * @see Page::readData() */ public function readData() { parent::readData(); $this->updateServers = UpdateServer::getActiveUpdateServers(); }