diff --git a/wcfsetup/install/files/lib/system/form/builder/field/MultipleSelectionFormField.class.php b/wcfsetup/install/files/lib/system/form/builder/field/MultipleSelectionFormField.class.php index 0fd353f38f..b8654cbc6e 100644 --- a/wcfsetup/install/files/lib/system/form/builder/field/MultipleSelectionFormField.class.php +++ b/wcfsetup/install/files/lib/system/form/builder/field/MultipleSelectionFormField.class.php @@ -43,6 +43,11 @@ class MultipleSelectionFormField extends AbstractFormField implements */ protected $value = []; + /** + * @since 6.2 + */ + private bool $ignoreInvalidValues = false; + /** * @inheritDoc */ @@ -130,13 +135,30 @@ public function value($value) throw new InvalidFormFieldValue($this, 'array', \gettype($value)); } - $unknownValues = \array_diff($value, \array_keys($this->getOptions())); - if (!empty($unknownValues)) { - throw new \InvalidArgumentException( - "Unknown values '" . \implode("', '", $unknownValues) . "' for field '{$this->getId()}'." - ); + $validKeys = \array_keys($this->getOptions()); + $unknownValues = \array_diff($value, $validKeys); + if ($unknownValues !== []) { + if ($this->ignoreInvalidValues) { + $value = \array_intersect($value, $validKeys); + } else { + throw new \InvalidArgumentException( + "Unknown values '" . \implode("', '", $unknownValues) . "' for field '{$this->getId()}'." + ); + } } return parent::value($value); } + + /** + * Ignores invalid values when reading them from data. + * + * @since 6.2 + */ + public function ignoreInvalidValues(bool $ignoreInvalidValues = true): self + { + $this->ignoreInvalidValues = $ignoreInvalidValues; + + return $this; + } } diff --git a/wcfsetup/install/files/lib/system/form/builder/field/SelectFormField.class.php b/wcfsetup/install/files/lib/system/form/builder/field/SelectFormField.class.php index efd9ac308f..b50afe8e75 100644 --- a/wcfsetup/install/files/lib/system/form/builder/field/SelectFormField.class.php +++ b/wcfsetup/install/files/lib/system/form/builder/field/SelectFormField.class.php @@ -31,6 +31,11 @@ final class SelectFormField extends AbstractFormField implements */ protected $templateName = 'shared_selectFormField'; + /** + * @since 6.2 + */ + private bool $ignoreInvalidValues = false; + /** * @inheritDoc */ @@ -75,10 +80,26 @@ public function value($value) { if ($value !== null && $value !== '') { if (!isset($this->getOptions()[$value])) { - throw new \InvalidArgumentException("Unknown value '{$value}' for field '{$this->getId()}'."); + if ($this->ignoreInvalidValues) { + $value = null; + } else { + throw new \InvalidArgumentException("Unknown value '{$value}' for field '{$this->getId()}'."); + } } } return parent::value($value); } + + /** + * Ignores invalid values when reading them from data. + * + * @since 6.2 + */ + public function ignoreInvalidValues(bool $ignoreInvalidValues = true): self + { + $this->ignoreInvalidValues = $ignoreInvalidValues; + + return $this; + } } diff --git a/wcfsetup/install/files/lib/system/form/option/CheckboxesFormOption.class.php b/wcfsetup/install/files/lib/system/form/option/CheckboxesFormOption.class.php index d6df509368..02fe4c53d7 100644 --- a/wcfsetup/install/files/lib/system/form/option/CheckboxesFormOption.class.php +++ b/wcfsetup/install/files/lib/system/form/option/CheckboxesFormOption.class.php @@ -30,7 +30,8 @@ public function getId(): string #[\Override] public function getFormField(string $id, array $configuration = []): AbstractFormField { - $formField = MultipleSelectionFormField::create($id); + $formField = MultipleSelectionFormField::create($id) + ->ignoreInvalidValues(); $this->setSelectOptions($formField, $configuration); return $formField; diff --git a/wcfsetup/install/files/lib/system/form/option/SelectFormOption.class.php b/wcfsetup/install/files/lib/system/form/option/SelectFormOption.class.php index c23bec8dd6..781299b8d1 100644 --- a/wcfsetup/install/files/lib/system/form/option/SelectFormOption.class.php +++ b/wcfsetup/install/files/lib/system/form/option/SelectFormOption.class.php @@ -30,7 +30,8 @@ public function getId(): string #[\Override] public function getFormField(string $id, array $configuration = []): AbstractFormField { - $formField = SelectFormField::create($id); + $formField = SelectFormField::create($id) + ->ignoreInvalidValues(); $this->setSelectOptions($formField, $configuration); return $formField;