Updated package validation
authorAlexander Ebert <ebert@woltlab.com>
Mon, 14 Apr 2014 13:45:59 +0000 (15:45 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Mon, 14 Apr 2014 13:45:59 +0000 (15:45 +0200)
13 files changed:
wcfsetup/install/files/lib/acp/form/PackageStartInstallForm.class.php
wcfsetup/install/files/lib/acp/page/PackageInstallationConfirmPage.class.php
wcfsetup/install/files/lib/system/package/plugin/ACPTemplatePackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/AbstractPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/AbstractXMLPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/FilePackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/IPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/SQLPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/TemplatePackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/validation/PackageValidationArchive.class.php
wcfsetup/install/files/lib/system/package/validation/PackageValidationException.class.php
wcfsetup/install/files/lib/system/package/validation/PackageValidationManager.class.php
wcfsetup/install/lang/de.xml

index a3da2c78accdd7d553fcbf21fdaec46fe6b09c61..5e711b75253f05562efbe27693f4bc9f3e49163a 100755 (executable)
@@ -137,14 +137,12 @@ class PackageStartInstallForm extends AbstractForm {
                        throw new UserInputException('uploadPackage', 'uploadFailed');
                }
                
-               if (PackageValidationManager::getInstance()->validate($this->uploadPackage['name'], false)) {
-                       die("win");
+               if (!PackageValidationManager::getInstance()->validate($this->uploadPackage['name'], false)) {
+                       // TODO: do something
+                       die("validation failed");
                }
-               else {
-                       die("failed");
-               }
-               $this->archive = new PackageArchive($this->uploadPackage['name'], $this->package);
-               $this->validateArchive('uploadPackage');
+               
+               $this->package = PackageValidationManager::getInstance()->getPackageValidationArchive()->getPackage();
        }
        
        /**
@@ -255,12 +253,12 @@ class PackageStartInstallForm extends AbstractForm {
                }
                
                // insert queue
-               $isApplication = $this->archive->getPackageInfo('isApplication');
+               $isApplication = PackageValidationManager::getInstance()->getPackageValidationArchive()->getArchive()->getPackageInfo('isApplication');
                $this->queue = PackageInstallationQueueEditor::create(array(
                        'processNo' => $processNo,
                        'userID' => WCF::getUser()->userID,
-                       'package' => $this->archive->getPackageInfo('name'),
-                       'packageName' => $this->archive->getLocalizedPackageInfo('packageName'),
+                       'package' => PackageValidationManager::getInstance()->getPackageValidationArchive()->getArchive()->getPackageInfo('name'),
+                       'packageName' => PackageValidationManager::getInstance()->getPackageValidationArchive()->getArchive()->getLocalizedPackageInfo('packageName'),
                        'packageID' => $packageID,
                        'archive' => $archive,
                        'action' => ($this->package != null ? 'update' : 'install'),
index 3864f72b62825c6e6de357b82d2e1f53df8ba601..0fd64fa803fc7854338e1de894061a72d9eda73a 100644 (file)
@@ -9,6 +9,7 @@ use wcf\system\package\PackageArchive;
 use wcf\system\package\PackageInstallationDispatcher;
 use wcf\system\WCF;
 use wcf\system\WCFACP;
+use wcf\system\package\validation\PackageValidationManager;
 
 /**
  * Shows a confirmation page prior to start installing.
@@ -102,6 +103,19 @@ class PackageInstallationConfirmPage extends AbstractPage {
                
                $this->packageInstallationDispatcher = new PackageInstallationDispatcher($this->queue);
                
+               // validate the package and all it's requirements
+               if (PackageValidationManager::getInstance()->validate($this->queue->archive, true)) {
+                       die("success");
+               }
+               else {
+                       /*echo "<pre>";
+                       foreach (PackageValidationManager::getInstance()->getPackageValidationArchiveList() as $archive) {
+                               echo '[' . $archive->getArchive()->getPackageInfo('name') . '] ' . $archive->getExceptionMessage() . "\n";
+                       }
+                       die("failed");*/
+                       return;
+               }
+               
                // get requirements
                $this->requirements = $this->packageInstallationDispatcher->getArchive()->getRequirements();
                $this->openRequirements = $this->packageInstallationDispatcher->getArchive()->getOpenRequirements();
