Add trophy image upload
authorJoshua Rüsweg <josh@bastelstu.be>
Sat, 8 Jul 2017 13:37:11 +0000 (15:37 +0200)
committerJoshua Rüsweg <josh@bastelstu.be>
Sat, 8 Jul 2017 13:37:35 +0000 (15:37 +0200)
See #2315

com.woltlab.wcf/templates/trophyImage.tpl [new file with mode: 0644]
wcfsetup/install/files/acp/templates/trophyAdd.tpl
wcfsetup/install/files/acp/templates/trophyImage.tpl [new file with mode: 0644]
wcfsetup/install/files/acp/templates/trophyList.tpl
wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Trophy/Upload.js [new file with mode: 0644]
wcfsetup/install/files/lib/acp/form/TrophyAddForm.class.php
wcfsetup/install/files/lib/data/trophy/Trophy.class.php
wcfsetup/install/files/lib/data/trophy/TrophyAction.class.php
wcfsetup/install/files/lib/system/upload/TrophyImageUploadFileValidationStrategy.class.php [new file with mode: 0644]
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

diff --git a/com.woltlab.wcf/templates/trophyImage.tpl b/com.woltlab.wcf/templates/trophyImage.tpl
new file mode 100644 (file)
index 0000000..38bc00f
--- /dev/null
@@ -0,0 +1,7 @@
+<img
+       src="{@$__wcf->getPath()}images/trophy/{$trophy->iconFile}"
+       style="width:{$size}px;height:{$size}px"
+       title="{$trophy->getTitle()}"
+       class="jsTooltip trophyIcon"
+       data-trophy-id="{$trophy->getObjectID()}"
+/>
index f5d2604e3d44a9ab54aa22e19535d164104165dc..a0d39ede1f8e85ce041af61cca42b81cb7004a9d 100644 (file)
                        '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}'
