コード例 #1
0
 /**
  * @see Action::execute()
  */
 public function execute()
 {
     parent::execute();
     // get session data
     $sessionData = WCF::getSession()->getVar('databaseImportData');
     $filesize = $sessionData['filesize'];
     $isGzip = $sessionData['isGzip'];
     $extendedCommand = $sessionData['extendedCommand'];
     $offset = $sessionData['offset'];
     $charset = $sessionData['importCharset'];
     $ignoreErrors = $sessionData['ignoreErrors'];
     $importErrors = '';
     $stepInfo = array();
     // start export operations
     $loopStart = time();
     $importFile = $sessionData['importFile'];
     if ($isGzip) {
         $file = new ZipFile($importFile, 'rb');
     } else {
         $file = new File($importFile, 'rb');
     }
     // import database operations (only up to $this->limit)
     $loopInfo = DatabaseDumper::import($file, $filesize, $isGzip, $this->limit, $loopStart, $offset, $charset, $extendedCommand, $ignoreErrors);
     $file->close();
     // store charset
     if (!empty($loopInfo['charset']) && $loopInfo['charset'] != $sessionData['wcfCharset']) {
         $sessionData['importCharset'] = $loopInfo['charset'];
     }
     // delete aftereffected erros (no insert errors will be displayed if the table caused an error before)
     $tableErrors = $sessionData['tableErrors'];
     foreach ($loopInfo['errors']['messages'] as $key => $message) {
         if (preg_match("/CREATE TABLE `?(\\w+)`?/i", $message, $match)) {
             $tableErrors[] = $match[1];
         } elseif (preg_match("/(INSERT|REPLACE).*?INTO `?(\\w+)`?/i", $message, $match)) {
             if (in_array($match[1], $tableErrors)) {
                 unset($loopInfo['errors']['messages'][$key]);
                 unset($loopInfo['errors']['errorDescriptions'][$key]);
             } else {
                 $tableErrors[] = $match[1];
             }
         }
     }
     // save errors
     $errors = array('messages' => array_merge($sessionData['errors']['messages'], $loopInfo['errors']['messages']), 'errorDescriptions' => array_merge($sessionData['errors']['errorDescriptions'], $loopInfo['errors']['errorDescriptions']));
     $sessionData['errors'] = $errors;
     $sessionData['tableErrors'] = $tableErrors;
     // refresh session data
     $sessionData['extendedCommand'] = $loopInfo['extendedCommand'];
     $sessionData['offset'] = $loopInfo['offset'];
     $sessionData['remain'] -= $loopInfo['done'];
     $sessionData['commandCount'] += $loopInfo['commandCount'];
     // calculate progressbar
     $this->calcProgress($sessionData['count'] - $sessionData['remain'], $sessionData['count']);
     // show finish
     if ($sessionData['remain'] <= 0) {
         // reset charset for database connection
         if (!empty($sessionData['importCharset'])) {
             WCF::getDB()->setCharset($sessionData['wcfCharset']);
         }
         // cleanup session data
         WCF::getSession()->unregister('databaseImportData');
         // delete imported upload/remote file
         if ($sessionData['isTmpFile']) {
             @unlink($importFile);
         }
         // clear all standalone caches
         // get standalone package directories
         $sql = "SELECT\tpackageDir \n\t\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\t\tWHERE\tstandalone = 1\n\t\t\t\t\tAND packageDir <> ''";
         $result = WCF::getDB()->sendQuery($sql);
         while ($row = WCF::getDB()->fetchArray($result)) {
             // check if standalone package got cache directory
             $realPackageDir = FileUtil::addTrailingSlash(FileUtil::getRealPath(WCF_DIR . $row['packageDir']));
             if (file_exists($realPackageDir . 'cache')) {
                 // delete all cache files
                 WCF::getCache()->clear($realPackageDir . 'cache', '*.php', true);
             }
         }
         // clear wcf cache
         WCF::getCache()->clear(WCF_DIR . 'cache', '*.php', true);
         // delete all language files
         LanguageEditor::updateAll();
         // set data for template
         WCF::getTPL()->assign(array('import' => true, 'success' => empty($errors['messages']) && $sessionData['commandCount'] > 0, 'commandCount' => $sessionData['commandCount'], 'errors' => $errors));
         WCF::getTPL()->append('message', WCF::getTPL()->fetch('dbMessage'));
         // show finish template
         $title = 'wcf.acp.db.progress.finish';
         $this->finish($title, 'index.php?form=DatabaseImport&packageID=' . PACKAGE_ID . SID_ARG_2ND_NOT_ENCODED);
     }
     WCF::getSession()->register('databaseImportData', $sessionData);
     // next loop
     $title = 'wcf.acp.db.import.progress.working';
     $this->nextLoop($title);
 }
