Use form builder for user ranks
authorCyperghost <olaf_schmitz_1@t-online.de>
Mon, 18 Nov 2024 10:54:03 +0000 (11:54 +0100)
committerCyperghost <olaf_schmitz_1@t-online.de>
Mon, 18 Nov 2024 10:54:03 +0000 (11:54 +0100)
wcfsetup/install/files/acp/templates/userRankAdd.tpl
wcfsetup/install/files/lib/acp/form/UserRankAddForm.class.php
wcfsetup/install/files/lib/acp/form/UserRankEditForm.class.php
wcfsetup/install/files/lib/data/user/rank/UserRank.class.php
wcfsetup/install/files/lib/data/user/rank/UserRankAction.class.php

index 78c53ec55db943355f3fe1127a48bbb70c90537a..b9797523570615c87277051b4a2ed92eba332581 100644 (file)
@@ -1,29 +1,5 @@
 {include file='header' pageTitle='wcf.acp.user.rank.'|concat:$action}
 
-<script data-relocate="true">
-       (function() {
-               var previews = [];
-               elBySelAll('#labelList .jsRankPreview', undefined, function(preview) {
-                       previews.push(preview);
-               });
-               
-               var input = elById('rankTitle');
-               function updatePreview() {
-                       var value = input.value.trim() || '{jslang}wcf.acp.user.rank.title{/jslang}';
-                       previews.forEach(function(preview) {
-                               preview.textContent = value;
-                       });
-               }
-               input.addEventListener('input', updatePreview, { passive: true });
-               
-               updatePreview();
-               
-               elById('customCssClassName').addEventListener('focus', function () {
-                       elBySel('.jsCustomCssClassName').checked = true;
-               });
-       })();
-</script>
-
 <header class="contentHeader">
        <div class="contentHeaderTitle">
                <h1 class="contentTitle">{lang}wcf.acp.user.rank.{$action}{/lang}</h1>
        </nav>
 </header>
 
