/** * Registers with wcf setup delivered packages in the package installation queue. */ protected function installPackages() { // init database connection $this->initDB(); // get admin account $admin = new User(1); // get delivered packages $wcfPackageFile = ''; $otherPackages = array(); $tar = new Tar(SETUP_FILE); foreach ($tar->getContentList() as $file) { if ($file['type'] != 'folder' && mb_strpos($file['filename'], 'install/packages/') === 0) { $packageFile = basename($file['filename']); // ignore any files which aren't an archive if (preg_match('~\\.(tar\\.gz|tgz|tar)$~', $packageFile)) { $packageName = preg_replace('!\\.(tar\\.gz|tgz|tar)$!', '', $packageFile); if ($packageName == 'com.woltlab.wcf') { $wcfPackageFile = $packageFile; } else { $isStrato = !empty($_SERVER['DOCUMENT_ROOT']) && strpos($_SERVER['DOCUMENT_ROOT'], 'strato') !== false; if (!$isStrato && preg_match('!\\.(tar\\.gz|tgz)$!', $packageFile)) { // try to unzip zipped package files if (FileUtil::uncompressFile(TMP_DIR . 'install/packages/' . $packageFile, TMP_DIR . 'install/packages/' . $packageName . '.tar')) { @unlink(TMP_DIR . 'install/packages/' . $packageFile); $packageFile = $packageName . '.tar'; } } $otherPackages[$packageName] = $packageFile; } } } } $tar->close(); // register packages in queue // get new process id $sql = "SELECT\tMAX(processNo) AS processNo\n\t\t\tFROM\twcf" . WCF_N . "_package_installation_queue"; $statement = self::getDB()->prepareStatement($sql); $statement->execute(); $result = $statement->fetchArray(); $processNo = intval($result['processNo']) + 1; // search existing wcf package $sql = "SELECT\tCOUNT(*) AS count\n\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\tWHERE\tpackage = 'com.woltlab.wcf'"; $statement = self::getDB()->prepareStatement($sql); $statement->execute(); $row = $statement->fetchArray(); if (!$row['count']) { if (empty($wcfPackageFile)) { throw new SystemException('the essential package com.woltlab.wcf is missing.'); } // register essential wcf package $queue = PackageInstallationQueueEditor::create(array('processNo' => $processNo, 'userID' => $admin->userID, 'package' => 'com.woltlab.wcf', 'packageName' => 'WoltLab Community Framework', 'archive' => TMP_DIR . 'install/packages/' . $wcfPackageFile, 'isApplication' => 1)); } // register all other delivered packages asort($otherPackages); foreach ($otherPackages as $packageName => $packageFile) { // extract packageName from archive's package.xml $archive = new PackageArchive(TMP_DIR . 'install/packages/' . $packageFile); try { $archive->openArchive(); } catch (\Exception $e) { // we've encountered a broken archive, revert everything and then fail $sql = "SELECT\tqueueID, parentQueueID\n\t\t\t\t\tFROM\twcf" . WCF_N . "_package_installation_queue"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(); $queues = array(); while ($row = $statement->fetchArray()) { $queues[$row['queueID']] = $row['parentQueueID']; } $queueIDs = array(); $queueID = $queue->queueID; while ($queueID) { $queueIDs[] = $queueID; $queueID = isset($queues[$queueID]) ? $queues[$queueID] : 0; } // remove previously created queues if (!empty($queueIDs)) { $sql = "DELETE FROM\twcf" . WCF_N . "_package_installation_queue\n\t\t\t\t\t\tWHERE\t\tqueueID = ?"; $statement = WCF::getDB()->prepareStatement($sql); WCF::getDB()->beginTransaction(); foreach ($queueIDs as $queueID) { $statement->execute(array($queueID)); } WCF::getDB()->commitTransaction(); } // remove package files @unlink(TMP_DIR . 'install/packages/' . $wcfPackageFile); foreach ($otherPackages as $packageFile) { @unlink(TMP_DIR . 'install/packages/' . $packageFile); } // throw exception again throw new SystemException('', 0, '', $e); } $queue = PackageInstallationQueueEditor::create(array('parentQueueID' => $queue->queueID, 'processNo' => $processNo, 'userID' => $admin->userID, 'package' => $packageName, 'packageName' => $archive->getLocalizedPackageInfo('packageName'), 'archive' => TMP_DIR . 'install/packages/' . $packageFile, 'isApplication' => 1)); } // login as admin $factory = new ACPSessionFactory(); $factory->load(); SessionHandler::getInstance()->changeUser($admin); SessionHandler::getInstance()->register('masterPassword', 1); SessionHandler::getInstance()->register('__wcfSetup_developerMode', self::$developerMode); SessionHandler::getInstance()->update(); $installPhpDeleted = @unlink('./install.php'); @unlink('./test.php'); $wcfSetupTarDeleted = @unlink('./WCFSetup.tar.gz'); // print page WCF::getTPL()->assign(array('installPhpDeleted' => $installPhpDeleted, 'wcfSetupTarDeleted' => $wcfSetupTarDeleted)); WCF::getTPL()->display('stepInstallPackages'); // delete tmp files $directory = TMP_DIR . '/'; DirectoryUtil::getInstance($directory)->removePattern(new Regex('\\.tar(\\.gz)?$'), true); }
/** * Unzips compressed package archives and returns the temporary file name. * * @param string $archive filename * @return string */ public static function unzipPackageArchive($archive) { if (!FileUtil::isURL($archive)) { $tar = new Tar($archive); $tar->close(); if ($tar->isZipped()) { $tmpName = FileUtil::getTemporaryFilename('package_'); if (FileUtil::uncompressFile($archive, $tmpName)) { return $tmpName; } } } return $archive; }