Add <void/> instruction
authorTim Düsterhus <duesterhus@woltlab.com>
Wed, 1 Jul 2020 12:30:10 +0000 (14:30 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Wed, 1 Jul 2020 12:30:10 +0000 (14:30 +0200)
The <void/> instruction may only be used during updates and only when no
other package installation plugin is used. It will result in a noop
when running the upgrade, allowing an upgrade to adjust package metadata
without actually changing anything.

Example usage:

<instructions type="update" fromversion="*">
<void/>
</instructions>

Resolves #3411

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/PackageValidationException.class.php
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index e67a9b5c41fe4ae3e6a5554b471f3a9051decec9..1e9d5008835f50481a4a50ad4fe31cf873046c4e 100644 (file)
@@ -88,6 +88,12 @@ class PackageArchive {
         */
        const INFO_FILE = 'package.xml';
        
+       /**
+        * marker for the void instruction
+        * @var string
+        */
+       const VOID_MARKER = "===void===";
+       
        /**
         * Creates a new PackageArchive object.
         * 
@@ -351,6 +357,24 @@ class PackageArchive {
                        $fromVersion = $element->getAttribute('fromversion');
                        $type = $element->getAttribute('type');
                        
+                       $void = $xpath->query('./ns:void', $element);
+                       if ($void->length > 1) {
+                               throw new PackageValidationException(PackageValidationException::VOID_NOT_ALONE);
+                       }
+                       else if ($void->length == 1) {
+                               if (!empty($instructionData)) {
+                                       throw new PackageValidationException(PackageValidationException::VOID_NOT_ALONE);
+                               }
+                               if ($type == 'install') {
+                                       throw new PackageValidationException(PackageValidationException::VOID_ON_INSTALL);
+                               }
+                               
+                               $instructionData[] = [
+                                       'pip' => self::VOID_MARKER,
+                                       'value' => '',
+                               ];
+                       }
+                       
                        if ($type == 'install') {
                                $this->instructions['install'] = $instructionData;
                        }
index ae1024bb905e1ce7f75e4d326fc7355f212a343f..e2621d57c0b5d1d774dbae771a0c2eb6c2074d65 100644 (file)
@@ -703,6 +703,10 @@ class PackageInstallationDispatcher {
        protected function executePIP(array $nodeData) {
                $step = new PackageInstallationStep();
                
+               if ($nodeData['pip'] == PackageArchive::VOID_MARKER) {
+                       return $step;
+               }
+               
                // fetch all pips associated with current PACKAGE_ID and include pips
                // previously installed by current installation queue
                $sql = "SELECT  pluginName, className
index 4f01326166ca3e02663f44171dc7081b7a67dd22..bf8971d688c74956c2c317e9f86a2faaf4f86d05 100644 (file)
@@ -114,6 +114,18 @@ class PackageValidationException extends SystemException {
         */
        const MISSING_API_VERSION = 15;
        
+       /**
+        * the void is not the only instruction
+        * @var integer
+        */
+       const VOID_NOT_ALONE = 16;
+       
+       /**
+        * the void is used during installation
+        * @var integer
+        */
+       const VOID_ON_INSTALL = 17;
+       
        /**
         * Creates a new PackageArchiveValidationException.
         * 
index 47205e236069da825a28631ea50276a9b8774b5c..7e437bbe23c41efe7e5ddd4d6f46a7805ad244af 100644 (file)
@@ -1937,6 +1937,8 @@ Die Datenbestände werden sorgfältig gepflegt, aber es ist nicht ausgeschlossen
                <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.errorCode.16"><![CDATA[Neben der &lt;void/&gt;-Anweisung werden weitere Package Installation Plugins angegeben.]]></item>
+               <item name="wcf.acp.package.validation.errorCode.17"><![CDATA[Die &lt;void/&gt;-Anweisung ist in den Installations-Anweisungen unzulässig.]]></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>
                <item name="wcf.acp.package.evaluation.expired"><![CDATA[Die Testphase von <strong>{$packageName}</strong> ist abgelaufen. Bitte aktualisiere{if !LANGUAGE_USE_INFORMAL_VARIANT}n Sie{/if} auf die aktuellste Version um diese Software weiterhin legal betreiben zu können.{if $pluginStoreFileID || $isWoltLab}<br>{if LANGUAGE_USE_INFORMAL_VARIANT}Du kannst{else}Sie können{/if} die aktuelle Version sicher und bequem <strong>{if $pluginStoreFileID}<a href="https://pluginstore.woltlab.com/file/{$pluginStoreFileID}/">im WoltLab Plugin-Store</a>{else}<a href="https://www.woltlab.com/purchase/">auf WoltLab.com</a>{/if}</strong> erwerben.{/if}]]></item>
                <item name="wcf.acp.package.evaluation.pending"><![CDATA[Bei den folgenden installierten Apps handelt es sich um Testversionen, die am <strong>{$evaluationEndDate|plainTime}</strong> ({@$evaluationEndDate|dateDiff:TIME_NOW:true}) ablaufen. Mit Ablauf der Frist deaktiviert sich die App automatisch, es ist dann notwendig diese auf die endgültige Version zu aktualisieren, um den legalen Betrieb fortzusetzen.
index 6e28519c9483b83e9c7e93ae325b5b59fd756e2d..0e3f655dac43ff37edf32aa666eb8baa3bcc2118 100644 (file)
@@ -1921,6 +1921,8 @@ The database is carefully maintained, but there will be always be a margin of er
                <item name="wcf.acp.package.validation.errorCode.13"><![CDATA[The 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.errorCode.16"><![CDATA[In addition to the &lt;void/&gt; instruction additional Package Installation Plugins are used.]]></item>
+               <item name="wcf.acp.package.validation.errorCode.17"><![CDATA[The &lt;void/&gt; instruction may not be used in the install-instructions.]]></item>
                <item name="wcf.acp.package.validation.failed"><![CDATA[The package cannot be installed, please review the validation results below.]]></item>
                <item name="wcf.acp.package.evaluation.expired"><![CDATA[The evaluation period of <strong>{$packageName}</strong> has expired. For a legal use of this software, please update to the latest available version.{if $pluginStoreFileID || $isWoltLab}<br>The latest version can be purchased quickly and securely <strong>{if $pluginStoreFileID}<a href="https://pluginstore.woltlab.com/file/{$pluginStoreFileID}/">in the WoltLab Plugin-Store</a>{else}<a href="https://www.woltlab.com/purchase/">on WoltLab.com</a>{/if}</strong>.{/if}]]></item>
                <item name="wcf.acp.package.evaluation.pending"><![CDATA[The evaluation period of the apps listed below will expire on <strong>{$evaluationEndDate|plainTime}</strong> ({@$evaluationEndDate|dateDiff:TIME_NOW:true}). The apps will automatically disable themselves after this date and become unusable, you'll need to install the latest versions of the apps to active them again.