Add trophy page
authorJoshua Rüsweg <josh@bastelstu.be>
Sun, 23 Jul 2017 19:02:19 +0000 (21:02 +0200)
committerJoshua Rüsweg <josh@bastelstu.be>
Sun, 23 Jul 2017 19:02:43 +0000 (21:02 +0200)
See #2315

com.woltlab.wcf/page.xml
com.woltlab.wcf/templates/trophy.tpl [new file with mode: 0644]
wcfsetup/install/files/lib/page/TrophyListPage.class.php
wcfsetup/install/files/lib/page/TrophyPage.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/page/handler/TrophyListPageHandler.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/page/handler/TrophyPageHandler.class.php [new file with mode: 0644]
wcfsetup/install/files/style/ui/trophy.scss

index 42540f272b7843f13b649b9e64945ea7b8be3e62..dc21e67eb384af7439475fa557d220adba95ddc0 100644 (file)
                <page identifier="com.woltlab.wcf.TrophyList">
                        <pageType>system</pageType>
                        <controller>wcf\page\TrophyListPage</controller>
+                       <handler>wcf\system\page\handler\TrophyListPageHandler</handler>
                        <name language="de">Trophäen</name>
                        <name language="en">Trophies</name>
                        <parent>com.woltlab.wcf.MembersList</parent>
+                       <requireObjectID>1</requireObjectID>
+                       <permissions>user.profile.trophy.canSeeTrophies</permissions>
+                       <options>module_trophy</options>
+                       <allowSpidersToIndex>1</allowSpidersToIndex>
+               </page>
+               <page identifier="com.woltlab.wcf.Trophy">
+                       <pageType>system</pageType>
+                       <controller>wcf\page\TrophyPage</controller>
+                       <handler>wcf\system\page\handler\TrophyPageHandler</handler>
+                       <name language="de">Trophäe</name>
+                       <name language="en">Trophy</name>
+                       <parent>com.woltlab.wcf.TrophyList</parent>
+                       <hasFixedParent>1</hasFixedParent>
+                       <requireObjectID>1</requireObjectID>
                        <permissions>user.profile.trophy.canSeeTrophies</permissions>
                        <options>module_trophy</options>
                        <allowSpidersToIndex>1</allowSpidersToIndex>
