Fixed requirements detection during installation
authorAlexander Ebert <ebert@woltlab.com>
Fri, 24 Feb 2012 14:04:05 +0000 (15:04 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Fri, 24 Feb 2012 14:04:05 +0000 (15:04 +0100)
wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php
wcfsetup/install/files/lib/system/package/PackageInstallationNodeBuilder.class.php

index c7253a7e71307491d2b0e231c03d8ac5cf821f88..e92e785f7b78c9aa17c48d8a6c0f5b6e3de947b0 100644 (file)
@@ -167,6 +167,42 @@ class PackageInstallationDispatcher {
        protected function installPackage(array $nodeData) {
                $installationStep = new PackageInstallationStep();
                
+               // check requirements
+               if (!empty($nodeData['requirements'])) {
+                       foreach ($nodeData['requirements'] as $package => $requirementData) {
+                               // get existing package
+                               if ($requirementData['packageID']) {
+                                       $sql = "SELECT  packageName, packageVersion
+                                               FROM    wcf".WCF_N."_package
+                                               WHERE   packageID = ?";
+                                       $statement = WCF::getDB()->prepareStatement($sql);
+                                       $statement->execute(array($requirementData['packageID']));
+                               }
+                               else {
+                                       // try to find matching package
+                                       $sql = "SELECT  packageName, packageVersion
+                                               FROM    wcf".WCF_N."_package
+                                               WHERE   package = ?";
+                                       $statement = WCF::getDB()->prepareStatement($sql);
+                                       $statement->execute(array($package));
+                               }
+                               $row = $statement->fetchArray();
+                               
+                               // package is required but not available
+                               if ($row === false) {
+                                       throw new SystemException("Package '".$package."' is required by '".$nodeData['packageName']."', but is neither installed nor shipped.");
+                               }
+                               
+                               // check version requirements
+                               if ($requirementData['minVersion']) {
+                                       if (Package::compareVersion($row['packageVersion'], $requirementData['minVersion']) < 0) {
+                                               throw new SystemException("Package '".$nodeData['packageName']."' requires the package '".$row['packageName']."' in version '".$requirementData['minVersion']."', but version '".$row['packageVersion']."'");
+                                       }
+                               }
+                       }
+               }
+               unset($nodeData['requirements']);
+               
                if (!$this->queue->packageID) {
                        // create package entry
                        $package = PackageEditor::create($nodeData);
index 502e2eace7ebf1687af4631a05c70236b469c377..8f641d0cb3cf2fb9e74b30149b5137bff62081bc 100644 (file)
@@ -41,6 +41,12 @@ class PackageInstallationNodeBuilder {
         */
        public $parentNode = '';
        
+       /**
+        * list of requirements to be checked before package installation
+        * @var array<array>
+        */
+       public $requirements = array();
+       
        /**
         * current sequence number within one node
         *
@@ -397,7 +403,8 @@ class PackageInstallationNodeBuilder {
                                'author' => $this->installation->getArchive()->getAuthorInfo('author'),
                                'authorURL' => $this->installation->getArchive()->getAuthorInfo('authorURL') !== null ? $this->installation->getArchive()->getAuthorInfo('authorURL') : '',
                                'installDate' => TIME_NOW,
-                               'updateDate' => TIME_NOW
+                               'updateDate' => TIME_NOW,
+                               'requirements' => $this->requirements
                        ))
                ));
        }
@@ -414,25 +421,12 @@ class PackageInstallationNodeBuilder {
                $requiredPackages = $this->installation->getArchive()->getOpenRequirements();
                foreach ($requiredPackages as $packageName => $package) {
                        if (!isset($package['file'])) {
-                               // package is installed but version does not match
-                               if ($package['packageID']) {
-                                       // get package version
-                                       $sql = "SELECT  packageVersion
-                                               FROM    wcf".WCF_N."_package
-                                               WHERE   packageID = ?";
-                                       $statement = WCF::getDB()->prepareStatement($sql);
-                                       $statement->execute(array($package['packageID']));
-                                       $row = $statement->fetchArray();
-                                       
-                                       throw new SystemException("Package '".$this->installation->getArchive()->getPackageInfo('packageName')."' requires the package '".$packageName."' in version '".$package['minversion']."', but '".$row['packageVersion']."' is installed.");
-                               }
-                               
-                               // package is required but not installed
-                               if (!$package['packageID']) {
-                                       throw new SystemException("Package '".$this->installation->getArchive()->getPackageInfo('packageName')."' requires the package '".$packageName."', but it is neither installed nor shipped.");
-                               }
+                               // requirements will be checked once package is about to be installed
+                               $this->requirements[$packageName] = array(
+                                       'minVersion' => (isset($package['minversion'])) ?: '',
+                                       'packageID' => $package['packageID']
+                               );
                                
-                               // ignore requirements which are not to be installed, but are already available
                                continue;
                        }