/**
  * 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 = PackageUpdateServer::getActiveUpdateServers();
     $packageUpdateServerIDs = 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, isApplication,\n\t\t\t\tCASE WHEN instanceName <> '' THEN instanceName ELSE packageName END AS packageName\n\t\t\tFROM\twcf" . WCF_N . "_package";
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute();
     while ($row = $statement->fetchArray()) {
         $existingPackages[$row['package']][] = $row;
     }
     if (empty($existingPackages)) {
         return $updates;
     }
     // get all update versions
     $conditions = new PreparedStatementConditionBuilder();
     $conditions->add("pu.packageUpdateServerID IN (?)", array($packageUpdateServerIDs));
     $conditions->add("package IN (SELECT DISTINCT package FROM wcf" . WCF_N . "_package)");
     $sql = "SELECT\t\tpu.packageUpdateID, pu.packageUpdateServerID, pu.package,\n\t\t\t\t\tpuv.packageUpdateVersionID, puv.updateType, puv.packageDate, puv.filename, 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\t" . $conditions;
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute($conditions->getParameters());
     while ($row = $statement->fetchArray()) {
         // 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'], 'packageDate' => $row['packageDate'], 'packageVersion' => $row['packageVersion'], 'servers' => array());
                 }
                 // server data
                 $updates[$existingVersion['packageID']]['versions'][$row['packageVersion']]['servers'][] = array('packageUpdateID' => $row['packageUpdateID'], 'packageUpdateServerID' => $row['packageUpdateServerID'], 'packageUpdateVersionID' => $row['packageUpdateVersionID'], 'filename' => $row['filename']);
             }
         }
     }
     // 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 application packages
     if ($removeRequirements) {
         foreach ($existingPackages as $identifier => $instances) {
             foreach ($instances as $instance) {
                 if ($instance['isApplication'] && isset($updates[$instance['packageID']])) {
                     $updates = self::removeUpdateRequirements($updates, $updates[$instance['packageID']]['version']['servers'][0]['packageUpdateVersionID']);
                 }
             }
         }
     }
     return $updates;
 }
Пример #2
0
 /**
  * Returns a result list of a search for installable packages.
  * 
  * @return	array
  */
 public function search()
 {
     PackageUpdateDispatcher::getInstance()->refreshPackageDatabase();
     $availableUpdateServers = PackageUpdateServer::getActiveUpdateServers();
     // there are no available package update servers
     if (empty($availableUpdateServers)) {
         WCF::getTPL()->assign(array('packageUpdates' => array()));
         return array('count' => 0, 'pageCount' => 0, 'searchID' => 0, 'template' => WCF::getTPL()->fetch('packageSearchResultList'));
     }
     $conditions = new PreparedStatementConditionBuilder();
     $conditions->add("package_update.packageUpdateServerID IN (?)", array(array_keys($availableUpdateServers)));
     if (!empty($this->parameters['package'])) {
         $conditions->add("package_update.package LIKE ?", array('%' . $this->parameters['package'] . '%'));
     }
     if (!empty($this->parameters['packageDescription'])) {
         $conditions->add("package_update.packageDescription LIKE ?", array('%' . $this->parameters['packageDescription'] . '%'));
     }
     if (!empty($this->parameters['packageName'])) {
         $conditions->add("package_update.packageName LIKE ?", array('%' . $this->parameters['packageName'] . '%'));
     }
     $conditions->add("package.packageID IS NULL");
     // find matching packages
     $sql = "SELECT\t\tpackage_update.packageUpdateID\n\t\t\tFROM\t\twcf" . WCF_N . "_package_update package_update\n\t\t\tLEFT JOIN\twcf" . WCF_N . "_package package\n\t\t\tON\t\t(package.package = package_update.package)\n\t\t\t" . $conditions . "\n\t\t\tORDER BY\tpackage_update.packageName ASC";
     $statement = WCF::getDB()->prepareStatement($sql, 1000);
     $statement->execute($conditions->getParameters());
     $packageUpdateIDs = array();
     while ($row = $statement->fetchArray()) {
         $packageUpdateIDs[] = $row['packageUpdateID'];
     }
     // no matches found
     if (empty($packageUpdateIDs)) {
         WCF::getTPL()->assign(array('packageUpdates' => array()));
         return array('count' => 0, 'pageCount' => 0, 'searchID' => 0, 'template' => WCF::getTPL()->fetch('packageSearchResultList'));
     }
     // get excluded packages
     $sql = "SELECT\t*\n\t\t\tFROM\twcf" . WCF_N . "_package_update_exclusion";
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute();
     $excludedPackages = array();
     while ($row = $statement->fetchArray()) {
         $package = $row['excludedPackage'];
         $packageVersion = $row['excludedPackageVersion'];
         $packageUpdateVersionID = $row['packageUpdateVersionID'];
         if (!isset($excludedPackages[$packageUpdateVersionID][$package])) {
             $excludedPackages[$packageUpdateVersionID][$package] = $packageVersion;
         } else {
             if (Package::compareVersion($excludedPackages[$packageUpdateVersionID][$package], $packageVersion) == 1) {
                 $excludedPackages[$packageUpdateVersionID][$package] = $packageVersion;
             }
         }
     }
     // get installed packages
     $sql = "SELECT\tpackage, packageVersion\n\t\t\tFROM\twcf" . WCF_N . "_package";
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute();
     $installedPackages = array();
     while ($row = $statement->fetchArray()) {
         $installedPackages[$row['package']] = $row['packageVersion'];
     }
     // filter by version
     $conditions = new PreparedStatementConditionBuilder();
     $conditions->add("puv.packageUpdateID IN (?)", array($packageUpdateIDs));
     $sql = "SELECT\t\tpu.package, puv.packageUpdateVersionID, puv.packageUpdateID, puv.packageVersion, puv.isAccessible\n\t\t\tFROM\t\twcf" . WCF_N . "_package_update_version puv\n\t\t\tLEFT JOIN\twcf" . WCF_N . "_package_update pu\n\t\t\tON\t\t(pu.packageUpdateID = puv.packageUpdateID)\n\t\t\t" . $conditions;
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute($conditions->getParameters());
     $packageVersions = array();
     while ($row = $statement->fetchArray()) {
         $package = $row['package'];
         $packageVersion = $row['packageVersion'];
         $packageUpdateVersionID = $row['packageUpdateVersionID'];
         // check excluded packages
         if (isset($excludedPackages[$packageUpdateVersionID])) {
             $isExcluded = false;
             foreach ($excludedPackages[$packageUpdateVersionID] as $excludedPackage => $excludedPackageVersion) {
                 if (isset($installedPackages[$excludedPackage]) && Package::compareVersion($excludedPackageVersion, $installedPackages[$excludedPackage]) <= 0) {
                     // excluded, ignore
                     $isExcluded = true;
                     break;
                 }
             }
             if ($isExcluded) {
                 continue;
             }
         }
         if (!isset($packageVersions[$package])) {
             $packageVersions[$package] = array();
         }
         $packageUpdateID = $row['packageUpdateID'];
         if (!isset($packageVersions[$package][$packageUpdateID])) {
             $packageVersions[$package][$packageUpdateID] = array('accessible' => array(), 'existing' => array());
         }
         if ($row['isAccessible']) {
             $packageVersions[$package][$packageUpdateID]['accessible'][$row['packageUpdateVersionID']] = $packageVersion;
         }
         $packageVersions[$package][$packageUpdateID]['existing'][$row['packageUpdateVersionID']] = $packageVersion;
     }
     // all found versions are excluded
     if (empty($packageVersions)) {
         WCF::getTPL()->assign(array('packageUpdates' => array()));
         return array('count' => 0, 'pageCount' => 0, 'searchID' => 0, 'template' => WCF::getTPL()->fetch('packageSearchResultList'));
     }
     // determine highest versions
     $packageUpdates = array();
     foreach ($packageVersions as $package => $versionData) {
         $accessible = $existing = $versions = array();
         foreach ($versionData as $packageUpdateID => $versionTypes) {
             // ignore unaccessible packages
             if (empty($versionTypes['accessible'])) {
                 continue;
             }
             uasort($versionTypes['accessible'], array('wcf\\data\\package\\Package', 'compareVersion'));
             uasort($versionTypes['existing'], array('wcf\\data\\package\\Package', 'compareVersion'));
             $accessibleVersion = array_slice($versionTypes['accessible'], -1, 1, true);
             $existingVersion = array_slice($versionTypes['existing'], -1, 1, true);
             $ak = key($accessibleVersion);
             $av = current($accessibleVersion);
             $ek = key($existingVersion);
             $ev = current($existingVersion);
             $accessible[$av] = $ak;
             $existing[$ev] = $ek;
             $versions[$ak] = $packageUpdateID;
             $versions[$ek] = $packageUpdateID;
         }
         // ignore packages without accessible versions
         if (empty($accessible)) {
             continue;
         }
         uksort($accessible, array('wcf\\data\\package\\Package', 'compareVersion'));
         uksort($existing, array('wcf\\data\\package\\Package', 'compareVersion'));
         $accessible = array_pop($accessible);
         $existing = array_pop($existing);
         $packageUpdates[$versions[$accessible]] = array('accessible' => $accessible, 'existing' => $existing);
     }
     // no found packages is accessible
     if (empty($packageUpdates)) {
         WCF::getTPL()->assign(array('packageUpdates' => array()));
         return array('count' => 0, 'pageCount' => 0, 'searchID' => 0, 'template' => WCF::getTPL()->fetch('packageSearchResultList'));
     }
     $search = SearchEditor::create(array('userID' => WCF::getUser()->userID, 'searchData' => serialize($packageUpdates), 'searchTime' => TIME_NOW, 'searchType' => 'acpPackageSearch'));
     // forward call to build the actual result list
     $updateAction = new PackageUpdateAction(array(), 'getResultList', array('pageNo' => 1, 'search' => $search));
     $returnValues = $updateAction->executeAction();
     return $returnValues['returnValues'];
 }
 /**
  * Returns a list of available updates for installed packages.
  * 
  * @param	boolean		$removeRequirements
  * @param	boolean		$removeOlderMinorReleases
  * @return	array
  */
 public function getAvailableUpdates($removeRequirements = true, $removeOlderMinorReleases = false)
 {
     $updates = array();
     // get update server data
     $updateServers = PackageUpdateServer::getActiveUpdateServers();
     $packageUpdateServerIDs = array_keys($updateServers);
     if (empty($packageUpdateServerIDs)) {
         return $updates;
     }
     // get existing packages and their versions
     $existingPackages = array();
     $sql = "SELECT\tpackageID, package, packageDescription, packageName,\n\t\t\t\tpackageVersion, packageDate, author, authorURL, isApplication\n\t\t\tFROM\twcf" . WCF_N . "_package";
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute();
     while ($row = $statement->fetchArray()) {
         $existingPackages[$row['package']][] = $row;
     }
     if (empty($existingPackages)) {
         return $updates;
     }
     // get all update versions
     $conditions = new PreparedStatementConditionBuilder();
     $conditions->add("pu.packageUpdateServerID IN (?)", array($packageUpdateServerIDs));
     $conditions->add("package IN (SELECT DISTINCT package FROM wcf" . WCF_N . "_package)");
     $sql = "SELECT\t\tpu.packageUpdateID, pu.packageUpdateServerID, pu.package,\n\t\t\t\t\tpuv.packageUpdateVersionID, puv.isCritical, puv.packageDate, puv.filename, 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 AND puv.isAccessible = 1)\n\t\t\t" . $conditions;
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute($conditions->getParameters());
     while ($row = $statement->fetchArray()) {
         // 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('isCritical' => $row['isCritical'], 'packageDate' => $row['packageDate'], 'packageVersion' => $row['packageVersion'], 'servers' => array());
                 }
                 // server data
                 $updates[$existingVersion['packageID']]['versions'][$row['packageVersion']]['servers'][] = array('packageUpdateID' => $row['packageUpdateID'], 'packageUpdateServerID' => $row['packageUpdateServerID'], 'packageUpdateVersionID' => $row['packageUpdateVersionID'], 'filename' => $row['filename']);
             }
         }
     }
     // sort package versions
     // and remove old versions
     foreach ($updates as $packageID => $data) {
         uksort($updates[$packageID]['versions'], array('wcf\\data\\package\\Package', 'compareVersion'));
         $updates[$packageID]['version'] = end($updates[$packageID]['versions']);
     }
     // remove requirements of application packages
     if ($removeRequirements) {
         foreach ($existingPackages as $identifier => $instances) {
             foreach ($instances as $instance) {
                 if ($instance['isApplication'] && isset($updates[$instance['packageID']])) {
                     $updates = $this->removeUpdateRequirements($updates, $updates[$instance['packageID']]['version']['servers'][0]['packageUpdateVersionID']);
                 }
             }
         }
     }
     // remove older minor releases from list, e.g. only display 1.0.2, even if 1.0.1 is available
     if ($removeOlderMinorReleases) {
         foreach ($updates as &$updateData) {
             $highestVersions = array();
             foreach ($updateData['versions'] as $versionNumber => $dummy) {
                 if (preg_match('~^(\\d+\\.\\d+)\\.~', $versionNumber, $matches)) {
                     $major = $matches[1];
                     if (isset($highestVersions[$major])) {
                         if (Package::compareVersion($highestVersions[$major], $versionNumber, '<')) {
                             // version is newer, discard current version
                             unset($updateData['versions'][$highestVersions[$major]]);
                             $highestVersions[$major] = $versionNumber;
                         } else {
                             // version is lower, discard
                             unset($updateData['versions'][$versionNumber]);
                         }
                     } else {
                         $highestVersions[$major] = $versionNumber;
                     }
                 }
             }
         }
         unset($updateData);
     }
     return $updates;
 }
 /**
  * Creates a new instance of PackageInstallationScheduler
  * 
  * @param	array<string>		$selectedPackages
  */
 public function __construct(array $selectedPackages)
 {
     $this->selectedPackages = $selectedPackages;
     $this->packageUpdateServers = PackageUpdateServer::getActiveUpdateServers();
 }
 /**
  * @see wcf\page\IPage::readData()
  */
 public function readData()
 {
     parent::readData();
     $this->updateServers = PackageUpdateServer::getActiveUpdateServers();
 }