From: Alexander Ebert Date: Sat, 29 Dec 2012 00:51:46 +0000 (+0100) Subject: Fixed package uninstallation and removed requirement map X-Git-Tag: 2.0.0_Beta_1~663 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=cd0fbe9ab6dfd015b0571a16f08cdcf44caa0590;p=GitHub%2FWoltLab%2FWCF.git Fixed package uninstallation and removed requirement map Fixes #962 Fixes #1002 Fixes #1021 --- diff --git a/wcfsetup/install/files/lib/acp/action/UninstallPackageAction.class.php b/wcfsetup/install/files/lib/acp/action/UninstallPackageAction.class.php index 58d85dddce..0e513da56e 100644 --- a/wcfsetup/install/files/lib/acp/action/UninstallPackageAction.class.php +++ b/wcfsetup/install/files/lib/acp/action/UninstallPackageAction.class.php @@ -103,6 +103,7 @@ class UninstallPackageAction extends InstallPackageAction { * @return string */ public function stepUninstall() { + die("current node is ".$this->node); $node = $this->installation->uninstall($this->node); if ($node == '') { diff --git a/wcfsetup/install/files/lib/data/package/Package.class.php b/wcfsetup/install/files/lib/data/package/Package.class.php index c90463f987..27378dcd94 100644 --- a/wcfsetup/install/files/lib/data/package/Package.class.php +++ b/wcfsetup/install/files/lib/data/package/Package.class.php @@ -32,10 +32,10 @@ class Package extends DatabaseObject { protected static $databaseTableIndexName = 'packageID'; /** - * package requirement map + * package requirements * @var array */ - protected static $requirementMap = null; + protected static $requirements = null; /** * list of packages that this package requires @@ -61,9 +61,9 @@ class Package extends DatabaseObject { * @return boolean */ public function isRequired() { - self::loadRequirementMap(); + self::loadRequiremens(); - return (isset(self::$requirementMap[$this->packageID])); + return (isset(self::$requirements[$this->packageID])); } /** @@ -160,8 +160,8 @@ class Package extends DatabaseObject { 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; } @@ -187,43 +187,22 @@ class Package extends DatabaseObject { } /** - * 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']; } } } @@ -333,81 +312,6 @@ class Package extends DatabaseObject { 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. * diff --git a/wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php b/wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php index b221662b13..f76cb3afcb 100644 --- a/wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php +++ b/wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php @@ -1,7 +1,5 @@ packageID); - // reload queue $this->queue = new PackageInstallationQueue($this->queue->queueID); $this->package = null; @@ -460,7 +456,13 @@ class PackageInstallationDispatcher { 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(); @@ -510,7 +512,7 @@ class PackageInstallationDispatcher { } /** - * 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 @@ -603,7 +605,11 @@ class PackageInstallationDispatcher { } } - // @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(); diff --git a/wcfsetup/install/files/lib/system/package/PackageUninstallationDispatcher.class.php b/wcfsetup/install/files/lib/system/package/PackageUninstallationDispatcher.class.php index ae6f96ed1e..62a4f1d695 100644 --- a/wcfsetup/install/files/lib/system/package/PackageUninstallationDispatcher.class.php +++ b/wcfsetup/install/files/lib/system/package/PackageUninstallationDispatcher.class.php @@ -184,95 +184,6 @@ class PackageUninstallationDispatcher extends PackageInstallationDispatcher { 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. * diff --git a/wcfsetup/install/files/lib/system/package/PackageUninstallationNodeBuilder.class.php b/wcfsetup/install/files/lib/system/package/PackageUninstallationNodeBuilder.class.php index b21e74265e..1fdb709977 100644 --- a/wcfsetup/install/files/lib/system/package/PackageUninstallationNodeBuilder.class.php +++ b/wcfsetup/install/files/lib/system/package/PackageUninstallationNodeBuilder.class.php @@ -23,9 +23,6 @@ class PackageUninstallationNodeBuilder extends PackageInstallationNodeBuilder { $this->node = $this->getToken(); } - // build nodes for dependent packages - $this->buildDependentPackageNodes(); - // build pip nodes $this->buildPluginNodes(); @@ -33,37 +30,6 @@ class PackageUninstallationNodeBuilder extends PackageInstallationNodeBuilder { $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() */ diff --git a/wcfsetup/setup/db/install.sql b/wcfsetup/setup/db/install.sql index f2866cb8fb..7922d74d30 100644 --- a/wcfsetup/setup/db/install.sql +++ b/wcfsetup/setup/db/install.sql @@ -396,14 +396,6 @@ CREATE TABLE wcf1_package_requirement ( 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, @@ -803,9 +795,6 @@ ALTER TABLE wcf1_package_installation_sql_log ADD FOREIGN KEY (packageID) REFERE 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;