@@ -157,10 +171,11 @@ class PackageInstallationConfirmPage extends AbstractPage {
                
                WCF::getTPL()->assign(array(
                        'archive' => $this->packageInstallationDispatcher->getArchive(),
-                       'requiredPackages' => $this->requirements,
+                       /*'requiredPackages' => $this->requirements,
                        'missingPackages' => $this->missingPackages,
                        'excludingPackages' => $this->packageInstallationDispatcher->getArchive()->getConflictedExcludingPackages(),
-                       'excludedPackages' => $this->packageInstallationDispatcher->getArchive()->getConflictedExcludedPackages(),
+                       'excludedPackages' => $this->packageInstallationDispatcher->getArchive()->getConflictedExcludedPackages(),*/
+                       'packageValidationArchives' => PackageValidationManager::getInstance()->getPackageValidationArchiveList(),
                        'queue' => $this->queue,
                        'installingImportedStyle' => $this->installingImportedStyle
                ));
index f1d76d46a7d4ffa5193e481d1a6aa1bdb5b79db8..0f7afb9eb8ef4ef65e1e72ebe5dd20e02d0398e3 100644 (file)
@@ -3,6 +3,7 @@ namespace wcf\system\package\plugin;
 use wcf\data\application\Application;
 use wcf\data\package\Package;
 use wcf\system\package\ACPTemplatesFileHandler;
+use wcf\system\package\PackageArchive;
 use wcf\system\WCF;
 
 /**
@@ -78,4 +79,25 @@ class ACPTemplatePackageInstallationPlugin extends AbstractPackageInstallationPl
                        parent::uninstall();
                }
        }
+       
+       /**
+        * @see \wcf\system\package\plugin\IPackageInstallationPlugin::isValid()
+        */
+       public static function isValid(PackageArchive $archive, $instruction) {
+               if (preg_match('~\.(tar(\.gz)?|tgz)$~', $instruction)) {
+                       // check if file actually exists
+                       try {
+                               if ($archive->getTar()->getIndexByFilename($instruction) === false) {
+                                       return false;
+                               }
+                       }
+                       catch (\SystemException $e) {
+                               return false;
+                       }
+                       
+                       return true;
+               }
+               
+               return false;
+       }
 }
index e4f0b42067657b5738bce3586bee7a0fda3dedf6..0ab137abd332524639ea25ccc7747458043ad851 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 namespace wcf\system\package\plugin;
 use wcf\system\event\EventHandler;
+use wcf\system\package\PackageArchive;
 use wcf\system\package\PackageInstallationDispatcher;
 use wcf\system\WCF;
 
@@ -99,4 +100,11 @@ abstract class AbstractPackageInstallationPlugin implements IPackageInstallation
                $statement = WCF::getDB()->prepareStatement($sql);
                $statement->execute(array($this->installation->getPackageID()));
        }
+       
+       /**
+        * @see \wcf\system\package\plugin\IPackageInstallationPlugin::isValid()
+        */
+       public static function isValid(PackageArchive $archive, $instruction) {
+               return true;
+       }
 }
index ab599a37ee6f0c550889e2a774c68a1104109489..853344d3efe3d87457161d8ea7afcca69938b356 100644 (file)
@@ -2,6 +2,7 @@
 namespace wcf\system\package\plugin;
 use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\exception\SystemException;
+use wcf\system\package\PackageArchive;
 use wcf\system\package\PackageInstallationDispatcher;
 use wcf\system\WCF;
 use wcf\util\FileUtil;
@@ -344,4 +345,25 @@ abstract class AbstractXMLPackageInstallationPlugin extends AbstractPackageInsta
                        return $showOrder;
                }
        }
+       
+       /**
+        * @see \wcf\system\package\plugin\IPackageInstallationPlugin::isValid()
+        */
+       public static function isValid(PackageArchive $archive, $instruction) {
+               if (preg_match('~\.xml$~', $instruction)) {
+                       // check if file actually exists
+                       try {
+                               if ($archive->getTar()->getIndexByFilename($instruction) === false) {
+                                       return false;
+                               }
+                       }
+                       catch (\SystemException $e) {
+                               return false;
+                       }
+                       
+                       return true;
+               }
+               
+               return false;
+       }
 }
