Added basic contact options
authorAlexander Ebert <ebert@woltlab.com>
Tue, 20 Jun 2017 12:09:02 +0000 (14:09 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Tue, 20 Jun 2017 12:09:02 +0000 (14:09 +0200)
See #2308

wcfsetup/install/files/acp/templates/contactSettings.tpl
wcfsetup/install/files/lib/acp/form/AbstractAcpForm.class.php
wcfsetup/install/files/lib/acp/form/AbstractCustomOptionForm.class.php
wcfsetup/install/files/lib/acp/form/ContactOptionAddForm.class.php
wcfsetup/install/files/lib/acp/form/ContactOptionEditForm.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/acp/page/ContactSettingsPage.class.php
wcfsetup/install/files/lib/data/custom/option/CustomOption.class.php
wcfsetup/install/files/lib/system/request/LinkHandler.class.php
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml
wcfsetup/setup/db/install.sql

index c6ca5f4b225ac5758566f9df2e54b57fdf490d56..49a0d444fcfb1b7e7beba38f5b1d3fd3046e43a9 100644 (file)
@@ -9,12 +9,14 @@
        });
        
        $(function() {
+               new WCF.Action.Delete('wcf\\data\\contact\\option\\ContactOptionAction', '.jsOptionRow');
+               new WCF.Action.Toggle('wcf\\data\\contact\\option\\ContactOptionAction', $('.jsOptionRow'));
+               
                new WCF.Action.Delete('wcf\\data\\contact\\recipient\\ContactRecipientAction', '.jsRecipient');
                new WCF.Action.Toggle('wcf\\data\\contact\\recipient\\ContactRecipientAction', '.jsRecipient');
        });
 </script>
 
-
 <header class="contentHeader">
        <div class="contentHeaderTitle">
                <h1 class="contentTitle">{lang}wcf.acp.contact.settings{/lang}</h1>
 
 <section class="section">
        <h2 class="sectionTitle">{lang}wcf.acp.contact.options{/lang}</h2>