-{include file='shared_formNotice'}
-
-<form method="post" action="{if $action == 'add'}{link controller='UserRankAdd'}{/link}{else}{link controller='UserRankEdit' id=$rankID}{/link}{/if}">
-       <div class="section">
-               <dl{if $errorField == 'rankTitle'} class="formError"{/if}>
-                       <dt><label for="rankTitle">{lang}wcf.acp.user.rank.title{/lang}</label></dt>
-                       <dd>
-                               <input type="text" id="rankTitle" name="rankTitle" value="{$i18nPlainValues['rankTitle']}" required autofocus class="long">
-                               {if $errorField == 'rankTitle'}
-                                       <small class="innerError">
-                                               {if $errorType == 'empty'}
-                                                       {lang}wcf.global.form.error.empty{/lang}
-                                               {elseif $errorType == 'multilingual'}
-                                                       {lang}wcf.global.form.error.multilingual{/lang}
-                                               {else}
-                                                       {lang}wcf.acp.user.rank.title.error.{@$errorType}{/lang}
-                                               {/if}
-                                       </small>
-                               {/if}
-                       </dd>
-               </dl>
-               {include file='shared_multipleLanguageInputJavascript' elementIdentifier='rankTitle' forceSelection=false}
-               
-               <dl{if $errorField == 'cssClassName'} class="formError"{/if}>
-                       <dt><label for="cssClassName">{lang}wcf.acp.user.rank.cssClassName{/lang}</label></dt>
-                       <dd>
-                               <ul id="labelList">
-                                       {foreach from=$availableCssClassNames item=className}
-                                               {if $className == 'custom'}
-                                                       <li class="labelCustomClass"><input type="radio" name="cssClassName" class="jsCustomCssClassName" value="custom"{if $cssClassName == 'custom'} checked{/if}> <span><input type="text" id="customCssClassName" name="customCssClassName" value="{$customCssClassName}" class="long"></span></li>
-                                               {else}
-                                                       <li><label><input type="radio" name="cssClassName" value="{$className}"{if $cssClassName == $className} checked{/if}> <span class="badge label{if $className != 'none'} {$className}{/if} jsRankPreview">{lang}wcf.acp.user.rank.title{/lang}</span></label></li>
-                                               {/if}
-                                       {/foreach}
-                               </ul>
-                               
-                               {if $errorField == 'cssClassName'}
-                                       <small class="innerError">
-                                               {if $errorType == 'empty'}
-                                                       {lang}wcf.global.form.error.empty{/lang}
-                                               {else}
-                                                       {lang}wcf.acp.user.rank.cssClassName.error.{@$errorType}{/lang}
-                                               {/if}
-                                       </small>
-                               {/if}
-                               <small>{lang}wcf.acp.user.rank.cssClassName.description{/lang}</small>
-                       </dd>
-               </dl>
-               
-               {event name='dataFields'}
-       </div>
-       
-       <section class="section">
-               <h2 class="sectionTitle">{lang}wcf.acp.user.rank.image{/lang}</h2>
-               
-               <dl{if $errorField == 'rankImage'} class="formError"{/if}>
-                       <dt><label for="rankImage">{lang}wcf.acp.user.rank.image{/lang}</label></dt>
-                       <dd>
-                               {@$__wcf->getUploadHandler()->renderField('rankImage')}
-                               {if $errorField == 'rankImage'}
-                                       <small class="innerError">
-                                               {if $errorType == 'empty'}
-                                                       {lang}wcf.global.form.error.empty{/lang}
-                                               {else}
-                                                       {lang}wcf.acp.user.rank.image.error.{$errorType}{/lang}
-                                               {/if}
-                                       </small>
-                               {/if}
-                       </dd>
-               </dl>
-               
-               <dl{if $errorField == 'repeatImage'} class="formError"{/if}>
-                       <dt><label for="repeatImage">{lang}wcf.acp.user.rank.repeatImage{/lang}</label></dt>
-                       <dd>
-                               <input type="number" id="repeatImage" name="repeatImage" value="{$repeatImage}" min="1" class="tiny">
-                               {if $errorField == 'rankImage'}
-                                       <small class="innerError">
-                                               {lang}wcf.acp.user.rank.repeatImage.error.{@$errorType}{/lang}
-                                       </small>
-                               {/if}
-                               <small>{lang}wcf.acp.user.rank.repeatImage.description{/lang}</small>
-                       </dd>
-               </dl>
-               
-               <dl{if $errorField == 'hideTitle'} class="formError"{/if}>
-                       <dt></dt>
-                       <dd>
-                               <label><input type="checkbox" id="hideTitle" name="hideTitle" value="1"{if $hideTitle} checked{/if}> {lang}wcf.acp.user.rank.hideTitle{/lang}</label>
-                               {if $errorField == 'hideTitle'}
-                                       <small class="innerError">
-                                               {lang}wcf.acp.user.rank.hideTitle.error.{@$errorType}{/lang}
-                                       </small>
-                               {/if}
-                               <small>{lang}wcf.acp.user.rank.hideTitle.description{/lang}</small>
-                       </dd>
-               </dl>
-               
-               {event name='imageFields'}
-       </section>
-       
-       <section class="section">
-               <h2 class="sectionTitle">{lang}wcf.acp.user.rank.requirement{/lang}</h2>
-               
-               <dl{if $errorField == 'groupID'} class="formError"{/if}>
-                       <dt><label for="groupID">{lang}wcf.user.group{/lang}</label></dt>
-                       <dd>
-                               <select id="groupID" name="groupID">
-                                       {foreach from=$availableGroups item=group}
-                                               <option value="{$group->groupID}"{if $group->groupID == $groupID} selected{/if}>{$group->getTitle()}</option>
-                                       {/foreach}
-                               </select>
-                               {if $errorField == 'groupID'}
-                                       <small class="innerError">
-                                               {if $errorType == 'empty'}
-                                                       {lang}wcf.global.form.error.empty{/lang}
-                                               {else}
-                                                       {lang}wcf.acp.user.rank.userGroup.error.{@$errorType}{/lang}
-                                               {/if}
-                                       </small>
-                               {/if}
-                               <small>{lang}wcf.acp.user.rank.userGroup.description{/lang}</small>
-                       </dd>
-               </dl>
-               
-               <dl{if $errorField == 'requiredGender'} class="formError"{/if}>
-                       <dt><label for="requiredGender">{lang}wcf.user.option.gender{/lang}</label></dt>
-                       <dd>
-                               <select id="requiredGender" name="requiredGender">
-                                       <option value="0">{lang}wcf.global.noSelection{/lang}</option>
-                                       <option value="1"{if $requiredGender == 1} selected{/if}>{lang}wcf.user.gender.male{/lang}</option>
-                                       <option value="2"{if $requiredGender == 2} selected{/if}>{lang}wcf.user.gender.female{/lang}</option>
-                                       <option value="3"{if $requiredGender == 3} selected{/if}>{lang}wcf.user.gender.other{/lang}</option>
-                               </select>
-                               {if $errorField == 'requiredGender'}
-                                       <small class="innerError">
-                                               {lang}wcf.acp.user.rank.requiredGender.error.{@$errorType}{/lang}
-                                       </small>
-                               {/if}
-                               <small>{lang}wcf.acp.user.rank.requiredGender.description{/lang}</small>
-                       </dd>
-               </dl>
-               
-               <dl{if $errorField == 'requiredPoints'} class="formError"{/if}>
-                       <dt><label for="requiredPoints">{lang}wcf.acp.user.rank.requiredPoints{/lang}</label></dt>
-                       <dd>
-                               <input type="number" id="requiredPoints" name="requiredPoints" value="{$requiredPoints}" min="0" class="tiny">
-                               {if $errorField == 'requiredPoints'}
-                                       <small class="innerError">
-                                               {lang}wcf.acp.user.rank.requiredPoints.error.{@$errorType}{/lang}
-                                       </small>
-                               {/if}
-                               <small>{lang}wcf.acp.user.rank.requiredPoints.description{/lang}</small>
-                       </dd>
-               </dl>
-               
-               {event name='requirementFields'}
-       </section>
-       
-       {event name='sections'}
-       
-       <div class="formSubmit">
-               <input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s">
-               {csrfToken}
-       </div>
-</form>
+{unsafe:$form->getHtml()}
 
 {include file='footer'}
