Add `TDecoratedCategoryOnlineLocationLookupPageHandler`
authorMatthias Schmidt <gravatronics@live.com>
Sun, 18 Sep 2016 12:20:45 +0000 (14:20 +0200)
committerMatthias Schmidt <gravatronics@live.com>
Sun, 18 Sep 2016 12:20:48 +0000 (14:20 +0200)
wcfsetup/install/files/lib/data/IAccessibleObject.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/data/article/category/ArticleCategory.class.php
wcfsetup/install/files/lib/system/page/handler/CategoryArticleListPageHandler.class.php
wcfsetup/install/files/lib/system/page/handler/TDecoratedCategoryLookupPageHandler.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/page/handler/TDecoratedCategoryMenuPageHandler.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/page/handler/TDecoratedCategoryOnlineLocationLookupPageHandler.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/page/handler/TDecoratedCategoryOnlineLocationPageHandler.class.php [new file with mode: 0644]

diff --git a/wcfsetup/install/files/lib/data/IAccessibleObject.class.php b/wcfsetup/install/files/lib/data/IAccessibleObject.class.php
new file mode 100644 (file)
index 0000000..d6c3202
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+namespace wcf\data;
+use wcf\data\user\User;
+
+/**
+ * Interface for objects whose access is restrictable so that access for every user
+ * has to be checked separately.
+ * 
+ * @author     Matthias Schmidt
+ * @copyright  2001-2016 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\Data
+ * @since      3.0
+ */
+interface IAccessibleObject {
+       /**
+        * Returns `true` if the given user can access the object.
+        * 
+        * @param       User    $user   checked user, if `null` active user is used instead
+        * @return      boolean
+        */
+       public function isAccessible(User $user = null);
+}
\ No newline at end of file
index 7936cb9b62ac8056baa1c977f57891e85807e39f..5f6a1cbca7aee2cadd3c3eda2ec038f8c7f038aa 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 namespace wcf\data\article\category;
 use wcf\data\category\AbstractDecoratedCategory;
+use wcf\data\IAccessibleObject;
 use wcf\data\user\User;
 use wcf\data\user\UserProfile;
 use wcf\data\ITitledLinkObject;
@@ -23,7 +24,7 @@ use wcf\system\WCF;
  * @method             ArticleCategory[]       getParentCategories()
  * @method static      ArticleCategory|null    getCategory($categoryID)
  */