+                       'wcf.acp.trophy.badge.edit': '{lang}wcf.acp.trophy.badge.edit{/lang}',
+                       'wcf.acp.trophy.imageUpload.error.notSquared': '{lang}wcf.acp.trophy.imageUpload.error.notSquared{/lang}',
+                       'wcf.acp.trophy.imageUpload.error.tooSmall': '{lang}wcf.acp.trophy.imageUpload.error.tooSmall{/lang}',
+                       'wcf.acp.trophy.imageUpload.error.noImage': '{lang}wcf.acp.trophy.imageUpload.error.noImage{/lang}'
                });
                
                elBySel('select[name=type]').addEventListener('change', function () {
                </dl>
                
                <dl>
-                       <dt>{lang}wcf.acp.trophy.type{/lang}</dt>
+                       <dt><label for="type">{lang}wcf.acp.trophy.type{/lang}</label></dt>
                        <dd>
                                <select name="type" id="type">
                                        {foreach from=$availableTypes item=trophyType key=key}
        
        <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>
+                       <h2 class="sectionTitle">{lang}wcf.acp.trophy.type.imageUpload{/lang}</h2>
                </header>
 
-               {* @TODO *}
+               <dl{if $errorField == 'imageUpload'} class="formError"{/if}>
+                       <dt>{lang}wcf.acp.trophy.type.imageUpload{/lang}</dt>
+                       <dd>
+                               <input type="hidden" name="tmpHash" value="{$tmpHash}" />
+                               <div class="row">
+                                       <div class="col-md-6">
+                                               <div id="uploadIconFileButton"></div>
+                                               {if $errorField == 'imageUpload'}
+                                                       <small class="innerError">
+                                                               {if $errorType == 'empty'}
+                                                                       {lang}wcf.global.form.error.empty{/lang}
+                                                               {/if}
+                                                       </small>
+                                               {/if}
+                                               <small>{lang}wcf.acp.trophy.type.imageUpload.description{/lang}</small>
+                                       </div>
+                                       <div class="col-md-6">
+                                               <div id="uploadIconFileContent">{if $action == 'add'}{if !$uploadedImageURL|empty}<img src="{$uploadedImageURL}">{/if}{else}{if $trophy->type == 2}<img src="{$__wcf->getPath()}images/trophy/{$trophy->iconFile}">{/if}{/if}</div>
+                                       </div>
+                               </div>
+
+                               <script data-relocate="true">
+                                       require(['WoltLabSuite/Core/Acp/Ui/Trophy/Upload'], function(IconUpload) {
+                                               new IconUpload({if $action == 'add'}0{else}{$trophy->trophyID}{/if}, '{$tmpHash}', {
+                                                       input: 'uploadIconFile'
+                                               });
+                                       });
+                               </script>
+                       </dd>
+               </dl>
        </section>
        
        <section id="badgeContainer" class="section"{if $type == 1} style="display: none;"{/if}>
diff --git a/wcfsetup/install/files/acp/templates/trophyImage.tpl b/wcfsetup/install/files/acp/templates/trophyImage.tpl
new file mode 100644 (file)
index 0000000..38bc00f
--- /dev/null
@@ -0,0 +1,7 @@
+<img
+       src="{@$__wcf->getPath()}images/trophy/{$trophy->iconFile}"
+       style="width:{$size}px;height:{$size}px"
+       title="{$trophy->getTitle()}"
+       class="jsTooltip trophyIcon"
+       data-trophy-id="{$trophy->getObjectID()}"
+/>
index 5f42ba77ab5257702846bf306a9c6547cb2a615d..876c35dddcf0cb6ab9ef1e0effe36466ffc7cb03 100644 (file)
                                <tr class="trophyRow">
                                        <td class="columnIcon">
                                                <span class="icon icon16 fa-{if !$trophy->isDisabled}check-{/if}square-o jsToggleButton jsTooltip pointer" title="{lang}wcf.global.button.{if !$trophy->isDisabled}disable{else}enable{/if}{/lang}" data-object-id="{@$trophy->getObjectID()}"></span>
-                                               <a href="{link controller='TrophyEdit' id=$trophy->getObjectID()}{/link}" data-tooltip="{lang}wcf.global.edit{/lang}"><span class="icon icon16 fa-pencil"></span></a>
-                                               <span class="icon icon16 fa-times pointer jsDeleteButton" data-confirm-message-html="{lang __encode=true}wcf.acp.trophy.delete.confirmMessage{/lang}" data-object-id="{@$trophy->getObjectID()}" data-tooltip="{lang}wcf.global.delete{/lang}"></span>
+                                               <a href="{link controller='TrophyEdit' id=$trophy->getObjectID()}{/link}" title="{lang}wcf.global.button.edit{/lang}" class="jsTooltip"><span class="icon icon16 fa-pencil"></span></a>
+                                               <span class="icon icon16 fa-times pointer jsDeleteButton jsTooltip" data-confirm-message-html="{lang __encode=true}wcf.acp.trophy.delete.confirmMessage{/lang}" data-object-id="{@$trophy->getObjectID()}" title="{lang}wcf.global.button.delete{/lang}"></span>
                                        </td>
                                        <td class="columnID columnTrophyID">{@$trophy->trophyID}</td>
                                        <td class="columnIcon">{@$trophy->renderTrophy(32)}</td>
-                                       <td class="columnTitle columnTrophyTitle"><a href="{link controller='TrophyEdit' id=$trophy->getObjectID()}{/link}" data-tooltip="{lang}wcf.global.edit{/lang}">{$trophy->getTitle()}</a></td>
+                                       <td class="columnTitle columnTrophyTitle"><a href="{link controller='TrophyEdit' id=$trophy->getObjectID()}{/link}" title="{lang}wcf.global.button.edit{/lang}">{$trophy->getTitle()}</a></td>
                                        <td class="columnText columnCategory">{$trophy->getCategory()->getTitle()}</td>
                                        
                                        {event name='columns'}
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Trophy/Upload.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Trophy/Upload.js
new file mode 100644 (file)
index 0000000..020f22b
--- /dev/null
@@ -0,0 +1,78 @@
+/**
+ * Handles the trophy image upload.
+ *
+ * @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/Upload
+ */
+define(['Core', 'Dom/Traverse', 'Language', 'Upload', 'Ui/Notification'], function(Core, DomTraverse, Language, Upload, UINotification) {
+       "use strict";
+       
+       /**
+        * @constructor
+        */
+       function TrophyUpload(trophyID, tmpHash, options) {
+               options = options || {};
+               
+               this._trophyID = ~~trophyID;
+               this._tmpHash = tmpHash;
+               
+               if (options.input === undefined) {
+                       throw new TypeError("invalid input given");
+               }
+               
+               Upload.call(this, 'uploadIconFileButton', 'uploadIconFileContent', Core.extend({
+                       className: 'wcf\\data\\trophy\\TrophyAction'
+               }, options));
+       }
+       
+       Core.inherit(TrophyUpload, Upload, {
+               /**
+                * @see WoltLabSuite/Core/Upload#_getParameters
+                */
+               _getParameters: function() {
+                       return {
+                               trophyID: this._trophyID,
+                               tmpHash: this._tmpHash
+                       };
+               },
+               
+               /**
+                * @see WoltLabSuite/Core/Upload#_success
+                */
+               _success: function(uploadId, data) {
+                       var error = DomTraverse.childByClass(this._button.parentNode, 'innerError');
+                       
+                       this._target.innerHTML = "<img src=\"" + data.returnValues.url + "?timestamp=" + Date.now() + "\" />";
+                       
+                       if (error) {
+                               elRemove(error);
+                       }
+                       
+                       UINotification.show();
+               },
+               
+               /**
+                * @see WoltLabSuite/Core/Upload#_failure
+                */
+               _failure: function(uploadId, data, responseText, xhr, requestOptions) {
+                       var error = DomTraverse.childByClass(this._button.parentNode, 'innerError');
+                       if (!error) {
+                               error = elCreate('small');
+                               error.className = 'innerError';
+                               
+                               this._button.parentNode.appendChild(error);
+                       }
+                       
+                       error.textContent = Language.get('wcf.acp.trophy.imageUpload.error.' + data.returnValues.errorType);
+                       
+                       // remove previous images 
+                       this._target.innerHTML = "";
+                       
+                       return false; 
+               }
+       });
+       
+       return TrophyUpload;
+});
\ No newline at end of file
index 621660086c4e0556ffce7960e5cc16402b1bb6e3..16f232bb54beb73bf5b3db50a2797d796ac8ad2b 100644 (file)
@@ -66,7 +66,7 @@ class TrophyAddForm extends AbstractAcpForm {
         * @var []
         */
        public $availableTypes = [
-               Trophy::TYPE_IMAGE => 'image',
+               Trophy::TYPE_IMAGE => 'imageUpload',
                Trophy::TYPE_BADGE => 'badge'
        ];
        
@@ -77,10 +77,16 @@ class TrophyAddForm extends AbstractAcpForm {
        public $type = Trophy::TYPE_BADGE;
        
        /**
-        * the location of the uploaded icon
+        * temporary hash for image icon
         * @var string
         */
-       public $uploadIconFile = '';
+       public $tmpHash = '';
+       
+       /**
+        * the url for the uploaded image
+        * @var string
+        */
+       public $uploadedImageURL = '';
        
        /**
         * the icon name for CSS icons (FA-Icon)
@@ -139,6 +145,14 @@ class TrophyAddForm extends AbstractAcpForm {
                $descriptionI18n = new I18nValue('description');
                $descriptionI18n->setLanguageItem('wcf.trophy.description', 'wcf.trophy', 'com.woltlab.wcf');
                $this->registerI18nValue($descriptionI18n);
+               
+               if (isset($_POST['tmpHash'])) {
+                       $this->tmpHash = StringUtil::trim($_POST['tmpHash']);
+               }
+               
+               if (empty($this->tmpHash)) {
+                       $this->tmpHash = StringUtil::getRandomID();
+               }
        }
        
        /**
@@ -150,11 +164,17 @@ class TrophyAddForm extends AbstractAcpForm {
                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']);
+               if (isset($_POST['awardAutomatically'])) $this->awardAutomatically = 1;
+               
+               // read file upload 
+               $fileExtension = WCF::getSession()->getVar('trophyImage-'.$this->tmpHash);
+               
+               if ($fileExtension !== null && file_exists(WCF_DIR.'images/trophy/tmp_'.$this->tmpHash.'.'.$fileExtension)) {
+                       $this->uploadedImageURL = WCF::getPath().'images/trophy/tmp_'.$this->tmpHash.'.'.$fileExtension;
+               }
                
                $this->category = TrophyCategoryCache::getInstance()->getCategoryByID($this->categoryID);
                
@@ -186,7 +206,15 @@ class TrophyAddForm extends AbstractAcpForm {
                
                switch ($this->type) {
                        case Trophy::TYPE_IMAGE:
-                               // @TODO
+                               $fileExtension = WCF::getSession()->getVar('trophyImage-'.$this->tmpHash);
+                               
+                               if ($fileExtension === null) {
+                                       throw new UserInputException('imageUpload');
+                               }
+                               
+                               if (!file_exists(WCF_DIR.'images/trophy/tmp_'.$this->tmpHash.'.'.$fileExtension)) {
+                                       throw new UserInputException('imageUpload');
+                               }
                                break;
                        
                        case Trophy::TYPE_BADGE:
@@ -229,9 +257,7 @@ class TrophyAddForm extends AbstractAcpForm {
                parent::save();
                
                $data = [];
-               if ($this->type == Trophy::TYPE_IMAGE) {
-                       // @ TODO 
-               } else if ($this->type == Trophy::TYPE_BADGE) {
+               if ($this->type == Trophy::TYPE_BADGE) {
                        $data['iconName'] = $this->iconName;
                        $data['iconColor'] = $this->iconColor;
                        $data['badgeColor'] = $this->badgeColor;
@@ -244,7 +270,8 @@ class TrophyAddForm extends AbstractAcpForm {
                                'categoryID' => $this->categoryID,
                                'type' => $this->type,
                                'isDisabled' => $this->isDisabled
-                       ])
+                       ]),
+                       'tmpHash' => $this->tmpHash
                ]);
                $this->objectAction->executeAction();
                
@@ -267,10 +294,11 @@ class TrophyAddForm extends AbstractAcpForm {
                
                $this->isDisabled = $this->awardAutomatically = $this->categoryID = 0;
                $this->type = Trophy::TYPE_BADGE;
-               $this->uploadIconFile = $this->iconName = '';
+               $this->iconName = $this->uploadedImageURL = '';
                $this->iconColor = 'rgba(255, 255, 255, 1)';
                $this->badgeColor = 'rgba(50, 92, 132, 1)';
                $this->iconName = 'trophy';
+               $this->tmpHash = StringUtil::getRandomID();
                
                foreach ($this->conditions as $conditions) {
                        foreach ($conditions as $condition) {
@@ -288,7 +316,6 @@ class TrophyAddForm extends AbstractAcpForm {
                WCF::getTPL()->assign([
                        'categoryID' => $this->categoryID,
                        'type' => $this->type,
-                       'iconFile' => $this->uploadIconFile,
                        'isDisabled' => $this->isDisabled,
                        'iconName' => $this->iconName,
                        'iconColor' => $this->iconColor,
@@ -296,7 +323,9 @@ class TrophyAddForm extends AbstractAcpForm {
                        'trophyCategories' => TrophyCategoryCache::getInstance()->getCategories(),
                        'groupedObjectTypes' => $this->conditions, 
                        'awardAutomatically' => $this->awardAutomatically,
-                       'availableTypes' => $this->availableTypes
+                       'availableTypes' => $this->availableTypes, 
+                       'tmpHash' => $this->tmpHash,
+                       'uploadedImageURL' => $this->uploadedImageURL
                ]);
        }
 }
index 6cb0086d098782224db69da92d96e4655e6171b0..0b97ab10e983ee7a262e45054d528af6149ad5af 100644 (file)
@@ -75,7 +75,10 @@ class Trophy extends DatabaseObject implements ITitledLinkObject, IRouteControll
        public function renderTrophy($size = self::DEFAULT_SIZE) {
                switch ($this->type) {
                        case self::TYPE_IMAGE: {
-                               // @TODO
+                               return WCF::getTPL()->fetch('trophyImage', 'wcf', [
+                                       'size' => $size,
+                                       'trophy' => $this
+                               ], true);
                                break;
                        }
                        
@@ -98,7 +101,6 @@ class Trophy extends DatabaseObject implements ITitledLinkObject, IRouteControll
                                        return $parameters['renderedTemplate']; 
                                }
                                
-                               // no one has rendered the trophy ; throw an exception
                                throw new \LogicException("Unable to render the trophy with the type '". $this->type ."'.");
                        break; 
                }
index 9c6462a6b323d51e499ea6218dd6c61ee269aef5..3531ce4534854e53342dacc2bc1c4a1ec4f49a50 100644 (file)
@@ -2,7 +2,12 @@
 namespace wcf\data\trophy;
 use wcf\data\AbstractDatabaseObjectAction;
 use wcf\data\IToggleAction;
+use wcf\data\IUploadAction;
+use wcf\system\exception\IllegalLinkException;
 use wcf\system\exception\UserInputException;
+use wcf\system\image\ImageHandler;
+use wcf\system\upload\TrophyImageUploadFileValidationStrategy;
+use wcf\system\upload\UploadFile;
 use wcf\system\WCF;
 
 /**
@@ -14,7 +19,7 @@ use wcf\system\WCF;
  * @package    WoltLabSuite\Core\Data\Trophy
  * @since      3.1
  */
-class TrophyAction extends AbstractDatabaseObjectAction implements IToggleAction {
+class TrophyAction extends AbstractDatabaseObjectAction implements IToggleAction, IUploadAction {
        /**
         * @inheritDoc
         */
@@ -25,6 +30,34 @@ class TrophyAction extends AbstractDatabaseObjectAction implements IToggleAction
         */
        protected $requireACP = ['toggle', 'delete'];
        
+       /**
+        * @inheritDoc
+        */
+       public function create() {
+               $trophy = parent::create();
+               
+               if (isset($this->parameters['tmpHash']) && $this->parameters['data']['type'] === Trophy::TYPE_IMAGE) {
+                       $this->updateTrophyImage($trophy);
+               }
+               
+               return $trophy;
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function update() {
+               parent::update();
+               
+               if (isset($this->parameters['data']['type']) && $this->parameters['data']['type'] === Trophy::TYPE_IMAGE) {
+                       foreach ($this->getObjects() as $trophy) {
+                               if (isset($this->parameters['tmpHash'])) {
+                                       $this->updateTrophyImage($trophy);
+                               }
+                       }
+               }
+       }
+       
        /**
         * @inheritDoc
         */
@@ -50,4 +83,106 @@ class TrophyAction extends AbstractDatabaseObjectAction implements IToggleAction
                        }
                }
        }
+       
+       /**
+        * @inheritDoc
+        */
+       public function validateUpload() {
+               WCF::getSession()->checkPermissions(['admin.trophy.canManageTrophy']);
+               
+               $this->readString('tmpHash');
+               $this->readInteger('trophyID', true);
+               
+               if ($this->parameters['trophyID']) {
+                       $this->parameters['trophy'] = new Trophy($this->parameters['trophyID']);
+                       
+                       if (!$this->parameters['trophy']->trophyID) {
+                               throw new IllegalLinkException(); 
+                       }
+               }
+               
+               $this->parameters['__files']->validateFiles(new TrophyImageUploadFileValidationStrategy());
+               
+               /** @var UploadFile[] $files */
+               $files = $this->parameters['__files']->getFiles();
+               
+               // only one file is allowed
+               if (count($files) !== 1) {
+                       throw new UserInputException('file');
+               }
+               
+               $this->parameters['file'] = reset($files);
+               
+               if ($this->parameters['file']->getValidationErrorType()) {
+                       throw new UserInputException('file', $this->parameters['file']->getValidationErrorType());
+               }
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function upload() {
+               $fileName = WCF_DIR.'images/trophy/tmp_'.$this->parameters['tmpHash'].'.'.$this->parameters['file']->getFileExtension(); 
+               if ($this->parameters['file']->getImageData()['height'] > 128) {
+                       $adapter = ImageHandler::getInstance()->getAdapter();
+                       $adapter->loadFile($this->parameters['file']->getLocation());
+                       $adapter->resize(0, 0, $this->parameters['file']->getImageData()['height'], $this->parameters['file']->getImageData()['height'], 128, 128);
+                       $adapter->writeImage($adapter->getImage(), $fileName);
+               } 
+               else {
+                       copy($this->parameters['file']->getLocation(), $fileName);
+               }
+               
+               // remove old image
+               @unlink($this->parameters['file']->getLocation());
+               
+               // store extension within session variables
+               WCF::getSession()->register('trophyImage-'.$this->parameters['tmpHash'], $this->parameters['file']->getFileExtension());
+               
+               if ($this->parameters['trophyID']) {
+                       $this->updateTrophyImage($this->parameters['trophy']);
+                       
+                       return [
+                               'url' => WCF::getPath().'images/trophy/trophyImage-'.$this->parameters['trophyID'].'.'.$this->parameters['file']->getFileExtension()
+                       ];
+               }
+               
+               return [
+                       'url' => WCF::getPath() . 'images/trophy/'. basename($fileName)
+               ];
+       }
+       
+       /**
+        * Updates style preview image.
+        *
+        * @param       Trophy          $trophy
+        */
+       protected function updateTrophyImage(Trophy $trophy) {
+               if (!isset($this->parameters['tmpHash'])) {
+                       return;
+               }
+               
+               $fileExtension = WCF::getSession()->getVar('trophyImage-'.$this->parameters['tmpHash']);
+               if ($fileExtension !== null) {
+                       $oldFilename = WCF_DIR.'images/trophy/tmp_'.$this->parameters['tmpHash'].'.'.$fileExtension;
+                       if (file_exists($oldFilename)) {
+                               $filename = 'trophyImage-'.$trophy->trophyID.'.'.$fileExtension;
+                               if (@rename($oldFilename, WCF_DIR.'images/trophy/'.$filename)) {
+                                       // delete old file if it has a different file extension
+                                       if ($trophy->iconFile != $filename) {
+                                               @unlink(WCF_DIR.'images/trophy/'.$trophy->iconFile);
+                                               
+                                               $trophyEditor = new TrophyEditor($trophy);
+                                               $trophyEditor->update([
+                                                       'iconFile' => $filename
+                                               ]);
+                                       }
+                               }
+                               else {
+                                       // remove temp file
+                                       @unlink($oldFilename);
+                               }
+                       }
+               }
+       }
 }
diff --git a/wcfsetup/install/files/lib/system/upload/TrophyImageUploadFileValidationStrategy.class.php b/wcfsetup/install/files/lib/system/upload/TrophyImageUploadFileValidationStrategy.class.php
new file mode 100644 (file)
index 0000000..fcd390a
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+namespace wcf\system\upload;
+use wcf\util\ImageUtil;
+
+/**
+ * Upload file validation strategy implementation for trophy images.
+ *
+ * @author     Joshua Ruesweg
+ * @copyright  2001-2017 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Upload
+ * @since      3.1
+ */
+class TrophyImageUploadFileValidationStrategy implements IUploadFileValidationStrategy {
+       /**
+        * minimum trophy image width and height
+        * @var integer
+        */
+       const MIN_TROPHY_IMAGE_SIZE = 64;
+       
+       /**
+        * @inheritDoc
+        */
+       public function validate(UploadFile $uploadFile) {
+               if ($uploadFile->getErrorCode()) {
+                       $uploadFile->setValidationErrorType('uploadFailed');
+                       return false;
+               }
+               
+               if ($uploadFile->getImageData() === null) {
+                       $uploadFile->setValidationErrorType('noImage');
+                       return false;
+               }
+               
+               if ($uploadFile->getImageData()['width'] != $uploadFile->getImageData()['height']) {
+                       $uploadFile->setValidationErrorType('notSquared');
+                       return false;
+               }
+               
+               if ($uploadFile->getImageData()['width'] < self::MIN_TROPHY_IMAGE_SIZE) {
+                       $uploadFile->setValidationErrorType('tooSmall');
+                       return false; 
+               }
+               
+               if (!ImageUtil::checkImageContent($uploadFile->getLocation())) {
+                       $uploadFile->setValidationErrorType('noImage');
+                       return false; 
+               }
+               
+               return true;
+       }
+}
index da181be35330ebf727fa8a825c324139baaa7013..8ec3ee54aa11c6ef56594b964b559f53931471f6 100644 (file)
@@ -3585,7 +3585,11 @@ Die E-Mail-Adresse des neuen Benutzers lautet: {@$user->email}
                <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.type.imageUpload"><![CDATA[Bild-Datei]]></item>
+               <item name="wcf.acp.trophy.type.imageUpload.description"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Lade{else}Laden Sie{/if} hier ein quadratisches Bild mit mindestens 64×64 Pixel hoch.]]></item>
+               <item name="wcf.acp.trophy.imageUpload.error.notSquared"><![CDATA[Das Bild ist nicht quadratisch.]]></item>
+               <item name="wcf.acp.trophy.imageUpload.error.tooSmall"><![CDATA[Das Bild muss mindestens 64×64 Pixel groß sein.]]></item>
+               <item name="wcf.acp.trophy.imageUpload.error.noImage"><![CDATA[Die hochgeladene Datei ist kein Bild.]]></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>
@@ -3593,7 +3597,7 @@ Die E-Mail-Adresse des neuen Benutzers lautet: {@$user->email}
                <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>
+               <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>
        
        <category name="wcf.user.usersOnline">
index 1b68213b5ccfbfc0dfde5f2dc0c10832ae8ccf03..fdf3d6bde6ca16cbb5dab43dd05276df14980305 100644 (file)
@@ -3572,7 +3572,11 @@ Open the link below to access the user profile:
                <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.type.imageUpload"><![CDATA[Image]]></item>
+               <item name="wcf.acp.trophy.type.imageUpload.description"><![CDATA[Upload a square image with at least 64×64 pixels.]]></item>
+               <item name="wcf.acp.trophy.imageUpload.error.notSquared"><![CDATA[The image isn't square.]]></item>
+               <item name="wcf.acp.trophy.imageUpload.error.tooSmall"><![CDATA[The image must be at least 64×64 pixels.]]></item>
+               <item name="wcf.acp.trophy.imageUpload.error.noImage"><![CDATA[The uploaded file isn't a 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>