index 64a005b6688ed52bf80726c78cab377b4e72ea5e..67ccccef101d1e30571c15ee8166e8d34815906b 100644 (file)
@@ -2,29 +2,33 @@
 
 namespace wcf\acp\form;
 
+use wcf\data\IStorableObject;
 use wcf\data\user\group\UserGroup;
+use wcf\data\user\rank\UserRank;
 use wcf\data\user\rank\UserRankAction;
-use wcf\data\user\rank\UserRankEditor;
-use wcf\data\user\UserProfile;
-use wcf\form\AbstractForm;
-use wcf\system\exception\UserInputException;
-use wcf\system\file\upload\UploadField;
-use wcf\system\file\upload\UploadFile;
-use wcf\system\file\upload\UploadHandler;
-use wcf\system\language\I18nHandler;
-use wcf\system\Regex;
-use wcf\system\request\LinkHandler;
+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\BadgeColorFormField;
+use wcf\system\form\builder\field\BooleanFormField;
+use wcf\system\form\builder\field\IntegerFormField;
+use wcf\system\form\builder\field\SelectFormField;
+use wcf\system\form\builder\field\SingleSelectionFormField;
+use wcf\system\form\builder\field\TextFormField;
+use wcf\system\form\builder\field\UploadFormField;
+use wcf\system\form\builder\IFormDocument;
 use wcf\system\WCF;
-use wcf\util\StringUtil;
 
 /**
  * Shows the user rank add form.
  *
- * @author  Marcel Werk
- * @copyright   2001-2019 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @author      Olaf Braun, Marcel Werk
+ * @copyright   2001-2024 WoltLab GmbH
+ * @license     GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ *
+ * @property UserRank $formObject
  */