+       
+       <table class="table">
+               <thead>
+                       <tr>
+                               <th class="columnID columnOptionID" colspan="2">{lang}wcf.global.objectID{/lang}</th>
+                               <th class="columnTitle columnOptionTitle">{lang}wcf.global.name{/lang}</th>
+                               <th class="columnText columnOptionType">{lang}wcf.acp.customOption.optionType{/lang}</th>
+                               <th class="columnDigits columnShowOrder">{lang}wcf.acp.customOption.showOrder{/lang}</th>
+                               
+                               {event name='columnHeads'}
+                       </tr>
+               </thead>
+               
+               <tbody>
+                       {foreach from=$optionList item=option}
+                               <tr class="jsOptionRow">
+                                       <td class="columnIcon">
+                                               <span class="icon icon16 fa-{if !$option->isDisabled}check-{/if}square-o jsToggleButton jsTooltip pointer" title="{lang}wcf.global.button.{if $option->isDisabled}enable{else}disable{/if}{/lang}" data-object-id="{@$option->optionID}"></span>
+                                               <a href="{link controller='ContactOptionEdit' id=$option->optionID}{/link}" title="{lang}wcf.global.button.edit{/lang}" class="jsTooltip"><span class="icon icon16 fa-pencil"></span></a>
+                                               {if $option->canDelete()}
+                                                       <span class="icon icon16 fa-times jsDeleteButton jsTooltip pointer" title="{lang}wcf.global.button.delete{/lang}" data-object-id="{@$option->optionID}" data-confirm-message-html="{lang __encode=true}wcf.acp.customOption.delete.confirmMessage{/lang}"></span>
+                                               {else}
+                                                       <span class="icon icon16 fa-times disabled"></span>
+                                               {/if}
+                                               
+                                               {event name='rowButtons'}
+                                       </td>
+                                       <td class="columnID">{@$option->optionID}</td>
+                                       <td class="columnTitle columnOptionTitle"><a href="{link controller='ContactOptionEdit' id=$option->optionID}{/link}">{$option->optionTitle|language}</a></td>
+                                       <td class="columnText columnOptionType">{lang}wcf.acp.customOption.optionType.{$option->optionType}{/lang}</td>
+                                       <td class="columnDigits columnShowOrder">{#$option->showOrder}</td>
+                                       
+                                       {event name='columns'}
+                               </tr>
+                       {/foreach}
+               </tbody>
+       </table>
 </section>
 
 <section class="section">
index 0d2387b3b93b537f510b54cdf4956387aca321e1..109aa1e53b113339aa773feef9a4bed99bffe6a2 100644 (file)
@@ -101,8 +101,6 @@ abstract class AbstractAcpForm extends AbstractForm {
         */
        public function readDataI18n(DatabaseObject $databaseObject) {
                if (empty($_POST) && !empty($this->i18nValues)) {
-                       I18nHandler::getInstance()->readValues();
-                       
                        foreach ($this->i18nValues as $fieldName => $value) {
                                I18nHandler::getInstance()->setOptions(
                                        $fieldName,
@@ -133,7 +131,7 @@ abstract class AbstractAcpForm extends AbstractForm {
                                        $value->getPackageID()
                                );
                                
-                               $value[$fieldName] = I18nHandler::getInstance()->getValues($fieldName)[WCF::getLanguage()->languageID];
+                               $values[$fieldName] = I18nHandler::getInstance()->getValues($fieldName)[WCF::getLanguage()->languageID];
                        }
                }
                
index aa6455739fca3d6f269b54f1713f3f5e91292a99..dcf1a0425e77b9ce14bda74467451e5b627d89da 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 namespace wcf\acp\form;
-use wcf\data\option\Option;
+use wcf\data\custom\option\CustomOption;
 use wcf\system\exception\IllegalLinkException;
 use wcf\system\exception\UserInputException;
 use wcf\system\language\I18nValue;
@@ -84,15 +84,15 @@ abstract class AbstractCustomOptionForm extends AbstractAcpForm {
        
        /**
         * object instance
-        * @var Option
+        * @var CustomOption
         */
-       public $object;
+       public $option;
        
        /**
         * object id
         * @var integer
         */
-       public $objectID;
+       public $optionID;
        
        /**
         * available option types
@@ -134,9 +134,9 @@ abstract class AbstractCustomOptionForm extends AbstractAcpForm {
                }
                
                if ($this->action === 'edit') {
-                       if (isset($_REQUEST['id'])) $this->objectID = intval($_REQUEST['id']);
-                       $this->object = new $this->baseClass($this->objectID);
-                       if (!$this->object->getObjectID()) {
+                       if (isset($_REQUEST['id'])) $this->optionID = intval($_REQUEST['id']);
+                       $this->option = new $this->baseClass($this->optionID);
+                       if (!$this->option->getObjectID()) {
                                throw new IllegalLinkException();
                        }
                }
@@ -186,6 +186,24 @@ abstract class AbstractCustomOptionForm extends AbstractAcpForm {
                }
        }
        
+       /**
+        * @inheritDoc
+        */
+       public function readData() {
+               if ($this->action === 'edit' && empty($_POST)) {
+                       $this->readDataI18n($this->option);
+                       
+                       $this->optionType = $this->option->optionType;
+                       $this->defaultValue = $this->option->defaultValue;
+                       $this->validationPattern = $this->option->validationPattern;
+                       $this->selectOptions = $this->option->selectOptions;
+                       $this->required = $this->option->required;
+                       $this->showOrder = $this->option->showOrder;
+               }
+               
+               parent::readData();
+       }
+       
        /**
         * Returns the list of database values including additional fields.
         * 
@@ -218,6 +236,11 @@ abstract class AbstractCustomOptionForm extends AbstractAcpForm {
                        $this->reset();
                }
                else {
+                       $this->beforeSaveI18n($this->option);
+                       
+                       $this->objectAction = new $this->actionClass([$this->option], 'update', ['data' => $this->getDatabaseValues()]);
+                       $this->objectAction->executeAction();
+                       
                        $this->saved();
                        
                        // show success message
@@ -243,7 +266,7 @@ abstract class AbstractCustomOptionForm extends AbstractAcpForm {
        public function assignVariables() {
                parent::assignVariables();
                
-               WCF::getTPL()->assign([
+               $variables = [
                        'defaultValue' => $this->defaultValue,
                        'validationPattern' => $this->validationPattern,
                        'optionType' => $this->optionType,
@@ -253,6 +276,13 @@ abstract class AbstractCustomOptionForm extends AbstractAcpForm {
                        'action' => $this->action,
                        'availableOptionTypes' => self::$availableOptionTypes,
                        'optionTypesUsingSelectOptions' => self::$optionTypesUsingSelectOptions
-               ]);
+               ];
+               
+               if ($this->action === 'edit') {
+                       $variables['option'] = $this->option;
+                       $variables['optionID'] = $this->optionID;
+               }
+               
+               WCF::getTPL()->assign($variables);
        }
 }
index c04a0de07a5321ed4fea3e741d47eed8c95a7999..a105291482343c3f35d372cdf3633e3f94d1d7de 100644 (file)
@@ -58,7 +58,7 @@ class ContactOptionAddForm extends AbstractCustomOptionForm {
        public function readParameters() {
                parent::readParameters();
                
-               $this->getI18nValue('optionTitle')->setLanguageItem('wcf.contact.field', 'wcf.contact', 'com.woltlab.wcf');
-               $this->getI18nValue('optionDescription')->setLanguageItem('wcf.contact.fieldDescription', 'wcf.contact', 'com.woltlab.wcf');
+               $this->getI18nValue('optionTitle')->setLanguageItem('wcf.contact.option', 'wcf.contact', 'com.woltlab.wcf');
+               $this->getI18nValue('optionDescription')->setLanguageItem('wcf.contact.optionDescription', 'wcf.contact', 'com.woltlab.wcf');
        }
 }
diff --git a/wcfsetup/install/files/lib/acp/form/ContactOptionEditForm.class.php b/wcfsetup/install/files/lib/acp/form/ContactOptionEditForm.class.php
new file mode 100644 (file)
index 0000000..9c2d3ac
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+namespace wcf\acp\form;
+
+/**
+ * Shows the contact option edit form.
+ * 
+ * @author     Alexander Ebert
+ * @copyright  2001-2017 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\Acp\Form
+ * @since       3.1
+ */
+class ContactOptionEditForm extends ContactOptionAddForm {
+       /**
+        * @inheritDoc
+        */
+       public $action = 'edit';
+}
index 4b5b2762f8fb596b34a9837974c29c4bb784d7a6..8c9a9829c4b366ea634c7cf54e79165b59b4569e 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\acp\page;
+use wcf\data\contact\option\ContactOptionList;
 use wcf\data\contact\recipient\ContactRecipientList;
 use wcf\page\AbstractPage;
 use wcf\system\WCF;
@@ -29,6 +30,11 @@ class ContactSettingsPage extends AbstractPage {
         */
        public $neededPermissions = ['admin.contact.canManageContactForm'];
        
+       /**
+        * @var ContactOptionList
+        */
+       public $optionList;
+       
        /**
         * @var ContactRecipientList
         */
@@ -40,6 +46,9 @@ class ContactSettingsPage extends AbstractPage {
        public function readData() {
                parent::readData();
                
+               $this->optionList = new ContactOptionList();
+               $this->optionList->readObjects();
+               
                $this->recipientList = new ContactRecipientList();
                $this->recipientList->readObjects();
        }
@@ -51,6 +60,7 @@ class ContactSettingsPage extends AbstractPage {
                parent::assignVariables();
                
                WCF::getTPL()->assign([
+                       'optionList' => $this->optionList,
                        'recipientList' => $this->recipientList
                ]);
        }
index 246c53ee01e0e87197fe69ce553f4aa0a06ce1a3..efeb6646fbfcc752ae14300c75916cce0b90dd66 100644 (file)
@@ -28,6 +28,7 @@ use wcf\util\StringUtil;
  * @property-read      integer         $required               is `1` if the option has to be filled out, otherwise `0`
  * @property-read      integer         $showOrder              position of the option relation tp the other options
  * @property-read      integer         $isDisabled             is `1` if the option is disabled, otherwise `0`
+ * @property-read      integer         $originIsSystem         is `1` if the option has been delivered by a package, otherwise `0` (i.e. the option has been created in the ACP)
  */
 abstract class CustomOption extends Option {
        /**
@@ -126,4 +127,14 @@ abstract class CustomOption extends Option {
                                return StringUtil::encodeHTML($this->optionValue);
                }
        }
+       
+       /**
+        * Returns true if this option can be deleted, defaults to false for
+        * options created through the package system.
+        * 
+        * @return      boolean
+        */
+       public function canDelete() {
+               return !$this->originIsSystem;
+       }
 }
index 4373daac1c83c8aec9d822f562f7b36262babff0..cd563015444ee72ba09054dfafc62f9b80cc727a 100644 (file)
@@ -179,7 +179,12 @@ class LinkHandler extends SingletonFactory {
                                $pageURL = RouteHandler::getHost() . str_replace('//', '/', RouteHandler::getPath(['acp']));
                        }
                        else {
-                               $pageURL = ApplicationHandler::getInstance()->getApplication($abbreviation)->getPageURL();
+                               $application = ApplicationHandler::getInstance()->getApplication($abbreviation);
+                               if ($application === null) {
+                                       throw new \InvalidArgumentException("Unknown application identifier '{$abbreviation}'.");
+                               }
+                               
+                               $pageURL = $application->getPageURL();
                        }
                        
                        $url = $pageURL . ($isACP ? 'acp/' : '') . $url;
index a704b40d76c6ee65c32f472a8a5d60a0ac14c71d..f89c0e8515843365434f355e0752c1556b8d5bfd 100644 (file)
        <category name="wcf.acp.contact">
                <item name="wcf.acp.contact.options"><![CDATA[Eingabefelder]]></item>
                <item name="wcf.acp.contact.option.add"><![CDATA[Eingabefeld hinzufügen]]></item>
+               <item name="wcf.acp.contact.option.edit"><![CDATA[Eingabefeld bearbeiten]]></item>
                <item name="wcf.acp.contact.recipients"><![CDATA[Empfänger]]></item>
                <item name="wcf.acp.contact.recipient.add"><![CDATA[Empfänger hinzufügen]]></item>
                <item name="wcf.acp.contact.recipient.edit"><![CDATA[Empfänger bearbeiten]]></item>
@@ -2340,6 +2341,9 @@ Fehler sind beispielsweise:
        </category>
        
        <category name="wcf.contact">
+               <item name="wcf.contact.option1"><![CDATA[Betreff]]></item>
+               <item name="wcf.contact.optionDescription1"><![CDATA[Kurze, prägnante Beschreibung der Anfrage.]]></item>
+               <item name="wcf.contact.option2"><![CDATA[Nachricht]]></item>
                <item name="wcf.contact.recipient.name1"><![CDATA[Administrator]]></item>
        </category>
        
index 702c38078222482dd2e374c2e6f1705709908fc5..1ee961f75e9b0340eaa042e0a717323ab8f1b5e6 100644 (file)
@@ -2273,12 +2273,16 @@ Errors are:
        </category>
        
        <category name="wcf.contact">
+               <item name="wcf.contact.option1"><![CDATA[Subject]]></item>
+               <item name="wcf.contact.optionDescription1"><![CDATA[Short and precise description of your inquiry.]]></item>
+               <item name="wcf.contact.option2"><![CDATA[Message]]></item>
                <item name="wcf.contact.recipient.name1"><![CDATA[Administrator]]></item>
        </category>
        
        <category name="wcf.acp.contact">
                <item name="wcf.acp.contact.options"><![CDATA[Input Fields]]></item>
                <item name="wcf.acp.contact.option.add"><![CDATA[Add Input Field]]></item>
+               <item name="wcf.acp.contact.option.edit"><![CDATA[Edit Input Field]]></item>
                <item name="wcf.acp.contact.recipients"><![CDATA[Recipients]]></item>
                <item name="wcf.acp.contact.recipient.add"><![CDATA[Add Recipient]]></item>
                <item name="wcf.acp.contact.recipient.edit"><![CDATA[Edit Recipient]]></item>
index d1885d090088fb59159fe54e9fecda29f8374f05..591626f6895e854fec707ed55536a2bee578cff5 100644 (file)
@@ -413,6 +413,21 @@ CREATE TABLE wcf1_condition (
        conditionData MEDIUMTEXT
 );
 
+DROP TABLE IF EXISTS wcf1_contact_option;
+CREATE TABLE wcf1_contact_option (
+       optionID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
+       optionTitle VARCHAR(255) NOT NULL DEFAULT '',
+       optionDescription TEXT,
+       optionType VARCHAR(255) NOT NULL DEFAULT '',
+       defaultValue MEDIUMTEXT,
+       validationPattern TEXT,
+       selectOptions MEDIUMTEXT,
+       required TINYINT(1) NOT NULL DEFAULT 0,
+       showOrder INT(10) NOT NULL DEFAULT 0,
+       isDisabled TINYINT(1) NOT NULL DEFAULT 0,
+       originIsSystem TINYINT(1) NOT NULL DEFAULT 0
+);
+
 DROP TABLE IF EXISTS wcf1_contact_recipient;
 CREATE TABLE wcf1_contact_recipient (
        recipientID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
@@ -2225,5 +2240,9 @@ INSERT INTO wcf1_user_rank (groupID, requiredPoints, rankTitle, cssClassName) VA
        (3, 9000, 'wcf.user.rank.user4', ''),
        (3, 15000, 'wcf.user.rank.user5', '');
 
+-- default options: subject and message
+INSERT INTO wcf1_contact_option (optionID, optionTitle, optionDescription, optionType, required, showOrder, originIsSystem) VALUES (1, 'wcf.contact.option1', 'wcf.contact.optionDescription1', 'text', 1, 1, 1);
+INSERT INTO wcf1_contact_option (optionID, optionTitle, optionDescription, optionType, required, showOrder, originIsSystem) VALUES (2, 'wcf.contact.option2', '', 'textarea', 1, 1, 1);
+
 -- default recipient: site administrator
 INSERT INTO wcf1_contact_recipient (recipientID, name, email, isAdministrator, originIsSystem) VALUES (1, 'wcf.contact.recipient.name1', '', 1, 1);