/**
  * Gets the package name of the first standalone application in WCFSetup.tar.gz.
  */
 protected static function getPackageName()
 {
     // get package name
     $tar = new Tar(SETUP_FILE);
     foreach ($tar->getContentList() as $file) {
         if ($file['type'] != 'folder' && StringUtil::indexOf($file['filename'], 'install/packages/') === 0) {
             $packageFile = basename($file['filename']);
             $packageName = preg_replace('!\\.(tar\\.gz|tgz|tar)$!', '', $packageFile);
             if ($packageName != 'com.woltlab.wcf') {
                 try {
                     $archive = new PackageArchive(TMP_DIR . TMP_FILE_PREFIX . $packageFile);
                     $archive->openArchive();
                     self::$setupPackageName = $archive->getPackageInfo('packageName');
                     $archive->getTar()->close();
                     break;
                 } catch (SystemException $e) {
                 }
             }
         }
     }
     $tar->close();
     // assign package name
     WCF::getTPL()->assign('setupPackageName', self::$setupPackageName);
 }
 /**
  * Tries to download a package from available update servers.
  * 
  * @param	string		$package		package identifier
  * @param	array		$packageUpdateVersions	package update versions
  * @return	string		tmp filename of a downloaded package
  */
 protected function downloadPackage($package, $packageUpdateVersions)
 {
     // get download from cache
     if ($filename = $this->getCachedDownload($package, $packageUpdateVersions[0]['package'])) {
         return $filename;
     }
     // download file
     $authorizationRequiredException = array();
     $systemExceptions = array();
     foreach ($packageUpdateVersions as $packageUpdateVersion) {
         try {
             // get auth data
             $authData = self::getAuthData($packageUpdateVersion);
             // send request
             if (!empty($packageUpdateVersion['file'])) {
                 $response = self::sendRequest($packageUpdateVersion['file'], array(), $authData);
             } else {
                 $response = self::sendRequest($packageUpdateVersion['server'], array('packageName' => $packageUpdateVersion['package'], 'packageVersion' => $packageUpdateVersion['packageVersion']), $authData);
             }
             // check response
             // check http code
             if ($response['httpStatusCode'] == 401) {
                 throw new PackageUpdateAuthorizationRequiredException($packageUpdateVersion['packageUpdateServerID'], !empty($packageUpdateVersion['file']) ? $packageUpdateVersion['file'] : $packageUpdateVersion['server'], $response);
             }
             if ($response['httpStatusCode'] != 200) {
                 throw new SystemException(WCF::getLanguage()->get('wcf.acp.packageUpdate.error.downloadFailed', array('$package' => $package)) . ' (' . $response['httpStatusLine'] . ')', 18009);
             }
             // write content to tmp file
             $filename = FileUtil::getTemporaryFilename('package_');
             $file = new File($filename);
             $file->write($response['content']);
             $file->close();
             unset($response['content']);
             // test package
             $archive = new PackageArchive($filename);
             $archive->openArchive();
             $archive->getTar()->close();
             // cache download in session
             $this->cacheDownload($package, $packageUpdateVersion['packageVersion'], $filename);
             return $filename;
         } catch (PackageUpdateAuthorizationRequiredException $e) {
             $authorizationRequiredException[] = $e;
         } catch (SystemException $e) {
             $systemExceptions[] = $e;
         }
     }
     if (count($authorizationRequiredException)) {
         throw array_shift($authorizationRequiredException);
     }
     if (count($systemExceptions)) {
         throw array_shift($systemExceptions);
     }
     return false;
 }
 /**
  * finalises installation of this package.
  * 
  * @return 	string 		nextStep
  */
 protected function finishInstallation()
 {
     $this->makeClear();
     // check language to package relations
     // a standalone package needs at least one language relation
     if ($this->packageArchive->getPackageInfo('standalone')) {
         $sql = "SELECT\tCOUNT(*) AS count\n\t\t\t\tFROM\twcf" . WCF_N . "_language_to_packages\n\t\t\t\tWHERE\tpackageID = " . $this->packageID;
         $row = WCF::getDB()->getFirstRow($sql);
         if ($row['count'] == 0) {
             $sql = "INSERT INTO\twcf" . WCF_N . "_language_to_packages\n\t\t\t\t\t\t\t(languageID, packageID)\n\t\t\t\t\tSELECT\t\tlanguageID, " . $this->packageID . "\n\t\t\t\t\tFROM\t\twcf" . WCF_N . "_language\n\t\t\t\t\tORDER BY\tisDefault DESC";
             WCF::getDB()->sendQuery($sql, 1);
             // reset language cache
             WCF::getCache()->clearResource('languages');
             LanguageEditor::updateAll();
         }
     }
     // unregister package installation plugins
     WCF::getSession()->unregister('queueID' . $this->queueID . 'PIPs');
     // mark this package installation as done
     $sql = "UPDATE\twcf" . WCF_N . "_package_installation_queue\n\t\t\tSET\tdone = 1\n\t\t\tWHERE\tqueueID = " . $this->queueID;
     WCF::getDB()->sendQuery($sql);
     // delete package archive
     $this->packageArchive->getTar()->close();
     $sql = "SELECT\tCOUNT(*) AS count\n\t\t\tFROM\twcf" . WCF_N . "_package_installation_queue\n\t\t\tWHERE\tarchive = '" . escapeString($this->packageArchive->getArchive()) . "'\n\t\t\t\tAND done = 0";
     $row = WCF::getDB()->getFirstRow($sql);
     if ($row['count'] == 0) {
         @unlink($this->packageArchive->getArchive());
     }
     // search for other open queue entries in current level
     $sql = "SELECT\t\tqueueID, action\n\t\t\tFROM\t\twcf" . WCF_N . "_package_installation_queue\n\t\t\tWHERE\t\tparentQueueID = " . $this->parentQueueID . "\n\t\t\t\t\tAND processNo = " . $this->processNo . "\n\t\t\t\t\tAND done = 0\n\t\t\tORDER BY\tqueueID";
     $row = WCF::getDB()->getFirstRow($sql);
     if (isset($row['queueID'])) {
         // other entries found
         WCF::getTPL()->assign(array('action' => $row['action'], 'queueID' => $row['queueID'], 'processNo' => $this->processNo));
         if ($this->parentQueueID == 0) {
             // reload installation frame
             // and install next package
             WCF::getTPL()->display('packageInstallationReloadFrame');
             exit;
         } else {
             // install next package in current window
             return '';
         }
     } else {
         if ($this->parentQueueID == 0) {
             // nothing to do
             // finish installation
             // get installationType ('setup', 'install' or 'other')
             $sql = "SELECT\tinstallationType\n\t\t\t\t\tFROM\twcf" . WCF_N . "_package_installation_queue\n\t\t\t\t\tWHERE\tqueueID = " . $this->queueID;
             $type = WCF::getDB()->getFirstRow($sql);
             // delete all package installation queue entries with the active process number
             $sql = "DELETE FROM\twcf" . WCF_N . "_package_installation_queue\n\t\t\t\t\tWHERE\t\tprocessNo = " . $this->processNo;
             WCF::getDB()->sendQuery($sql);
             // reset sessions
             Session::resetSessions();
             // var to redirect to installation form or acp index
             WCF::getTPL()->assign('installationType', $type['installationType']);
             // show finish page
             WCF::getTPL()->display('packageInstallationFinish');
             exit;
         } else {
             // jump to parent package installation
             // get information about parent queue id
             $sql = "SELECT\t*\n\t\t\t\t\tFROM\twcf" . WCF_N . "_package_installation_queue\n\t\t\t\t\tWHERE\tqueueID = " . $this->parentQueueID;
             $parentQueueEntry = WCF::getDB()->getFirstRow($sql);
             WCF::getTPL()->assign(array('action' => $parentQueueEntry['action'], 'queueID' => $this->parentQueueID));
             if ($this->packageType == 'requirement') {
                 return 'requirements';
             }
             if ($this->packageType == 'optional') {
                 return 'finish';
             }
         }
     }
 }