Add labeledUrl user option type
authorjoshuaruesweg <ruesweg@woltlab.com>
Sun, 8 Nov 2020 11:09:43 +0000 (12:09 +0100)
committerjoshuaruesweg <ruesweg@woltlab.com>
Sat, 14 Nov 2020 10:28:36 +0000 (11:28 +0100)
Closes #3651

wcfsetup/install/files/acp/templates/userOptionAdd.tpl
wcfsetup/install/files/lib/acp/form/UserOptionAddForm.class.php
wcfsetup/install/files/lib/acp/form/UserOptionEditForm.class.php
wcfsetup/install/files/lib/data/user/option/UserOption.class.php
wcfsetup/install/files/lib/system/option/LabeledUrlOptionType.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/option/user/LabeledUrlUserOptionOutput.class.php [new file with mode: 0644]
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml
wcfsetup/setup/db/install.sql

index 01c50aed849e5139e35f0eaff87d7dd0ae9b34b3..37eeb263ec707eea833ac5ec1884d6c96ec2f151 100644 (file)
                                </dd>
                        </dl>
                        
+                       <dl{if $errorField == 'labeledUrl'} class="formError"{/if}>
+                               <dt><label for="labeledUrl">{lang}wcf.acp.user.option.labeledUrl{/lang}</label></dt>
+                               <dd>
+                                       <input type="text" id="labeledUrl" name="labeledUrl" value="{$labeledUrl}" class="long">
+                                       {if $errorField == 'labeledUrl'}
+                                               <small class="innerError">
+                                                       {if $errorType == 'empty'}
+                                                               {lang}wcf.global.form.error.empty{/lang}
+                                                       {else}
+                                                               {lang}wcf.acp.user.option.labeledUrl.error.{@$errorType}{/lang}
+                                                       {/if}
+                                               </small>
+                                       {/if}
+                                       <small>{lang}wcf.acp.user.option.labeledUrl.description{/lang}</small>
+                               </dd>
+                       </dl>
+                       
                        <dl{if $errorField == 'outputClass'} class="formError"{/if}>
                                <dt><label for="outputClass">{lang}wcf.acp.user.option.outputClass{/lang}</label></dt>
                                <dd>
index 231b16ccced1130877a496bd850200bdafe2b520..b01e20792ddc66877398b7b646b51e234330837d 100644 (file)
@@ -9,6 +9,7 @@ use wcf\form\AbstractForm;
 use wcf\system\exception\UserInputException;
 use wcf\system\language\I18nHandler;
 use wcf\system\option\user\DateUserOptionOutput;
+use wcf\system\option\user\LabeledUrlUserOptionOutput;
 use wcf\system\option\user\SelectOptionsUserOptionOutput;
 use wcf\system\option\user\URLUserOptionOutput;
 use wcf\system\request\LinkHandler;
