Fix PHP 8.1 compatibility when saving I18n options
authorTim Düsterhus <duesterhus@woltlab.com>
Thu, 6 Jan 2022 09:50:13 +0000 (10:50 +0100)
committerTim Düsterhus <duesterhus@woltlab.com>
Thu, 6 Jan 2022 09:50:13 +0000 (10:50 +0100)
As I18n options are special-cased, they will not be provided in `rawValues`,
thus passing `null` to `->getData()`, which the option types are not prepared
to handle. Before PHP 8.1 this was implicitly treated as an empty string, with
the types introduced to native functions, e.g. `explode()` or `preg_replace()`
this will result in an error.

wcfsetup/install/files/lib/system/option/OptionHandler.class.php

index b167df80986471bfedff8c9a1467fb4baddc6ef6..2f2e10e6ade4cce2e2f5aa95ad2031e0b6c858ad 100644 (file)
@@ -393,18 +393,22 @@ class OptionHandler implements IOptionHandler
         // get new value
         $newValue = $this->rawValues[$option->optionName] ?? null;
 
-        // get save value
-        $this->optionValues[$option->optionName] = $typeObj->getData($option, $newValue);
-
-        // validate with pattern
-        if ($option->validationPattern) {
-            if (
-                !\preg_match(
-                    '~' . \str_replace('~', '\~', $option->validationPattern) . '~',
-                    $this->optionValues[$option->optionName]
-                )
-            ) {
-                throw new UserInputException($option->optionName, 'validationFailed');
+        // Skip validation for I18n options. They are special cased and are not provided
+        // within the `rawValues`, thus causing validation to be effectively useless.
+        if (!$this->supportI18n || !$option->supportI18n) {
+            // get save value
+            $this->optionValues[$option->optionName] = $typeObj->getData($option, $newValue);
+
+            // validate with pattern
+            if ($option->validationPattern) {
+                if (
+                    !\preg_match(
+                        '~' . \str_replace('~', '\~', $option->validationPattern) . '~',
+                        $this->optionValues[$option->optionName]
+                    )
+                ) {
+                    throw new UserInputException($option->optionName, 'validationFailed');
+                }
             }
         }