コード例 #2
0
 /**
  * Registers package information into database.
  */
 protected function installPackage()
 {
     $requirements = $this->packageArchive->getAllExistingRequirements();
     // finish installation
     if ($this->action == 'install') {
         $requirementsChanged = true;
         // calculate the number of instances of this package
         $instanceNo = 1;
         $sql = "SELECT\tCOUNT(*) AS count, MAX(instanceNo) AS instanceNo\n\t\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\t\tWHERE\tpackage = '" . escapeString($this->packageArchive->getPackageInfo('name')) . "'";
         $row = WCF::getDB()->getFirstRow($sql);
         if ($row['count'] > 0) {
             $instanceNo = $row['instanceNo'] + 1;
         }
         // register this package
         $sql = "INSERT INTO \twcf" . WCF_N . "_package\n\t\t\t\t\t\t(package, packageName, instanceNo, packageDescription, packageVersion, packageDate, packageURL, \n\t\t\t\t\t\tisUnique, standalone, author, authorURL, installDate, updateDate)\n\t\t\t\tVALUES\t\t('" . escapeString($this->packageArchive->getPackageInfo('name')) . "',\n\t\t\t\t\t\t'" . escapeString($this->packageArchive->getPackageInfo('packageName')) . "',\n\t\t\t\t\t\t" . $instanceNo . ",\n\t\t\t\t\t\t'" . escapeString($this->packageArchive->getPackageInfo('packageDescription')) . "',\n\t\t\t\t\t\t'" . escapeString($this->packageArchive->getPackageInfo('version')) . "',\n\t\t\t\t\t\t" . intval($this->packageArchive->getPackageInfo('date')) . ",\n\t\t\t\t\t\t'" . escapeString($this->packageArchive->getPackageInfo('packageURL')) . "',\n\t\t\t\t\t\t'" . intval($this->packageArchive->getPackageInfo('isUnique')) . "',\n\t\t\t\t\t\t'" . intval($this->packageArchive->getPackageInfo('standalone')) . "',\n\t\t\t\t\t\t'" . escapeString($this->packageArchive->getAuthorInfo('author')) . "',\n\t\t\t\t\t\t'" . escapeString($this->packageArchive->getAuthorInfo('authorURL')) . "',\n\t\t\t\t\t\t" . TIME_NOW . ",\n\t\t\t\t\t\t" . TIME_NOW . ")";
         WCF::getDB()->sendQuery($sql);
         $this->packageID = WCF::getDB()->getInsertID();
         // package package id in queue
         $sql = "UPDATE\twcf" . WCF_N . "_package_installation_queue\n\t\t\t\tSET \tpackageID \t= " . $this->packageID . " \n\t\t\t\tWHERE \tqueueID \t= " . $this->queueID;
         WCF::getDB()->sendQuery($sql);
     } else {
         $requirementsChanged = false;
         // update this package
         try {
             $sql = "UPDATE \twcf" . WCF_N . "_package \n\t\t\t\t\tSET \tpackageName \t\t= '" . escapeString($this->packageArchive->getPackageInfo('packageName')) . "', \n\t\t\t\t\t\tpackageDescription \t= '" . escapeString($this->packageArchive->getPackageInfo('packageDescription')) . "', \n\t\t\t\t\t\tpackageDate \t\t= " . intval($this->packageArchive->getPackageInfo('date')) . ", \n\t\t\t\t\t\tpackageURL \t\t= '" . escapeString($this->packageArchive->getPackageInfo('packageURL')) . "', \n\t\t\t\t\t\tauthor \t\t\t= '" . escapeString($this->packageArchive->getAuthorInfo('author')) . "', \n\t\t\t\t\t\tauthorURL \t\t= '" . escapeString($this->packageArchive->getAuthorInfo('authorURL')) . "',\n\t\t\t\t\t\tupdateDate\t\t= " . TIME_NOW . "\n\t\t\t\t\tWHERE \tpackageID \t\t= " . $this->packageID;
             WCF::getDB()->sendQuery($sql);
         } catch (DatabaseException $e) {
             // horizon update workaround
             $sql = "UPDATE \twcf" . WCF_N . "_package \n\t\t\t\t\tSET \tpackageName \t\t= '" . escapeString($this->packageArchive->getPackageInfo('packageName')) . "', \n\t\t\t\t\t\tpackageDescription \t= '" . escapeString($this->packageArchive->getPackageInfo('packageDescription')) . "', \n\t\t\t\t\t\tpackageDate \t\t= " . intval($this->packageArchive->getPackageInfo('date')) . ", \n\t\t\t\t\t\tpackageURL \t\t= '" . escapeString($this->packageArchive->getPackageInfo('packageURL')) . "', \n\t\t\t\t\t\tauthor \t\t\t= '" . escapeString($this->packageArchive->getAuthorInfo('author')) . "', \n\t\t\t\t\t\tauthorURL \t\t= '" . escapeString($this->packageArchive->getAuthorInfo('authorURL')) . "'\n\t\t\t\t\tWHERE \tpackageID \t\t= " . $this->packageID;
             WCF::getDB()->sendQuery($sql);
         }
         // check whether the requirements were changed
         $newRequirements = $this->packageArchive->getExistingRequirements();
         // get old requirements
         $sql = "SELECT\trequirement\n\t\t\t\tFROM\twcf" . WCF_N . "_package_requirement\n\t\t\t\tWHERE\tpackageID = " . $this->packageID;
         $result = WCF::getDB()->sendQuery($sql);
         while ($row = WCF::getDB()->fetchArray($result)) {
             $oldRequirement = false;
             foreach ($newRequirements as $key => $requirement) {
                 if ($row['requirement'] == $requirement['packageID']) {
                     $oldRequirement = true;
                     unset($newRequirements[$key]);
                     break;
                 }
             }
             if (!$oldRequirement) {
                 $requirementsChanged = true;
                 break;
             }
         }
         if (count($newRequirements) != 0) {
             $requirementsChanged = true;
         }
         // delete old excluded packages
         $sql = "DELETE FROM\twcf" . WCF_N . "_package_exclusion \n\t\t\t\tWHERE \t\tpackageID = " . $this->packageID;
         WCF::getDB()->sendQuery($sql);
         // delete old requirements
         $sql = "DELETE FROM\twcf" . WCF_N . "_package_requirement \n\t\t\t\tWHERE \t\tpackageID = " . $this->packageID;
         WCF::getDB()->sendQuery($sql);
     }
     // save excluded packages
     if (count($this->packageArchive->getExcludedPackages()) > 0) {
         $insertExcludedPackages = '';
         foreach ($this->packageArchive->getExcludedPackages() as $excludedPackage) {
             if (!empty($insertExcludedPackages)) {
                 $insertExcludedPackages .= ',';
             }
             $insertExcludedPackages .= "(" . $this->packageID . ", '" . escapeString($excludedPackage['name']) . "', '" . (!empty($excludedPackage['version']) ? escapeString($excludedPackage['version']) : '') . "')";
         }
         $sql = "INSERT INTO\twcf" . WCF_N . "_package_exclusion \n\t\t\t\t\t\t(packageID, excludedPackage, excludedPackageVersion)\n\t\t\t\tVALUES \t\t" . $insertExcludedPackages;
         WCF::getDB()->sendQuery($sql);
     }
     // register package requirements
     if (count($requirements) > 0) {
         $insertRequirements = '';
         $requirementIDs = '';
         foreach ($requirements as $identifier => $possibleRequirements) {
             if (count($possibleRequirements) == 1) {
                 $requirement = array_shift($possibleRequirements);
             } else {
                 $requirement = $possibleRequirements[$this->selectedRequirements[$identifier]];
             }
             if (!empty($insertRequirements)) {
                 $insertRequirements .= ',';
             }
             $insertRequirements .= "(" . $this->packageID . ", " . $requirement['packageID'] . ")";
             if (!empty($requirementIDs)) {
                 $requirementIDs .= ',';
             }
             $requirementIDs .= $requirement['packageID'];
         }
         $sql = "INSERT INTO\twcf" . WCF_N . "_package_requirement \n\t\t\t\t\t\t(packageID, requirement)\n\t\t\t\tVALUES \t\t" . $insertRequirements;
         WCF::getDB()->sendQuery($sql);
     }
     // rebuild package dependencies
     if ($requirementsChanged) {
         // build requirement map
         Package::rebuildPackageRequirementMap($this->packageID);
         // rebuild dependencies
         Package::rebuildPackageDependencies($this->packageID);
         if ($this->action == 'update') {
             Package::rebuildParentPackageDependencies($this->packageID);
         }
     }
     // reset package cache
     WCF::getCache()->clearResource('packages');
     // reset all cache resources
     //WCF::getCache()->clear(WCF_DIR.'cache', '*.php');
     // this is a bad fix to avoid
     // logout and some language errors
     // during the installation of package com.woltlab.wcf
     if ($this->action == 'install' && $this->packageArchive->getPackageInfo('name') == 'com.woltlab.wcf') {
         // avoid logout
         // update package id in acp sessions
         $sql = "UPDATE\twcf" . WCF_N . "_acp_session\n\t\t\t\tSET\tpackageID = " . $this->packageID . "\n\t\t\t\tWHERE\tpackageID = 0";
         WCF::getDB()->sendQuery($sql);
         // avoid language errors
         // update package id in language to packages relations
         $sql = "UPDATE\twcf" . WCF_N . "_language_to_packages\n\t\t\t\tSET\tpackageID = " . $this->packageID . "\n\t\t\t\tWHERE\tpackageID = 0";
         WCF::getDB()->sendQuery($sql);
         // update package id in language items
         $sql = "UPDATE\twcf" . WCF_N . "_language_item\n\t\t\t\tSET\tpackageID = " . $this->packageID . "\n\t\t\t\tWHERE\tpackageID = 0";
         WCF::getDB()->sendQuery($sql);
         // reset language cache
         WCF::getCache()->clearResource('languages');
         // rebuild language files
         LanguageEditor::updateAll();
         // delete language files of package 0
         LanguageEditor::deleteLanguageFiles('*', '*', 0);
         // update default group options
         // to avoid permission denied errors after next login
         $sql = "UPDATE\twcf" . WCF_N . "_group_option\n\t\t\t\tSET\tpackageID = " . $this->packageID . "\n\t\t\t\tWHERE\tpackageID = 0";
         WCF::getDB()->sendQuery($sql);
     }
 }