Experimental support for nested packages
authorAlexander Ebert <ebert@woltlab.com>
Tue, 4 Oct 2011 17:57:16 +0000 (19:57 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Tue, 4 Oct 2011 17:57:16 +0000 (19:57 +0200)
wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php
wcfsetup/install/files/lib/system/package/PackageInstallationNodeBuilder.class.php

index e8e549516ffe08e3992611c075b5b543fad1c8c8..cec793fe6a071bd9003f33a19fb3c867aad9085a 100644 (file)
@@ -32,42 +32,36 @@ use wcf\util\StringUtil;
 class PackageInstallationDispatcher {
        /**
         * current installation type
-        *
         * @var string
         */
        protected $action = '';
        
        /**
         * instance of PackageArchive
-        *
-        * @var PackageArchive
+        * @var wcf\system\package\PackageArchive
         */
        public $archive = null;
        
        /**
         * instance of PackageInstallationNodeBuilder
-        *
-        * @var PackageInstallationNodeBuilder
+        * @var wcf\system\package\PackageInstallationNodeBuilder
         */
        public $nodeBuilder = null;
        
        /**
         * instance of Package
-        *
-        * @var Package
+        * @var wcf\data\package\Package
         */
        public $package = null;
        
        /**
         * instance of PackageInstallationQueue
-        *
-        * @var PackageInstallationQueue
+        * @var wcf\system\package\PackageInstallationQueue
         */
        public $queue = null;
        
        /**
         * default name of the config file
-        *
         * @var string
         */
        const CONFIG_FILE = 'config.inc.php';
index 428b75e550c3eed0ad885d736725f24e75633a2d..1bde19551222a869c89830149b930ab4142fc371 100644 (file)
@@ -52,6 +52,15 @@ class PackageInstallationNodeBuilder {
                $this->installation = $installation;
        }
        
+       /**
+        * Sets parent node.
+        * 
+        * @param       string          $parentNode
+        */
+       public function setParentNode($parentNode) {
+               $this->parentNode = $parentNode;
+       }
+       
        /**
         * Builds nodes for current installation queue.
         */
@@ -177,11 +186,9 @@ class PackageInstallationNodeBuilder {
                
                $sql = "SELECT  done
                        FROM    wcf".WCF_N."_package_installation_node
-                       WHERE   queueID = ?
-                               AND processNo = ?";
+                       WHERE   processNo = ?";
                $statement = WCF::getDB()->prepareStatement($sql);
                $statement->execute(array(
-                       $this->installation->queue->queueID,
                        $this->installation->queue->processNo
                ));
                while ($row = $statement->fetchArray()) {
@@ -339,6 +346,7 @@ class PackageInstallationNodeBuilder {
         */
        protected function buildRequirementNodes() {
                $packageNodes = array();
+               $queue = $this->installation->queue;
                
                $requiredPackages = $this->installation->getArchive()->getRequirements();
                foreach ($requiredPackages as $packageName => $package) {
@@ -347,40 +355,51 @@ class PackageInstallationNodeBuilder {
                                continue;
                        }
                        
-                       $this->parentNode = $this->node;
-                       $this->node = $this->getToken();
-                       $this->sequenceNo = 0;
+                       if ($this->node == '' && !empty($this->parentNode)) {
+                               $this->node = $this->parentNode;
+                       }
                        
-                       $packageNodes[] = array(
-                               'data' => array(
-                                       'file' => $package['file'],
-                                       'packageName' => $packageName
-                               ),
-                               'node' => $this->node,
-                               'parentNode' => $this->parentNode,
-                               'sequenceNo' => $this->sequenceNo
-                       );
-               }
-               
-               if (!empty($packageNodes)) {
-                       $sql = "INSERT INTO     wcf".WCF_N."_package_installation_node
-                                               (queueID, processNo, sequenceNo, node, parentNode, nodeType, nodeData)
-                               VALUES          (?, ?, ?, ?, ?, ?, ?)";
-                       $statement = WCF::getDB()->prepareStatement($sql);
-                       foreach ($packageNodes as $nodeData) {
-                               $statement->execute(array(
-                                       $this->installation->queue->queueID,
-                                       $this->installation->queue->processNo,
-                                       $nodeData['sequenceNo'],
-                                       $nodeData['node'],
-                                       $nodeData['parentNode'],
-                                       'requiredPackage',
-                                       serialize($nodeData['data'])
-                               ));
+                       // extract package
+                       $index = $this->installation->getArchive()->getTar()->getIndexByFilename($package['file']);
+                       if ($index === false) {
+                               throw new SystemException("Unable to find required package '".$package['file']."' within archive.");
                        }
+                       
+                       $fileName = FileUtil::getTemporaryFilename('package_', preg_replace('!^.*(?=\.(?:tar\.gz|tgz|tar)$)!i', '', basename($package['file'])));
+                       $this->installation->getArchive()->getTar()->extract($index, $fileName);
+                       
+                       // get archive data
+                       $archive = new PackageArchive($fileName);
+                       $archive->openArchive();
+                       
+                       // create new queue
+                       $queue = PackageInstallationQueueEditor::create(array(
+                               'parentQueueID' => $queue->queueID,
+                               'processNo' => $queue->processNo,
+                               'userID' => WCF::getUser()->userID,
+                               'package' => $archive->getPackageInfo('name'),
+                               'packageName' => $archive->getPackageInfo('packageName'),
+                               'archive' => $fileName,
+                               'action' => $queue->action
+                       ));
+                       
+                       // spawn nodes
+                       $installation = new PackageInstallationDispatcher($queue);
+                       $installation->nodeBuilder->setParentNode($this->node);
+                       $installation->nodeBuilder->buildNodes();
+                       $this->node = $installation->nodeBuilder->getCurrentNode();
                }
        }
        
+       /**
+        * Returns current node
+        * 
+        * @return      string
+        */
+       public function getCurrentNode() {
+               return $this->node;
+       }
+       
        /**
         * Builds package installation plugin nodes, whereas pips could be grouped within
         * one node, differ from each by nothing but the sequence number.