From: Marcel Werk Date: Wed, 3 May 2023 16:06:10 +0000 (+0200) Subject: Add a dedicated form field for plain select fields X-Git-Tag: 6.0.0_Alpha_1~161^2~3 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=0cb2234e773f237c2469482860fd9ec58799de5c;p=GitHub%2FWoltLab%2FWCF.git Add a dedicated form field for plain select fields The existing `SingleSelectionFormField` has multiple design flaws that are difficult to solve in a backward compatible way. The main issue with the existing implementation is that it tries to solve too many problems at once, creating an API that is inconsistent and difficult to use / easy to misuse. This is the first implementation with more to follow that will eventually allow us to phase out the `SingleSelectionFormField`. Closes #5265 Closes #4789 --- diff --git a/com.woltlab.wcf/templates/__selectFormField.tpl b/com.woltlab.wcf/templates/__selectFormField.tpl new file mode 100644 index 0000000000..7c966276e0 --- /dev/null +++ b/com.woltlab.wcf/templates/__selectFormField.tpl @@ -0,0 +1,15 @@ + diff --git a/wcfsetup/install/files/acp/templates/__selectFormField.tpl b/wcfsetup/install/files/acp/templates/__selectFormField.tpl new file mode 100644 index 0000000000..7c966276e0 --- /dev/null +++ b/wcfsetup/install/files/acp/templates/__selectFormField.tpl @@ -0,0 +1,15 @@ + 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 new file mode 100644 index 0000000000..f35a2d7369 --- /dev/null +++ b/wcfsetup/install/files/lib/system/form/builder/field/SelectFormField.class.php @@ -0,0 +1,97 @@ + + * @since 6.0 + */ +final class SelectFormField extends AbstractFormField implements + ICssClassFormField, + IImmutableFormField +{ + use TCssClassFormField; + use TImmutableFormField; + use TSelectionFormField; + + /** + * @inheritDoc + */ + protected $javaScriptDataHandlerModule = 'WoltLabSuite/Core/Form/Builder/Field/Value'; + + /** + * @inheritDoc + */ + protected $templateName = '__selectFormField'; + + /** + * @inheritDoc + */ + public function getSaveValue() + { + if ($this->getValue() === '') { + return; + } + + return parent::getSaveValue(); + } + + /** + * @inheritDoc + */ + public function readValue() + { + if ($this->getDocument()->hasRequestData($this->getPrefixedId())) { + $value = $this->getDocument()->getRequestData($this->getPrefixedId()); + + if (\is_string($value)) { + $this->value = $value; + } + } + + return $this; + } + + /** + * @inheritDoc + */ + public function validate() + { + if ($this->getValue() === '') { + if ($this->isRequired()) { + $this->addValidationError(new FormFieldValidationError('empty')); + } + } else if (!isset($this->getOptions()[$this->getValue()])) { + $this->addValidationError(new FormFieldValidationError( + 'invalidValue', + 'wcf.global.form.error.noValidSelection' + )); + } + + parent::validate(); + } + + /** + * @inheritDoc + */ + public function value($value) + { + // ignore `null` as value which can be passed either for nullable + // fields or as value if no options are available + if ($value === null) { + return $this; + } + + if (!isset($this->getOptions()[$value])) { + throw new \InvalidArgumentException("Unknown value '{$value}' for field '{$this->getId()}'."); + } + + return parent::value($value); + } +}