index 75fe6fbd040cad5b9880f8a9af591b545f319501..02faf929e2ad832232ce2601be41fad6ac5fb159 100644 (file)
@@ -3,6 +3,7 @@ namespace wcf\system\package\plugin;
 use wcf\data\application\Application;
 use wcf\data\package\Package;
 use wcf\system\package\FilesFileHandler;
+use wcf\system\package\PackageArchive;
 use wcf\system\package\PackageInstallationDispatcher;
 use wcf\system\WCF;
 use wcf\util\StyleUtil;
@@ -106,4 +107,25 @@ class FilePackageInstallationPlugin extends AbstractPackageInstallationPlugin {
                        parent::uninstall();
                }
        }
+       
+       /**
+        * @see \wcf\system\package\plugin\IPackageInstallationPlugin::isValid()
+        */
+       public static function isValid(PackageArchive $archive, $instruction) {
+               if (preg_match('~\.(tar(\.gz)?|tgz)$~', $instruction)) {
+                       // check if file actually exists
+                       try {
+                               if ($archive->getTar()->getIndexByFilename($instruction) === false) {
+                                       return false;
+                               }
+                       }
+                       catch (\SystemException $e) {
+                               return false;
+                       }
+                       
+                       return true;
+               }
+               
+               return false;
+       }
 }
index d2fb5e5e89fccf2e9133d76027d292449525cde5..616324c2c1ca6a65939a57c444816323f76e9ab7 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\package\plugin;
+use wcf\system\package\PackageArchive;
 
 /**
  * Every PackageInstallationPlugin has to implement this interface.
@@ -34,4 +35,14 @@ interface IPackageInstallationPlugin {
         * Executes the uninstallation of this plugin.
         */
        public function uninstall();
+       
+       /**
+        * Validates if the passed instruction is valid for this package installation plugin. If anything is
+        * wrong with it, this method should return false.
+        * 
+        * @param       \wcf\system\package\PackageArchive      $packageArchive
+        * @param       string                                  $instruction
+        * @return      boolean
+        */
+       public static function isValid(PackageArchive $packageArchive, $instruction);
 }
index 993729ba535a07d4a1954f298e0cba4c56c0107d..59a27f8d34782abd8bf6e9e433630396e6f8ebb5 100644 (file)
@@ -3,6 +3,7 @@ namespace wcf\system\package\plugin;
 use wcf\data\package\Package;
 use wcf\data\package\PackageList;
 use wcf\system\exception\SystemException;
+use wcf\system\package\PackageArchive;
 use wcf\system\package\PackageInstallationSQLParser;
 use wcf\system\WCF;
 
@@ -150,4 +151,25 @@ class SQLPackageInstallationPlugin extends AbstractPackageInstallationPlugin {
                // extract sql file to string
                return $this->installation->getArchive()->getTar()->extractToString($fileindex);
        }
+       
+       /**
+        * @see \wcf\system\package\plugin\IPackageInstallationPlugin::isValid()
+        */
+       public static function isValid(PackageArchive $archive, $instruction) {
+               if (preg_match('~\.sql$~', $instruction)) {
+                       // check if file actually exists
+                       try {
+                               if ($archive->getTar()->getIndexByFilename($instruction) === false) {
+                                       return false;
+                               }
+                       }
+                       catch (\SystemException $e) {
+                               return false;
+                       }
+                       
+                       return true;
+               }
+               
+               return false;
+       }
 }
index f221b11eba627a238859cafbc5fe02e9e9a61761..b8a7b856e41525d2c2bf8277adc84c8fdf00fb7a 100644 (file)
@@ -2,6 +2,7 @@
 namespace wcf\system\package\plugin;
 use wcf\data\application\Application;
 use wcf\data\package\Package;
+use wcf\system\package\PackageArchive;
 use wcf\system\package\TemplatesFileHandler;
 use wcf\system\WCF;
 
@@ -80,4 +81,25 @@ class TemplatePackageInstallationPlugin extends AbstractPackageInstallationPlugi
                        parent::uninstall();
                }
        }
