Add trophy add form (WIP)
authorJoshua Rüsweg <josh@bastelstu.be>
Wed, 5 Jul 2017 20:02:41 +0000 (22:02 +0200)
committerJoshua Rüsweg <josh@bastelstu.be>
Wed, 5 Jul 2017 20:02:41 +0000 (22:02 +0200)
See #2315

com.woltlab.wcf/acpMenu.xml
wcfsetup/install/files/acp/templates/trophyAdd.tpl [new file with mode: 0644]
wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Trophy/Badge.js [new file with mode: 0644]
wcfsetup/install/files/lib/acp/form/TrophyAddForm.class.php [new file with mode: 0644]
wcfsetup/install/files/style/ui/trophy.scss
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index f8395b3ca23469f8be14d4de6c19f958b9882852..a4e2365f7ecbcd86dfbcc73b87bccf3a72476dbf 100644 (file)
                                <permissions>admin.trophy.canManageTrophy</permissions>
                                <options>module_trophy</options>
                        </acpmenuitem>
+                       <acpmenuitem name="wcf.acp.menu.link.trophy.add">
+                               <controller>wcf\acp\form\TrophyAddForm</controller>
+                               <parent>wcf.acp.menu.link.trophy.list</parent>
+                               <permissions>admin.trophy.canManageTrophy</permissions>
+                               <options>module_trophy</options>
+                               <icon>fa-plus</icon>
+                       </acpmenuitem>
                        <!-- /trophy -->
                
                <!-- /user -->
