diff --git a/wcfsetup/install/files/acp/templates/packageUpdateServerAdd.tpl b/wcfsetup/install/files/acp/templates/packageUpdateServerAdd.tpl index 79a322a3d84..ad94a982e87 100644 --- a/wcfsetup/install/files/acp/templates/packageUpdateServerAdd.tpl +++ b/wcfsetup/install/files/acp/templates/packageUpdateServerAdd.tpl @@ -1,4 +1,4 @@ -{include file='header' pageTitle='wcf.acp.updateServer.'|concat:$action} +{include file='header' pageTitle="wcf.acp.updateServer.$action"}
@@ -17,57 +17,10 @@
-{if $packageUpdateServer|isset && $packageUpdateServer->errorMessage} - {lang}wcf.acp.updateServer.lastErrorMessage{/lang}
{$packageUpdateServer->errorMessage}
+{if $formObject|isset && $formObject->errorMessage} + {lang}wcf.acp.updateServer.lastErrorMessage{/lang}
{$formObject->errorMessage}
{/if} -{include file='shared_formNotice'} - -
-
- -
-
- - {if $errorField == 'serverURL'} - - {if $errorType == 'empty'} - {lang}wcf.global.form.error.empty{/lang} - {elseif $errorType[duplicate]|isset} - {lang}wcf.acp.updateServer.serverURL.error.duplicate{/lang} - {else} - {lang}wcf.acp.updateServer.serverURL.error.{$errorType}{/lang} - {/if} - - {/if} -
- - -
-
-
- - {lang}wcf.acp.updateServer.loginUsername.description{/lang} -
-
- -
-
-
- - {lang}wcf.acp.updateServer.loginPassword.description{/lang} -
-
- - {event name='dataFields'} -
- - {event name='sections'} - -
- - {csrfToken} -
-
+{unsafe:$form->getHtml()} {include file='footer'} diff --git a/wcfsetup/install/files/lib/acp/form/PackageUpdateServerAddForm.class.php b/wcfsetup/install/files/lib/acp/form/PackageUpdateServerAddForm.class.php index f036ebd1a55..94492ad44d9 100755 --- a/wcfsetup/install/files/lib/acp/form/PackageUpdateServerAddForm.class.php +++ b/wcfsetup/install/files/lib/acp/form/PackageUpdateServerAddForm.class.php @@ -6,20 +6,27 @@ use wcf\data\package\update\server\PackageUpdateServer; use wcf\data\package\update\server\PackageUpdateServerAction; use wcf\data\package\update\server\PackageUpdateServerList; -use wcf\form\AbstractForm; -use wcf\system\exception\UserInputException; -use wcf\system\request\LinkHandler; -use wcf\system\WCF; -use wcf\util\StringUtil; +use wcf\form\AbstractFormBuilderForm; +use wcf\system\form\builder\container\FormContainer; +use wcf\system\form\builder\data\processor\CustomFormDataProcessor; +use wcf\system\form\builder\field\BooleanFormField; +use wcf\system\form\builder\field\PasswordFormField; +use wcf\system\form\builder\field\TextFormField; +use wcf\system\form\builder\field\UrlFormField; +use wcf\system\form\builder\field\validation\FormFieldValidationError; +use wcf\system\form\builder\field\validation\FormFieldValidator; +use wcf\system\form\builder\IFormDocument; /** * Shows the server add form. * - * @author Marcel Werk - * @copyright 2001-2019 WoltLab GmbH - * @license GNU Lesser General Public License + * @author Marcel Werk + * @copyright 2001-2025 WoltLab GmbH + * @license GNU Lesser General Public License + * + * @extends AbstractFormBuilderForm */ -class PackageUpdateServerAddForm extends AbstractForm +class PackageUpdateServerAddForm extends AbstractFormBuilderForm { /** * @inheritDoc @@ -31,158 +38,151 @@ class PackageUpdateServerAddForm extends AbstractForm */ public $neededPermissions = ['admin.configuration.package.canEditServer']; - /** - * server url - * @var string - */ - public $serverURL = ''; - - /** - * server login username - * @var string - */ - public $loginUsername = ''; - - /** - * server login password - * @var string - */ - public $loginPassword = ''; - /** * @inheritDoc */ - public function readFormParameters() - { - parent::readFormParameters(); - - if (isset($_POST['serverURL'])) { - $this->serverURL = StringUtil::trim($_POST['serverURL']); - } - if (isset($_POST['loginUsername'])) { - $this->loginUsername = $_POST['loginUsername']; - } - if (isset($_POST['loginPassword'])) { - $this->loginPassword = $_POST['loginPassword']; - } - } + public $objectActionClass = PackageUpdateServerAction::class; /** * @inheritDoc */ - public function validate() - { - parent::validate(); + public $objectEditLinkController = PackageUpdateServerEditForm::class; - $this->validateServerURL(); + #[\Override] + protected function createForm() + { + parent::createForm(); + + $this->form->appendChildren([ + FormContainer::create('data') + ->appendChildren([ + UrlFormField::create('serverURL') + ->label('wcf.acp.updateServer.serverURL') + ->required() + ->autoFocus() + ->addValidator( + new FormFieldValidator('serverUrlValidator', function (UrlFormField $formField) { + try { + $url = new Uri($formField->getValue()); + + if (!$url->getHost()) { + $formField->addValidationError( + new FormFieldValidationError( + 'invalid', + 'wcf.acp.updateServer.serverURL.error.invalid' + ) + ); + return; + } + if ($url->getHost() !== 'localhost') { + if ($url->getScheme() !== 'https') { + $formField->addValidationError( + new FormFieldValidationError( + 'invalidScheme', + 'wcf.acp.updateServer.serverURL.error.invalidScheme' + ) + ); + return; + } + if ($url->getPort()) { + $formField->addValidationError( + new FormFieldValidationError( + 'nonStandardPort', + 'wcf.acp.updateServer.serverURL.error.nonStandardPort' + ) + ); + return; + } + } + if ($url->getUserInfo()) { + $formField->addValidationError( + new FormFieldValidationError( + 'userinfo', + 'wcf.acp.updateServer.serverURL.error.userinfo' + ) + ); + return; + } + if (\str_ends_with(\strtolower($url->getHost()), '.woltlab.com')) { + $formField->addValidationError( + new FormFieldValidationError( + 'woltlab', + 'wcf.acp.updateServer.serverURL.error.woltlab' + ) + ); + return; + } + } catch (\InvalidArgumentException) { + $formField->addValidationError( + new FormFieldValidationError( + 'invalid', + 'wcf.acp.updateServer.serverURL.error.invalid' + ) + ); + return; + } + + if (($duplicate = $this->findDuplicateServer((string)$url))) { + $formField->addValidationError( + new FormFieldValidationError( + 'duplicate', + 'wcf.acp.updateServer.serverURL.error.duplicate', + ['duplicate' => $duplicate] + ) + ); + return; + } + }) + ), + TextFormField::create('loginUsername') + ->label('wcf.acp.updateServer.loginUsername') + ->description('wcf.acp.updateServer.loginUsername.description') + ->addFieldClass('medium'), + PasswordFormField::create('loginPassword') + ->label('wcf.acp.updateServer.loginPassword') + ->description('wcf.acp.updateServer.loginPassword.description') + ->addFieldClass('medium') + ->passwordStrengthMeter(false) + ->autocomplete('off'), + BooleanFormField::create('isDisabled') + ->label('wcf.acp.updateServer.isDisabled'), + ]), + ]); } - /** - * Validates the server URL. - * - * @return void - * @since 5.3 - */ - protected function validateServerURL() + #[\Override] + public function finalizeForm() { - if (empty($this->serverURL)) { - throw new UserInputException('serverURL'); - } + parent::finalizeForm(); - try { - $url = new Uri($this->serverURL); - $this->serverURL = (string)$url; + $this->form->getDataHandler()->addProcessor( + new CustomFormDataProcessor( + 'saveServerProcessor', + function (IFormDocument $document, array $parameters) { + // This ensures that the URL is well-formed. + $uri = new Uri($parameters['data']['serverURL']); + $parameters['data']['serverURL'] = (string)$uri; - if (!$url->getHost()) { - throw new UserInputException('serverURL', 'invalid'); - } - if ($url->getHost() !== 'localhost') { - if ($url->getScheme() !== 'https') { - throw new UserInputException('serverURL', 'invalidScheme'); - } - if ($url->getPort()) { - throw new UserInputException('serverURL', 'nonStandardPort'); + return $parameters; } - } - if ($url->getUserInfo()) { - throw new UserInputException('serverURL', 'userinfo'); - } - if (\str_ends_with(\strtolower($url->getHost()), '.woltlab.com')) { - throw new UserInputException('serverURL', 'woltlab'); - } - } catch (\InvalidArgumentException) { - throw new UserInputException('serverURL', 'invalid'); - } - - if (($duplicate = $this->findDuplicateServer())) { - throw new UserInputException('serverURL', [ - 'duplicate' => $duplicate, - ]); - } + ) + ); } /** * Returns the first package update server with a matching serverURL. - * - * @return ?PackageUpdateServer - * @since 5.3 + * @since 5.3 */ - protected function findDuplicateServer() + protected function findDuplicateServer(string $serverURL): ?PackageUpdateServer { $packageServerList = new PackageUpdateServerList(); $packageServerList->readObjects(); foreach ($packageServerList as $packageServer) { - if ($packageServer->serverURL == $this->serverURL) { + if ($packageServer->serverURL == $serverURL) { return $packageServer; } } return null; } - - /** - * @inheritDoc - */ - public function save() - { - parent::save(); - - // save server - $this->objectAction = new PackageUpdateServerAction([], 'create', [ - 'data' => \array_merge($this->additionalFields, [ - 'serverURL' => $this->serverURL, - 'loginUsername' => $this->loginUsername, - 'loginPassword' => $this->loginPassword, - ]), - ]); - $returnValues = $this->objectAction->executeAction(); - $this->saved(); - - // reset values - $this->serverURL = $this->loginUsername = $this->loginPassword = ''; - - // show success message - WCF::getTPL()->assign([ - 'success' => true, - 'objectEditLink' => LinkHandler::getInstance()->getControllerLink( - PackageUpdateServerEditForm::class, - ['id' => $returnValues['returnValues']->packageUpdateServerID] - ), - ]); - } - - /** - * @inheritDoc - */ - public function assignVariables() - { - parent::assignVariables(); - - WCF::getTPL()->assign([ - 'serverURL' => $this->serverURL, - 'loginUsername' => $this->loginUsername, - 'loginPassword' => $this->loginPassword, - 'action' => 'add', - ]); - } } diff --git a/wcfsetup/install/files/lib/acp/form/PackageUpdateServerEditForm.class.php b/wcfsetup/install/files/lib/acp/form/PackageUpdateServerEditForm.class.php index c71175c7497..f48a6cd2fdb 100755 --- a/wcfsetup/install/files/lib/acp/form/PackageUpdateServerEditForm.class.php +++ b/wcfsetup/install/files/lib/acp/form/PackageUpdateServerEditForm.class.php @@ -2,12 +2,17 @@ namespace wcf\acp\form; +use CuyZ\Valinor\Mapper\MappingError; use Laminas\Diactoros\Response\RedirectResponse; use wcf\acp\page\PackageUpdateServerListPage; +use wcf\data\IStorableObject; use wcf\data\package\update\server\PackageUpdateServer; -use wcf\data\package\update\server\PackageUpdateServerAction; -use wcf\form\AbstractForm; +use wcf\http\Helper; use wcf\system\exception\IllegalLinkException; +use wcf\system\form\builder\data\processor\CustomFormDataProcessor; +use wcf\system\form\builder\field\PasswordFormField; +use wcf\system\form\builder\field\UrlFormField; +use wcf\system\form\builder\IFormDocument; use wcf\system\interaction\admin\PackageUpdateServerInteractions; use wcf\system\interaction\StandaloneInteractionContextMenuComponent; use wcf\system\request\LinkHandler; @@ -16,9 +21,9 @@ /** * Shows the server edit form. * - * @author Marcel Werk - * @copyright 2001-2019 WoltLab GmbH - * @license GNU Lesser General Public License + * @author Marcel Werk + * @copyright 2001-2025 WoltLab GmbH + * @license GNU Lesser General Public License */ class PackageUpdateServerEditForm extends PackageUpdateServerAddForm { @@ -27,103 +32,93 @@ class PackageUpdateServerEditForm extends PackageUpdateServerAddForm */ public $activeMenuItem = 'wcf.acp.menu.link.package.server.list'; - /** - * update server id - * @var int - */ - public $packageUpdateServerID = 0; - - /** - * active package update server - * @var PackageUpdateServer - */ - public $updateServer; - /** * @inheritDoc */ + public $formAction = 'edit'; + + #[\Override] public function readParameters() { parent::readParameters(); - if (isset($_REQUEST['id'])) { - $this->packageUpdateServerID = \intval($_REQUEST['id']); - } - $this->updateServer = new PackageUpdateServer($this->packageUpdateServerID); - if (!$this->updateServer->packageUpdateServerID) { + try { + $queryParameters = Helper::mapQueryParameters( + $_GET, + <<<'EOT' + array { + id: positive-int + } + EOT + ); + $this->formObject = new PackageUpdateServer($queryParameters['id']); + + if (!$this->formObject->getObjectID()) { + throw new IllegalLinkException(); + } + } catch (MappingError) { throw new IllegalLinkException(); } - if ($this->updateServer->isWoltLabUpdateServer() || $this->updateServer->isWoltLabStoreServer()) { + if ($this->formObject->isWoltLabUpdateServer() || $this->formObject->isWoltLabStoreServer()) { return new RedirectResponse( LinkHandler::getInstance()->getControllerLink(LicenseEditForm::class), ); } } - /** - * Does nothing. - * - * @since 5.3 - */ - public function validateServerURL() + #[\Override] + protected function createForm() { - // The server URL cannot be modified, thus we do not need to validate it. - } + parent::createForm(); - /** - * @inheritDoc - */ - public function save() - { - AbstractForm::save(); + $serverUrlField = $this->form->getFormField('serverURL'); + \assert($serverUrlField instanceof UrlFormField); + $serverUrlField->immutable(); + // The server URL cannot be modified, thus we do not need to validate it. + $serverUrlField->removeValidator('serverUrlValidator'); - $data = []; - if ($this->loginUsername != $this->updateServer->loginUsername || $this->loginPassword) { - $data['loginUsername'] = $this->loginUsername; - $data['loginPassword'] = $this->loginPassword; + if ($this->formObject->loginUsername) { + $passwordField = $this->form->getFormField('loginPassword'); + \assert($passwordField instanceof PasswordFormField); + $passwordField->placeholder('wcf.acp.updateServer.loginPassword.noChange'); } - - // save server - $this->objectAction = new PackageUpdateServerAction( - [$this->packageUpdateServerID], - 'update', - ['data' => \array_merge($this->additionalFields, $data)] - ); - $this->objectAction->executeAction(); - $this->saved(); - - // show success message - WCF::getTPL()->assign('success', true); } - /** - * @inheritDoc - */ - public function readData() + #[\Override] + public function finalizeForm() { - parent::readData(); - - $this->serverURL = $this->updateServer->serverURL; - if (empty($_POST)) { - $this->loginUsername = $this->updateServer->loginUsername; - } + parent::finalizeForm(); + + $this->form->getDataHandler()->addProcessor( + new CustomFormDataProcessor( + 'editServerProcessor', + function (IFormDocument $document, array $parameters) { + if ($parameters['data']['loginUsername'] === $this->formObject->loginUsername && !$parameters['data']['loginPassword']) { + unset($parameters['data']['loginUsername']); + unset($parameters['data']['loginPassword']); + } + + return $parameters; + }, + function (IFormDocument $document, array $data, IStorableObject $object) { + unset($data['loginPassword']); + + return $data; + } + ) + ); } - /** - * @inheritDoc - */ + #[\Override] public function assignVariables() { parent::assignVariables(); WCF::getTPL()->assign([ - 'packageUpdateServerID' => $this->packageUpdateServerID, - 'packageUpdateServer' => $this->updateServer, - 'action' => 'edit', 'interactionContextMenu' => StandaloneInteractionContextMenuComponent::forContentHeaderButton( new PackageUpdateServerInteractions(), - $this->updateServer, + $this->formObject, LinkHandler::getInstance()->getControllerLink(PackageUpdateServerListPage::class) ), ]); diff --git a/wcfsetup/install/lang/de.xml b/wcfsetup/install/lang/de.xml index 2ed721af8ae..1360431a48e 100644 --- a/wcfsetup/install/lang/de.xml +++ b/wcfsetup/install/lang/de.xml @@ -2846,7 +2846,6 @@ Abschnitte dürfen nicht leer sein und nur folgende Zeichen enthalten: [a-z - @@ -2862,9 +2861,10 @@ Abschnitte dürfen nicht leer sein und nur folgende Zeichen enthalten: [a-z - packageUpdateServerID}{/link}">den bestehenden Paketserver bearbeiten.]]> + packageUpdateServerID}{/link}">den bestehenden Paketserver bearbeiten.]]> + username}“]]> diff --git a/wcfsetup/install/lang/en.xml b/wcfsetup/install/lang/en.xml index 351c710e86a..14bc2b3eece 100644 --- a/wcfsetup/install/lang/en.xml +++ b/wcfsetup/install/lang/en.xml @@ -2773,7 +2773,6 @@ If you have already bought the licenses for the listed apps, th - @@ -2789,9 +2788,10 @@ If you have already bought the licenses for the listed apps, th - packageUpdateServerID}{/link}">edit this server instead.]]> + packageUpdateServerID}{/link}">edit this server instead.]]> + username}”]]>