+       
+       /**
+        * @see \wcf\system\package\plugin\IPackageInstallationPlugin::isValid()
+        */
+       public static function isValid(PackageArchive $archive, $instruction) {
+               if (preg_match('~\.(tar(\.gz)?|tgz)$~', $instruction)) {
+                       // check if file actually exists
+                       try {
+                               if ($archive->getTar()->getIndexByFilename($instruction) === false) {
+                                       return false;
+                               }
+                       }
+                       catch (\SystemException $e) {
+                               return false;
+                       }
+                       
+                       return true;
+               }
+               
+               return false;
+       }
 }
index b9825fec3caf6b843fda5cc281401e287538aaa8..40587c3d10a8730bf92dc0486e8b0260b1e75378 100644 (file)
@@ -27,12 +27,30 @@ class PackageValidationArchive implements \RecursiveIterator {
         */
        protected $children = array();
        
+       /**
+        * nesting depth
+        * @var integer
+        */
+       protected $depth = 0;
+       
        /**
         * exception occured during validation
         * @var \Exception
         */
        protected $exception = null;
        
+       /**
+        * associated package object
+        * @var \wcf\data\package\Package
+        */
+       protected $package = null;
+       
+       /**
+        * parent package validation archive object
+        * @var \wcf\system\package\validation\PackageValidationArchive
+        */
+       protected $parent = null;
+       
        /**
         * children pointer
         * @var integer
@@ -42,10 +60,14 @@ class PackageValidationArchive implements \RecursiveIterator {
        /**
         * Creates a new package validation archive instance.
         * 
-        * @param       string          $archive
+        * @param       string                                                          $archive
+        * @param       \wcf\system\package\validation\PackageValidationArchive         $parent
+        * @param       integer                                                         $depth
         */
-       public function __construct($archive) {
+       public function __construct($archive, PackageValidationArchive $parent = null, $depth = 0) {
                $this->archive = new PackageArchive($archive);
+               $this->parent = $parent;
+               $this->depth = $depth;
        }
        
        /**
@@ -62,7 +84,7 @@ class PackageValidationArchive implements \RecursiveIterator {
                        $this->archive->openArchive();
                        
                        // check if package is installable or suitable for an update
-                       $this->validateInstructions($requiredVersion);
+                       $this->validateInstructions($requiredVersion, $deepInspection);
                }
                catch (\Exception $e) {
                        $this->exception = $e;
@@ -81,22 +103,28 @@ class PackageValidationArchive implements \RecursiveIterator {
                                
                                // traverse open requirements
                                foreach ($this->archive->getOpenRequirements() as $requirement) {
-                                       if (empty($requirement['file'])) {
-                                               throw new PackageValidationException(PackageValidationException::MISSING_REQUIREMENT, array(
-                                                       'packageName' => $requirement['name'],
-                                                       'packageVersion' => $requirement['minversion']
-                                               ));
-                                       }
-                                       
-                                       $archive = $this->archive->extractTar($requirement->file);
-                                       
-                                       $index = count($this->children);
-                                       $this->children[$index] = new PackageValidationArchive($archive);
-                                       if (!$this->children[$index]->validate(true, $requirement['minversion'])) {
-                                               return false;
+                                       $virtualPackageVersion = PackageValidationManager::getInstance()->getVirtualPackage($requirement['name']);
+                                       if ($virtualPackageVersion === null || Package::compareVersion($virtualPackageVersion, $requirement['minversion'], '<')) {
+                                               if (empty($requirement['file'])) {
+                                                       throw new PackageValidationException(PackageValidationException::MISSING_REQUIREMENT, array(
+                                                               'packageName' => $requirement['name'],
+                                                               'packageVersion' => $requirement['minversion']
+                                                       ));
+                                               }
+                                               
+                                               $archive = $this->archive->extractTar($requirement['file']);
+                                               
+                                               $index = count($this->children);
+                                               $this->children[$index] = new PackageValidationArchive($archive, $this, $this->depth + 1);
+                                               if (!$this->children[$index]->validate(true, $requirement['minversion'])) {
+                                                       return false;
+                                               }
+                                               
+                                               PackageValidationManager::getInstance()->addVirtualPackage(
+                                                       $this->children[$index]->getArchive()->getPackageInfo('name'),
+                                                       $this->children[$index]->getArchive()->getPackageInfo('version')
+                                               );
                                        }
-                                       
-                                       PackageValidationManager::getInstance()->addVirtualPackage($this->archive->getPackageInfo('name'), $this->archive->getPackageInfo('version'));
                                }
                        }
                        catch (PackageValidationException $e) {
@@ -110,8 +138,8 @@ class PackageValidationArchive implements \RecursiveIterator {
                
        }
        
-       protected function validateInstructions($requiredVersion) {
-               $package = PackageCache::getInstance()->getPackageByIdentifier($this->archive->getPackageInfo('name'));
+       protected function validateInstructions($requiredVersion, $deepInspection) {
+               $package = $this->getPackage();
                
                // delivered package does not provide the minimum required version
                if (Package::compareVersion($requiredVersion, $this->archive->getPackageInfo('version'), '>')) {
@@ -124,9 +152,12 @@ class PackageValidationArchive implements \RecursiveIterator {
                
                // package is not installed yet
                if ($package === null) {
-                       if (empty($this->archive->getInstallInstructions())) {
+                       $instructions = $this->archive->getInstallInstructions();
+                       if (empty($instructions)) {
                                throw new PackageValidationException(PackageValidationException::NO_INSTALL_PATH, array('packageName' => $this->archive->getPackageInfo('name')));
                        }
+                       
+                       $this->validatePackageInstallationPlugins('install', $instructions);
                }
                else {
                        // package is already installed, check update path
@@ -137,6 +168,22 @@ class PackageValidationArchive implements \RecursiveIterator {
                                        'deliveredPackageVersion' => $this->archive->getPackageInfo('version')
                                ));
                        }
+                       
+                       $this->validatePackageInstallationPlugins('update', $this->archive->getUpdateInstructions());
+               }
+               exit;
+       }
+       
+       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']
+                               ));
+                       }
                }
        }
        
@@ -147,7 +194,7 @@ class PackageValidationArchive implements \RecursiveIterator {
                }
                
                $excludedPackages = $this->archive->getConflictedExcludedPackages();
-               if (!empty($excludingPackages)) {
+               if (!empty($excludedPackages)) {
                        throw new PackageValidationException(PackageValidationException::EXCLUDED_PACKAGES, array('packages' => $excludedPackages));
                }
        }
@@ -169,6 +216,36 @@ class PackageValidationArchive implements \RecursiveIterator {
                return $this->exception->getMessage();
        }
        
+       public function getArchive() {
+               return $this->archive;
+       }
+       
+       public function getPackage() {
+               if ($this->package === null) {
+                       $this->package = PackageCache::getInstance()->getPackageByIdentifier($this->archive->getPackageInfo('name'));
+               }
+               
+               return $this->package;
+       }
+       
+       /**
+        * Returns nesting depth.
+        * 
+        * @return      integer
+        */
+       public function getDepth() {
+               return $this->depth;
+       }
+       
+       /**
+        * Sets the children of this package validation archive.
+        * 
+        * @param       array<\wcf\system\package\validation\PackageValidationArchive>          $children
+        */
+       public function setChildren(array $children) {
+               $this->children = $children;
+       }
+       
        /**
         * @see \Iterator::rewind()
         */
index 7484cc8daf85978d82b69785b3f471e247084ea2..44c97a46d4b18a5a8b3940ff5f0dc9a21cb2e103 100644 (file)
@@ -76,6 +76,18 @@ class PackageValidationException extends SystemException {
         */
        const INSUFFICIENT_VERSION = 9;
        
+       /**
+        * requirement is set but neither installed nor provided, expects the details 'packageName' and 'packageVersion'
+        * @var integer
+        */
+       const MISSING_REQUIREMENT = 10;
+       
+       /**
+        * file reference for a package installation plugin is missing, expects the details 'pip', 'type' and 'value'
+        * @var integer
+        */
+       const MISSING_INSTRUCTION_FILE = 11;
+       
        /**
         * Creates a new PackageArchiveValidationException.
         * 
@@ -103,7 +115,7 @@ class PackageValidationException extends SystemException {
         * @return      string
         */
        public function getErrorMessage() {
-               return WCF::getLanguage()->getDynamicVariable('wcf.package.validation.errorCode.' . $this->getCode(), $this->getDetails());
+               return WCF::getLanguage()->getDynamicVariable('wcf.acp.package.validation.errorCode.' . $this->getCode(), $this->getDetails());
        }
        
        /**
index 4e679eaed47323e27d62e94cea1db6bd3b573907..c599971b119c0aded52b2122aaa69adfef654e5c 100644 (file)
@@ -2,6 +2,8 @@
 namespace wcf\system\package\validation;
 use wcf\data\package\Package;
 use wcf\system\SingletonFactory;
+use wcf\data\package\installation\plugin\PackageInstallationPluginList;
+use wcf\system\package\PackageArchive;
 
 /**
  * Manages recursive validation of package archives.
@@ -14,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
@@ -26,6 +34,17 @@ class PackageValidationManager extends SingletonFactory {
         */
        protected $virtualPackageList = array();
        
+       /**
+        * @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
@@ -40,7 +59,7 @@ class PackageValidationManager extends SingletonFactory {
                $this->virtualPackageList = array();
                $this->packageValidationArchive = new PackageValidationArchive($archive);
                
-               return $this->packageValidationArchive->validate();
+               return $this->packageValidationArchive->validate($deepInspection);
        }
        
        /**
@@ -78,11 +97,31 @@ class PackageValidationManager extends SingletonFactory {
         * @param       string          $package
         * @return      string
         */
-       public function geVirtualPackageVersion($package) {
+       public function getVirtualPackage($package) {
                if (isset($this->virtualPackageList[$package])) {
                        return $this->virtualPackageList[$package];
                }
                
                return null;
        }
+       
+       /**
+        * Returns the iteratable package archive list.
+        * 
+        * @return      \RecursiveIteratorIterator
+        */
+       public function getPackageValidationArchiveList() {
+               $packageValidationArchive = new PackageValidationArchive('');
+               $packageValidationArchive->setChildren(array($this->packageValidationArchive));
+               
+               return new \RecursiveIteratorIterator($packageValidationArchive, \RecursiveIteratorIterator::SELF_FIRST);
+       }
+       
+       public function validatePackageInstallationPluginInstruction(PackageArchive $archive, $pip, $instruction) {
+               if (isset($this->packageInstallationPlugins[$pip])) {
+                       return call_user_func(array($this->packageInstallationPlugins[$pip], 'isValid'), $archive, $instruction);
+               }
+               echo "(default success)\n";
+               return true;
+       }
 }
index 3c429a1143bfceb26f1d8d11690800d8c80cf7f5..faff0f42615d0e27448b0a0fef467ea985255a90 100644 (file)
@@ -991,6 +991,11 @@ GmbH=Gesellschaft mit beschränkter Haftung]]></item>
                <item name="wcf.acp.package.updates"><![CDATA[Aktualisierungen]]></item>
                <item name="wcf.acp.package.error.downloadFailed"><![CDATA[Das Herunterladen des Paketes{if $__downloadPackage|isset} „{$__downloadPackage}“{/if} ist fehlgeschlagen.]]></item>
                <item name="wcf.acp.package.newVersion"><![CDATA[Neue Version]]></item>
+               
+               <!-- TODO: most error codes are still missing, they will be added during testing -->
+               <item name="wcf.acp.package.validation.errorCode.8"><![CDATA[Dieses Paket ist inkompatibel mit den folgenden, installierten Paketen: <ul class="nativeList">{foreach from=$packages item=package}<li>„{$package}“ ({$package->package})</li>{/foreach}</ul>]]></item>
+               <item name="wcf.acp.package.validation.errorCode.10"><![CDATA[Benötigt das Paket „{$packageName}“ in Version „{$packageVersion}“ oder höher, dies ist aber weder installiert noch wird es mitgeliefert.]]></item>
+               <item name="wcf.acp.package.validation.errorCode.11"><![CDATA[Die {if $type == 'install'}Installations{else}Update{/if}-Anweisungen geben für das Package Installation Plugin „{$pip}“ die Datei „{$value}“ an, diese ist jedoch nicht im Archiv enthalten. Mögliche Ursachen:<ul class="nativeList"><li>Die Datei wurde dem Archiv nicht hinzugefügt</li><li>Die Datei existiert, jedoch sind der Dateiname und die Angabe in den Anweisungen abweichend (Tippfehler)</li></ul>]]></item>
        </category>
        
        <category name="wcf.acp.pageMenu">