Optional packages are working right now
authorAlexander Ebert <ebert@woltlab.com>
Fri, 7 Oct 2011 15:20:04 +0000 (17:20 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Fri, 7 Oct 2011 15:20:04 +0000 (17:20 +0200)
Hooray!

wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php
wcfsetup/install/files/lib/system/package/PackageInstallationNodeBuilder.class.php
wcfsetup/setup/db/install.sql

index ed565dcd6123e9914a1c518b3d05455970789785..1d1bfe6a10f1f6c475262c1693981e3d9f85d7dd 100644 (file)
@@ -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('<pre>'.print_r($packages, true));
+                       return $document->getValue('optionalPackages');
                }
        }
        
index 2218da4e437f12b74588f3a1ee832cfd7190f035..219865add074040e19742dc388c64710bbb57cc5 100644 (file)
@@ -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.
         */
index 4731a85fc156b44b775b8f2a67ceec8437f42361..ee887c1629f4762334544251965a5736e2bdc63c 100644 (file)
@@ -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
 );