Add user trophy dialog (WIP)
authorJoshua Rüsweg <josh@bastelstu.be>
Tue, 25 Jul 2017 20:22:08 +0000 (22:22 +0200)
committerJoshua Rüsweg <josh@bastelstu.be>
Tue, 25 Jul 2017 20:22:33 +0000 (22:22 +0200)
See #2315

com.woltlab.wcf/templates/groupedUserTrophyList.tpl [new file with mode: 0644]
com.woltlab.wcf/templates/headIncludeJavaScript.tpl
com.woltlab.wcf/templates/userInformationStatistics.tpl
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/User/Trophy/List.js [new file with mode: 0644]
wcfsetup/install/files/lib/data/user/trophy/UserTrophyAction.class.php
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

diff --git a/com.woltlab.wcf/templates/groupedUserTrophyList.tpl b/com.woltlab.wcf/templates/groupedUserTrophyList.tpl
new file mode 100644 (file)
index 0000000..944c01e
--- /dev/null
@@ -0,0 +1,20 @@
+{if $userTrophyList|count}
+       <ol class="containerList jsUserTrophyList">
+               {foreach from=$userTrophyList item=userTrophy}
+                       <li data-object-id="{@$userTrophy->userTrophyID}">
+                               <div class="box48">
+                                       <div><a href="{link controller='Trophy' object=$userTrophy->getTrophy()}{/link}">{@$userTrophy->getTrophy()->renderTrophy(48)}</a></div>
+
+                                       <div class="containerHeadline">
+                                               <h3><a href="{link controller='Trophy' object=$userTrophy->getTrophy()}{/link}">{@$userTrophy->getTrophy()->getTitle()}</a></h3>
+                                               <small>{@$userTrophy->getDescription()} - {@$userTrophy->time|time}</small>
+                                       </div>
+                               </div>
+                       </li>
+               {/foreach}
+       </ol>
+
+       <div class="paginationBottom jsPagination"></div>
+{else}
+       <p>{lang}wcf.user.trophy.noTrophies{/lang}</p>
+{/if}
index bf76e257ed272fddbc3d170b1d6243ed9121f766..fba84fd2943d247222e24d43bcf7401ddf4d1ace 100644 (file)
@@ -184,6 +184,12 @@ requirejs.config({
                WCF.System.PageNavigation.init('.pagination');
                WCF.User.Profile.ActivityPointList.init();
                
+               {if MODULE_TROPHY && $__wcf->session->getPermission('user.profile.trophy.canSeeTrophies')}
+                       require(['WoltLabSuite/Core/Ui/User/Trophy/List'], function (UserTrophyList) {
+                               new UserTrophyList();
+                       });
+               {/if}
+               
                {event name='javascriptInit'}
                
                {if $executeCronjobs}
index 624ccb57f688c14add760fd323fbe3c336e97cd9..5fca2dadf08035e0481e13ea5ea68d24a81c7b1b 100644 (file)
@@ -9,3 +9,8 @@
        <dt><a href="#" class="activityPointsDisplay jsTooltip" title="{lang}wcf.user.activityPoint.showActivityPoints{/lang}" data-user-id="{@$user->userID}">{lang}wcf.user.activityPoint{/lang}</a></dt>
        <dd>{#$user->activityPoints}</dd>
 {/if}
+
+{if MODULE_TROPHY && $__wcf->session->getPermission('user.profile.trophy.canSeeTrophies') && ($user->isAccessible('canViewTrophies') || $user->userID == $__wcf->session->userID)}
+       <dt><a href="#" class="trophyPoints jsTooltip userTrophyOverlayList" data-user-id="{$user->userID}" data-username="" title="{lang}wcf.user.trophy.showTrophies{/lang}">{lang}wcf.user.trophy.trophyPoints{/lang}</a></dt>
+       <dd>{#$user->trophyPoints}</dd>
+{/if}
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/User/Trophy/List.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/User/Trophy/List.js
new file mode 100644 (file)
index 0000000..c521c7a
--- /dev/null
@@ -0,0 +1,121 @@
+/**
+ * Handles the user trophy dialog.
+ *
+ * @author     Joshua Ruesweg
+ * @copyright  2001-2017 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module     WoltLabSuite/Core/Ui/User/Trophy/List
+ */
+define(['Ajax', 'Core', 'Dictionary', 'Dom/Util', 'Ui/Dialog', 'WoltLabSuite/Core/Ui/Pagination'], function(Ajax, Core, Dictionary, DomUtil, UiDialog, UiPagination) {
+       "use strict";
+       
+       /**
+        * @constructor
+        */
+       function UiUserTrophyList() { this.init(); }
+       UiUserTrophyList.prototype = {
+               /**
+                * Initializes the user trophy list.
+                *
+                * @param       {object}        options         list of initialization options
+                */
+               init: function() {
+                       this._cache = new Dictionary();
+                       
+                       this._options = {
+                               className: 'wcf\\data\\user\\trophy\\UserTrophyAction',
+                               parameters: {}
+                       };
+                       
+                       elBySelAll('.userTrophyOverlayList', undefined, (function (element) {
+                               element.addEventListener(WCF_CLICK_EVENT, this._open.bind(this, elData(element, 'user-id')));
+                       }).bind(this));
+               },
+               
+               /**
+                * Opens the user trophy list for a specific user.
+                */
+               _open: function(userID) {
+                       this._currentPageNo = 1; 
+                       this._currentUser = userID;
+                       this._showPage();
+               },
+               
+               /**
+                * Shows the current or given page.
+                *
+                * @param       {int=}          pageNo          page number
+                */
+               _showPage: function(pageNo) {
+                       if (pageNo !== undefined) {
+                               this._currentPageNo = pageNo;
+                       }
+                       
+                       if (this._cache.has(this._currentUser)) {
+                               // validate pageNo
+                               if (this._cache.get(this._currentUser).get('pageCount') !== 0 && (this._currentPageNo < 1 || this._currentPageNo > this._cache.get(this._currentUser).get('pageCount'))) {
+                                       throw new RangeError("pageNo must be between 1 and " + this._cache.get(this._currentUser).get('pageCount') + " (" + this._currentPageNo + " given).");
+                               }
+                       }
+                       else {
+                               // init user page cache
+                               this._cache.set(this._currentUser, new Dictionary());
+                       }
+                       
+                       if (this._cache.get(this._currentUser).has(this._currentPageNo)) {
+                               var dialog = UiDialog.open(this, this._cache.get(this._currentUser).get(this._currentPageNo));
+                               UiDialog.setTitle('userTrophyListOverlay', this._cache.get(this._currentUser).get('title'));
+                               
+                               if (this._cache.get(this._currentUser).get('pageCount') > 1) {
+                                       var element = elBySel('.jsPagination', dialog.content);
+                                       if (element !== null) {
+                                               new UiPagination(element, {
+                                                       activePage: this._currentPageNo,
+                                                       maxPage: this._cache.get(this._currentUser).get('pageCount'),
+                                                       callbackSwitch: this._showPage.bind(this)
+                                               });
+                                       }
+                               }
+                       }
+                       else {
+                               this._options.parameters.pageNo = this._currentPageNo;
+                               this._options.parameters.userID = this._currentUser;
+                               
+                               Ajax.api(this, {
+                                       parameters: this._options.parameters
+                               });
+                       }
+               },
+               
+               _ajaxSuccess: function(data) {
+                       if (data.returnValues.pageCount !== undefined) {
+                               this._cache.get(this._currentUser).set('pageCount', ~~data.returnValues.pageCount);
+                       }
+                       
+                       this._cache.get(this._currentUser).set(this._currentPageNo, data.returnValues.template);
+                       this._cache.get(this._currentUser).set('title', data.returnValues.title);
+                       this._showPage();
+               },
+               
+               _ajaxSetup: function() {
+                       return {
+                               data: {
+                                       actionName: 'getGroupedUserTrophyList',
+                                       className: this._options.className
+                               }
+                       };
+               },
+               
+               _dialogSetup: function() {
+                       return {
+                               id: 'userTrophyListOverlay',
+                               options: {
+                                       title: ""
+                               },
+                               source: null
+                       };
+               }
+       };
+       
+       return UiUserTrophyList;
+});
index a10888ac33204caf7b3a91f74e2d6fa424761362..28f7db6c81097dd62faff8e125a62234d3042bed 100644 (file)
@@ -2,9 +2,12 @@
 namespace wcf\data\user\trophy;
 use wcf\data\user\UserAction;
 use wcf\data\AbstractDatabaseObjectAction;
+use wcf\system\cache\runtime\UserProfileRuntimeCache;
+use wcf\system\exception\IllegalLinkException;
 use wcf\system\exception\PermissionDeniedException;
 use wcf\system\user\notification\object\UserTrophyNotificationObject;
 use wcf\system\user\notification\UserNotificationHandler;
+use wcf\system\WCF;
 
 /**
  * Provides user trophy actions. 
@@ -21,6 +24,11 @@ class UserTrophyAction extends AbstractDatabaseObjectAction {
         */
        protected $permissionsDelete = ['admin.trophy.canAwardTrophy'];
        
+       /**
+        * @inheritDoc
+        */
+       protected $allowGuestAccess = ['getGroupedUserTrophyList'];
+       
        /**
         * @inheritDoc
         */
@@ -78,4 +86,55 @@ class UserTrophyAction extends AbstractDatabaseObjectAction {
                
                return $returnValues;
        }
+       
+       /**
+        * Validates the getGroupedUserTrophyList method. 
+        */
+       public function validateGetGroupedUserTrophyList() {
+               if (!MODULE_TROPHY) {
+                       throw new IllegalLinkException();
+               }
+               
+               WCF::getSession()->checkPermissions(['user.profile.trophy.canSeeTrophies']);
+               
+               $this->readInteger('pageNo');
+               $this->readInteger('userID');
+               
+               $this->userProfile = UserProfileRuntimeCache::getInstance()->getObject($this->parameters['userID']);
+               if (!$this->userProfile->isAccessible('canViewTrophies') && !($this->userProfile->userID == WCF::getSession()->userID)) {
+                       throw new PermissionDeniedException();
+               }
+       }
+       
+       /**
+        * Returns a viewable user trophy list for a specific user. 
+        */
+       public function getGroupedUserTrophyList() {
+               $userTrophyList = new UserTrophyList();
+               $userTrophyList->getConditionBuilder()->add('userID = ?', [$this->parameters['userID']]);
+               if (!empty($userTrophyList->sqlJoins)) $userTrophyList->sqlJoins .= ' ';
+               if (!empty($userTrophyList->sqlConditionJoins)) $userTrophyList->sqlConditionJoins .= ' ';
+               $userTrophyList->sqlJoins .= 'LEFT JOIN wcf'. WCF_N . '_trophy trophy ON user_trophy.trophyID = trophy.trophyID';
+               $userTrophyList->sqlConditionJoins .= 'LEFT JOIN wcf'. WCF_N . '_trophy trophy ON user_trophy.trophyID = trophy.trophyID';
+               
+               // trophy category join
+               $userTrophyList->sqlJoins .= ' LEFT JOIN wcf'. WCF_N . '_category category ON trophy.categoryID = category.categoryID';
+               $userTrophyList->sqlConditionJoins .= ' LEFT JOIN wcf'. WCF_N . '_category category ON trophy.categoryID = category.categoryID';
+               
+               $userTrophyList->getConditionBuilder()->add('trophy.isDisabled = ?', [0]);
+               $userTrophyList->getConditionBuilder()->add('category.isDisabled = ?', [0]);
+               $userTrophyList->sqlLimit = 10; 
+               $userTrophyList->sqlOffset = ($this->parameters['pageNo'] - 1) * 10;
+               $userTrophyList->sqlOrderBy = 'time DESC';
+               $pageCount = ceil($userTrophyList->countObjects() / 10);
+               $userTrophyList->readObjects();
+               
+               return [
+                       'pageCount' => $pageCount,
+                       'title' => WCF::getLanguage()->getDynamicVariable('wcf.user.trophy.dialogTitle', ['username' => $this->userProfile->username]),
+                       'template' => WCF::getTPL()->fetch('groupedUserTrophyList', 'wcf', [
+                               'userTrophyList' => $userTrophyList
+                       ])
+               ];
+       }
 }
index 9ec6b58b50e287bf2b770336195d14f789430397..a89327bd4f5186552001c0bb5ef738cb18290244 100644 (file)
@@ -3658,6 +3658,13 @@ Die E-Mail-Adresse des neuen Benutzers lautet: {@$user->email}
 <p><small><em>Quelle: <a href="http://www.mustervorlage.net/disclaimer-muster" class="externalURL">Mustervorlage.net</a></em></small></p>]]></item>
        </category>
        
+       <category name="wcf.user.trophy">
+               <item name="wcf.user.trophy.trophyPoints"><![CDATA[Trophäen]]></item>
+               <item name="wcf.user.trophy.showTrophies"><![CDATA[Trophäen von {$user->username} anzeigen]]></item>
+               <item name="wcf.user.trophy.noTrophies"><![CDATA[Der Benutzer hat noch keine Trophäen]]></item>
+               <item name="wcf.user.trophy.dialogTitle"><![CDATA[Trophäen von {$username}]]></item>
+       </category>
+       
        <category name="wcf.acp.trophy">
                <item name="wcf.acp.trophy"><![CDATA[Trophäe]]></item>
                <item name="wcf.acp.trophy.description"><![CDATA[Beschreibung]]></item>
index fe1bdbdd351f137c691436a288ea1845d7e1b03f..d076dd5a6c68dc75b9d26b8afd25e992486060ad 100644 (file)
@@ -3649,6 +3649,13 @@ Open the link below to access the user profile:
 <p><small><em>Source: <a href="http://www.mustervorlage.net/disclaimer-muster" class="externalURL">Mustervorlage.net</a></em></small></p>]]></item>
        </category>
        
+       <category name="wcf.user.trophy">
+               <item name="wcf.user.trophy.trophyPoints"><![CDATA[Trophies]]></item>
+               <item name="wcf.user.trophy.showTrophies"><![CDATA[Display Trophies of {$user->username}]]></item>
+               <item name="wcf.user.trophy.noTrophies"><![CDATA[The user has no trophies]]></item>
+               <item name="wcf.user.trophy.dialogTitle"><![CDATA[Trophies of {$username}]]></item>
+       </category>
+       
        <category name="wcf.acp.trophy">
                <item name="wcf.acp.trophy"><![CDATA[Trophy]]></item>
                <item name="wcf.acp.trophy.description"><![CDATA[Description]]></item>