From 5718cdd6b02f26e5a3abbf03b55269d110f3e80c Mon Sep 17 00:00:00 2001 From: Matthias Schmidt Date: Fri, 12 Oct 2018 19:10:20 +0200 Subject: [PATCH] Add GUI support for user group option package installation plugin See #2545 --- .../builder/field/OptionFormField.class.php | 14 +- ...tOptionPackageInstallationPlugin.class.php | 39 ++++- ...pOptionPackageInstallationPlugin.class.php | 158 +++++++++++++++++- wcfsetup/install/lang/en.xml | 16 +- 4 files changed, 217 insertions(+), 10 deletions(-) diff --git a/wcfsetup/install/files/lib/system/form/builder/field/OptionFormField.class.php b/wcfsetup/install/files/lib/system/form/builder/field/OptionFormField.class.php index 4c46f1c333..a3905a9e78 100644 --- a/wcfsetup/install/files/lib/system/form/builder/field/OptionFormField.class.php +++ b/wcfsetup/install/files/lib/system/form/builder/field/OptionFormField.class.php @@ -72,8 +72,18 @@ class OptionFormField extends ItemListFormField { parent::validate(); if (empty($this->getValidationErrors()) && is_array($this->getValue()) && !empty($this->getValue())) { + // ignore `module_attachment`, see https://github.com/WoltLab/WCF/issues/2531 + $options = $this->getValue(); + if (($index = array_search('module_attachment', $options)) !== false) { + unset($options[$index]); + } + + if (empty($options)) { + return; + } + $conditionBuilder = new PreparedStatementConditionBuilder(); - $conditionBuilder->add('optionName IN (?)', [$this->getValue()]); + $conditionBuilder->add('optionName IN (?)', [$options]); if (!empty($this->getPackageIDs())) { $conditionBuilder->add('packageID IN (?)', [$this->getPackageIDs()]); } @@ -85,7 +95,7 @@ class OptionFormField extends ItemListFormField { $statement->execute($conditionBuilder->getParameters()); $availableOptions = $statement->fetchAll(\PDO::FETCH_COLUMN); - $unknownOptions = array_diff($this->getValue(), $availableOptions); + $unknownOptions = array_diff($options, $availableOptions); if (!empty($unknownOptions)) { $this->addValidationError( diff --git a/wcfsetup/install/files/lib/system/package/plugin/AbstractOptionPackageInstallationPlugin.class.php b/wcfsetup/install/files/lib/system/package/plugin/AbstractOptionPackageInstallationPlugin.class.php index 428011fabf..7c8bdb6cb5 100644 --- a/wcfsetup/install/files/lib/system/package/plugin/AbstractOptionPackageInstallationPlugin.class.php +++ b/wcfsetup/install/files/lib/system/package/plugin/AbstractOptionPackageInstallationPlugin.class.php @@ -447,11 +447,14 @@ abstract class AbstractOptionPackageInstallationPlugin extends AbstractXMLPackag break; case 'options': + $classnamePieces = explode('\\', get_class($this)); + $pipPrefix = str_replace('PackageInstallationPlugin', '', array_pop($classnamePieces)); + $dataContainer->appendChildren([ TextFormField::create('optionName') ->objectProperty('name') ->label('wcf.acp.pip.abstractOption.options.optionName') - ->description('wcf.acp.pip.abstractOption.categories.options.description') + ->description('wcf.acp.pip.abstractOption.options.optionName.description') ->required(), SingleSelectionFormField::create('categoryName') @@ -490,7 +493,7 @@ abstract class AbstractOptionPackageInstallationPlugin extends AbstractXMLPackag SingleSelectionFormField::create('optionType') ->objectProperty('optiontype') ->label('wcf.acp.pip.abstractOption.options.optionType') - ->description('wcf.acp.pip.' . $this->tagName . '.options.optionType.description') + ->description('wcf.acp.pip.' . lcfirst($pipPrefix) . '.options.optionType.description') ->required() ->options(function(): array { $classnamePieces = explode('\\', get_class()); @@ -774,6 +777,32 @@ abstract class AbstractOptionPackageInstallationPlugin extends AbstractXMLPackag throw new \LogicException('Unreachable'); } + if ($saveData) { + $lowercaseData = [ + 'packageID' => $this->installation->getPackage()->packageID + ]; + + $lowercaseFields = [ + 'categoryName', + 'optionName', + 'optionType', + 'defaultValue', + 'enableOptions', + 'validationPattern', + 'showOrder', + 'parentCategoryName', + 'showOrder' + ]; + + foreach ($lowercaseFields as $name) { + if (isset($data[$name])) { + $lowercaseData[strtolower($name)] = $data[$name]; + } + } + + return $lowercaseData; + } + return $data; } @@ -854,7 +883,7 @@ abstract class AbstractOptionPackageInstallationPlugin extends AbstractXMLPackag case 'options': $optionData = $this->getElementData($newElement, true); - $this->saveOption($optionData, $optionData['categoryName']); + $this->saveOption($optionData, $optionData['categoryname']); break; } @@ -1023,7 +1052,7 @@ abstract class AbstractOptionPackageInstallationPlugin extends AbstractXMLPackag 'options' => '', 'permissions' => '', - // object-type specific elements + // option type-specific elements 'minvalue' => null, 'maxvalue' => null, 'suffix' => '', @@ -1034,7 +1063,7 @@ abstract class AbstractOptionPackageInstallationPlugin extends AbstractXMLPackag ]; foreach ($fields as $field => $defaultValue) { if (isset($formData[$field]) && $formData[$field] !== $defaultValue) { - $option->appendChild($document->createElement($field, (string) $formData[$field])); + $option->appendChild($document->createElement($field, StringUtil::unifyNewlines((string) $formData[$field]))); } } 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 8942b26523..dda019f57f 100644 --- a/wcfsetup/install/files/lib/system/package/plugin/UserGroupOptionPackageInstallationPlugin.class.php +++ b/wcfsetup/install/files/lib/system/package/plugin/UserGroupOptionPackageInstallationPlugin.class.php @@ -1,10 +1,20 @@ * @package WoltLabSuite\Core\System\Package\Plugin */ -class UserGroupOptionPackageInstallationPlugin extends AbstractOptionPackageInstallationPlugin implements IIdempotentPackageInstallationPlugin { +class UserGroupOptionPackageInstallationPlugin extends AbstractOptionPackageInstallationPlugin implements IGuiPackageInstallationPlugin { /** * list of group ids by type * @var integer[][] @@ -28,6 +38,11 @@ class UserGroupOptionPackageInstallationPlugin extends AbstractOptionPackageInst */ public $tableName = 'user_group_option'; + /** + * @inheritDoc + */ + public $tagName = 'option'; + /** * list of names of tags which aren't considered as additional data * @var string[] @@ -189,4 +204,143 @@ class UserGroupOptionPackageInstallationPlugin extends AbstractOptionPackageInst return $this->groupIDs; } + + /** + * @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([ + MultilineTextFormField::create('adminDefaultValue') + ->objectProperty('admindefaultvalue') + ->label('wcf.acp.pip.userGroupOption.options.adminDefaultValue') + ->description('wcf.acp.pip.userGroupOption.options.adminDefaultValue.description') + ->rows(5), + + MultilineTextFormField::create('modDefaultValue') + ->objectProperty('moddefaultvalue') + ->label('wcf.acp.pip.userGroupOption.options.modDefaultValue') + ->description('wcf.acp.pip.userGroupOption.options.modDefaultValue.description') + ->rows(5), + + BooleanFormField::create('usersOnly') + ->objectProperty('usersonly') + ->label('wcf.acp.pip.userGroupOption.options.usersOnly') + ->description('wcf.acp.pip.userGroupOption.options.usersOnly.description'), + + BooleanFormField::create('excludedInTinyBuild') + ->label('wcf.acp.pip.userGroupOption.options.excludedInTinyBuild') + ->description('wcf.acp.pip.userGroupOption.options.excludedInTinyBuild.description'), + + TextFormField::create('wildcard') + ->label('wcf.acp.pip.userGroupOption.options.wildcard') + ->description('wcf.acp.pip.userGroupOption.options.wildcard.description') + ->addDependency( + ValueFormFieldDependency::create('optionType') + ->field($optionType) + ->values(['textarea']) + ) + ]); + } + } + + /** + * @inheritDoc + * @since 3.2 + */ + protected function getElementData(\DOMElement $element, $saveData = false) { + $data = parent::getElementData($element, $saveData); + + switch ($this->entryType) { + case 'options': + foreach (['adminDefaultValue', 'modDefaultValue', 'usersOnly', 'excludedInTinyBuild', 'wildcard'] as $optionalPropertyName) { + $optionalProperty = $element->getElementsByTagName(strtolower($optionalPropertyName))->item(0); + if ($optionalProperty !== null) { + if ($saveData && $optionalPropertyName !== 'excludedInTinyBuild') { + $data[strtolower($optionalPropertyName)] = $optionalProperty->nodeValue; + } + else { + $data[$optionalPropertyName] = $optionalProperty->nodeValue; + } + } + } + + break; + } + + return $data; + } + + /** + * @inheritDoc + * @since 3.2 + */ + protected function getSortOptionHandler() { + // reuse UserGroupOptionHandler + return new class(true) extends UserGroupOptionHandler { + /** + * @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 = [ + 'admindefaultvalue' => '', + 'moddefaultvalue' => '', + 'usersonly' => 0, + 'excludedInTinyBuild' => 0, + 'wildcard' => '' + ]; + + 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 11e2f9e309..5b23ca02ea 100644 --- a/wcfsetup/install/lang/en.xml +++ b/wcfsetup/install/lang/en.xml @@ -2137,7 +2137,7 @@ If you have already bought the licenses for the listed apps, th - + @@ -2188,6 +2188,20 @@ If you have already bought the licenses for the listed apps, th {'WCF_DIR'|constant}.]]> + + + + + + + + + + + + + + -- 2.20.1