Added partial support for forward-compatibility
authorAlexander Ebert <ebert@woltlab.com>
Mon, 25 Sep 2017 09:59:18 +0000 (11:59 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Mon, 25 Sep 2017 09:59:26 +0000 (11:59 +0200)
See #2427

18 files changed:
XSD/package.xsd
com.woltlab.wcf/package.xml
com.woltlab.wcf/templates/headIncludeJavaScript.tpl
wcfsetup/install/files/acp/templates/header.tpl
wcfsetup/install/files/acp/templates/index.tpl
wcfsetup/install/files/acp/templates/package.tpl
wcfsetup/install/files/lib/acp/action/InstallPackageAction.class.php
wcfsetup/install/files/lib/acp/page/PackageInstallationConfirmPage.class.php
wcfsetup/install/files/lib/acp/page/PackagePage.class.php
wcfsetup/install/files/lib/system/WCF.class.php
wcfsetup/install/files/lib/system/html/input/filter/MessageHtmlInputFilter.class.php
wcfsetup/install/files/lib/system/package/PackageArchive.class.php
wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php
wcfsetup/install/files/lib/system/package/validation/PackageValidationArchive.class.php
wcfsetup/install/files/lib/system/package/validation/PackageValidationException.class.php
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml
wcfsetup/setup/db/install.sql

index d22f0a4b62075fe8eec62dc52ac1e19005324552..0aea56cb249c0d27d00b5e1faf2035c000f479da 100644 (file)
@@ -13,6 +13,7 @@
                                <xs:element name="requiredpackages" type="requiredPackages" minOccurs="0" maxOccurs="1" />
                                <xs:element name="optionalpackages" type="optionalPackages" minOccurs="0" maxOccurs="1" />
                                <xs:element name="excludedpackages" type="excludedPackages" minOccurs="0" maxOccurs="1" />
+                               <xs:element name="compatibility" type="compatibility" minOccurs="0" maxOccurs="1" />
                        </xs:choice>
                        <xs:attribute name="name" type="woltlab_varchar" use="required" />
                </xs:complexType>
                        </xs:extension>
                </xs:simpleContent>
        </xs:complexType>
-
+       
+       <!-- api compatibility version element -->
+       <xs:complexType name="apiVersion">
+               <xs:simpleContent>
+                       <xs:extension base="xs:string">
+                               <xs:attribute name="version" type="xs:integer" use="required" />
+                       </xs:extension>
+               </xs:simpleContent>
+       </xs:complexType>
+       
        <!-- instructions elements -->
        <xs:complexType name="instructions">
                <xs:sequence>
                        <xs:element name="excludedpackage" type="excludedPackage" minOccurs="0" maxOccurs="unbounded" />
                </xs:sequence>
        </xs:complexType>
+       
+       <!-- api compatibility element -->
+       <xs:complexType name="compatibility">
+               <xs:sequence>
+                       <xs:element name="api" type="apiVersion" minOccurs="1" maxOccurs="unbounded" />
+               </xs:sequence>
+       </xs:complexType>
 
        <xs:complexType name="instructionType">
                <xs:simpleContent>
index 68687ce4227dd472f2b8edee4a1d806624169970..def7a2ca6af2bb9493ea2480ab8560cc91ad10d1 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<package name="com.woltlab.wcf" xmlns="http://www.woltlab.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.woltlab.com http://www.woltlab.com/XSD/vortex/package.xsd">
+<package name="com.woltlab.wcf" xmlns="http://www.woltlab.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.woltlab.com http://www.woltlab.com/XSD/tornado/package.xsd">
        <packageinformation>
                <packagename>WoltLab Suite Core</packagename>
                <packagedescription>Free CMS and web-framework, designed for awesome websites and communities.</packagedescription>
index 553f36eafd2ff3e581f09b78dfc997108a06f7f2..4e07f2560f0ec7109b2140e5ac8ed2961372568c 100644 (file)
@@ -14,6 +14,7 @@
        var URL_LEGACY_MODE = false;
        var ENABLE_DEBUG_MODE = {if ENABLE_DEBUG_MODE}true{else}false{/if};
        var ENABLE_DEVELOPER_TOOLS = {if ENABLE_DEVELOPER_TOOLS}true{else}false{/if};
+       var WSC_API_VERSION = {@WSC_API_VERSION};
        
        {if ENABLE_DEBUG_MODE}
                {* This constant is a compiler option, it does not exist in production. *}
index c4a5534717dabef3a90497d0ca51cf78619a09cf..5c8dadb00280d300cce77198fe47c5787b9384f5 100644 (file)
@@ -30,6 +30,7 @@
                var URL_LEGACY_MODE = false;
                var ENABLE_DEBUG_MODE = {if ENABLE_DEBUG_MODE}true{else}false{/if};
                var ENABLE_DEVELOPER_TOOLS = {if ENABLE_DEVELOPER_TOOLS}true{else}false{/if};
+               var WSC_API_VERSION = {@WSC_API_VERSION};
                
                {* This constant is a compiler option, it does not exist in production. *}
                {* Unlike the frontend, this option must be defined in the ACP at all times. *}
index 511793d3f9e1706d41cf5db71252eeed94810fdd..87cc2a7907c0db753dfc8fa3dbce17d4f08e999b 100644 (file)
                <section class="section">
                        <h2 class="sectionTitle">{lang}wcf.acp.index.system.software{/lang}</h2>
                        
-                       {event name='softwareVersions'}
-                       
                        <dl>
-                               <dt>{lang}wcf.acp.index.system.software.wcfVersion{/lang}</dt>
-                               <dd>{@WCF_VERSION}</dd>
+                               <dt>{lang}wcf.acp.index.system.software.apiVersion{/lang}</dt>
+                               <dd>{@WSC_API_VERSION}</dd>
                        </dl>
+                       {if !$__wcf->getSupportedLegacyApiVersions()|empty}
+                               <dl>
+                                       <dt>{lang}wcf.acp.index.system.software.legacyApiVersions{/lang}</dt>
+                                       <dd><small>{implode from=$__wcf->getSupportedLegacyApiVersions() item=version glue=', '}{$version}{/implode}</small></dd>
+                               </dl>
+                       {/if}
                        
                        {event name='softwareFields'}
                </section>
index 5e7708ead5c789bfc68914cb507cdd671d54c7ca..bf408c616a00fdbb5ecb1c2e3b68de1866dcb1b8 100644 (file)
                                        <dd><a href="{@$__wcf->getPath()}acp/dereferrer.php?url={$_storeUrl|rawurlencode}" class="externalURL">{lang}wcf.acp.pluginStore.file.link{/lang}</a></dd>
                                </dl>
                        {/if}
+                       {if $package->packageID != 1}
+                               <dl>
+                                       <dt>{lang}wcf.acp.package.apiVersions{/lang}</dt>
+                                       <dd>
+                                               {if $compatibleVersions|empty}
+                                                       <small>{lang}wcf.acp.package.apiVersions.missing{/lang}</small>
+                                               {else}
+                                                       {implode from=$compatibleVersions item=version glue=', '}{$version}{/implode}
+                                               {/if}
+                                       </dd>
+                               </dl>
+                       {/if}
                        
                        {event name='propertyFields'}
                </div>
index 684724a5c64a4e024fb4340fbbd567c5c250ab15..1db9891ab0ad17c6e7cb9392a96196ad61a3e76d 100755 (executable)
@@ -30,13 +30,13 @@ class InstallPackageAction extends AbstractDialogAction {
         * PackageInstallationDispatcher object
         * @var PackageInstallationDispatcher
         */
-       public $installation = null;
+       public $installation;
        
        /**
         * PackageInstallationQueue object
         * @var PackageInstallationQueue
         */
-       public $queue = null;
+       public $queue;
        
        /**
         * current queue id
index fdc01b386b4191ac6da29313159c9ed3f8268133..a17dfda4910a71f9242a930595a43b5a4d0e2f57 100644 (file)
@@ -26,13 +26,13 @@ class PackageInstallationConfirmPage extends AbstractPage {
         * package installation dispatcher object
         * @var PackageInstallationDispatcher
         */
-       public $packageInstallationDispatcher = null;
+       public $packageInstallationDispatcher;
        
        /**
         * package installation queue object
         * @var PackageInstallationQueue
         */
-       public $queue = null;
+       public $queue;
        
        /**
         * queue id
index 99bfff286fb3674d20d41b154e7f4cbd3a390b53..6323802606e9b8b7a0a8516b89c8367943fde220 100755 (executable)
@@ -19,6 +19,12 @@ class PackagePage extends AbstractPage {
         */
        public $activeMenuItem = 'wcf.acp.menu.link.package';
        
+       /**
+        * list of compatible API versions
+        * @var integer[]
+        */
+       public $compatibleVersions = [];
+       
        /**
         * @inheritDoc
         */
@@ -68,6 +74,20 @@ class PackagePage extends AbstractPage {
                $statement = WCF::getDB()->prepareStatement($sql);
                $statement->execute([$this->package->package]);
                $this->pluginStoreFileID = intval($statement->fetchSingleColumn());
+               
+               $sql = "SELECT          version
+                       FROM            wcf".WCF_N."_package_compatibility
+                       WHERE           packageID = ?
+                                       AND version >= ?
+                       ORDER BY        version";
+               $statement = WCF::getDB()->prepareStatement($sql);
+               $statement->execute([
+                       $this->package->packageID,
+                       WSC_API_VERSION
+               ]);
+               while ($version = $statement->fetchColumn()) {
+                       $this->compatibleVersions[] = $version;
+               }
        }
        
        /**
@@ -77,6 +97,7 @@ class PackagePage extends AbstractPage {
                parent::assignVariables();
                
                WCF::getTPL()->assign([
+                       'compatibleVersions' => $this->compatibleVersions,
                        'package' => $this->package,
                        'pluginStoreFileID' => $this->pluginStoreFileID
                ]);
index 28a379d69ec287cb070bdb25a66836f50893a419..0144814d02d8b4b9223c908d14f2faedc41ba984 100644 (file)
@@ -49,6 +49,9 @@ if (!@ini_get('date.timezone')) {
 // define current woltlab suite version
 define('WCF_VERSION', '3.1.0 Alpha 4');
 
+// define current API version
+define('WSC_API_VERSION', 2018);
+
 // define current unix timestamp
 define('TIME_NOW', time());
 
@@ -68,6 +71,12 @@ if (!defined('NO_IMPORTS')) {
  * @package    WoltLabSuite\Core\System
  */
 class WCF {
+       /**
+        * list of supported legacy API versions
+        * @var integer[]
+        */
+       private static $supportedLegacyApiVersions = [2017];
+       
        /**
         * list of currently loaded applications
         * @var Application[]
@@ -1046,6 +1055,25 @@ class WCF {
                return self::getActiveRequest()->isLandingPage();
        }
        
+       /**
+        * Returns true if the given API version is currently supported.
+        * 
+        * @param       integer         $apiVersion
+        * @return      boolean
+        */
+       public static function isSupportedApiVersion($apiVersion) {
+               return ($apiVersion == WSC_API_VERSION) || in_array($apiVersion, self::$supportedLegacyApiVersions);
+       }
+       
+       /**
+        * Returns the list of supported legacy API versions.
+        * 
+        * @return      integer[]
+        */
+       public static function getSupportedLegacyApiVersions() {
+               return self::$supportedLegacyApiVersions;
+       }
+       
        /**
         * Initialises the cronjobs.
         */
index 86334d9fd486f7bde91c4d860134ae8fcf5c79fb..4e193f06c1acfc71cefee2b41ba27fee308c84a5 100644 (file)
@@ -76,7 +76,7 @@ class MessageHtmlInputFilter implements IHtmlInputFilter {
         */
        protected function setAttributeDefinitions(\HTMLPurifier_Config $config) {
                $definition = $config->getHTMLDefinition(true);
-               
+               wcfDebug($config->get('HTML.AllowedAttributes'));
                // code
                $definition->addAttribute('pre', 'data-file', 'Text');
                $definition->addAttribute('pre', 'data-line', 'Number');
index 6883153d12a8eb471c58c249791adfcf290b8bd9..82077a993f3a894568cfc9dca886f04668058f60 100644 (file)
@@ -22,19 +22,19 @@ class PackageArchive {
         * path to package archive
         * @var string
         */
-       protected $archive = null;
+       protected $archive;
        
        /**
         * package object of an existing package
         * @var Package
         */
-       protected $package = null;
+       protected $package;
        
        /**
         * tar archive object
         * @var Tar
         */
-       protected $tar = null;
+       protected $tar;
        
        /**
         * general package information
@@ -66,6 +66,12 @@ class PackageArchive {
         */
        protected $excludedPackages = [];
        
+       /**
+        * list of compatible API versions
+        * @var integer[]
+        */
+       protected $compatibility = [];
+       
        /**
         * list of instructions
         * @var mixed[][]
@@ -282,6 +288,19 @@ class PackageArchive {
                        $this->excludedPackages[] = $data;
                }
                
+               // get api compatibility
+               $elements = $xpath->query('child::ns:compatibility/ns:api', $package);
+               foreach ($elements as $element) {
+                       if (!$element->hasAttribute('version')) continue;
+                       
+                       $version = $element->getAttribute('version');
+                       if (!preg_match('~^(?:201[7-9]|20[2-9][0-9])$~', $version)) {
+                               throw new PackageValidationException(PackageValidationException::INVALID_API_VERSION, ['version' => $version]);
+                       }
+                       
+                       $this->compatibility[] = $version;
+               }
+               
                // get instructions
                $elements = $xpath->query('./ns:instructions', $package);
                foreach ($elements as $element) {
@@ -528,6 +547,15 @@ class PackageArchive {
                return $this->excludedPackages;
        }
        
+       /**
+        * Returns the list of compatible API versions.
+        * 
+        * @return      integer[]
+        */
+       public function getCompatibleVersions() {
+               return $this->compatibility;
+       }
+       
        /**
         * Returns the package installation instructions.
         * 
index 9d3298ecf9f4a794cd43916ceeb65ef4a7fb5995..fcf9c6d90c3c081a6ef6f9ae02ae51b6a76e7c97 100644 (file)
@@ -436,6 +436,21 @@ class PackageInstallationDispatcher {
                        }
                }
                
+               // save compatible versions
+               if (!empty($this->getArchive()->getCompatibleVersions())) {
+                       $sql = "INSERT INTO     wcf".WCF_N."_package_compatibility
+                                               (packageID, version)
+                               VALUES          (?, ?)";
+                       $statement = WCF::getDB()->prepareStatement($sql);
+                       
+                       foreach ($this->getArchive()->getCompatibleVersions() as $version) {
+                               $statement->execute([
+                                       $this->queue->packageID,
+                                       $version
+                               ]);
+                       }
+               }
+               
                // insert requirements and dependencies
                $requirements = $this->getArchive()->getAllExistingRequirements();
                if (!empty($requirements)) {
index 8c80576e4643bb7280b1d03e4fd5021fb0f4edbe..265268d4d12e6c41908f7ce368f416bfc6ad4958 100644 (file)
@@ -17,7 +17,7 @@ use wcf\system\WCF;
 class PackageValidationArchive implements \RecursiveIterator {
        /**
         * list of excluded packages grouped by package
-        * @var string[]
+        * @var string[][]
         */
        protected static $excludedPackages = [];
        
@@ -25,7 +25,7 @@ class PackageValidationArchive implements \RecursiveIterator {
         * package archive object
         * @var PackageArchive
         */
-       protected $archive = null;
+       protected $archive;
        
        /**
         * list of direct requirements delivered by this package
@@ -43,19 +43,19 @@ class PackageValidationArchive implements \RecursiveIterator {
         * exception occurred during validation
         * @var \Exception
         */
-       protected $exception = null;
+       protected $exception;
        
        /**
         * associated package object
         * @var Package
         */
-       protected $package = null;
+       protected $package;
        
        /**
         * parent package validation archive object
         * @var PackageValidationArchive
         */
-       protected $parent = null;
+       protected $parent;
        
        /**
         * children pointer
@@ -198,6 +198,29 @@ class PackageValidationArchive implements \RecursiveIterator {
                        ]);
                }
                
+               // check if this package exposes compatible api versions
+               $compatibleVersions = $this->archive->getCompatibleVersions();
+               if (!empty($compatibleVersions)) {
+                       $isCompatible = $isOlderVersion = false;
+                       foreach ($compatibleVersions as $version) {
+                               if (WCF::isSupportedApiVersion($version)) {
+                                       $isCompatible = true;
+                                       break;
+                               }
+                               else if ($version < WSC_API_VERSION) {
+                                       $isOlderVersion = true;
+                               }
+                       }
+                       
+                       if (!$isCompatible) {
+                               
+                               throw new PackageValidationException(PackageValidationException::INCOMPATIBLE_API_VERSION, ['isOlderVersion' => $isOlderVersion]);
+                       }
+               }
+               else if (ENABLE_DEBUG_MODE && ENABLE_DEVELOPER_TOOLS) {
+                       throw new PackageValidationException(PackageValidationException::MISSING_API_VERSION);
+               }
+               
                // package is not installed yet
                if ($package === null) {
                        $instructions = $this->archive->getInstallInstructions();
index 677fdce0ed9455b508722e5e524d408383d8ebac..6c16caa7ebc822bda763fc4e69e9c03a7abadf4d 100644 (file)
@@ -93,6 +93,24 @@ class PackageValidationException extends SystemException {
         */
        const ALREADY_INSTALLED = 12;
        
+       /**
+        * the provided API version string is invalid and does not fall into the range from `2017` through `2099`
+        * @var integer
+        */
+       const INVALID_API_VERSION = 13;
+       
+       /**
+        * the package is not compatible with the current API version or any other of the supported ones
+        * @var integer
+        */
+       const INCOMPATIBLE_API_VERSION = 14;
+       
+       /**
+        * the package lacks any sort of API compatibility data
+        * @var integer
+        */
+       const MISSING_API_VERSION = 15;
+       
        /**
         * Creates a new PackageArchiveValidationException.
         * 
index 487bf4a1d937200699b2b7c6f5bf1abdb23782d5..a38f458deecb502b483dc8cbd9fdda7e1d39f142 100644 (file)
                <item name="wcf.acp.index.setup.title"><![CDATA[Bitte warten]]></item>
                <item name="wcf.acp.index.system"><![CDATA[System]]></item>
                <item name="wcf.acp.index.system.software"><![CDATA[Software]]></item>
-               <item name="wcf.acp.index.system.software.wcfVersion"><![CDATA[WoltLab Suite&trade;-Version]]></item>
+               <item name="wcf.acp.index.system.software.apiVersion"><![CDATA[WoltLab Suite&trade; API-Version]]></item>
+               <item name="wcf.acp.index.system.software.legacyApiVersions"><![CDATA[Ältere, noch unterstützte API-Versionen]]></item>
                <item name="wcf.acp.index.system.server"><![CDATA[Server]]></item>
                <item name="wcf.acp.index.system.os"><![CDATA[Betriebssystem]]></item>
                <item name="wcf.acp.index.system.webserver"><![CDATA[Webserver]]></item>
@@ -1449,6 +1450,8 @@ Als Benachrichtigungs-URL in der Konfiguration der sofortigen Zahlungsbestätigu
        </category>
        
        <category name="wcf.acp.package">
+               <item name="wcf.acp.package.apiVersions"><![CDATA[Unterstütze WoltLab Suite&trade; API-Versionen]]></item>
+               <item name="wcf.acp.package.apiVersions.missing"><![CDATA[Dieses Paket stellt keine Informationen zur Kompatibilität bereit.]]></item>
                <item name="wcf.acp.package.application.installed"><![CDATA[Installierte Apps]]></item>
                <item name="wcf.acp.package.application.title"><![CDATA[Apps]]></item>
                <item name="wcf.acp.package.author"><![CDATA[Entwickler]]></item>
@@ -1577,6 +1580,9 @@ Als Benachrichtigungs-URL in der Konfiguration der sofortigen Zahlungsbestätigu
                <item name="wcf.acp.package.validation.errorCode.10"><![CDATA[Benötigt das Paket {if $package === null}„{$packageName}“{else}„{$package}“{/if} in Version „{$packageVersion}“ oder höher, {if $package === null}dies ist aber weder installiert noch wird es mitgeliefert.{else}es ist aber nur Version „{$package->packageVersion}“ installiert.{/if}]]></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>
                <item name="wcf.acp.package.validation.errorCode.12"><![CDATA[Das Paket „{lang}{$packageName}{/lang}“ ist bereits in Version „{$packageVersion}“ installiert.]]></item>
+               <item name="wcf.acp.package.validation.errorCode.13"><![CDATA[Die API-Version „{$version}“ ist ungültig.]]></item>
+               <item name="wcf.acp.package.validation.errorCode.14"><![CDATA[Das Paket wurde für eine {if $isOlderVersion}ältere{else}neuere{/if} Version von WoltLab Suite entwickelt und ist nicht kompatibel.]]></item>
+               <item name="wcf.acp.package.validation.errorCode.15"><![CDATA[Das Paket verfügt über keine Angaben zur API-Kompatibilität, eine Installation  mit aktivierten Entwickler-Werkzeugen ist daher nicht möglich.]]></item>
                <item name="wcf.acp.package.validation.failed"><![CDATA[Das hochgeladene Paket kann nicht installiert werden, bitte {if LANGUAGE_USE_INFORMAL_VARIANT}beachte{else}beachten Sie{/if} das unten stehende Prüfungsergebnis.]]></item>
        </category>
        
index 83b712671b449ab23a065521b2d4d3298aa6698d..a6755ff53d9384a6ceb8a0998bbc89202521fca2 100644 (file)
                <item name="wcf.acp.index.setup.title"><![CDATA[Please Wait]]></item>
                <item name="wcf.acp.index.system"><![CDATA[System]]></item>
                <item name="wcf.acp.index.system.software"><![CDATA[Software]]></item>
-               <item name="wcf.acp.index.system.software.wcfVersion"><![CDATA[WoltLab Suite&trade; Version]]></item>
+               <item name="wcf.acp.index.system.software.apiVersion"><![CDATA[WoltLab Suite&trade; API-version]]></item>
+               <item name="wcf.acp.index.system.software.legacyApiVersions"><![CDATA[Older, still supported, API-versions]]></item>
                <item name="wcf.acp.index.system.server"><![CDATA[Server]]></item>
                <item name="wcf.acp.index.system.os"><![CDATA[Operating System]]></item>
                <item name="wcf.acp.index.system.webserver"><![CDATA[Web Server]]></item>
@@ -1443,6 +1444,8 @@ When prompted for the notification URL for the instant payment notifications, pl
        </category>
        
        <category name="wcf.acp.package">
+               <item name="wcf.acp.package.apiVersions"><![CDATA[Supported WoltLab Suite&trade; API-versions]]></item>
+               <item name="wcf.acp.package.apiVersions.missing"><![CDATA[This package does not provide any compatibility data.]]></item>
                <item name="wcf.acp.package.application.installed"><![CDATA[Installed Apps]]></item>
                <item name="wcf.acp.package.application.title"><![CDATA[Apps]]></item>
                <item name="wcf.acp.package.author"><![CDATA[Developer]]></item>
@@ -1571,6 +1574,9 @@ When prompted for the notification URL for the instant payment notifications, pl
                <item name="wcf.acp.package.validation.errorCode.10"><![CDATA[Requires the package {if $package === null}“{$packageName}”{else}“{$package}”{/if} in version “{$packageVersion}” or higher, {if $package === null}but it is neither installed nor shipped.{else}but only version “{$package->packageVersion}” is installed.{/if}]]></item>
                <item name="wcf.acp.package.validation.errorCode.11"><![CDATA[The {if $type == 'install'}install{else}update{/if}-instructions specify the file “{$value}” for the Package Installation Plugin “{$pip}”, but it cannot be found in the specified location. Possible causes:<ul class="nativeList"><li>The file has not been added to the archive at all</li><li>The file exists but under a (slightly) different name (typo)</li></ul>]]></item>
                <item name="wcf.acp.package.validation.errorCode.12"><![CDATA[The package “{lang}{$packageName}{/lang}” is already installed in version “{$packageVersion}”.]]></item>
+               <item name="wcf.acp.package.validation.errorCode.13"><![CDATA[The API version  API-Version “{$version}” is invalid.]]></item>
+               <item name="wcf.acp.package.validation.errorCode.14"><![CDATA[This package was created for {if $isOlderVersion}an older{else}a newer{/if} version of WoltLab Suite and is not compatible.]]></item>
+               <item name="wcf.acp.package.validation.errorCode.15"><![CDATA[This package does not contain any data on API compatibility, the installation is prevented while the developer tools are enabled.]]></item>
                <item name="wcf.acp.package.validation.failed"><![CDATA[The package cannot be installed, please review the validation results below.]]></item>
        </category>
        
index 4c86bcaaa496532040db1cdf9cdfe9f84df98aab..ca08ce48f265e43b0f2e50fffa44dcd6d910e5c3 100644 (file)
@@ -872,6 +872,13 @@ CREATE TABLE wcf1_package (
        KEY package (package)
 );
 
+DROP TABLE IF EXISTS wcf1_package_compatibility;
+CREATE TABLE wcf1_package_compatibility (
+       packageID INT(10) NOT NULL,
+       version SMALLINT(4) NOT NULL,
+       UNIQUE KEY compatibleVersion (packageID, version)
+);
+
 DROP TABLE IF EXISTS wcf1_package_exclusion;
 CREATE TABLE wcf1_package_exclusion (
        packageID INT(10) NOT NULL,
@@ -956,6 +963,13 @@ CREATE TABLE wcf1_package_update (
        UNIQUE KEY packageUpdateServerID (packageUpdateServerID, package)
 );
 
+DROP TABLE IF EXISTS wcf1_package_update_compatibility;
+CREATE TABLE wcf1_package_update_compatibility (
+       packageUpdateVersionID INT(10) NOT NULL,
+       version SMALLINT(4) NOT NULL,
+       UNIQUE KEY compatibleVersion (packageUpdateVersionID, version)
+);
+
 DROP TABLE IF EXISTS wcf1_package_update_exclusion;
 CREATE TABLE wcf1_package_update_exclusion (
        packageUpdateVersionID INT(10) NOT NULL,
@@ -1886,6 +1900,8 @@ ALTER TABLE wcf1_option ADD FOREIGN KEY (packageID) REFERENCES wcf1_package (pac
 
 ALTER TABLE wcf1_option_category ADD FOREIGN KEY (packageID) REFERENCES wcf1_package (packageID) ON DELETE CASCADE;
 
+ALTER TABLE wcf1_package_compatibility ADD FOREIGN KEY (packageID) REFERENCES wcf1_package (packageID) ON DELETE CASCADE;
+
 ALTER TABLE wcf1_package_exclusion ADD FOREIGN KEY (packageID) REFERENCES wcf1_package (packageID) ON DELETE CASCADE;
 
 ALTER TABLE wcf1_package_installation_file_log ADD FOREIGN KEY (packageID) REFERENCES wcf1_package (packageID) ON DELETE CASCADE;
@@ -1908,6 +1924,8 @@ ALTER TABLE wcf1_package_requirement ADD FOREIGN KEY (requirement) REFERENCES wc
 
 ALTER TABLE wcf1_package_update ADD FOREIGN KEY (packageUpdateServerID) REFERENCES wcf1_package_update_server (packageUpdateServerID) ON DELETE CASCADE;
 
+ALTER TABLE wcf1_package_update_compatibility ADD FOREIGN KEY (packageUpdateVersionID) REFERENCES wcf1_package_update_version (packageUpdateVersionID) ON DELETE CASCADE;
+
 ALTER TABLE wcf1_package_update_exclusion ADD FOREIGN KEY (packageUpdateVersionID) REFERENCES wcf1_package_update_version (packageUpdateVersionID) ON DELETE CASCADE;
 
 ALTER TABLE wcf1_package_update_fromversion ADD FOREIGN KEY (packageUpdateVersionID) REFERENCES wcf1_package_update_version (packageUpdateVersionID) ON DELETE CASCADE;
@@ -2136,7 +2154,9 @@ INSERT INTO wcf1_user_group_option_value (groupID, optionID, optionValue) VALUES
 
 -- default update servers
 INSERT INTO wcf1_package_update_server (serverURL, status, isDisabled, errorMessage, lastUpdateTime, loginUsername, loginPassword) VALUES ('http://update.woltlab.com/vortex/', 'online', 0, NULL, 0, '', '');
+INSERT INTO wcf1_package_update_server (serverURL, status, isDisabled, errorMessage, lastUpdateTime, loginUsername, loginPassword) VALUES ('http://update.woltlab.com/tornado/', 'online', 0, NULL, 0, '', '');
 INSERT INTO wcf1_package_update_server (serverURL, status, isDisabled, errorMessage, lastUpdateTime, loginUsername, loginPassword) VALUES ('http://store.woltlab.com/vortex/', 'online', 0, NULL, 0, '', '');
+INSERT INTO wcf1_package_update_server (serverURL, status, isDisabled, errorMessage, lastUpdateTime, loginUsername, loginPassword) VALUES ('http://store.woltlab.com/tornado/', 'online', 0, NULL, 0, '', '');
 
 -- style default values
 INSERT INTO wcf1_style_variable (variableName, defaultValue) VALUES ('individualScss', '');