Skip to content

Commit 5789cb4

Browse files
committed
Add AbstractFormOptionAddForm
1 parent 4046975 commit 5789cb4

19 files changed

+161
-137
lines changed

wcfsetup/install/files/acp/database/update_com.woltlab.wcf_6.2.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use wcf\system\database\table\column\IntDatabaseTableColumn;
1212
use wcf\system\database\table\column\MediumtextDatabaseTableColumn;
1313
use wcf\system\database\table\column\TextDatabaseTableColumn;
14+
use wcf\system\database\table\column\TinyintDatabaseTableColumn;
1415
use wcf\system\database\table\index\DatabaseTableForeignKey;
1516
use wcf\system\database\table\PartialDatabaseTable;
1617

@@ -57,6 +58,8 @@
5758
->drop(),
5859
MediumtextDatabaseTableColumn::create('selectOptions')
5960
->drop(),
61+
TinyintDatabaseTableColumn::create('required')
62+
->drop(),
6063
MediumtextDatabaseTableColumn::create('configurationData'),
6164
]),
6265
PartialDatabaseTable::create('wcf1_file')

wcfsetup/install/files/acp/templates/contactSettings.tpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
</td>
6565
<td class="columnID">{@$option->optionID}</td>
6666
<td class="columnTitle columnOptionTitle"><a href="{link controller='ContactOptionEdit' id=$option->optionID}{/link}">{$option->getTitle()}</a></td>
67-
<td class="columnText columnOptionType">{lang}wcf.acp.customOption.optionType.{$option->optionType}{/lang}</td>
67+
<td class="columnText columnOptionType">{lang}wcf.form.option.{$option->optionType}{/lang}</td>
6868
<td class="columnDigits columnShowOrder">{#$option->showOrder}</td>
6969

7070
{event name='columns'}

wcfsetup/install/files/lib/acp/form/AbstractCustomOptionForm.class.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* @copyright 2001-2019 WoltLab GmbH
1616
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
1717
* @since 3.1
18-
* @deprecated 6.2 Use `IFormOption` instead
18+
* @deprecated 6.2 Use `AbstractFormOptionAddForm` instead
1919
*/
2020
abstract class AbstractCustomOptionForm extends AbstractAcpForm
2121
{
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
<?php
2+
3+
namespace wcf\acp\form;
4+
5+
use wcf\data\DatabaseObject;
6+
use wcf\data\IStorableObject;
7+
use wcf\form\AbstractFormBuilderForm;
8+
use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
9+
use wcf\system\form\builder\field\dependency\ValueFormFieldDependency;
10+
use wcf\system\form\builder\field\SelectFormField;
11+
use wcf\system\form\builder\IFormDocument;
12+
use wcf\system\form\option\FormOptionHandler;
13+
use wcf\system\form\option\SharedConfigurationFormFields;
14+
use wcf\system\WCF;
15+
use wcf\util\JSON;
16+
17+
/**
18+
* Default implementation for a form that adds custom options based on the form option system.
19+
*
20+
* @author Marcel Werk
21+
* @copyright 2001-2025 WoltLab GmbH
22+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
23+
* @since 6.2
24+
*/
25+
abstract class AbstractFormOptionAddForm extends AbstractFormBuilderForm
26+
{
27+
#[\Override]
28+
public function finalizeForm()
29+
{
30+
parent::finalizeForm();
31+
32+
$this->form->getDataHandler()->addProcessor(
33+
new CustomFormDataProcessor(
34+
'saveOptionProcessor',
35+
function (IFormDocument $document, array $parameters) {
36+
$configurationData = [];
37+
38+
foreach ($this->getConfigurationFormFieldIds() as $parameter) {
39+
if (isset($parameters['data'][$parameter])) {
40+
$configurationData[$parameter] = $parameters['data'][$parameter];
41+
unset($parameters['data'][$parameter]);
42+
}
43+
}
44+
45+
if ($configurationData !== []) {
46+
$parameters['data']['configurationData'] = JSON::encode($configurationData);
47+
}
48+
49+
return $parameters;
50+
},
51+
function (IFormDocument $document, array $data, IStorableObject $object) {
52+
\assert($object instanceof DatabaseObject);
53+
54+
if ($object->configurationData) {
55+
$data = \array_merge($data, JSON::decode($object->configurationData));
56+
}
57+
58+
return $data;
59+
}
60+
)
61+
);
62+
}
63+
64+
/**
65+
* @return string[]
66+
*/
67+
protected function getConfigurationFormFieldIds(): array
68+
{
69+
$ids = [];
70+
71+
foreach (FormOptionHandler::getInstance()->getOptions() as $option) {
72+
foreach ($option->getConfigurationFormFields() as $formFieldId) {
73+
$ids[] = $formFieldId;
74+
}
75+
}
76+
77+
return \array_unique($ids);
78+
}
79+
80+
/**
81+
* @return IFormField[]
82+
*/
83+
protected function getSharedConfigurationFormFields(): array
84+
{
85+
$sharedConfigurationFormFields = new SharedConfigurationFormFields();
86+
$matrix = [];
87+
88+
foreach (FormOptionHandler::getInstance()->getOptions() as $option) {
89+
foreach ($option->getConfigurationFormFields() as $formFieldId) {
90+
if (!isset($matrix[$formFieldId])) {
91+
$matrix[$formFieldId] = [];
92+
}
93+
94+
$matrix[$formFieldId][] = $option->getId();
95+
}
96+
}
97+
98+
$formFields = [];
99+
100+
foreach ($matrix as $formFieldId => $dependencies) {
101+
$formField = $sharedConfigurationFormFields->getFormField($formFieldId);
102+
$formField->addDependency(
103+
ValueFormFieldDependency::create($formFieldId . 'OptionTypeDependency')
104+
->fieldId('optionType')
105+
->values($dependencies)
106+
);
107+
$formFields[] = $formField;
108+
}
109+
110+
return $formFields;
111+
}
112+
113+
/**
114+
* @return array<string, string>
115+
*/
116+
protected function getAvailableOptionTypes(): array
117+
{
118+
$optionTypes = \array_map(fn($option) => $option->getTitle(), FormOptionHandler::getInstance()->getOptions());
119+
120+
$collator = new \Collator(WCF::getLanguage()->getLocale());
121+
\uasort(
122+
$optionTypes,
123+
static fn(string $a, string $b) => $collator->compare($a, $b)
124+
);
125+
126+
return $optionTypes;
127+
}
128+
129+
protected function getOptionTypeFormField(): SelectFormField
130+
{
131+
return SelectFormField::create('optionType')
132+
->label('wcf.form.option.optionType')
133+
->immutable($this->formAction != 'create')
134+
->options($this->getAvailableOptionTypes())
135+
->required();
136+
}
137+
}

wcfsetup/install/files/lib/acp/form/ContactOptionAddForm.class.php

Lines changed: 2 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,11 @@
55
use wcf\data\contact\option\ContactOption;
66
use wcf\data\contact\option\ContactOptionAction;
77
use wcf\data\contact\option\ContactOptionList;
8-
use wcf\data\IStorableObject;
98
use wcf\form\AbstractFormBuilderForm;
10-
use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
119
use wcf\system\form\builder\field\BooleanFormField;
12-
use wcf\system\form\builder\field\dependency\ValueFormFieldDependency;
13-
use wcf\system\form\builder\field\IFormField;
1410
use wcf\system\form\builder\field\MultilineTextFormField;
15-
use wcf\system\form\builder\field\SelectFormField;
1611
use wcf\system\form\builder\field\ShowOrderFormField;
1712
use wcf\system\form\builder\field\TextFormField;
18-
use wcf\system\form\builder\IFormDocument;
19-
use wcf\system\form\option\FormOptionHandler;
20-
use wcf\system\form\option\SharedConfigurationFormFields;
21-
use wcf\system\WCF;
22-
use wcf\util\JSON;
2313

2414
/**
2515
* Shows the contact option add form.
@@ -31,7 +21,7 @@
3121
*
3222
* @extends AbstractFormBuilderForm<ContactOption>
3323
*/
34-
class ContactOptionAddForm extends AbstractFormBuilderForm
24+
class ContactOptionAddForm extends AbstractFormOptionAddForm
3525
{
3626
/**
3727
* @inheritDoc
@@ -73,56 +63,13 @@ protected function createForm()
7363
->languageItemPattern('wcf.contact.optionDescription\d+'),
7464
ShowOrderFormField::create('showOrder')
7565
->options($this->getContactOptions()),
76-
SelectFormField::create('optionType')
77-
->label('wcf.acp.customOption.optionType')
78-
->immutable($this->formAction != 'create')
79-
->options($this->getAvailableOptionTypes())
80-
->required(),
66+
$this->getOptionTypeFormField(),
8167
...$this->getSharedConfigurationFormFields(),
82-
BooleanFormField::create('required')
83-
->label('wcf.acp.customOption.required'),
8468
BooleanFormField::create('isDisabled')
8569
->label('wcf.acp.customOption.isDisabled'),
8670
]);
8771
}
8872

89-
#[\Override]
90-
public function finalizeForm()
91-
{
92-
parent::finalizeForm();
93-
94-
$this->form->getDataHandler()->addProcessor(
95-
new CustomFormDataProcessor(
96-
'saveOptionProcessor',
97-
function (IFormDocument $document, array $parameters) {
98-
$configurationData = [];
99-
100-
foreach ($this->getConfigurationFormFieldIds() as $parameter) {
101-
if (isset($parameters['data'][$parameter])) {
102-
$configurationData[$parameter] = $parameters['data'][$parameter];
103-
unset($parameters['data'][$parameter]);
104-
}
105-
}
106-
107-
if ($configurationData !== []) {
108-
$parameters['data']['configurationData'] = JSON::encode($configurationData);
109-
}
110-
111-
return $parameters;
112-
},
113-
function (IFormDocument $document, array $data, IStorableObject $object) {
114-
\assert($object instanceof ContactOption);
115-
116-
if ($object->configurationData) {
117-
$data = \array_merge($data, JSON::decode($object->configurationData));
118-
}
119-
120-
return $data;
121-
}
122-
)
123-
);
124-
}
125-
12673
/**
12774
* @return array<int, string>
12875
*/
@@ -134,69 +81,4 @@ private function getContactOptions(): array
13481

13582
return \array_map(static fn($option) => $option->getTitle(), $optionList->getObjects());
13683
}
137-
138-
/**
139-
* @return array<string, string>
140-
*/
141-
private function getAvailableOptionTypes(): array
142-
{
143-
$optionTypes = \array_map(fn($option) => $option->getTitle(), FormOptionHandler::getInstance()->getOptions());
144-
145-
$collator = new \Collator(WCF::getLanguage()->getLocale());
146-
\uasort(
147-
$optionTypes,
148-
static fn(string $a, string $b) => $collator->compare($a, $b)
149-
);
150-
151-
return $optionTypes;
152-
}
153-
154-
/**
155-
* @return IFormField[]
156-
*/
157-
private function getSharedConfigurationFormFields(): array
158-
{
159-
$sharedConfigurationFormFields = new SharedConfigurationFormFields();
160-
$matrix = [];
161-
162-
foreach (FormOptionHandler::getInstance()->getOptions() as $option) {
163-
foreach ($option->getConfigurationFormFields() as $formFieldId) {
164-
if (!isset($matrix[$formFieldId])) {
165-
$matrix[$formFieldId] = [];
166-
}
167-
168-
$matrix[$formFieldId][] = $option->getId();
169-
}
170-
}
171-
172-
$formFields = [];
173-
174-
foreach ($matrix as $formFieldId => $dependencies) {
175-
$formField = $sharedConfigurationFormFields->getFormField($formFieldId);
176-
$formField->addDependency(
177-
ValueFormFieldDependency::create($formFieldId . 'OptionTypeDependency')
178-
->fieldId('optionType')
179-
->values($dependencies)
180-
);
181-
$formFields[] = $formField;
182-
}
183-
184-
return $formFields;
185-
}
186-
187-
/**
188-
* @return string[]
189-
*/
190-
private function getConfigurationFormFieldIds(): array
191-
{
192-
$ids = [];
193-
194-
foreach (FormOptionHandler::getInstance()->getOptions() as $option) {
195-
foreach ($option->getConfigurationFormFields() as $formFieldId) {
196-
$ids[] = $formFieldId;
197-
}
198-
}
199-
200-
return \array_unique($ids);
201-
}
20284
}

wcfsetup/install/files/lib/data/contact/option/ContactOption.class.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
* @property-read string $optionDescription description of the option or name of language item which contains the description
2424
* @property-read string $optionType type of the option which determines its input and output
2525
* @property-read string $configurationData JSON-encoded configuration information depending on the option type
26-
* @property-read int $required is `1` if the option has to be filled out, otherwise `0`
2726
* @property-read int $showOrder position of the option in relation to the other options
2827
* @property-read int $isDisabled is `1` if the option is disabled, otherwise `0`
2928
* @property-read int $originIsSystem is `1` if the option has been delivered by a package, otherwise `0` (i.e. the option has been created in the ACP)

wcfsetup/install/files/lib/form/ContactForm.class.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ protected function getOptionFormFields(): array
213213
$formField->label($option->optionTitle);
214214
$formField->description($option->optionDescription);
215215

216-
if ($option->required) {
216+
if (!empty($option->getConfigurationData()['required'])) {
217217
$formField->required();
218218
}
219219

wcfsetup/install/files/lib/system/form/option/AbstractFormOption.class.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ abstract class AbstractFormOption implements IFormOption
2020
#[\Override]
2121
public function getConfigurationFormFields(): array
2222
{
23-
return [];
23+
return ['required'];
2424
}
2525

2626
#[\Override]

wcfsetup/install/files/lib/system/form/option/CheckboxesFormOption.class.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,7 @@ public function getFormField(string $id, array $configurationData = []): Multipl
5353
#[\Override]
5454
public function getConfigurationFormFields(): array
5555
{
56-
return [
57-
'selectOptions'
58-
];
56+
return ['selectOptions', 'required'];
5957
}
6058

6159
#[\Override]

wcfsetup/install/files/lib/system/form/option/CurrencyFormOption.class.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public function getFormField(string $id, array $configurationData = []): Abstrac
4242
#[\Override]
4343
public function getConfigurationFormFields(): array
4444
{
45-
return ['currency', 'minFloatValue', 'maxFloatValue'];
45+
return ['currency', 'minFloatValue', 'maxFloatValue', 'required'];
4646
}
4747

4848
#[\Override]

0 commit comments

Comments
 (0)