diff --git a/com.woltlab.wcf/templates/trophy.tpl b/com.woltlab.wcf/templates/trophy.tpl
new file mode 100644 (file)
index 0000000..0005360
--- /dev/null
@@ -0,0 +1,71 @@
+{capture assign='pageTitle'}{$trophy->getTitle()}{if $pageNo > 1} - {lang}wcf.page.pageNo{/lang}{/if}{/capture}
+
+{capture assign='headContent'}
+       {if $pageNo < $pages}
+               <link rel="next" href="{link controller='Trophy' object=$trophy}pageNo={@$pageNo+1}{/link}">
+       {/if}
+       {if $pageNo > 1}
+               <link rel="prev" href="{link controller='Trophy' object=$trophy}{if $pageNo > 2}pageNo={@$pageNo-1}{/if}{/link}">
+       {/if}
+{/capture}
+
+{capture assign='contentHeader'}
+       <header class="contentHeader messageGroupContentHeader">
+               <div class="contentHeaderIcon">
+                       {@$trophy->renderTrophy(64)}
+               </div>
+
+               <div class="contentHeaderTitle">
+                       <h1 class="contentTitle">{$trophy->getTitle()}</h1>
+                       <ul class="inlineList contentHeaderMetaData">
+                               <li>{@$trophy->getDescription()}</li>
+                               <li><span class="icon icon16 fa-users"></span> {@$items}</li>
+                       </ul>
+               </div>
+       </header>
+{/capture}
+
+{include file='header'}
+
+{hascontent}
+       <div class="paginationTop">
+               {content}
+                       {pages print=true assign='pagesLinks' controller='Trophy' object=$trophy link="pageNo=%d"}
+               {/content}
+       </div>
+{/hascontent}
+
+{if $objects|count}
+       <ol class="section containerBoxList trophyCategoryList tripleColumned">
+               {foreach from=$objects item=userTrophy}
+                       <li class="box64">
+                               <div>{@$userTrophy->getUserProfile()->getAvatar()->getImageTag(64)}</div>
+
+                               <div class="sidebarItemTitle">
+                                       <h3>{@$userTrophy->getUserProfile()->getAnchorTag()}</h3>
+                                       <small>{@$userTrophy->getDescription()} - {@$userTrophy->time|time}</small>
+                               </div>
+                       </li>
+               {/foreach}
+       </ol>
+{else}
+       <p class="info">{lang}wcf.global.noItems{/lang}</p>
+{/if}
+
+<footer class="contentFooter">
+       {hascontent}
+               <div class="paginationBottom">
+                       {content}{@$pagesLinks}{/content}
+               </div>
+       {/hascontent}
+
+       {hascontent}
+               <nav class="contentFooterNavigation">
+                       <ul>
+                               {content}{event name='contentFooterNavigation'}{/content}
+                       </ul>
+               </nav>
+       {/hascontent}
+</footer>
+
+{include file='footer'}
\ No newline at end of file
index a60d379de197e28a31e2d5009fafbe150e31b459..c097febf2278ead786784cbce9a6d27d4b3753c0 100644 (file)
@@ -70,19 +70,6 @@ class TrophyListPage extends MultipleLinkPage {
                
                if (isset($_REQUEST['id'])) $this->categoryID = intval($_REQUEST['id']);
                
-               // read category id, if no categoryID is selected
-               if ($this->categoryID == 0) {
-                       $categories = TrophyCategoryCache::getInstance()->getEnabledCategories();
-                       
-                       if (count($categories)) {
-                               $category = reset($categories);
-                               $this->categoryID = $category->getObjectID();
-                       } 
-                       else {
-                               throw new IllegalLinkException(); 
-                       }
-               }
-               
                $this->category = TrophyCategoryCache::getInstance()->getCategoryByID($this->categoryID);
                
                if ($this->category === null) {
@@ -110,16 +97,14 @@ class TrophyListPage extends MultipleLinkPage {
        public function assignVariables() {
                parent::assignVariables();
                
-               if (!isset($_REQUEST['id'])) {
-                       WCF::getTPL()->assign([
-                               'canonicalURL' => $this->category->getLink()
-                       ]);
-               }
-               
                WCF::getTPL()->assign([
                        'category' => $this->category,
                        'categoryID' => $this->categoryID,
                        'categories' => TrophyCategoryCache::getInstance()->getEnabledCategories()
                ]);
+               
+               if (count($this->objectList) === 0) {
+                       @header('HTTP/1.0 404 Not Found');
+               }
        }
 }
diff --git a/wcfsetup/install/files/lib/page/TrophyPage.class.php b/wcfsetup/install/files/lib/page/TrophyPage.class.php
new file mode 100644 (file)
index 0000000..bacca17
--- /dev/null
@@ -0,0 +1,148 @@
+<?php
+namespace wcf\page;
+use wcf\data\trophy\Trophy;
+use wcf\data\trophy\TrophyCache;
+use wcf\data\user\trophy\UserTrophy;
+use wcf\data\user\trophy\UserTrophyList;
+use wcf\system\cache\builder\UserOptionCacheBuilder;
+use wcf\system\cache\runtime\UserProfileRuntimeCache;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
+use wcf\system\exception\IllegalLinkException;
+use wcf\system\exception\PermissionDeniedException;
+use wcf\system\page\PageLocationManager;
+use wcf\system\WCF;
+
+/**
+ * Represents a trophy page.
+ *
+ * @author     Joshua Ruesweg
+ * @copyright  2001-2017 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\Page
+ * @since      3.1
+ *
+ * @property   UserTrophyList          $objectList
+ */
+class TrophyPage extends MultipleLinkPage {
+       /**
+        * @inheritDoc
+        */
+       public $neededModules = ['MODULE_TROPHY'];
+       
+       /**
+        * @inheritDoc
+        */
+       public $neededPermissions = ['user.profile.trophy.canSeeTrophies'];
+       
+       /**
+        * @inheritDoc
+        */
+       public $itemsPerPage = 30;
+       
+       /**
+        * @inheritDoc
+        */
+       public $objectListClassName = UserTrophyList::class;
+       
+       /**
+        * @inheritDoc
+        */
+       public $sortField = 'time';
+       
+       /**
+        * @inheritDoc
+        */
+       public $sortOrder = 'DESC';
+       
+       /**
+        * the trophy id
+        * @var int
+        */
+       public $trophyID = 0;
+       
+       /**
+        * The trophy instance
+        * @var Trophy
+        */
+       public $trophy;
+       
+       public function readData() {
+               parent::readData();
+               
+               PageLocationManager::getInstance()->addParentLocation('com.woltlab.wcf.TrophyList', $this->trophy->getCategory()->getObjectID(), $this->trophy->getCategory());
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function readParameters() {
+               parent::readParameters();
+               
+               if (isset($_REQUEST['id'])) $this->trophyID = intval($_REQUEST['id']);
+               
+               $this->trophy = TrophyCache::getInstance()->getTrophyByID($this->trophyID);
+               if ($this->trophy === null) {
+                       throw new IllegalLinkException();
+               }
+               
+               if ($this->trophy->isDisabled()) {
+                       throw new PermissionDeniedException();
+               }
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function readObjects() {
+               parent::readObjects();
+               
+               $userIDs = [];
+               /** @var UserTrophy $trophy */
+               foreach ($this->objectList->getObjects() as $trophy) {
+                       $userIDs[] = $trophy->userID;
+               }
+               
+               UserProfileRuntimeCache::getInstance()->cacheObjectIDs(array_unique($userIDs));
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       protected function initObjectList() {
+               parent::initObjectList();
+               
+               $this->objectList->getConditionBuilder()->add('user_trophy.trophyID = ?', [$this->trophy->getObjectID()]);
+               
+               if (!WCF::getUser()->userID) {
+                       $this->objectList->getConditionBuilder()->add('user_trophy.userID IN (SELECT userID FROM wcf'. WCF_N .'_user_option_value WHERE userOption'. UserOptionCacheBuilder::getInstance()->getData()['options']['canViewTrophies']->optionID .' = 0)');
+               } 
+               else if (!WCF::getSession()->getPermission('admin.general.canViewPrivateUserOptions')) {
+                       $conditionBuilder = new PreparedStatementConditionBuilder(false, 'OR');
+                       $conditionBuilder->add('user_trophy.userID IN (SELECT userID FROM wcf'. WCF_N .'_user_option_value WHERE (userOption'. UserOptionCacheBuilder::getInstance()->getData()['options']['canViewTrophies']->optionID .' = 0 OR userOption'. UserOptionCacheBuilder::getInstance()->getData()['options']['canViewTrophies']->optionID .' = 1))');
+                       
+                       $friendshipConditionBuilder = new PreparedStatementConditionBuilder(false);
+                       $friendshipConditionBuilder->add('user_trophy.userID IN (SELECT userID FROM wcf'. WCF_N .'_user_option_value WHERE userOption'. UserOptionCacheBuilder::getInstance()->getData()['options']['canViewTrophies']->optionID .' = 2)');
+                       $friendshipConditionBuilder->add('user_trophy.userID IN (SELECT userID FROM wcf'. WCF_N .'_user_follow WHERE followUserID = ?)', [WCF::getUser()->userID]);
+                       $conditionBuilder->add('(' . $friendshipConditionBuilder . ')', $friendshipConditionBuilder->getParameters());
+                       $conditionBuilder->add('user_trophy.userID = ?', [WCF::getUser()->userID]);
+                       
+                       $this->objectList->getConditionBuilder()->add('('. $conditionBuilder .')', $conditionBuilder->getParameters());
+               }
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function assignVariables() {
+               parent::assignVariables();
+               
+               WCF::getTPL()->assign([
+                       'trophy' => $this->trophy,
+                       'trophyID' => $this->trophyID
+               ]);
+               
+               if (count($this->objectList) === 0) {
+                       @header('HTTP/1.0 404 Not Found');
+               }
+       }
+}
diff --git a/wcfsetup/install/files/lib/system/page/handler/TrophyListPageHandler.class.php b/wcfsetup/install/files/lib/system/page/handler/TrophyListPageHandler.class.php
new file mode 100644 (file)
index 0000000..7182263
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+namespace wcf\system\page\handler;
+use wcf\data\trophy\category\TrophyCategory;
+
+/**
+ * Menu page handler for the trophy list page.
+ *
+ * @author     Joshua Rüsweg
+ * @copyright  2001-2017 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Page\Handler
+ * @since      3.1
+ */
+class TrophyListPageHandler extends AbstractLookupPageHandler {
+       use TDecoratedCategoryOnlineLocationLookupPageHandler;
+       
+       /**
+        * @inheritDoc
+        */
+       protected function getDecoratedCategoryClass() {
+               return TrophyCategory::class;
+       }
+}
diff --git a/wcfsetup/install/files/lib/system/page/handler/TrophyPageHandler.class.php b/wcfsetup/install/files/lib/system/page/handler/TrophyPageHandler.class.php
new file mode 100644 (file)
index 0000000..08b0c0f
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+namespace wcf\system\page\handler;
+use wcf\data\trophy\TrophyCache;
+use wcf\data\trophy\TrophyList;
+use wcf\system\WCF;
+
+/**
+ * Menu page handler for the trophy page.
+ *
+ * @author     Joshua Rüsweg
+ * @copyright  2001-2017 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Page\Handler
+ * @since      3.1
+ */
+class TrophyPageHandler extends AbstractLookupPageHandler {
+       /**
+        * @inheritDoc
+        */
+       public function getLink($objectID) {
+               return TrophyCache::getInstance()->getTrophyByID($objectID)->getLink();
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function isValid($objectID) {
+               return TrophyCache::getInstance()->getTrophyByID($objectID) !== null; 
+       }
+       
+       /** @noinspection PhpMissingParentCallCommonInspection */
+       /**
+        * @inheritDoc
+        */
+       public function isVisible($objectID = null) {
+               return WCF::getSession()->getPermission('user.profile.trophy.canSeeTrophies');
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function lookup($searchString) {
+               $trophyList = new TrophyList();
+               if (!empty($trophyList->sqlJoins)) $trophyList->sqlJoins .= ', ';
+               $trophyList->sqlJoins = "LEFT JOIN wcf".WCF_N."_language_item language_item ON (language_item.languageItem = trophy.title)"; 
+               $trophyList->getConditionBuilder()->add('(trophy.title LIKE ? OR language_item.languageItemValue LIKE ?)', ['%' . $searchString . '%', '%' . $searchString . '%']);
+               $trophyList->sqlLimit = 10;
+               $trophyList->sqlOrderBy = 'title';
+               $trophyList->readObjects();
+               
+               $results = [];
+               foreach ($trophyList->getObjects() as $trophy) {
+                       $results[] = [
+                               'description' => $trophy->getDescription(),
+                               'image' => $trophy->renderTrophy(48),
+                               'link' => $trophy->getLink(),
+                               'objectID' => $trophy->trophyID,
+                               'title' => $trophy->getTitle()
+                       ];
+               }
+               
+               return $results;
+       }
+}
index 94c25b53f474509a5174ace0d3adcf3c87dcc21f..6458ff70451d5dcedc186f669e53071fefd5ef08 100644 (file)
                font-size: 18px;
        }
        
+       &.icon48 {
+               font-size: 27px;
+       }
+       
        &.icon64 {
                font-size: 36px;
        }