/**
  * 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);
     }
 }