@@ -76,6 +77,12 @@ class UserOptionAddForm extends AbstractForm {
         */
        public $selectOptions = '';
        
+       /**
+        * @var string
+        * @since 5.4
+        */
+       public $labeledUrl = '';
+       
        /**
         * field is required
         * @var boolean
@@ -154,7 +161,8 @@ class UserOptionAddForm extends AbstractForm {
                'text',
                'textarea',
                'message',
-               'URL'
+               'URL',
+               'labeledUrl',
        ];
        
        /**
@@ -206,6 +214,7 @@ class UserOptionAddForm extends AbstractForm {
                if (isset($_POST['searchable'])) $this->searchable = intval($_POST['searchable']);
                if (isset($_POST['showOrder'])) $this->showOrder = intval($_POST['showOrder']);
                if (isset($_POST['outputClass'])) $this->outputClass = StringUtil::trim($_POST['outputClass']);
+               if (isset($_POST['labeledUrl'])) $this->labeledUrl = StringUtil::trim($_POST['labeledUrl']);
                
                if ($this->optionType == 'boolean' || $this->optionType == 'integer') {
                        $this->defaultValue = intval($this->defaultValue);
@@ -238,6 +247,10 @@ class UserOptionAddForm extends AbstractForm {
                        if ($this->optionType == 'URL') {
                                $this->outputClass = URLUserOptionOutput::class;
                        }
+                       
+                       if ($this->optionType == 'labeledUrl') {
+                               $this->outputClass = LabeledUrlUserOptionOutput::class;
+                       }
                }
        }
        
@@ -282,6 +295,10 @@ class UserOptionAddForm extends AbstractForm {
                if (!in_array($this->editable, $this->validEditableBits)) {
                        $this->editable = UserOption::EDITABILITY_ALL;
                }
+               
+               if ($this->optionType == 'labeledUrl' && strpos($this->labeledUrl, '%s') === false) {
+                       throw new UserInputException('labeledUrl', 'invalid');
+               }
        }
        
        /**
@@ -309,7 +326,8 @@ class UserOptionAddForm extends AbstractForm {
                        'editable' => $this->editable,
                        'visible' => $this->visible,
                        'packageID' => 1,
-                       'additionalData' => !empty($additionalData) ? serialize($additionalData) : ''
+                       'additionalData' => !empty($additionalData) ? serialize($additionalData) : '',
+                       'labeledUrl' => $this->labeledUrl,
                ])]);
                $this->objectAction->executeAction();
                
@@ -366,7 +384,8 @@ class UserOptionAddForm extends AbstractForm {
                        'outputClass' => $this->outputClass,
                        'action' => 'add',
                        'availableCategories' => $this->availableCategories,
-                       'availableOptionTypes' => self::$availableOptionTypes
+                       'availableOptionTypes' => self::$availableOptionTypes,
+                       'labeledUrl' => $this->labeledUrl,
                ]);
        }
 }
index 1c05d541b9c0d8a9cbe2ad91cf6a14c1f8476f01..340b3fa018a2c2fa4093a12ac1797cf6c090e38b 100644 (file)
@@ -89,7 +89,8 @@ class UserOptionEditForm extends UserOptionAddForm {
                        'searchable' => $this->searchable,
                        'editable' => $this->editable,
                        'visible' => $this->visible,
-                       'additionalData' => !empty($additionalData) ? serialize($additionalData) : ''
+                       'additionalData' => !empty($additionalData) ? serialize($additionalData) : '',
+                       'labeledUrl' => $this->labeledUrl,
                ])]);
                $this->objectAction->executeAction();
                $this->saved();
@@ -119,6 +120,7 @@ class UserOptionEditForm extends UserOptionAddForm {
                        $this->searchable = $this->userOption->searchable;
                        $this->showOrder = $this->userOption->showOrder;
                        $this->outputClass = $this->userOption->outputClass;
+                       $this->labeledUrl = $this->userOption->labeledUrl;
                }
        }
        
index c4731bb8d14ed012da4251c0ad9567d0190df4cd..ac5c8a1e5ffb92dad0c46fb2012240892db4117f 100644 (file)
@@ -22,6 +22,7 @@ use wcf\system\WCF;
  * @property-read      integer         $searchable             is `1` if the user option can be searched, otherwise `0`
  * @property-read      integer         $isDisabled             is `1` if the user option is disabled and thus neither shown nor editable, otherwise `0`
  * @property-read      integer         $originIsSystem         is `1` if the user option was created by the system and not manually by an administrator, otherwise `0`
+ * @property-read      string          $labeledUrl             the url, if the option type is `labeledUrl`
  */
 class UserOption extends Option implements ITitledObject {
        /**
diff --git a/wcfsetup/install/files/lib/system/option/LabeledUrlOptionType.class.php b/wcfsetup/install/files/lib/system/option/LabeledUrlOptionType.class.php
new file mode 100644 (file)
index 0000000..f461045
--- /dev/null
@@ -0,0 +1,12 @@
+<?php
+namespace wcf\system\option;
+/**
+ * Option type implementation for url input fields.
+ *
+ * @author     Joshua Ruesweg
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Option
+ * @since       5.4
+ */
+class LabeledUrlOptionType extends TextOptionType { }
diff --git a/wcfsetup/install/files/lib/system/option/user/LabeledUrlUserOptionOutput.class.php b/wcfsetup/install/files/lib/system/option/user/LabeledUrlUserOptionOutput.class.php
new file mode 100644 (file)
index 0000000..d91a104
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+namespace wcf\system\option\user;
+use wcf\data\user\option\UserOption;
+use wcf\data\user\User;
+use wcf\util\StringUtil;
+
+/**
+ * User option output implementation for the output of an url.
+ *
+ * @author     Joshua Ruesweg
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Option\User
+ * @since       5.4
+ */
+class LabeledUrlUserOptionOutput implements IUserOptionOutput {
+       /**
+        * @inheritDoc
+        */
+       public function getOutput(User $user, UserOption $option, $value) {
+               return StringUtil::getAnchorTag(self::getURL($option, $value), $value, true, true);
+       }
+       
+       /**
+        * Formats the URL.
+        */
+       private static function getURL(UserOption $option, string $value): string {
+               return sprintf($option->labeledUrl, rawurlencode($value));
+       }
+}
index 97ceff7f38f540112fb023ee237484d533e5bc8f..73829ea4ecafea8060e86eb5074549c7f80d566a 100644 (file)
@@ -3084,6 +3084,9 @@ Wenn {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} unter „Konfiguration 
                <item name="wcf.acp.user.option.editable.2"><![CDATA[Administrator]]></item>
                <item name="wcf.acp.user.option.editable.3"><![CDATA[Eigentümer und Administrator]]></item>
                <item name="wcf.acp.user.option.editable.6"><![CDATA[Eigentümer bei Erstanmeldung und Administrator]]></item>
+               <item name="wcf.acp.user.option.labeledUrl"><![CDATA[URL]]></item>
+               <item name="wcf.acp.user.option.labeledUrl.description"><![CDATA[Wenn der Feldtyp „labeledUrl“ ist, muss hier die URL hinterlegt werden, auf die verlinkt werden soll. {if LANGUAGE_USE_INFORMAL_VARIANT}Nutze{else}Nutzen Sie{/if} <span class="inlineCode">%s</span> als Platzhalter für die Eingabe des Benutzers.]]></item>
+               <item name="wcf.acp.user.option.labeledUrl.error.invalid"><![CDATA[Der Platzhalter <span class="inlineCode">%s</span> fehlt in der URL.]]></item>
                <item name="wcf.acp.user.option.optionType"><![CDATA[Feldtyp]]></item>
                <item name="wcf.acp.user.option.optionType.description"><![CDATA[Die Namen entsprechen in der Regel den HTML-Elementen, die benötigt werden, um so ein Feld beim Benutzer abzufragen.]]></item>
                <item name="wcf.acp.user.option.askDuringRegistration"><![CDATA[Das Feld wird im Registrierungs-Formular angezeigt.]]></item>
index de6610797701a41894923f86dc7cf8468166c44b..ea0a7d71203a36b13acb00c1ee31d0f68a715caf 100644 (file)
@@ -3012,6 +3012,9 @@ You can define the default sender in “Configuration » Options » General » E
                <item name="wcf.acp.user.option.editable.2"><![CDATA[Administrator]]></item>
                <item name="wcf.acp.user.option.editable.3"><![CDATA[Owner and Administrator]]></item>
                <item name="wcf.acp.user.option.editable.6"><![CDATA[Owner during registration and Administrator]]></item>
+               <item name="wcf.acp.user.option.labeledUrl"><![CDATA[URL]]></item>
+               <item name="wcf.acp.user.option.labeledUrl.description"><![CDATA[If the field type is “labeledUrl”, the URL to be linked to must be entered here. Use <span class="inlineCode">%s</span> as placeholder for the user input.]]></item>
+               <item name="wcf.acp.user.option.labeledUrl.error.invalid"><![CDATA[The URL does not contain the placeholder <span class="inlineCode">%s</span>.]]></item>
                <item name="wcf.acp.user.option.optionType"><![CDATA[Option Type]]></item>
                <item name="wcf.acp.user.option.optionType.description"><![CDATA[The option names usually equal the HTML-tag used as input element.]]></item>
                <item name="wcf.acp.user.option.askDuringRegistration"><![CDATA[Field will be visible during registration]]></item>
index 939404fe159c1ba1620220363d0111e8b3fe04b4..99a0e86205b1aa81b1f3d8398ce81b277cffbb0a 100644 (file)
@@ -1762,6 +1762,7 @@ CREATE TABLE wcf1_user_option (
        validationPattern TEXT,
        selectOptions MEDIUMTEXT,
        enableOptions MEDIUMTEXT,
+       labeledUrl MEDIUMTEXT,
        required TINYINT(1) NOT NULL DEFAULT 0,
        askDuringRegistration TINYINT(1) NOT NULL DEFAULT 0,
        editable TINYINT(1) NOT NULL DEFAULT 0,