* @return string
*/
public function stepUninstall() {
+ die("current node is ".$this->node);
$node = $this->installation->uninstall($this->node);
if ($node == '') {
protected static $databaseTableIndexName = 'packageID';
/**
- * package requirement map
+ * package requirements
* @var array<integer>
*/
- protected static $requirementMap = null;
+ protected static $requirements = null;
/**
* list of packages that this package requires
* @return boolean
*/
public function isRequired() {
- self::loadRequirementMap();
+ self::loadRequiremens();
- return (isset(self::$requirementMap[$this->packageID]));
+ return (isset(self::$requirements[$this->packageID]));
}
/**
return false;
}
- // check if package is required by current application
- if (self::isRequiredBy($this->packageID, PACKAGE_ID)) {
+ // check if package is required by another package
+ if (self::isRequired($this->packageID)) {
return false;
}
}
/**
- * Returns true, if package $packageID is required by package $targetPackageID.
- *
- * @param integer $packageID
- * @param integer $targetPackageID
- * @return boolean
- */
- public static function isRequiredBy($packageID, $targetPackageID) {
- self::loadRequirementMap();
-
- if (isset(self::$requirementMap[$packageID])) {
- foreach (self::$requirementMap[$packageID] as $requiredBy) {
- if ($requiredBy == $targetPackageID) {
- return true;
- }
- }
- }
-
- return false;
- }
-
- /**
- * Loads package requirement map.
+ * Loads package requirements.
*/
- protected static function loadRequirementMap() {
+ protected static function loadRequirements() {
if (self::$requirementMap === null) {
$sql = "SELECT packageID, requirement
- FROM wcf".WCF_N."_package_requirement_map";
+ FROM wcf".WCF_N."_package_requirement";
$statement = WCF::getDB()->prepareStatement($sql);
$statement->execute();
- self::$requirementMap = array();
+ self::$requirements = array();
while ($row = $statement->fetchArray()) {
- if (!isset(self::$requirementMap[$row['requirement']])) {
- self::$requirementMap[$row['requirement']] = array();
+ if (!isset(self::$requirements[$row['packageID']])) {
+ self::$requirements[$row['packageID']] = array();
}
- self::$requirementMap[$row['requirement']][] = $row['packageID'];
+ self::$requirements[$row['packageID']][] = $row['requirement'];
}
}
}
return $version;
}
- /**
- * Rebuilds the requirement map for the given package id.
- *
- * @param integer $packageID
- */
- public static function rebuildPackageRequirementMap($packageID) {
- // delete old entries
- $sql = "DELETE FROM wcf".WCF_N."_package_requirement_map
- WHERE packageID = ?";
- $statement = WCF::getDB()->prepareStatement($sql);
- $statement->execute(array($packageID));
-
- // fetch requirements of requirements
- $requirements = array();
- $sql = "SELECT requirement, level
- FROM wcf".WCF_N."_package_requirement_map
- WHERE packageID IN (
- SELECT requirement
- FROM wcf".WCF_N."_package_requirement
- WHERE packageID = ?
- )
- ORDER BY level ASC";
- $statement = WCF::getDB()->prepareStatement($sql);
- $statement->execute(array($packageID));
- while ($row = $statement->fetchArray()) {
- // use reverse order, highest level epic wins
- $requirements[$row['requirement']] = $row['level'];
- }
-
- // insert requirements of requirements
- if (!empty($requirements)) {
- $sql = "INSERT INTO wcf".WCF_N."_package_requirement_map
- (packageID, requirement, level)
- VALUES (?, ?, ?)";
- $statement = WCF::getDB()->prepareStatement($sql);
- foreach ($requirements as $requirement => $level) {
- $statement->execute(array($packageID, $requirement, $level));
- }
- }
-
- // fetch requirements
- $directRequirements = array();
- $conditions = new PreparedStatementConditionBuilder($sql);
- $conditions->add("packageID = ?", array($packageID));
- if (!empty($requirements)) {
- $conditions->add("requirement NOT IN (?)", array(array_keys($requirements)));
- }
-
- $sql = "SELECT requirement,
- (
- SELECT MAX(level) AS requirementLevel
- FROM wcf".WCF_N."_package_requirement_map
- WHERE packageID = package_requirement.requirement
- ) AS requirementLevel
- FROM wcf".WCF_N."_package_requirement package_requirement
- ".$conditions;
- $statement = WCF::getDB()->prepareStatement($sql);
- $statement->execute($conditions->getParameters());
- while ($row = $statement->fetchArray()) {
- $row['requirementLevel'] = intval($row['requirementLevel']) + 1;
- $directRequirements[$row['requirement']] = $row['requirementLevel'];
- }
-
- // insert requirements
- if (!empty($directRequirements)) {
- $sql = "INSERT INTO wcf".WCF_N."_package_requirement_map
- (packageID, requirement, level)
- VALUES (?, ?, ?)";
- $statement = WCF::getDB()->prepareStatement($sql);
- foreach ($directRequirements as $requirement => $level) {
- $statement->execute(array($packageID, $requirement, $level));
- }
- }
- }
-
/**
* Writes the config.inc.php for an application.
*
<?php
namespace wcf\system\package;
-use wcf\system\style\StyleHandler;
-
use wcf\data\application\Application;
use wcf\data\application\ApplicationEditor;
use wcf\data\language\category\LanguageCategory;
use wcf\system\language\LanguageFactory;
use wcf\system\request\LinkHandler;
use wcf\system\request\RouteHandler;
+use wcf\system\style\StyleHandler;
use wcf\system\WCF;
use wcf\util\FileUtil;
use wcf\util\HeaderUtil;
}
}
- // build requirement map
- Package::rebuildPackageRequirementMap($package->packageID);
-
// reload queue
$this->queue = new PackageInstallationQueue($this->queue->queueID);
$this->package = null;
return $step;
}
- // @todo: comment
+ /**
+ * Displays a list to select optional packages or installs selection.
+ *
+ * @param string $currentNode
+ * @param array $nodeData
+ * @return wcf\system\package\PackageInstallationStep
+ */
protected function selectOptionalPackages($currentNode, array $nodeData) {
$installationStep = new PackageInstallationStep();
}
/**
- * Extracts files from .tar (or .tar.gz) archive and installs them
+ * Extracts files from .tar(.gz) archive and installs them
*
* @param string $targetDir
* @param string $sourceArchive
}
}
- // @todo: comment
+ /**
+ * Prompts a selection of optional packages.
+ *
+ * @return mixed
+ */
protected function promptOptionalPackages(array $packages) {
if (!PackageInstallationFormManager::findForm($this->queue, 'optionalPackages')) {
$container = new container\MultipleSelectionFormElementContainer();
self::addQueueEntries($package, $dependentPackages);
}
- /**
- * Get all packages which require this package.
- *
- * @param integer $packageID
- * @return array
- */
- public static function getPackageDependencies($packageID) {
- $sql = "SELECT *
- FROM wcf".WCF_N."_package
- WHERE packageID IN (
- SELECT packageID
- FROM wcf".WCF_N."_package_requirement_map
- WHERE requirement = ?
- )";
- $statement = WCF::getDB()->prepareStatement($sql);
- $statement->execute(array($packageID));
- $packages = array();
- while ($row = $statement->fetchArray()) {
- $packages[] = $row;
- }
-
- return $packages;
- }
-
- /**
- * Returns an ordered list of depenencies for given package id. The order is
- * curcial, whereas the first package has to be uninstalled first.
- *
- * @package integer
- * @return wcf\data\package\PackageList
- */
- public static function getOrderedPackageDependencies($packageID) {
- $sql = "SELECT packageID, MAX(level) AS level
- FROM wcf".WCF_N."_package_requirement_map
- WHERE requirement = ?
- GROUP BY packageID";
- $statement = WCF::getDB()->prepareStatement($sql);
- $statement->execute(array($packageID));
-
- $dependencies = array();
- while ($row = $statement->fetchArray()) {
- $dependencies[$row['packageID']] = $row['level'];
- }
-
- $packageIDs = array();
- $maxLevel = max(array_values($dependencies));
- if ($maxLevel == 0) {
- // order does not matter
- $packageIDs = array_keys($dependencies);
- }
- else {
- // order by level while ignoring individual connections as they don't
- // matter if uninstall begins with the lowest dependency in tree
- for ($i = $maxLevel; $i >= 0; $i--) {
- foreach ($dependencies as $packageID => $level) {
- if ($level == $i) {
- $packageIDs[] = $packageID;
- unset($dependencies[$packageID]);
- }
- }
- }
- }
-
- // get packages
- $packageList = new PackageList();
- $packageList->sqlLimit = 0;
- $packageList->getConditionBuilder()->add("packageID IN (?)", array($packageIDs));
- $packageList->readObjects();
-
- return $packageList;
- }
-
- /**
- * Returns true if package has dependencies
- *
- * @param integer $packageID
- * @return boolean
- */
- public static function hasDependencies($packageID) {
- $sql = "SELECT COUNT(*) AS count
- FROM wcf".WCF_N."_package_requirement
- WHERE requirement = ?";
- $statement = WCF::getDB()->prepareStatement($sql);
- $statement->execute(array($packageID));
- $row = $statement->fetchArray();
-
- return ($row['count'] > 0);
- }
-
/**
* Adds an uninstall entry to the package installation queue.
*
$this->node = $this->getToken();
}
- // build nodes for dependent packages
- $this->buildDependentPackageNodes();
-
// build pip nodes
$this->buildPluginNodes();
$this->buildPackageNode();
}
- /**
- * Builds nodes for all dependent packages.
- */
- protected function buildDependentPackageNodes() {
- if (!PackageUninstallationDispatcher::hasDependencies($this->installation->queue->packageID)) {
- return;
- }
-
- $packageList = PackageUninstallationDispatcher::getOrderedPackageDependencies($this->installation->queue->packageID);
- $queue = $this->installation->queue;
-
- foreach ($packageList as $package) {
- $queue = PackageInstallationQueueEditor::create(array(
- 'processNo' => $queue->processNo,
- 'parentQueueID' => $queue->queueID,
- 'userID' => WCF::getUser()->userID,
- 'package' => $package->package,
- 'packageName' => $package->getName(),
- 'packageID' => $package->packageID,
- 'action' => 'uninstall'
- ));
-
- // spawn nodes
- $uninstallation = new PackageUninstallationDispatcher($queue);
- $uninstallation->nodeBuilder->setParentNode($this->node);
- $uninstallation->nodeBuilder->buildNodes();
- $this->parentNode = $uninstallation->nodeBuilder->getCurrentNode();
- $this->node = $this->getToken();
- }
- }
-
/**
* @see wcf\system\package\PackageInstallationNodeBuilder::buildPluginNodes()
*/
UNIQUE KEY packageID (packageID, requirement)
);
-DROP TABLE IF EXISTS wcf1_package_requirement_map;
-CREATE TABLE wcf1_package_requirement_map (
- packageID INT(10) NOT NULL,
- requirement INT(10) NOT NULL,
- level INT(10) NOT NULL DEFAULT 0,
- UNIQUE KEY packageID (packageID, requirement)
-);
-
DROP TABLE IF EXISTS wcf1_package_update;
CREATE TABLE wcf1_package_update (
packageUpdateID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
ALTER TABLE wcf1_package_requirement ADD FOREIGN KEY (packageID) REFERENCES wcf1_package (packageID) ON DELETE CASCADE;
ALTER TABLE wcf1_package_requirement ADD FOREIGN KEY (requirement) REFERENCES wcf1_package (packageID) ON DELETE CASCADE;
-ALTER TABLE wcf1_package_requirement_map ADD FOREIGN KEY (packageID) REFERENCES wcf1_package (packageID) ON DELETE CASCADE;
-ALTER TABLE wcf1_package_requirement_map ADD FOREIGN KEY (requirement) REFERENCES wcf1_package (packageID) ON DELETE CASCADE;
-
ALTER TABLE wcf1_package_update ADD FOREIGN KEY (packageUpdateServerID) REFERENCES wcf1_package_update_server (packageUpdateServerID) ON DELETE CASCADE;
ALTER TABLE wcf1_package_update_exclusion ADD FOREIGN KEY (packageUpdateVersionID) REFERENCES wcf1_package_update_version (packageUpdateVersionID) ON DELETE CASCADE;