-class UserRankAddForm extends AbstractForm
+class UserRankAddForm extends AbstractFormBuilderForm
 {
     /**
      * @inheritDoc
@@ -41,271 +45,103 @@ class UserRankAddForm extends AbstractForm
      */
     public $neededModules = ['MODULE_USER_RANK'];
 
-    /**
-     * rank group id
-     * @var int
-     */
-    public $groupID = 0;
-
-    /**
-     * rank title
-     * @var string
-     */
-    public $rankTitle = '';
-
-    /**
-     * CSS class name
-     * @var string
-     */
-    public $cssClassName = '';
-
-    /**
-     * custom CSS class name
-     * @var string
-     */
-    public $customCssClassName = '';
-
-    /**
-     * required activity points to acquire the rank
-     * @var int
-     */
-    public $requiredPoints = 0;
-
-    /**
-     * @deprecated since 5.4
-     */
-    public $rankImage = '';
-
-    /**
-     * number of image repeats
-     * @var int
-     */
-    public $repeatImage = 1;
-
-    /**
-     * required gender setting (1=male; 2=female)
-     * @var int
-     */
-    public $requiredGender = 0;
-
-    /**
-     * hide generic user title
-     * @var int
-     */
-    public $hideTitle = 0;
-
-    /**
-     * list of pre-defined css class names
-     * @var string[]
-     */
-    public $availableCssClassNames = [
-        'yellow',
-        'orange',
-        'brown',
-        'red',
-        'pink',
-        'purple',
-        'blue',
-        'green',
-        'black',
-
-        'none', /* not a real value */
-        'custom', /* not a real value */
-    ];
-
-    /**
-     * @var UploadFile[]
-     */
-    public $removedRankImages;
-
-    /**
-     * @var UploadFile|bool
-     */
-    public $rankImageFile;
-
     /**
      * @inheritDoc
      */
-    public function readParameters()
-    {
-        parent::readParameters();
-
-        I18nHandler::getInstance()->register('rankTitle');
-
-        $this->rebuildUploadField();
-    }
-
-    protected function rebuildUploadField(): void
-    {
-        if (UploadHandler::getInstance()->isRegisteredFieldId('rankImage')) {
-            UploadHandler::getInstance()->unregisterUploadField('rankImage');
-        }
-        $field = new UploadField('rankImage');
-        $field->setImageOnly(true);
-        $field->setAllowSvgImage(true);
-        $field->maxFiles = 1;
-        UploadHandler::getInstance()->registerUploadField($field);
-    }
+    public $objectActionClass = UserRankAction::class;
 
     /**
      * @inheritDoc
      */
-    public function readFormParameters()
-    {
-        parent::readFormParameters();
-
-        I18nHandler::getInstance()->readValues();
-
-        if (I18nHandler::getInstance()->isPlainValue('rankTitle')) {
-            $this->rankTitle = I18nHandler::getInstance()->getValue('rankTitle');
-        }
-        if (isset($_POST['cssClassName'])) {
-            $this->cssClassName = StringUtil::trim($_POST['cssClassName']);
-        }
-        if (isset($_POST['customCssClassName'])) {
-            $this->customCssClassName = StringUtil::trim($_POST['customCssClassName']);
-        }
-        if (isset($_POST['groupID'])) {
-            $this->groupID = \intval($_POST['groupID']);
-        }
-        if (isset($_POST['requiredPoints'])) {
-            $this->requiredPoints = \intval($_POST['requiredPoints']);
-        }
-        if (isset($_POST['repeatImage'])) {
-            $this->repeatImage = \intval($_POST['repeatImage']);
-        }
-        if (isset($_POST['requiredGender'])) {
-            $this->requiredGender = \intval($_POST['requiredGender']);
-        }
-        if (isset($_POST['hideTitle'])) {
-            $this->hideTitle = \intval($_POST['hideTitle']);
-        }
-
-        $this->removedRankImages = UploadHandler::getInstance()->getRemovedFilesByFieldId('rankImage');
-        $rankImageFiles = UploadHandler::getInstance()->getFilesByFieldId('rankImage');
-        $this->rankImageFile = \reset($rankImageFiles);
-    }
-
-    /**
-     * @inheritDoc
-     */
-    public function validate()
-    {
-        parent::validate();
-
-        // validate label
-        if (!I18nHandler::getInstance()->validateValue('rankTitle')) {
-            if (I18nHandler::getInstance()->isPlainValue('rankTitle')) {
-                throw new UserInputException('rankTitle');
-            } else {
-                throw new UserInputException('rankTitle', 'multilingual');
-            }
-        }
-
-        // validate group
-        if (!$this->groupID) {
-            throw new UserInputException('groupID');
-        }
-        $userGroup = UserGroup::getGroupByID($this->groupID);
-        if ($userGroup === null || $userGroup->groupType == UserGroup::GUESTS || $userGroup->groupType == UserGroup::EVERYONE) {
-            throw new UserInputException('groupID', 'invalid');
-        }
-
-        // css class name
-        if (empty($this->cssClassName)) {
-            throw new UserInputException('cssClassName', 'empty');
-        } elseif (!\in_array($this->cssClassName, $this->availableCssClassNames)) {
-            throw new UserInputException('cssClassName', 'invalid');
-        } elseif ($this->cssClassName == 'custom') {
-            if (!empty($this->customCssClassName) && !Regex::compile('^-?[_a-zA-Z]+[_a-zA-Z0-9-]+$')->match($this->customCssClassName)) {
-                throw new UserInputException('cssClassName', 'invalid');
-            }
-        }
+    public $objectEditLinkController = UserRankEditForm::class;
 
-        // required gender
-        if ($this->requiredGender < 0 || $this->requiredGender > UserProfile::GENDER_OTHER) {
-            $this->requiredGender = 0;
-        }
-
-        if ($this->hideTitle && !$this->rankImageFile) {
-            throw new UserInputException('hideTitle', 'rankImage');
-        }
-    }
-
-    /**
-     * @inheritDoc
-     */
-    public function save()
+    #[\Override]
+    public function createForm()
     {
-        parent::save();
-
-        // save label
-        $this->objectAction = new UserRankAction([], 'create', [
-            'data' => \array_merge($this->additionalFields, [
-                'rankTitle' => $this->rankTitle,
-                'cssClassName' => $this->cssClassName == 'custom' ? $this->customCssClassName : $this->cssClassName,
-                'groupID' => $this->groupID,
-                'requiredPoints' => $this->requiredPoints,
-                'repeatImage' => $this->repeatImage,
-                'requiredGender' => $this->requiredGender,
-                'hideTitle' => ($this->hideTitle ? 1 : 0),
-            ]),
-            'rankImageFile' => $this->rankImageFile,
-        ]);
-        $returnValues = $this->objectAction->executeAction();
-        $rankID = $returnValues['returnValues']->rankID;
-
-        if (!I18nHandler::getInstance()->isPlainValue('rankTitle')) {
-            I18nHandler::getInstance()->save('rankTitle', 'wcf.user.rank.userRank' . $rankID, 'wcf.user', 1);
-
-            // update name
-            $rankEditor = new UserRankEditor($returnValues['returnValues']);
-            $rankEditor->update([
-                'rankTitle' => 'wcf.user.rank.userRank' . $rankID,
-            ]);
-        }
-        $this->saved();
-
-        // reset values
-        $this->rankTitle = $this->cssClassName = $this->customCssClassName = $this->rankImage = '';
-        $this->groupID = $this->requiredPoints = $this->requiredGender = $this->hideTitle = 0;
-        $this->repeatImage = 1;
-
-        I18nHandler::getInstance()->reset();
-        $this->rebuildUploadField();
-
-        // show success message
-        WCF::getTPL()->assign([
-            'success' => true,
-            'objectEditLink' => LinkHandler::getInstance()->getControllerLink(
-                UserRankEditForm::class,
-                ['id' => $rankID]
-            ),
+        parent::createForm();
+
+        $this->form->appendChildren([
+            FormContainer::create('section')
+                ->appendChildren([
+                    TextFormField::create('rankTitle')
+                        ->label('wcf.acp.user.rank.title')
+                        ->i18n()
+                        ->languageItemPattern('wcf.user.rank.userRank\d+')
+                        ->required(),
+                    BadgeColorFormField::create('cssClassName')
+                        ->label('wcf.acp.user.rank.cssClassName')
+                        ->description('wcf.acp.user.rank.cssClassName.description')
+                        ->textReferenceNodeId('rankTitle')
+                        ->defaultLabelText(WCF::getLanguage()->get('wcf.acp.user.rank.title'))
+                        ->required()
+                ]),
+            FormContainer::create('imageContainer')
+                ->label('wcf.acp.user.rank.image')
+                ->appendChildren([
+                    UploadFormField::create('rankImageFile')
+                        ->label('wcf.acp.user.rank.image')
+                        ->imageOnly()
+                        ->maximum(1)
+                        ->allowSvgImage(),
+                    IntegerFormField::create('repeatImage')
+                        ->label('wcf.acp.user.rank.repeatImage')
+                        ->description('wcf.acp.user.rank.repeatImage.description')
+                        ->addFieldClass('tiny')
+                        ->minimum(1)
+                        ->value(1),
+                    BooleanFormField::create('hideTitle')
+                        ->label('wcf.acp.user.rank.hideTitle')
+                        ->description('wcf.acp.user.rank.hideTitle.description')
+                        ->value(false)
+                ]),
+            FormContainer::create('requirementsContainer')
+                ->label('wcf.acp.user.rank.requirement')
+                ->appendChildren([
+                    SingleSelectionFormField::create('groupID')
+                        ->label('wcf.user.group')
+                        ->description('wcf.acp.user.rank.userGroup.description')
+                        ->options(UserGroup::getSortedGroupsByType([], [UserGroup::GUESTS, UserGroup::EVERYONE]))
+                        ->required(),
+                    SelectFormField::create('requiredGender')
+                        ->label('wcf.user.option.gender')
+                        ->description('wcf.acp.user.rank.requiredGender.description')
+                        ->options([
+                            1 => 'wcf.user.gender.male',
+                            2 => 'wcf.user.gender.female',
+                            3 => 'wcf.user.gender.other'
+                        ]),
+                    IntegerFormField::create('requiredPoints')
+                        ->label('wcf.acp.user.rank.requiredPoints')
+                        ->description('wcf.acp.user.rank.requiredPoints.description')
+                        ->addFieldClass('tiny')
+                        ->minimum(0)
+                        ->value(0),
+                ])
         ]);
     }
 
-    /**
-     * @inheritDoc
-     */
-    public function assignVariables()
+    #[\Override]
+    protected function finalizeForm()
     {
-        parent::assignVariables();
-
-        I18nHandler::getInstance()->assignVariables();
-
-        WCF::getTPL()->assign([
-            'action' => 'add',
-            'availableCssClassNames' => $this->availableCssClassNames,
-            'cssClassName' => $this->cssClassName,
-            'customCssClassName' => $this->customCssClassName,
-            'groupID' => $this->groupID,
-            'rankTitle' => $this->rankTitle,
-            'availableGroups' => UserGroup::getSortedGroupsByType([], [UserGroup::GUESTS, UserGroup::EVERYONE]),
-            'requiredPoints' => $this->requiredPoints,
-            'rankImage' => $this->rankImage,
-            'repeatImage' => $this->repeatImage,
-            'requiredGender' => $this->requiredGender,
-            'hideTitle' => $this->hideTitle,
-        ]);
+        parent::finalizeForm();
+
+        $this->form->getDataHandler()
+            ->addProcessor(
+                new CustomFormDataProcessor(
+                    'requiredGenderProcessor',
+                    function (IFormDocument $document, array $parameters) {
+                        $parameters['data']['requiredGender'] = $parameters['data']['requiredGender'] ?: 0;
+
+                        return $parameters;
+                    },
+                    function (IFormDocument $document, array $data, IStorableObject $object) {
+                        \assert($object instanceof UserRank);
+
+                        $data['requiredGender'] = $data['requiredGender'] ?: null;
+
+                        return $data;
+                    }
+                )
+            );
     }
 }
index 5c5df25bfff090aca700d9b5b991b4b60330b8b3..b09526a01256695f969212608a4981183b343996 100644 (file)
@@ -2,13 +2,10 @@
 
 namespace wcf\acp\form;
 
+use CuyZ\Valinor\Mapper\MappingError;
 use wcf\data\user\rank\UserRank;
-use wcf\data\user\rank\UserRankAction;
-use wcf\form\AbstractForm;
+use wcf\http\Helper;
 use wcf\system\exception\IllegalLinkException;
-use wcf\system\file\upload\UploadHandler;
-use wcf\system\language\I18nHandler;
-use wcf\system\WCF;
 
 /**
  * Shows the user rank edit form.
@@ -25,16 +22,9 @@ class UserRankEditForm extends UserRankAddForm
     public $activeMenuItem = 'wcf.acp.menu.link.user.rank.list';
 
     /**
-     * rank id
-     * @var int
-     */
-    public $rankID = 0;
-
-    /**
-     * rank object
-     * @var UserRank
+     * @inheritDoc
      */
-    public $rank;
+    public $formAction = 'edit';
 
     /**
      * @inheritDoc
@@ -43,99 +33,22 @@ class UserRankEditForm extends UserRankAddForm
     {
         parent::readParameters();
 
-        if (isset($_REQUEST['id'])) {
-            $this->rankID = \intval($_REQUEST['id']);
-        }
-        $this->rank = new UserRank($this->rankID);
-        if (!$this->rank->rankID) {
-            throw new IllegalLinkException();
-        }
-    }
-
-    /**
-     * @inheritDoc
-     */
-    public function save()
-    {
-        AbstractForm::save();
-
-        $this->rankTitle = 'wcf.user.rank.userRank' . $this->rank->rankID;
-        if (I18nHandler::getInstance()->isPlainValue('rankTitle')) {
-            I18nHandler::getInstance()->remove($this->rankTitle);
-            $this->rankTitle = I18nHandler::getInstance()->getValue('rankTitle');
-        } else {
-            I18nHandler::getInstance()->save('rankTitle', $this->rankTitle, 'wcf.user', 1);
-        }
-
-        // update label
-        $this->objectAction = new UserRankAction([$this->rank], 'update', [
-            'data' => \array_merge($this->additionalFields, [
-                'rankTitle' => $this->rankTitle,
-                'cssClassName' => $this->cssClassName == 'custom' ? $this->customCssClassName : $this->cssClassName,
-                'groupID' => $this->groupID,
-                'requiredPoints' => $this->requiredPoints,
-                'repeatImage' => $this->repeatImage,
-                'requiredGender' => $this->requiredGender,
-                'hideTitle' => $this->hideTitle,
-            ]),
-            'rankImageFile' => $this->rankImageFile,
-            'rankImageFile__removedFiles' => $this->removedRankImages,
-        ]);
-        $this->objectAction->executeAction();
-        $this->saved();
-
-        // reset values if non-custom value was chosen
-        if ($this->cssClassName != 'custom') {
-            $this->customCssClassName = '';
-        }
-
-        // show success message
-        WCF::getTPL()->assign('success', true);
-    }
-
-    /**
-     * @inheritDoc
-     */
-    public function readData()
-    {
-        parent::readData();
-
-        if (empty($_POST)) {
-            I18nHandler::getInstance()->setOptions('rankTitle', 1, $this->rank->rankTitle, 'wcf.user.rank.userRank\d+');
-            $this->rankTitle = $this->rank->rankTitle;
-            $this->cssClassName = $this->rank->cssClassName;
-            if (!\in_array($this->cssClassName, $this->availableCssClassNames)) {
-                $this->customCssClassName = $this->cssClassName;
-                $this->cssClassName = 'custom';
-            }
-            $this->groupID = $this->rank->groupID;
-            $this->requiredPoints = $this->rank->requiredPoints;
-            $this->requiredGender = $this->rank->requiredGender;
-            $this->repeatImage = $this->rank->repeatImage;
-            $this->rankImage = $this->rank->rankImage;
-            $this->hideTitle = $this->rank->hideTitle;
-
-            if ($this->rank->getImageFile()) {
-                UploadHandler::getInstance()->registerFilesByField('rankImage', [
-                    $this->rank->getImageFile(),
-                ]);
+        try {
+            $queryParameters = Helper::mapQueryParameters(
+                $_GET,
+                <<<'EOT'
+                    array {
+                        id: positive-int
+                    }
+                    EOT
+            );
+            $this->formObject = new UserRank($queryParameters['id']);
+
+            if (!$this->formObject->getObjectID()) {
+                throw new IllegalLinkException();
             }
+        } catch (MappingError) {
+            throw new IllegalLinkException();
         }
     }
-
-    /**
-     * @inheritDoc
-     */
-    public function assignVariables()
-    {
-        parent::assignVariables();
-
-        I18nHandler::getInstance()->assignVariables(!empty($_POST));
-
-        WCF::getTPL()->assign([
-            'rankID' => $this->rankID,
-            'rank' => $this->rank,
-            'action' => 'edit',
-        ]);
-    }
 }
index e36cb2ed34b53c0746df4730c25856a1b90ad9d3..fd8186b577c20456d267bbf64fdba81b8d20b4b1 100644 (file)
@@ -4,7 +4,7 @@ namespace wcf\data\user\rank;
 
 use wcf\data\DatabaseObject;
 use wcf\data\ITitledObject;
-use wcf\system\file\upload\UploadFile;
+use wcf\system\form\builder\field\UploadFormField;
 use wcf\system\WCF;
 use wcf\util\StringUtil;
 
@@ -68,25 +68,14 @@ class UserRank extends DatabaseObject implements ITitledObject
     }
 
     /**
-     * Returns the currently uploaded rank image or null, if the rank has no image.
-     *
-     * @since       5.4
+     * @see UploadFormField::updatedObject()
      */
-    public function getImageFile(): ?UploadFile
+    public function getRankImageFileUploadFileLocations(): array
     {
-        if ($this->rankImage) {
-            $location = WCF_DIR . self::RANK_IMAGE_DIR . $this->rankImage;
-            if (\file_exists($location)) {
-                return new UploadFile(
-                    $location,
-                    $this->rankImage,
-                    true,
-                    true,
-                    true
-                );
-            }
+        if (!$this->rankImage) {
+            return [];
         }
 
-        return null;
+        return [WCF_DIR . self::RANK_IMAGE_DIR . $this->rankImage];
     }
 }
index c0e51151ec10220cc12f79eef93dba458613d69b..b3a353d5442590568de7ace9e376964475f8abcc 100644 (file)
@@ -36,23 +36,25 @@ class UserRankAction extends AbstractDatabaseObjectAction
         /** @var UserRank $rank */
         $rank = parent::create();
 
-        if (isset($this->parameters['rankImageFile']) && $this->parameters['rankImageFile']) {
-            if (!($this->parameters['rankImageFile'] instanceof UploadFile)) {
+        if (isset($this->parameters['rankImageFile']) && !empty($this->parameters['rankImageFile'])) {
+            $rankImageFile = \reset($this->parameters['rankImageFile']);
+
+            if (!($rankImageFile instanceof UploadFile)) {
                 throw new InvalidObjectArgument(
-                    $this->parameters['rankImageFile'],
+                    $rankImageFile,
                     UploadFile::class,
                     "The parameter 'rankImageFile'"
                 );
             }
 
-            if (!$this->parameters['rankImageFile']->isProcessed()) {
-                $fileName = $rank->rankID . '-' . $this->parameters['rankImageFile']->getFilename();
+            if (!$rankImageFile->isProcessed()) {
+                $fileName = $rank->rankID . '-' . $rankImageFile->getFilename();
 
                 \rename(
-                    $this->parameters['rankImageFile']->getLocation(),
+                    $rankImageFile->getLocation(),
                     WCF_DIR . UserRank::RANK_IMAGE_DIR . $fileName
                 );
-                $this->parameters['rankImageFile']->setProcessed(WCF_DIR . UserRank::RANK_IMAGE_DIR . $fileName);
+                $rankImageFile->setProcessed(WCF_DIR . UserRank::RANK_IMAGE_DIR . $fileName);
 
                 $updateData['rankImage'] = $fileName;
 
@@ -89,26 +91,27 @@ class UserRankAction extends AbstractDatabaseObjectAction
             }
 
             $object = \reset($this->objects);
+            $rankImageFile = \reset($this->parameters['rankImageFile']);
 
-            if (!$this->parameters['rankImageFile']) {
+            if (!$rankImageFile) {
                 $this->parameters['data']['rankImage'] = "";
             } else {
-                if (!($this->parameters['rankImageFile'] instanceof UploadFile)) {
+                if (!($rankImageFile instanceof UploadFile)) {
                     throw new InvalidObjectArgument(
-                        $this->parameters['rankImageFile'],
+                        $rankImageFile,
                         UploadFile::class,
                         "The parameter 'rankImageFile'"
                     );
                 }
 
-                if (!$this->parameters['rankImageFile']->isProcessed()) {
-                    $fileName = $object->rankID . '-' . $this->parameters['rankImageFile']->getFilename();
+                if (!$rankImageFile->isProcessed()) {
+                    $fileName = $object->rankID . '-' . $rankImageFile->getFilename();
 
                     \rename(
-                        $this->parameters['rankImageFile']->getLocation(),
+                        $rankImageFile->getLocation(),
                         WCF_DIR . UserRank::RANK_IMAGE_DIR . $fileName
                     );
-                    $this->parameters['rankImageFile']->setProcessed(WCF_DIR . UserRank::RANK_IMAGE_DIR . $fileName);
+                    $rankImageFile->setProcessed(WCF_DIR . UserRank::RANK_IMAGE_DIR . $fileName);
 
                     $this->parameters['data']['rankImage'] = $fileName;
                 }