diff --git a/wcfsetup/install/files/acp/templates/trophyAdd.tpl b/wcfsetup/install/files/acp/templates/trophyAdd.tpl
new file mode 100644 (file)
index 0000000..f5d2604
--- /dev/null
@@ -0,0 +1,235 @@
+{include file='header' pageTitle='wcf.acp.menu.link.trophy.'|concat:$action}
+
+{js application='wcf' file='WCF.ColorPicker' bundle='WCF.Combined'}
+{include file='fontAwesomeJavaScript'}
+
+<script data-relocate="true">
+       require(['Language', 'WoltLabSuite/Core/Acp/Ui/Trophy/Badge'], function (Language, BadgeHandler) {
+               Language.addObject({
+                       'wcf.style.colorPicker': '{lang}wcf.style.colorPicker{/lang}',
+                       'wcf.style.colorPicker.new': '{lang}wcf.style.colorPicker.new{/lang}',
+                       'wcf.style.colorPicker.current': '{lang}wcf.style.colorPicker.current{/lang}',
+                       'wcf.style.colorPicker.button.apply': '{lang}wcf.style.colorPicker.button.apply{/lang}',
+                       'wcf.acp.style.image.error.invalidExtension': '{lang}wcf.acp.style.image.error.invalidExtension{/lang}',
+                       'wcf.acp.trophy.badge.edit': '{lang}wcf.acp.trophy.badge.edit{/lang}'
+               });
+               
+               elBySel('select[name=type]').addEventListener('change', function () {
+                       if (elBySel('select[name=type]').value == 1) {
+                               elById('imageContainer').style.display = 'block';
+                               elById('badgeContainer').style.display = 'none';
+                       } 
+                       else if (elBySel('select[name=type]').value == 2) {
+                               elById('imageContainer').style.display = 'none';
+                               elById('badgeContainer').style.display = 'block';
+                       }
+               });
+               
+               elBySel('input[name=awardAutomatically]').addEventListener('change', function () {
+                       if (elBySel('input[name=awardAutomatically]').checked) {
+                               elBySel('.conditionSection').style.display = 'block';
+                       } 
+                       else {
+                               elBySel('.conditionSection').style.display = 'none';
+                       }
+               });
+               
+               BadgeHandler.init(); 
+       });
+</script>
+
+<header class="contentHeader">
+       <div class="contentHeaderTitle">
+               <h1 class="contentTitle">{lang}wcf.acp.menu.link.trophy.{$action}{/lang}</h1>
+       </div>
+       
+       <nav class="contentHeaderNavigation">
+               <ul>
+                       <li><a href="{link controller='TrophyList'}{/link}" class="button"><span class="icon icon16 fa-list"></span> <span>{lang}wcf.acp.menu.link.trophy.list{/lang}</span></a></li>
+
+                       {event name='contentHeaderNavigation'}
+               </ul>
+       </nav>
+</header>
+
+{include file='formError'}
+
+{if $success|isset}
+       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
+{/if}
+
+<form id="adForm" method="post" action="{if $action == 'add'}{link controller='TrophyAdd'}{/link}{else}{link controller='TrophyEdit' id=$trophy->getObjectID()}{/link}{/if}">
+       <section>
+               <dl{if $errorField == 'title'} class="formError"{/if}>
+                       <dt><label for="title">{lang}wcf.global.title{/lang}</label></dt>
+                       <dd>
+                               <input id="title" name="title" type="text" value="{$i18nPlainValues[title]}">
+                               {if $errorField == 'title'}
+                                       <small class="innerError">
+                                               {if $errorType == 'empty'}
+                                                       {lang}wcf.global.form.error.empty{/lang}
+                                               {elseif $errorType == 'multilingual'}
+                                                       {lang}wcf.global.form.error.multilingual{/lang}
+                                               {/if}
+                                       </small>
+                               {/if}
+                       </dd>
+               </dl>
+               {include file='multipleLanguageInputJavascript' elementIdentifier='title' forceSelection=false}
+               
+               <dl{if $errorField == 'description'} class="formError"{/if}>
+                       <dt><label for="description">{lang}wcf.acp.trophy.description{/lang}</label></dt>
+                       <dd>
+                               <textarea id="description" name="description" cols="40" rows="10">{$i18nPlainValues[description]}</textarea>
+                               {if $errorField == 'description'}
+                                       <small class="innerError">
+                                               {if $errorType == 'empty'}
+                                                       {lang}wcf.global.form.error.empty{/lang}
+                                               {elseif $errorType == 'multilingual'}
+                                                       {lang}wcf.global.form.error.multilingual{/lang}
+                                               {/if}
+                                       </small>
+                               {/if}
+                       </dd>
+               </dl>
+               {include file='multipleLanguageInputJavascript' elementIdentifier='description' forceSelection=false}
+               
+               <dl{if $errorField == 'categoryID'} class="formError"{/if}>
+                       <dt><label for="categoryID">{lang}wcf.acp.trophy.category{/lang}</label></dt>
+                       <dd>
+                               <select name="categoryID" id="categoryID">
+                                       <option value="0">{lang}wcf.global.noSelection{/lang}</option>
+
+                                       {foreach from=$trophyCategories item=category}
+                                               <option value="{$category->getObjectID()}"{if $category->getObjectID() == $categoryID} selected{/if}>{$category->getTitle()}</option>
+                                       {/foreach}
+                               </select>
+                               {if $errorField == 'categoryID'}
+                                       <small class="innerError">
+                                               {if $errorType == 'empty'}
+                                                       {lang}wcf.global.form.error.empty{/lang}
+                                               {/if}
+                                       </small>
+                               {/if}
+                       </dd>
+               </dl>
+               
+               <dl>
+                       <dt></dt>
+                       <dd>
+                               <label><input type="checkbox" name="isDisabled" value="1"{if $isDisabled} checked{/if}> {lang}wcf.acp.trophy.isDisabled{/lang}</label>
+                       </dd>
+               </dl>
+               
+               <dl>
+                       <dt></dt>
+                       <dd>
+                               <label><input type="checkbox" name="awardAutomatically" value="1"{if $awardAutomatically} checked{/if}> {lang}wcf.acp.trophy.awardAutomatically{/lang}</label>
+                       </dd>
+               </dl>
+               
+               <dl>
+                       <dt>{lang}wcf.acp.trophy.type{/lang}</dt>
+                       <dd>
+                               <select name="type" id="type">
+                                       {foreach from=$availableTypes item=trophyType key=key}
+                                               <option value="{$key}"{if $type == $key} selected{/if}>{lang}wcf.acp.trophy.type.{$trophyType}{/lang}</option>
+                                       {/foreach}
+                               </select>
+                       </dd>
+               </dl>
+               
+               {event name='dataFields'}
+       </section>
+       
+       <section id="imageContainer" class="section"{if $type == 2} style="display: none;"{/if}>
+               <header class="sectionHeader">
+                       <h2 class="sectionTitle">{lang}wcf.acp.trophy.type.image{/lang}</h2>
+               </header>
+
+               {* @TODO *}
+       </section>
+       
+       <section id="badgeContainer" class="section"{if $type == 1} style="display: none;"{/if}>
+               <header class="sectionHeader">
+                       <h2 class="sectionTitle">{lang}wcf.acp.trophy.type.badge{/lang}</h2>
+               </header>
+
+               <dl>
+                       <dt>{lang}wcf.acp.trophy.type.badge{/lang}</dt>
+                       <dd>
+                               <span class="icon icon64 fa-{$iconName} jsTrophyIcon trophyIcon" style="color: {$iconColor}; background-color: {$badgeColor}"></span>
+                               <button class="small">{lang}wcf.global.button.edit{/lang}</button>
+                               
+                               <input type="hidden" name="iconName" value="{$iconName}">
+                               <input type="hidden" name="iconColor" value="{$iconColor}">
+                               <input type="hidden" name="badgeColor" value="{$badgeColor}">
+                       </dd>
+               </dl>
+       </section>
+       
+       {event name='sections'}
+       
+       <section class="section conditionSection"{if !$awardAutomatically} style="display: none;"{/if}>
+               <header class="sectionHeader">
+                       <h2 class="sectionTitle">{lang}wcf.acp.trophy.conditions{/lang}</h2>
+                       <p class="sectionDescription">{lang}wcf.acp.trophy.conditions.description{/lang}</p>
+               </header>
+               
+               {if $errorField == 'conditions'}
+                       <p class="error">{lang}wcf.acp.trophy.conditions.error.noConditions{/lang}</p>
+               {/if}
+               
+               {include file='userConditions'}
+       </section>
+       
+       {event name='conditionSections'}
+       
+       <div class="formSubmit">
+               <input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s">
+               {@SECURITY_TOKEN_INPUT_TAG}
+       </div>
+</form>
+
+<div id="trophyIconEditor" style="display: none;">
+       <div class="box128">
+               <span class="icon icon144 fa-{$iconName} jsTrophyIcon trophyIcon" style="color: {$iconColor}; background-color: {$badgeColor}"></span>
+               <div>
+                       <dl>
+                               <dt>{lang}wcf.acp.trophy.badge.iconName{/lang}</dt>
+                               <dd>
+                                       <span class="jsTrophyIconName">{$iconName}</span>
+                                       <a href="#" class="button small"><span class="icon icon16 fa-search"></span></a>
+                               </dd>
+                       </dl>
+                       
+                       <dl id="jsIconColorContainer">
+                               <dt>{lang}wcf.acp.trophy.badge.iconColor{/lang}</dt>
+                               <dd>
+                                       <span class="colorBox">
+                                               <span id="iconColorValue" class="colorBoxValue jsColorPicker" data-store="iconColorValue"></span>
+                                               <input type="hidden" id="iconColorValue">
+                                       </span>
+                                       <a href="#" class="button small jsButtonIconColorPicker"><span class="icon icon16 fa-paint-brush"></span></a>
+                               </dd>
+                       </dl>
+                       
+                       <dl id="jsBadgeColorContainer">
+                               <dt>{lang}wcf.acp.trophy.badge.badgeColor{/lang}</dt>
+                               <dd>
+                                       <span class="colorBox">
+                                               <span id="badgeColorValue" class="colorBoxValue jsColorPicker" data-store="badgeColorValue"></span>
+                                               <input type="hidden" id="badgeColorValue">
+                                       </span>
+                                       <a href="#" id="test" class="button small jsButtonBadgeColorPicker"><span class="icon icon16 fa-paint-brush"></span></a>
+                               </dd>
+                       </dl>
+               </div>
+       </div>
+
+       <div class="formSubmit">
+               <button class="buttonPrimary">{lang}wcf.global.button.save{/lang}</button>
+       </div>
+</div>
+
+{include file='footer'}
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Trophy/Badge.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Trophy/Badge.js
new file mode 100644 (file)
index 0000000..12f90db
--- /dev/null
@@ -0,0 +1,182 @@
+/**
+ * Provides the trophy icon designer.
+ *
+ * @author     Joshua Ruesweg
+ * @copyright  2001-2017 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module     WoltLabSuite/Core/Acp/Ui/Trophy/Badge
+ */
+define(['Core', 'Dictionary', 'Language', 'Ui/Dialog', 'WoltLabSuite/Core/Ui/Color/Picker', 'WoltLabSuite/Core/Ui/Style/FontAwesome'], function (Core, Dictionary, Language, UiDialog, UiColorPicker, UiStyleFontAwesome) {
+       "use strict";
+       
+       var _icon, _iconNameInput, _iconColorInput, _badgeColorInput, _dialogContent, _iconColor, _badgeColor;
+       
+       /**
+        * @exports     WoltLabSuite/Core/Acp/Ui/Trophy/Badge
+        */
+       return {
+               /**
+                * Initializes the badge designer.
+                */
+               init: function () {
+                       var iconContainer = elById('badgeContainer');
+                       elBySel('button', iconContainer).addEventListener(WCF_CLICK_EVENT, this._click.bind(this));
+                       
+                       _iconNameInput = elBySel('input[name="iconName"]', iconContainer);
+                       _iconColorInput = elBySel('input[name="iconColor"]', iconContainer);
+                       _badgeColorInput = elBySel('input[name="badgeColor"]', iconContainer);
+               },
+               
+               /**
+                * Opens the icon designer.
+                * 
+                * @param       {Event}         event           event object
+                * @protected
+                */
+               _click: function (event) {
+                       event.preventDefault();
+                       
+                       UiDialog.open(this);
+               },
+               
+               /**
+                * Sets the icon name.
+                *
+                * @param       {string}        iconName        icon name
+                * @protected
+                */
+               _setIcon: function (iconName) {
+                       _icon.textContent = iconName;
+                       
+                       this._renderIcon();
+               },
+               
+               /**
+                * Sets the icon color, can be either a string or an object holding the
+                * individual r, g, b and a values.
+                *
+                * @param       {(string|Object)}       color           color data
+                * @protected
+                */
+               _setIconColor: function (color) {
+                       if (typeof color !== "string") {
+                               color = 'rgba(' + color.r + ', ' + color.g + ', ' + color.b + ', ' + color.a + ')';
+                       }
+                       
+                       elData(_iconColor, 'color', color);
+                       _iconColor.style.setProperty('background-color', color, '');
+                       
+                       this._renderIcon();
+               },
+               
+               /**
+                * Sets the badge color, can be either a string or an object holding the
+                * individual r, g, b and a values.
+                *
+                * @param       {(string|Object)}       color           color data
+                * @protected
+                */
+               _setBadgeColor: function (color) {
+                       if (typeof color !== "string") {
+                               color = 'rgba(' + color.r + ', ' + color.g + ', ' + color.b + ', ' + color.a + ')';
+                       }
+                       
+                       elData(_badgeColor, 'color', color);
+                       _badgeColor.style.setProperty('background-color', color, '');
+                       
+                       this._renderIcon();
+               },
+               
+               /**
+                * Renders the custom icon preview.
+                *
+                * @protected
+                */
+               _renderIcon: function () {
+                       var iconColor = _iconColor.style.getPropertyValue('background-color');
+                       var badgeColor = _badgeColor.style.getPropertyValue('background-color');
+                       
+                       var icon = elBySel('.jsTrophyIcon', _dialogContent);
+                       
+                       // set icon
+                       icon.className = icon.className.replace(/\b(fa-[a-z0-9\-]+)\b/, '');
+                       icon.classList.add('fa-' + _icon.textContent);
+                       
+                       icon.style.setProperty('color', iconColor, '');
+                       icon.style.setProperty('background-color', badgeColor, '');
+               },
+               
+               /**
+                * Saves the custom icon design.
+                *
+                * @param       {Event}         event           event object
+                * @protected
+                */
+               _save: function(event) {
+                       event.preventDefault();
+                       
+                       var iconColor = _iconColor.style.getPropertyValue('background-color');
+                       var badgeColor = _badgeColor.style.getPropertyValue('background-color');
+                       var icon = _icon.textContent;
+                       
+                       _iconNameInput.value = icon; 
+                       _badgeColorInput.value = badgeColor; 
+                       _iconColorInput.value = iconColor; 
+                       
+                       var previewIcon = elBySel('.jsTrophyIcon', elById('iconContainer'));
+                       
+                       // set icon
+                       previewIcon.className = previewIcon.className.replace(/\b(fa-[a-z0-9\-]+)\b/, '');
+                       previewIcon.classList.add('fa-' + icon);
+                       previewIcon.style.setProperty('color', iconColor, '');
+                       previewIcon.style.setProperty('background-color', badgeColor, '');
+                       
+                       UiDialog.close(this);
+               },
+               
+               _dialogSetup: function () {
+                       return {
+                               id: 'trophyIconEditor',
+                               options: {
+                                       onSetup: (function (context) {
+                                               _dialogContent = context;
+                                               
+                                               _iconColor = elBySel('#jsIconColorContainer .colorBoxValue', context);
+                                               _badgeColor = elBySel('#jsBadgeColorContainer .colorBoxValue', context);
+                                               _icon = elBySel('.jsTrophyIconName', context);
+                                               
+                                               elBySel('.jsTrophyIconName + .button', context).addEventListener(WCF_CLICK_EVENT, (function (event) {
+                                                       event.preventDefault();
+                                                       
+                                                       UiStyleFontAwesome.open(this._setIcon.bind(this));
+                                               }).bind(this));
+                                               
+                                               elBySel('.jsButtonIconColorPicker', elById('jsIconColorContainer')).addEventListener(WCF_CLICK_EVENT, function (event) {
+                                                       event.preventDefault();
+                                                       
+                                                       Core.triggerEvent(elBySel('.jsColorPicker', elById('jsIconColorContainer')), WCF_CLICK_EVENT);
+                                               });
+                                               
+                                               elBySel('.jsButtonBadgeColorPicker', elById('jsBadgeColorContainer')).addEventListener(WCF_CLICK_EVENT, function (event) {
+                                                       event.preventDefault();
+                                                       
+                                                       Core.triggerEvent(elBySel('.jsColorPicker', elById('jsBadgeColorContainer')), WCF_CLICK_EVENT);
+                                               });
+                                               
+                                               var colorPicker = new WCF.ColorPicker('.jsColorPicker');
+                                               colorPicker.setCallbackSubmit(this._renderIcon.bind(this));
+                                               
+                                               elBySel('.formSubmit > .buttonPrimary', context).addEventListener(WCF_CLICK_EVENT, this._save.bind(this));
+                                               return;
+                                       }).bind(this),
+                                       onShow: (function () {
+                                               this._setIcon(_iconNameInput.value);
+                                               this._setIconColor(_iconColorInput.value);
+                                               this._setBadgeColor(_badgeColorInput.value);
+                                       }).bind(this),
+                                       title: Language.get('wcf.acp.trophy.badge.edit')
+                               }
+                       };
+               }
+       };
+});
diff --git a/wcfsetup/install/files/lib/acp/form/TrophyAddForm.class.php b/wcfsetup/install/files/lib/acp/form/TrophyAddForm.class.php
new file mode 100644 (file)
index 0000000..6216600
--- /dev/null
@@ -0,0 +1,302 @@
+<?php
+namespace wcf\acp\form;
+use wcf\data\category\Category;
+use wcf\data\object\type\ObjectType;
+use wcf\data\trophy\category\TrophyCategoryCache;
+use wcf\data\trophy\Trophy;
+use wcf\data\trophy\TrophyAction;
+use wcf\system\condition\ConditionHandler;
+use wcf\system\exception\UserInputException;
+use wcf\system\language\I18nValue;
+use wcf\system\trophy\condition\TrophyConditionHandler;
+use wcf\system\WCF;
+use wcf\util\StringUtil;
+
+/**
+ * Represents the trophy add form. 
+ *
+ * @author     Joshua Ruesweg
+ * @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 TrophyAddForm extends AbstractAcpForm {
+       /**
+        * @inheritDoc
+        */
+       public $activeMenuItem = 'wcf.acp.menu.link.trophy.add';
+       
+       /**
+        * @inheritDoc
+        */
+       public $neededPermissions = ['admin.trophy.canManageTrophy'];
+       
+       /**
+        * @inheritDoc
+        */
+       public $neededModules = ['MODULE_TROPHY'];
+       
+       /**
+        * category id for the trophy.
+        * @var integer
+        */
+       public $categoryID = 0;
+       
+       /**
+        * Category object.
+        * @var Category
+        */
+       public $category = null;
+       
+       /**
+        * Trophy description.
+        * @var string
+        */
+       public $description = '';
+       
+       /**
+        * Trophy title. 
+        * @var string
+        */
+       public $title = '';
+       
+       /**
+        * All available trophy types. 
+        * @var []
+        */
+       public $availableTypes = [
+               Trophy::TYPE_IMAGE => 'image',
+               Trophy::TYPE_BADGE => 'badge'
+       ];
+       
+       /**
+        * Type of the trophy (whether this is an image or not)
+        * @var int
+        */
+       public $type = Trophy::TYPE_BADGE;
+       
+       /**
+        * the location of the uploaded icon
+        * @var string
+        */
+       public $uploadIconFile = '';
+       
+       /**
+        * the icon name for CSS icons (FA-Icon)
+        * @var string
+        */
+       public $iconName = 'trophy';
+       
+       /**
+        * The icon color (rgba format with rgba prefix)
+        * @var string
+        */
+       public $iconColor = 'rgba(255, 255, 255, 1)';
+       
+       /**
+        * The badge color (rgba format with rgba prefix)
+        * @var string
+        */
+       public $badgeColor = 'rgba(50, 92, 132, 1)';
+       
+       /**
+        * `1` if the trophy is disabled. 
+        * @var int
+        */
+       public $isDisabled = 0;
+       /**
+        * `1` if the trophy has conditions to reward automatically trophies. 
+        * @var int
+        */
+       public $awardAutomatically = 0;
+       
+       /**
+        * list of grouped user group assignment condition object types
+        * @var ObjectType[][]
+        */
+       public $conditions = [];
+       
+       /**
+        * @inheritDoc
+        */
+       public function readData() {
+               $this->conditions = TrophyConditionHandler::getInstance()->getGroupedObjectTypes();
+               
+               parent::readData();
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function readParameters() {
+               parent::readParameters();
+               
+               $titleI18n = new I18nValue('title');
+               $titleI18n->setLanguageItem('wcf.trophy.title', 'wcf.trophy', 'com.woltlab.wcf');
+               $this->registerI18nValue($titleI18n);
+               
+               $descriptionI18n = new I18nValue('description');
+               $descriptionI18n->setLanguageItem('wcf.trophy.description', 'wcf.trophy', 'com.woltlab.wcf');
+               $this->registerI18nValue($descriptionI18n);
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function readFormParameters() {
+               parent::readFormParameters();
+               
+               if (isset($_POST['categoryID'])) $this->categoryID = intval($_POST['categoryID']);
+               if (isset($_POST['type'])) $this->type = intval($_POST['type']);
+               if (isset($_POST['isDisabled'])) $this->isDisabled = intval($_POST['isDisabled']);
+               if (isset($_POST['uploadIconFile'])) $this->uploadIconFile = StringUtil::trim($_POST['uploadIconFile']);
+               if (isset($_POST['iconName'])) $this->iconName = StringUtil::trim($_POST['iconName']);
+               if (isset($_POST['iconColor'])) $this->iconColor = $_POST['iconColor'];
+               if (isset($_POST['badgeColor'])) $this->badgeColor = $_POST['badgeColor'];
+               if (isset($_POST['awardAutomatically'])) $this->awardAutomatically = intval($_POST['awardAutomatically']);
+               
+               $this->category = TrophyCategoryCache::getInstance()->getCategoryByID($this->categoryID);
+               
+               foreach ($this->conditions as $conditions) {
+                       /** @var ObjectType $condition */
+                       foreach ($conditions as $condition) {
+                               $condition->getProcessor()->readFormParameters();
+                       }
+               }
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function validate() {
+               parent::validate();
+               
+               if (!in_array($this->type, array_keys($this->availableTypes))) {
+                       throw new UserInputException('type');
+               }
+               
+               if (!$this->categoryID) {
+                       throw new UserInputException('categoryID');
+               }
+               
+               if (!$this->category->getObjectID()) {
+                       throw new UserInputException('categoryID');
+               }
+               
+               switch ($this->type) {
+                       case Trophy::TYPE_IMAGE:
+                               // @TODO
+                               break;
+                       
+                       case Trophy::TYPE_BADGE:
+                               if (empty($this->iconName)) {
+                                       throw new UserInputException('iconName');
+                               }
+                               
+                               if (empty($this->iconColor)) {
+                                       throw new UserInputException('iconColor');
+                               }
+                               
+                               if (empty($this->badgeColor)) {
+                                       throw new UserInputException('badgeColor');
+                               }
+                               break;
+               }
+               
+               if ($this->awardAutomatically) {
+                       $hasData = false;
+                       foreach ($this->conditions as $conditions) {
+                               foreach ($conditions as $condition) {
+                                       $condition->getProcessor()->validate();
+                                       
+                                       if (!$hasData && $condition->getProcessor()->getData() !== null) {
+                                               $hasData = true;
+                                       }
+                               }
+                       }
+                       
+                       if (!$hasData) {
+                               throw new UserInputException('conditions');
+                       }       
+               }
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function save() {
+               parent::save();
+               
+               $data = [];
+               if ($this->type == Trophy::TYPE_IMAGE) {
+                       // @ TODO 
+               } else if ($this->type == Trophy::TYPE_BADGE) {
+                       $data['iconName'] = $this->iconName;
+                       $data['iconColor'] = $this->iconColor;
+                       $data['badgeColor'] = $this->badgeColor;
+               }
+               
+               $this->objectAction = new TrophyAction([], 'create', [
+                       'data' => array_merge($this->additionalFields, $data, [
+                               'title' => $this->title,
+                               'description' => $this->description,
+                               'categoryID' => $this->categoryID,
+                               'type' => $this->type,
+                               'isDisabled' => $this->isDisabled
+                       ])
+               ]);
+               $this->objectAction->executeAction();
+               
+               // transform conditions array into one-dimensional array
+               $conditions = [];
+               foreach ($this->conditions as $groupedObjectTypes) {
+                       $conditions = array_merge($conditions, $groupedObjectTypes);
+               }
+               
+               ConditionHandler::getInstance()->createConditions($this->objectAction->getReturnValues()['returnValues']->trophyID, $conditions);
+               
+               $this->reset();
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function reset() {
+               parent::reset();
+               
+               $this->isDisabled = $this->awardAutomatically = $this->categoryID = 0;
+               $this->type = Trophy::TYPE_BADGE;
+               $this->uploadIconFile = $this->iconName = '';
+               $this->iconColor = 'rgba(255, 255, 255, 1)';
+               $this->badgeColor = 'rgba(50, 92, 132, 1)';
+               $this->iconName = 'trophy';
+               
+               foreach ($this->conditions as $conditions) {
+                       foreach ($conditions as $condition) {
+                               $condition->getProcessor()->reset();
+                       }
+               }
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function assignVariables() {
+               parent::assignVariables();
+               
+               WCF::getTPL()->assign([
+                       'categoryID' => $this->categoryID,
+                       'type' => $this->type,
+                       'iconFile' => $this->uploadIconFile,
+                       'isDisabled' => $this->isDisabled,
+                       'iconName' => $this->iconName,
+                       'iconColor' => $this->iconColor,
+                       'badgeColor' => $this->badgeColor,
+                       'trophyCategories' => TrophyCategoryCache::getInstance()->getCategories(),
+                       'groupedObjectTypes' => $this->conditions, 
+                       'awardAutomatically' => $this->awardAutomatically,
+                       'availableTypes' => $this->availableTypes
+               ]);
+       }
+}
index 6c7bb4cc0e66409657a05128c1b9451dadbbe227..94c25b53f474509a5174ace0d3adcf3c87dcc21f 100644 (file)
@@ -1,3 +1,21 @@
+#trophyIconEditor .colorBoxValue {
+       display: block;
+       height: 24px;
+       width: 24px;
+}
+
+#trophyIconEditor .colorBox {
+       background-color: rgb(255, 255, 255);
+       border: 1px solid rgb(204, 204, 204);
+       display: inline-block;
+       padding: 1px;
+       vertical-align: middle;
+}
+
+#badgeContainer .icon {
+       vertical-align: middle;
+}
+
 .trophyIcon {
        display: inline-block;
        border-radius: 50%;
index e183d78b4613ef8a06edd23e0c4fcfe6ef886f6c..da181be35330ebf727fa8a825c324139baaa7013 100644 (file)
                <item name="wcf.acp.menu.link.trophy.category.list"><![CDATA[Kategorien]]></item>
                <item name="wcf.acp.menu.link.trophy.category.add"><![CDATA[Kategorie hinzufügen]]></item>
                <item name="wcf.acp.menu.link.trophy.list"><![CDATA[Trophäen]]></item>
+               <item name="wcf.acp.menu.link.trophy.add"><![CDATA[Trophäe hinzufügen]]></item>
        </category>
        
        <category name="wcf.acp.notice">
@@ -3578,7 +3579,20 @@ Die E-Mail-Adresse des neuen Benutzers lautet: {@$user->email}
        </category>
        
        <category name="wcf.acp.trophy">
+               <item name="wcf.acp.trophy.description"><![CDATA[Beschreibung]]></item>
                <item name="wcf.acp.trophy.category"><![CDATA[Kategorie]]></item>
+               <item name="wcf.acp.trophy.isDisabled"><![CDATA[Trophäe deaktivieren]]></item>
+               <item name="wcf.acp.trophy.awardAutomatically"><![CDATA[Trophäe automatisch vergeben]]></item>
+               <item name="wcf.acp.trophy.type"><![CDATA[Trophäen-Typ]]></item>
+               <item name="wcf.acp.trophy.type.badge"><![CDATA[Badge]]></item>
+               <item name="wcf.acp.trophy.type.image"><![CDATA[Bild-Datei]]></item>
+               <item name="wcf.acp.trophy.badge.iconName"><![CDATA[Icon]]></item>
+               <item name="wcf.acp.trophy.badge.iconColor"><![CDATA[Icon-Farbe]]></item>
+               <item name="wcf.acp.trophy.badge.badgeColor"><![CDATA[Badge-Farbe]]></item>
+               <item name="wcf.acp.trophy.badge.edit"><![CDATA[Badge bearbeiten]]></item>
+               <item name="wcf.acp.trophy.conditions"><![CDATA[Bedingungen]]></item>
+               <item name="wcf.acp.trophy.conditions.description"><![CDATA[Der aktive Benutzer muss die folgenden Bedingungen erfüllen, damit der die Trophäe vergeben wird.]]></item>
+               <item name="wcf.acp.trophy.conditions.error.noConditions"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du hast{else}Sie haben{/if} keine Bedingungen ausgewählt.]]></item>
                <item name="wcf.acp.trophy.delete.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} die Trophäe <span class="confirmationObject">{trophy->getTitle()}</span> wirklich löschen?]]></item>
        </category>
        
index 2a7829a08c756c4cd66f6540992b9495152acf07..1b68213b5ccfbfc0dfde5f2dc0c10832ae8ccf03 100644 (file)
                <item name="wcf.acp.menu.link.trophy.category.list"><![CDATA[Categories]]></item>
                <item name="wcf.acp.menu.link.trophy.category.add"><![CDATA[Add Category]]></item>
                <item name="wcf.acp.menu.link.trophy.list"><![CDATA[Trophies]]></item>
+               <item name="wcf.acp.menu.link.trophy.add"><![CDATA[Add Trophy]]></item>
        </category>
        
        <category name="wcf.acp.notice">
@@ -3565,7 +3566,20 @@ Open the link below to access the user profile:
        </category>
        
        <category name="wcf.acp.trophy">
+               <item name="wcf.acp.trophy.description"><![CDATA[Description]]></item>
                <item name="wcf.acp.trophy.category"><![CDATA[Category]]></item>
+               <item name="wcf.acp.trophy.isDisabled"><![CDATA[Disable Trophy]]></item>
+               <item name="wcf.acp.trophy.awardAutomatically"><![CDATA[Award trophy automatically]]></item>
+               <item name="wcf.acp.trophy.type"><![CDATA[Trophy Type]]></item>
+               <item name="wcf.acp.trophy.type.badge"><![CDATA[Badge]]></item>
+               <item name="wcf.acp.trophy.type.image"><![CDATA[Image]]></item>
+               <item name="wcf.acp.trophy.badge.iconName"><![CDATA[Icon]]></item>
+               <item name="wcf.acp.trophy.badge.iconColor"><![CDATA[Icon Color]]></item>
+               <item name="wcf.acp.trophy.badge.badgeColor"><![CDATA[Badge Color]]></item>
+               <item name="wcf.acp.trophy.badge.edit"><![CDATA[Edit Badge]]></item>
+               <item name="wcf.acp.trophy.conditions"><![CDATA[Conditions]]></item>
+               <item name="wcf.acp.trophy.conditions.description"><![CDATA[The users need to fulfill the following conditions to automatically be awarded with the trophy.]]></item>
+               <item name="wcf.acp.trophy.conditions.error.noConditions"><![CDATA[You have not provided any conditions yet.]]></item>
                <item name="wcf.acp.trophy.delete.confirmMessage"><![CDATA[Do you really want to delete the trophy <span class="confirmationObject">{$trophy->getTitle()}</span>?]]></item>
        </category>