From 0cb2234e773f237c2469482860fd9ec58799de5c Mon Sep 17 00:00:00 2001 From: Marcel Werk Date: Wed, 3 May 2023 18:06:10 +0200 Subject: [PATCH] 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 --- .../templates/__selectFormField.tpl | 15 +++ .../files/acp/templates/__selectFormField.tpl | 15 +++ .../builder/field/SelectFormField.class.php | 97 +++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 com.woltlab.wcf/templates/__selectFormField.tpl create mode 100644 wcfsetup/install/files/acp/templates/__selectFormField.tpl create mode 100644 wcfsetup/install/files/lib/system/form/builder/field/SelectFormField.class.php 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); + } +} -- 2.20.1