From 5cda3a530ceb505a7f3017fcab98a0e21fb34a53 Mon Sep 17 00:00:00 2001 From: Matthias Schmidt Date: Sat, 13 Oct 2018 10:40:38 +0200 Subject: [PATCH] Add GUI support for user option package installation plugin See #2545 --- ...pOptionPackageInstallationPlugin.class.php | 2 +- ...rOptionPackageInstallationPlugin.class.php | 246 +++++++++++++++++- wcfsetup/install/lang/en.xml | 19 ++ 3 files changed, 261 insertions(+), 6 deletions(-) diff --git a/wcfsetup/install/files/lib/system/package/plugin/UserGroupOptionPackageInstallationPlugin.class.php b/wcfsetup/install/files/lib/system/package/plugin/UserGroupOptionPackageInstallationPlugin.class.php index dda019f57f..596bd7347d 100644 --- a/wcfsetup/install/files/lib/system/package/plugin/UserGroupOptionPackageInstallationPlugin.class.php +++ b/wcfsetup/install/files/lib/system/package/plugin/UserGroupOptionPackageInstallationPlugin.class.php @@ -21,7 +21,7 @@ use wcf\util\StringUtil; /** * Installs, updates and deletes user group options. * - * @author Alexander Ebert + * @author Alexander Ebert, Matthias Schmidt * @copyright 2001-2018 WoltLab GmbH * @license GNU Lesser General Public License * @package WoltLabSuite\Core\System\Package\Plugin diff --git a/wcfsetup/install/files/lib/system/package/plugin/UserOptionPackageInstallationPlugin.class.php b/wcfsetup/install/files/lib/system/package/plugin/UserOptionPackageInstallationPlugin.class.php index 8aac2d462b..d07ffdb53c 100644 --- a/wcfsetup/install/files/lib/system/package/plugin/UserOptionPackageInstallationPlugin.class.php +++ b/wcfsetup/install/files/lib/system/package/plugin/UserOptionPackageInstallationPlugin.class.php @@ -1,28 +1,48 @@ * @package WoltLabSuite\Core\System\Package\Plugin */ -class UserOptionPackageInstallationPlugin extends AbstractOptionPackageInstallationPlugin implements IIdempotentPackageInstallationPlugin { +class UserOptionPackageInstallationPlugin extends AbstractOptionPackageInstallationPlugin implements IGuiPackageInstallationPlugin { /** * @inheritDoc */ public $tableName = 'user_option'; + /** + * @inheritDoc + */ + public $tagName = 'option'; + /** * list of names of tags which aren't considered as additional data * @var string[] @@ -36,8 +56,8 @@ class UserOptionPackageInstallationPlugin extends AbstractOptionPackageInstallat // use for create and update $data = [ 'parentCategoryName' => $category['parentCategoryName'], - 'permissions' => $category['permissions'], - 'options' => $category['options'] + 'permissions' => $category['permissions'] ?? '', + 'options' => $category['options'] ?? '' ]; // append show order if explicitly stated if ($category['showOrder'] !== null) $data['showOrder'] = $category['showOrder']; @@ -163,4 +183,220 @@ class UserOptionPackageInstallationPlugin extends AbstractOptionPackageInstallat // uninstall options and categories parent::uninstall(); } + + /** + * @inheritDoc + * @since 3.2 + */ + public function addFormFields(IFormDocument $form) { + parent::addFormFields($form); + + if ($this->entryType === 'options') { + /** @var IFormContainer $dataContainer */ + $dataContainer = $form->getNodeById('data'); + + /** @var SingleSelectionFormField $optionType */ + $optionType = $form->getNodeById('optionType'); + + $dataContainer->appendChildren([ + BooleanFormField::create('required') + ->label('wcf.acp.pip.userOption.options.required') + ->description('wcf.acp.pip.userOption.options.required.description'), + + BooleanFormField::create('askDuringRegistration') + ->objectProperty('askduringregistration') + ->label('wcf.acp.pip.userOption.options.askDuringRegistration') + ->description('wcf.acp.pip.userOption.options.askDuringRegistration.description'), + + SingleSelectionFormField::create('editable') + ->label('wcf.acp.pip.userOption.options.editable') + ->description('wcf.acp.pip.userOption.options.editable.description') + ->options([ + 1 => 'wcf.acp.user.option.editable.1', + 2 => 'wcf.acp.user.option.editable.2', + 3 => 'wcf.acp.user.option.editable.3', + 6 => 'wcf.acp.user.option.editable.6' + ]), + + SingleSelectionFormField::create('visible') + ->label('wcf.acp.pip.userOption.options.visible') + ->description('wcf.acp.pip.userOption.options.visible.description') + ->options([ + 0 => 'wcf.acp.user.option.visible.0', + 1 => 'wcf.acp.user.option.visible.1', + 2 => 'wcf.acp.user.option.visible.2', + 3 => 'wcf.acp.user.option.visible.3', + 7 => 'wcf.acp.user.option.visible.7', + 15 => 'wcf.acp.user.option.visible.15', + ]), + + ClassNameFormField::create('outputClass') + ->objectProperty('outputclass') + ->label('wcf.acp.pip.userOption.options.outputClass') + ->implementedInterface(IUserOptionOutput::class), + + BooleanFormField::create('searchable') + ->label('wcf.acp.pip.userOption.options.searchable') + ->description('wcf.acp.pip.userOption.options.searchable.description'), + + BooleanFormField::create('isDisabled') + ->objectProperty('isdisabled') + ->label('wcf.acp.pip.userOption.options.isDisabled') + ->description('wcf.acp.pip.userOption.options.isDisabled.description'), + + // option type-specific fields + SingleSelectionFormField::create('messageObjectType') + ->label('wcf.acp.pip.userOption.options.messageObjectType') + ->description('wcf.acp.pip.userOption.options.messageObjectType.description') + ->options(function() { + $options = []; + foreach (ObjectTypeCache::getInstance()->getObjectTypes('com.woltlab.wcf.message') as $objectType) { + $options[$objectType->objectType] = $objectType->objectType; + } + + asort($options); + + return $options; + }, false, false) + ->addDependency( + ValueFormFieldDependency::create('optionType') + ->field($optionType) + ->values(['aboutMe', 'message']) + ), + + TextFormField::create('contentPattern') + ->objectProperty('contentpattern') + ->label('wcf.acp.pip.userOption.options.contentPattern') + ->description('wcf.acp.pip.userOption.options.contentPattern.description') + ->addValidator(new FormFieldValidator('regex', function(TextFormField $formField) { + if ($formField->getSaveValue() !== '') { + if (!Regex::compile($formField->getSaveValue())->isValid()) { + $formField->addValidationError( + new FormFieldValidationError( + 'invalid', + 'wcf.acp.pip.userOption.options.contentPattern.error.invalid' + ) + ); + } + } + })) + ->addDependency( + ValueFormFieldDependency::create('optionType') + ->field($optionType) + ->values(['text']) + ), + ]); + } + } + + /** + * @inheritDoc + * @since 3.2 + */ + protected function getElementData(\DOMElement $element, $saveData = false) { + $data = parent::getElementData($element, $saveData); + + switch ($this->entryType) { + case 'options': + $optionals = [ + 'required', + 'askDuringRegistration', + 'editable', + 'visible', + 'outputClass', + 'searchable', + 'isDisabled', + 'contentPattern' + ]; + + foreach ($optionals as $optionalPropertyName) { + $optionalProperty = $element->getElementsByTagName(strtolower($optionalPropertyName))->item(0); + if ($optionalProperty !== null) { + if ($saveData) { + $data[strtolower($optionalPropertyName)] = $optionalProperty->nodeValue; + } + else { + $data[$optionalPropertyName] = $optionalProperty->nodeValue; + } + } + } + + $messageObjectType = $element->getElementsByTagName('messageObjectType')->item(0); + if ($messageObjectType !== null) { + $data['messageObjectType'] = $messageObjectType->nodeValue; + } + + break; + } + + return $data; + } + + /** + * @inheritDoc + * @since 3.2 + */ + protected function getSortOptionHandler() { + // reuse UserGroupOptionHandler + return new class(true) extends UserOptionHandler { + /** + * @inheritDoc + */ + protected function checkCategory(OptionCategory $category) { + // we do not care for category checks here + return true; + } + + /** + * @inheritDoc + */ + protected function checkOption(Option $option) { + // we do not care for option checks here + return true; + } + + /** + * @inheritDoc + */ + public function getCategoryOptions($categoryName = '', $inherit = true) { + // we just need to ensure that the category is not empty + return [new Option(null, [])]; + } + }; + } + + /** + * @inheritDoc + * @since 3.2 + */ + protected function writeEntry(\DOMDocument $document, IFormDocument $form) { + $option = parent::writeEntry($document, $form); + + $formData = $form->getData()['data']; + + switch ($this->entryType) { + case 'options': + $fields = [ + 'outputclass' => '', + 'required' => 0, + 'askduringregistration' => 0, + 'editable' => 0, + 'visible' => 0, + 'searchable' => 0, + 'isdisabled' => 0, + 'messageObjectType' => '', + 'contentpattern' => '' + ]; + + foreach ($fields as $field => $defaultValue) { + if (isset($formData[$field]) && $formData[$field] !== $defaultValue) { + $option->appendChild($document->createElement($field, (string) $formData[$field])); + } + } + + break; + } + + return $option; + } } diff --git a/wcfsetup/install/lang/en.xml b/wcfsetup/install/lang/en.xml index 1f6ad77349..f0da18b35e 100644 --- a/wcfsetup/install/lang/en.xml +++ b/wcfsetup/install/lang/en.xml @@ -2204,6 +2204,25 @@ If you have already bought the licenses for the listed apps, th + + + + + + + + + + + + + + + + wcf\system\html\input\HtmlInputProcessor object used to process the user option value.]]> + + + -- 2.20.1