Restored PIP validation for WCF 2.1
authorAlexander Ebert <ebert@woltlab.com>
Mon, 22 Sep 2014 16:08:36 +0000 (18:08 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Mon, 22 Sep 2014 16:08:36 +0000 (18:08 +0200)
wcfsetup/install/files/lib/system/package/validation/PackageValidationArchive.class.php
wcfsetup/install/files/lib/system/package/validation/PackageValidationManager.class.php

index 2b7186d699d12c9b41955c623e445b787c0811da..d568c6084ba61e4deb35b009ba074e41aa218a24 100644 (file)
@@ -92,7 +92,7 @@ class PackageValidationArchive implements \RecursiveIterator {
                                $this->archive->openArchive();
                                
                                // check if package is installable or suitable for an update
-                               $this->validateInstructions($requiredVersion);
+                               $this->validateInstructions($requiredVersion, $validationMode);
                        }
                        catch (\Exception $e) {
                                $this->exception = $e;
@@ -184,8 +184,9 @@ class PackageValidationArchive implements \RecursiveIterator {
         * Validates if the package has suitable install or update instructions
         * 
         * @param       string          $requiredVersion
+        * @param       integer         $validationMode
         */
-       protected function validateInstructions($requiredVersion) {
+       protected function validateInstructions($requiredVersion, $validationMode) {
                $package = $this->getPackage();
                
                // delivered package does not provide the minimum required version
@@ -203,6 +204,10 @@ class PackageValidationArchive implements \RecursiveIterator {
                        if (empty($instructions)) {
                                throw new PackageValidationException(PackageValidationException::NO_INSTALL_PATH, array('packageName' => $this->archive->getPackageInfo('name')));
                        }
+                       
+                       if ($validationMode == PackageValidationManager::VALIDATION_RECURSIVE) {
+                               $this->validatePackageInstallationPlugins('install', $instructions);
+                       }
                }
                else {
                        // package is already installed, check update path
@@ -213,6 +218,29 @@ class PackageValidationArchive implements \RecursiveIterator {
                                        'deliveredPackageVersion' => $this->archive->getPackageInfo('version')
                                ));
                        }
+                       
+                       if ($validationMode === PackageValidationManager::VALIDATION_RECURSIVE) {
+                               $this->validatePackageInstallationPlugins('update', $this->archive->getUpdateInstructions());
+                       }
+               }
+       }
+       
+       /**
+        * Validates install or update instructions against the corresponding PIP, unknown PIPs will be silently ignored.
+        *
+        * @param       string          $type
+        * @param       array<array>    $instructions
+        */
+       protected function validatePackageInstallationPlugins($type, array $instructions) {
+               for ($i = 0, $length = count($instructions); $i < $length; $i++) {
+                       $instruction = $instructions[$i];
+                       if (!PackageValidationManager::getInstance()->validatePackageInstallationPluginInstruction($this->archive, $instruction['pip'], $instruction['value'])) {
+                               throw new PackageValidationException(PackageValidationException::MISSING_INSTRUCTION_FILE, array(
+                                       'pip' => $instruction['pip'],
+                                       'type' => $type,
+                                       'value' => $instruction['value']
+                               ));
+                       }
                }
        }
        
index 7804873fb7f20d24e34a96b42ccbb52c5d1c2fc0..e0f19ab74f11fec4a89f742399d73da6f811ee6a 100644 (file)
@@ -16,6 +16,12 @@ use wcf\system\SingletonFactory;
  * @category   Community Framework
  */
 class PackageValidationManager extends SingletonFactory {
+       /**
+        * list of known package installation plugins
+        * @var array<string>
+        */
+       protected $packageInstallationPlugins = array();
+       
        /**
         * package validation archive object
         * @var \wcf\system\package\validation\PackageValidationArchive
@@ -46,6 +52,17 @@ class PackageValidationManager extends SingletonFactory {
         */
        const VALIDATION_EXCLUSION = 2;
        
+       /**
+        * @see \wcf\system\SingletonFactory::init()
+        */
+       protected function init() {
+               $pipList = new PackageInstallationPluginList();
+               $pipList->readObjects();
+               foreach ($pipList as $pip) {
+                       $this->packageInstallationPlugins[$pip->pluginName] = $pip->className;
+               }
+       }
+       
        /**
         * Validates given archive for existance and ability to be installed/updated. If you set the
         * second parameter $deepInspection to "false", the system will only check if the archive
@@ -155,4 +172,22 @@ class PackageValidationManager extends SingletonFactory {
                
                return null;
        }
+       
+       /**
+        * Validates an instruction against the corresponding package installation plugin.
+        *
+        * Please be aware that unknown PIPs will silently ignored and cause no error.
+        *
+        * @param       \wcf\data\package\PackageArchive        $archive
+        * @param       string                                  $pip
+        * @param       string                                  $instruction
+        * @return      boolean
+        */
+       public function validatePackageInstallationPluginInstruction(PackageArchive $archive, $pip, $instruction) {
+               if (isset($this->packageInstallationPlugins[$pip])) {
+                       return call_user_func(array($this->packageInstallationPlugins[$pip], 'isValid'), $archive, $instruction);
+               }
+               
+               return true;
+       }
 }