From 456008dbd19ec695df9b143abc8b3f3ce5934ebe Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Fri, 7 Oct 2011 17:20:04 +0200 Subject: [PATCH] Optional packages are working right now Hooray! --- .../PackageInstallationDispatcher.class.php | 54 ++++++++++++++----- .../PackageInstallationNodeBuilder.class.php | 53 +++++++++++++++++- wcfsetup/setup/db/install.sql | 2 +- 3 files changed, 94 insertions(+), 15 deletions(-) diff --git a/wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php b/wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php index ed565dcd61..1d1bfe6a10 100644 --- a/wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php +++ b/wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php @@ -101,7 +101,7 @@ class PackageInstallationDispatcher { break; case 'optionalPackages': - $step = $this->selectOptionalPackages($nodeData); + $step = $this->selectOptionalPackages($node, $nodeData); break; default: @@ -110,7 +110,7 @@ class PackageInstallationDispatcher { } if ($step->splitNode()) { - $this->nodeBuilder->insertNode($node, $data['sequenceNo']); + $this->nodeBuilder->cloneNode($node, $data['sequenceNo']); break; } } @@ -340,15 +340,50 @@ class PackageInstallationDispatcher { return $installationStep; } - protected function selectOptionalPackages(array $nodeData) { + protected function selectOptionalPackages($currentNode, array $nodeData) { $installationStep = new PackageInstallationStep(); $document = $this->promptOptionalPackages($nodeData); if ($document !== null && $document instanceof form\FormDocument) { $installationStep->setDocument($document); + $installationStep->setSplitNode(); + } + // insert new nodes for each package + else if (is_array($document)) { + // get target child node + $node = $currentNode; + $queue = $this->queue; + $shiftNodes = false; + + foreach ($nodeData as $package) { + if (in_array($package['package'], $document)) { + if (!$shiftNodes) { + $this->nodeBuilder->shiftNodes($currentNode, 'tempNode'); + $shiftNodes = true; + } + + $queue = PackageInstallationQueueEditor::create(array( + 'parentQueueID' => $queue->queueID, + 'processNo' => $this->queue->processNo, + 'userID' => WCF::getUser()->userID, + 'package' => $package['package'], + 'packageName' => $package['packageName'], + 'archive' => $package['archive'], + 'action' => $queue->action + )); + + $installation = new PackageInstallationDispatcher($queue); + $installation->nodeBuilder->setParentNode($node); + $installation->nodeBuilder->buildNodes(); + $node = $installation->nodeBuilder->getCurrentNode(); + } + } + + // shift nodes + if ($shiftNodes) { + $this->nodeBuilder->shiftNodes('tempNode', $node); + } } - - $installationStep->setSplitNode(); return $installationStep; } @@ -445,14 +480,7 @@ class PackageInstallationDispatcher { $document = PackageInstallationFormManager::getForm($this->queue, 'optionalPackages'); $document->handleRequest(); - $packages = $document->getValue('optionalPackages'); - if (!empty($packages)) { - foreach ($packages as $package) { - // haha, this is going to be mad - - } - } - die('
'.print_r($packages, true));
+			return $document->getValue('optionalPackages');
 		}
 	}
 	
diff --git a/wcfsetup/install/files/lib/system/package/PackageInstallationNodeBuilder.class.php b/wcfsetup/install/files/lib/system/package/PackageInstallationNodeBuilder.class.php
index 2218da4e43..219865add0 100644
--- a/wcfsetup/install/files/lib/system/package/PackageInstallationNodeBuilder.class.php
+++ b/wcfsetup/install/files/lib/system/package/PackageInstallationNodeBuilder.class.php
@@ -214,7 +214,7 @@ class PackageInstallationNodeBuilder {
 	 * @param	string		$node
 	 * @param	integer		$sequenceNo
 	 */
-	public function insertNode($node, $sequenceNo) {
+	public function cloneNode($node, $sequenceNo) {
 		$newNode = $this->getToken();
 		
 		// update descendants
@@ -277,6 +277,57 @@ class PackageInstallationNodeBuilder {
 		));
 	}
 	
+	/**
+	 * Inserts a node before given target node. Will shift all target
+	 * nodes to provide to be descendants of the new node. If you intend
+	 * to insert more than a single node, you should prefer shiftNodes().
+	 * 
+	 * @param	string		$beforeNode
+	 * @param	function	$callback
+	 */
+	public function insertNode($beforeNode, $callback) {
+		// verify if callback is a valid function
+		if (!is_callable($callback)) {
+			throw new SystemException("Provided callback is not a callable function.");
+		}
+		
+		$newNode = $this->getToken();
+		
+		// update descendants
+		$sql = "UPDATE	wcf".WCF_N."_package_installation_node
+			SET	parentNode = ?
+			WHERE	parentNode = ?
+				AND processNo = ?";
+		$statement = WCF::getDB()->prepareStatement($sql);
+		$statement->execute(array(
+			$newNode,
+			$beforeNode,
+			$this->installation->queue->processNo
+		));
+		
+		// execute callback
+		$callback($beforeNode, $newNode);
+	}
+	
+	/**
+	 * Shifts nodes to allow dynamic inserts at runtime.
+	 * 
+	 * @param	string		$oldParentNode
+	 * @param	string		$newParentNode
+	 */
+	public function shiftNodes($oldParentNode, $newParentNode) {
+		$sql = "UPDATE	wcf".WCF_N."_package_installation_node
+			SET	parentNode = ?
+			WHERE	parentNode = ?
+				AND processNo = ?";
+		$statement = WCF::getDB()->prepareStatement($sql);
+		$statement->execute(array(
+			$newParentNode,
+			$oldParentNode,
+			$this->installation->queue->processNo
+		));
+	}
+	
 	/**
 	 * Builds package node used to install the package itself.
 	 */
diff --git a/wcfsetup/setup/db/install.sql b/wcfsetup/setup/db/install.sql
index 4731a85fc1..ee887c1629 100644
--- a/wcfsetup/setup/db/install.sql
+++ b/wcfsetup/setup/db/install.sql
@@ -321,7 +321,7 @@ CREATE TABLE wcf1_package_installation_node (
 	sequenceNo SMALLINT(4) NOT NULL DEFAULT 0,
 	node CHAR(8) NOT NULL DEFAULT '',
 	parentNode CHAR(8) NOT NULL DEFAULT '',
-	nodeType ENUM('package', 'pip') NOT NULL DEFAULT 'package',
+	nodeType ENUM('optionalPackages','package', 'pip') NOT NULL DEFAULT 'package',
 	nodeData TEXT NOT NULL,
 	done TINYINT(1) NOT NULL DEFAULT 0
 );
-- 
2.20.1