-class ArticleCategory extends AbstractDecoratedCategory implements ITitledLinkObject {
+class ArticleCategory extends AbstractDecoratedCategory implements IAccessibleObject, ITitledLinkObject {
        /**
         * object type name of the article categories
         * @var string
@@ -38,10 +39,7 @@ class ArticleCategory extends AbstractDecoratedCategory implements ITitledLinkOb
        protected $userPermissions = [];
        
        /**
-        * Returns true if the category is accessible for the active user.
-        * 
-        * @param       User            $user
-        * @return      boolean
+        * @inheritDoc
         */
        public function isAccessible(User $user = null) {
                if ($this->getObjectType()->objectType != self::OBJECT_TYPE_NAME) return false;
@@ -84,6 +82,7 @@ class ArticleCategory extends AbstractDecoratedCategory implements ITitledLinkOb
         */
        public function getLink() {
                return LinkHandler::getInstance()->getLink('CategoryArticleList', [
+                       'forceFrontend' => true,
                        'object' => $this->getDecoratedObject()
                ]);
        }
index c6ed7ee4814748acf54c2cb0a8e4961e50f5522e..85bb3e0fe67678eb83aa5afdf7abf43d069450b3 100644 (file)
@@ -1,12 +1,7 @@
 <?php
 namespace wcf\system\page\handler;
 use wcf\data\article\category\ArticleCategory;
-use wcf\data\object\type\ObjectTypeCache;
-use wcf\data\page\Page;
-use wcf\data\user\online\UserOnline;
-use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\request\LinkHandler;
-use wcf\system\WCF;
 
 /**
  * Menu page handler for the category article list page.
@@ -18,82 +13,12 @@ use wcf\system\WCF;
  * @since      3.0
  */
 class CategoryArticleListPageHandler extends AbstractLookupPageHandler implements IOnlineLocationPageHandler {
-       use TOnlineLocationPageHandler;
+       use TDecoratedCategoryOnlineLocationLookupPageHandler;
        
        /**
-        * @inheritDoc
+        * @see TDecoratedCategoryLookupPageHandler::getDecoratedCategoryClass()
         */
-       public function getLink($objectID) {
-               return LinkHandler::getInstance()->getLink('CategoryArticleList', [
-                       'object' => ArticleCategory::getCategory($objectID),
-                       'forceFrontend' => true
-               ]);
-       }
-       
-       /**
-        * @inheritDoc
-        */
-       public function isValid($objectID) {
-               return ArticleCategory::getCategory($objectID) !== null;
-       }
-       
-       /** @noinspection PhpMissingParentCallCommonInspection */
-       /**
-        * @inheritDoc
-        */
-       public function isVisible($objectID = null) {
-               return ArticleCategory::getCategory($objectID)->isAccessible();
-       }
-       
-       /**
-        * @inheritDoc
-        */
-       public function lookup($searchString) {
-               $conditionBuilder = new PreparedStatementConditionBuilder();
-               $conditionBuilder->add('category.objectTypeID = ?', [ObjectTypeCache::getInstance()->getObjectTypeIDByName('com.woltlab.wcf.category', 'com.woltlab.wcf.article.category')]);
-               $conditionBuilder->add('(category.title LIKE ? OR language_item.languageItemValue LIKE ?)', ['%' . $searchString . '%', '%' . $searchString . '%']);
-               $sql = "SELECT          DISTINCT categoryID
-                       FROM            wcf".WCF_N."_category category
-                       LEFT JOIN       wcf".WCF_N."_language_item language_item
-                       ON              (language_item.languageItem = category.title)
-                       ".$conditionBuilder;
-               $statement = WCF::getDB()->prepareStatement($sql, 10);
-               $statement->execute($conditionBuilder->getParameters());
-               $results = [];
-               while ($categoryID = $statement->fetchColumn()) {
-                       $category = ArticleCategory::getCategory($categoryID);
-                       
-                       // build hierarchy
-                       $description = '';
-                       foreach ($category->getParentCategories() as $parentCategory) {
-                               $description .= $parentCategory->getTitle() . ' &raquo; ';
-                       }
-                       
-                       $results[] = [
-                               'description' => $description,
-                               'image' => 'fa-folder-open-o',
-                               'link' => $category->getLink(),
-                               'objectID' => $categoryID,
-                               'title' => $category->getTitle()
-                       ];
-               }
-               
-               return $results;
-       }
-       
-       /**
-        * @inheritDoc
-        */
-       public function getOnlineLocation(Page $page, UserOnline $user) {
-               if ($user->pageObjectID === null) {
-                       return '';
-               }
-               
-               $category = ArticleCategory::getCategory($user->pageObjectID);
-               if ($category === null || !$category->isAccessible()) {
-                       return '';
-               }
-               
-               return WCF::getLanguage()->getDynamicVariable('wcf.page.onlineLocation.'.$page->identifier, ['category' => $category]);
+       protected function getDecoratedCategoryClass() {
+               return ArticleCategory::class;
        }
 }
diff --git a/wcfsetup/install/files/lib/system/page/handler/TDecoratedCategoryLookupPageHandler.class.php b/wcfsetup/install/files/lib/system/page/handler/TDecoratedCategoryLookupPageHandler.class.php
new file mode 100644 (file)
index 0000000..e382460
--- /dev/null
@@ -0,0 +1,94 @@
+<?php
+namespace wcf\system\page\handler;
+use wcf\data\category\AbstractDecoratedCategory;
+use wcf\data\ILinkableObject;
+use wcf\data\object\type\ObjectTypeCache;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
+use wcf\system\exception\ParentClassException;
+use wcf\system\WCF;
+
+/**
+ * Provides the `isValid` and `lookup` methods for looking up decorated categories.
+ * 
+ * Note: This only works in the class extends `AbstractDecoratedCategory` and defines a
+ * constant `OBJECT_TYPE_NAME` with the name of the `com.woltlab.wcf.category` object type.
+ * 
+ * @author     Matthias Schmidt
+ * @copyright  2001-2016 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Page\Handler
+ * @since      3.0
+ */
+trait TDecoratedCategoryLookupPageHandler {
+       /**
+        * Returns the name of the decorated class name.
+        *
+        * @return      string
+        */
+       abstract protected function getDecoratedCategoryClass();
+       
+       /**
+        * @see ILookupPageHandler::getLink()
+        */
+       public function getLink($objectID) {
+               $className = $this->getDecoratedCategoryClass();
+               $category = $className::getCategory($objectID);
+               
+               if ($category instanceof ILinkableObject) {
+                       return $category->getLink();
+               }
+               
+               throw new \LogicException("If '" . $className . "' does not implement '" . ILinkableObject::class . "', the 'getLink' method needs to be overwritten.");
+       }
+       
+       /**
+        * @see ILookupPageHandler::isValid()
+        */
+       public function isValid($objectID = null) {
+               $className = $this->getDecoratedCategoryClass();
+               
+               return $className::getCategory($objectID)->isAccessible();
+       }
+       
+       /**
+        * @see ILookupPageHandler::lookup()
+        */
+       public function lookup($searchString) {
+               $className = $this->getDecoratedCategoryClass();
+               if (!is_subclass_of($className, AbstractDecoratedCategory::class)) {
+                       throw new ParentClassException($className, AbstractDecoratedCategory::class);
+               }
+               
+               $conditionBuilder = new PreparedStatementConditionBuilder();
+               $conditionBuilder->add('category.objectTypeID = ?', [ObjectTypeCache::getInstance()->getObjectTypeIDByName('com.woltlab.wcf.category', $className::OBJECT_TYPE_NAME)]);
+               $conditionBuilder->add('(category.title LIKE ? OR language_item.languageItemValue LIKE ?)', ['%' . $searchString . '%', '%' . $searchString . '%']);
+               $sql = "SELECT          DISTINCT categoryID
+                       FROM            wcf".WCF_N."_category category
+                       LEFT JOIN       wcf".WCF_N."_language_item language_item
+                       ON              (language_item.languageItem = category.title)
+                       ".$conditionBuilder;
+               $statement = WCF::getDB()->prepareStatement($sql, 10);
+               $statement->execute($conditionBuilder->getParameters());
+               $results = [];
+               while ($categoryID = $statement->fetchColumn()) {
+                       /** @var AbstractDecoratedCategory $category */
+                       $category = $className::getCategory($categoryID);
+                       
+                       // build hierarchy
+                       $description = '';
+                       foreach ($category->getParentCategories() as $parentCategory) {
+                               $description .= $parentCategory->getTitle() . ' &raquo; ';
+                       }
+                       
+                       $results[] = [
+                               'description' => $description,
+                               'image' => 'fa-folder-open-o',
+                               'link' => $category->getLink(),
+                               'objectID' => $categoryID,
+                               'title' => $category->getTitle()
+                       ];
+               }
+               
+               return $results;
+       }
+}
\ No newline at end of file
diff --git a/wcfsetup/install/files/lib/system/page/handler/TDecoratedCategoryMenuPageHandler.class.php b/wcfsetup/install/files/lib/system/page/handler/TDecoratedCategoryMenuPageHandler.class.php
new file mode 100644 (file)
index 0000000..30a94cb
--- /dev/null
@@ -0,0 +1,45 @@
+<?php
+namespace wcf\system\page\handler;
+use wcf\data\category\AbstractDecoratedCategory;
+use wcf\data\IAccessibleObject;
+
+/**
+ * Implementation of the `IMenuPageHandler::isVisible()` methods for decorated category-bound pages.
+ * 
+ * @author     Matthias Schmidt
+ * @copyright  2001-2016 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Page\Handler
+ * @since      3.0
+ */
+trait TDecoratedCategoryMenuPageHandler {
+       /**
+        * Returns the name of the decorated class name.
+        *
+        * @return      string
+        */
+       abstract protected function getDecoratedCategoryClass();
+       
+       /**
+        * @see IMenuPageHandler::isVisible()
+        */
+       public function isVisible($objectID = null) {
+               $className = $this->getDecoratedCategoryClass();
+               
+               /** @var AbstractDecoratedCategory $category */
+               $category = $className::getCategory($objectID);
+               
+               // check if category exists
+               if ($category === null) {
+                       return false;
+               }
+               
+               // check if access to category is restricted
+               if ($category instanceof IAccessibleObject && !$className->isAccessible()) {
+                       return false;
+               }
+               
+               // fallback to default value of AbstractMenuPageHandler::isVisible()
+               return true;
+       }
+}
\ No newline at end of file
diff --git a/wcfsetup/install/files/lib/system/page/handler/TDecoratedCategoryOnlineLocationLookupPageHandler.class.php b/wcfsetup/install/files/lib/system/page/handler/TDecoratedCategoryOnlineLocationLookupPageHandler.class.php
new file mode 100644 (file)
index 0000000..45588ca
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+namespace wcf\system\page\handler;
+
+/**
+ * Implementation of the `IOnlineLocationPageHandler` and `ILookupPageHandler` interfaces
+ * and implementing the `IMenuPageHandler::isVisible()` method..
+ *
+ * @author     Matthias Schmidt
+ * @copyright  2001-2016 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Page\Handler
+ * @since      3.0
+ */
+trait TDecoratedCategoryOnlineLocationLookupPageHandler {
+       use TDecoratedCategoryOnlineLocationPageHandler;
+       use TDecoratedCategoryLookupPageHandler;
+       use TDecoratedCategoryMenuPageHandler;
+}
diff --git a/wcfsetup/install/files/lib/system/page/handler/TDecoratedCategoryOnlineLocationPageHandler.class.php b/wcfsetup/install/files/lib/system/page/handler/TDecoratedCategoryOnlineLocationPageHandler.class.php
new file mode 100644 (file)
index 0000000..41909dd
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+namespace wcf\system\page\handler;
+use wcf\data\category\AbstractDecoratedCategory;
+use wcf\data\IAccessibleObject;
+use wcf\data\page\Page;
+use wcf\data\user\online\UserOnline;
+use wcf\system\exception\ParentClassException;
+use wcf\system\WCF;
+
+/**
+ * Implementation of the `IOnlineLocationPageHandler` interface for decorated category-bound pages.
+ * 
+ * @author     Matthias Schmidt
+ * @copyright  2001-2016 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Page\Handler
+ * @since      3.0
+ */
+trait TDecoratedCategoryOnlineLocationPageHandler {
+       use TOnlineLocationPageHandler;
+       
+       /**
+        * Returns the name of the decorated class name.
+        *
+        * @return      string
+        */
+       abstract protected function getDecoratedCategoryClass();
+       
+       /**
+        * @see IOnlineLocationPageHandler::getOnlineLocation()
+        */
+       public function getOnlineLocation(Page $page, UserOnline $user) {
+               if ($user->pageObjectID === null) {
+                       return '';
+               }
+               
+               $className = $this->getDecoratedCategoryClass();
+               if (!is_subclass_of($className, AbstractDecoratedCategory::class)) {
+                       throw new ParentClassException($className, AbstractDecoratedCategory::class);
+               }
+               
+               /** @var AbstractDecoratedCategory $category */
+               $category = $className::getCategory($user->pageObjectID);
+               if ($category === null) {
+                       return '';
+               }
+               
+               if ($category instanceof IAccessibleObject && !$category->isAccessible()) {
+                       return null;
+               }
+               
+               return WCF::getLanguage()->getDynamicVariable('wcf.page.onlineLocation.'.$page->identifier, ['category' => $category]);
+       }
+}
\ No newline at end of file