Add feature to subscribe article categories
authorJoshua Rüsweg <josh@bastelstu.be>
Wed, 29 Aug 2018 13:03:28 +0000 (15:03 +0200)
committerJoshua Rüsweg <josh@bastelstu.be>
Wed, 29 Aug 2018 13:03:28 +0000 (15:03 +0200)
See #2642

com.woltlab.wcf/objectType.xml
com.woltlab.wcf/templates/categoryArticleList.tpl
wcfsetup/install/files/lib/data/article/category/ArticleCategory.class.php
wcfsetup/install/files/lib/system/user/object/watch/ArticleCategoryUserObjectWatch.class.php [new file with mode: 0644]
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index 99b1d69fcd72c4f5775d4281040fe8746dfb55a9..53b1a60064cc5b0fc0b42e45719701eb6d0e64cf 100644 (file)
                        <definitionname>com.woltlab.wcf.moderation.report</definitionname>
                        <classname>wcf\system\moderation\queue\report\ArticleModerationQueueReportHandler</classname>
                </type>
+               <type>
+                       <name>com.woltlab.wcf.article.category</name>
+                       <definitionname>com.woltlab.wcf.user.objectWatch</definitionname>
+                       <classname>wcf\system\user\object\watch\ArticleCategoryUserObjectWatch</classname>
+               </type>
                <!-- /articles -->
                
                <type>
index c53cb508ebff867d30048602166adf6d5f7e70c7..c13eeebc7b241871eb848a8a30b0b44a7b692253 100644 (file)
@@ -23,6 +23,9 @@
        {if ARTICLE_ENABLE_VISIT_TRACKING}
                <li class="jsOnly"><a href="#" title="{lang}wcf.article.markAllAsRead{/lang}" class="markAllAsReadButton jsTooltip"><span class="icon icon16 fa-check"></span> <span class="invisible">{lang}wcf.article.markAllAsRead{/lang}</span></a></li>
        {/if}
+       {if $__wcf->user->userID}
+               <li class="jsOnly"><a href="#" title="{lang}wcf.user.objectWatch.manageSubscription{/lang}" class="jsSubscribeButton jsTooltip" data-object-type="com.woltlab.wcf.article.category" data-object-id="{@$category->categoryID}"><span class="icon icon16 fa-bookmark{if !$category->isSubscribed()}-o{/if}"></span> <span class="invisible">{lang}wcf.user.objectWatch.manageSubscription{/lang}</span></a></li>
+       {/if}
 {/capture}
 
 {if $__wcf->getSession()->getPermission('admin.content.article.canManageArticle')}
        </script>
 {/if}
 
+<script data-relocate="true">
+       $(function() {
+               WCF.Language.addObject({
+                       'wcf.user.objectWatch.manageSubscription': '{lang}wcf.user.objectWatch.manageSubscription{/lang}'
+               });
+               
+               new WCF.User.ObjectWatch.Subscribe();
+       });
+</script>
+
 {include file='footer'}
index 33dd8b405a189f1db5fd8a1e3125626abc014b0c..97aa8df914e4c02e110161f903c9df7abc174fd8 100644 (file)
@@ -11,6 +11,8 @@ use wcf\system\category\CategoryHandler;
 use wcf\system\category\CategoryPermissionHandler;
 use wcf\system\label\LabelHandler;
 use wcf\system\request\LinkHandler;
+use wcf\system\user\object\watch\UserObjectWatchHandler;
+use wcf\system\user\storage\UserStorageHandler;
 use wcf\system\WCF;
 
 /**
@@ -44,6 +46,12 @@ class ArticleCategory extends AbstractDecoratedCategory implements IAccessibleOb
         */
        protected $userPermissions = [];
        
+       /**
+        * subscribed categories
+        * @var integer[]
+        */
+       protected static $subscribedCategories;
+       
        /**
         * @inheritDoc
         */
@@ -143,4 +151,51 @@ class ArticleCategory extends AbstractDecoratedCategory implements IAccessibleOb
                
                return LabelHandler::getInstance()->getLabelGroups(array_unique($groupIDs));
        }
+       
+       /**
+        * Returns true if the active user has subscribed to this category.
+        *
+        * @return      boolean
+        * @since       3.2
+        */
+       public function isSubscribed() {
+               return in_array($this->categoryID, self::getSubscribedCategoryIDs());
+       }
+       
+       /**
+        * Returns the list of subscribed categories.
+        *
+        * @return      integer[]
+        * @since       3.2
+        */
+       public static function getSubscribedCategoryIDs() {
+               if (self::$subscribedCategories === null) {
+                       self::$subscribedCategories = [];
+                       
+                       if (WCF::getUser()->userID) {
+                               $data = UserStorageHandler::getInstance()->getField('articleSubscribedCategories');
+                               
+                               // cache does not exist or is outdated
+                               if ($data === null) {
+                                       $objectTypeID = UserObjectWatchHandler::getInstance()->getObjectTypeID('com.woltlab.wcf.article.category');
+                                       
+                                       $sql = "SELECT  objectID
+                                               FROM    wcf".WCF_N."_user_object_watch
+                                               WHERE   objectTypeID = ?
+                                                       AND userID = ?";
+                                       $statement = WCF::getDB()->prepareStatement($sql);
+                                       $statement->execute([$objectTypeID, WCF::getUser()->userID]);
+                                       self::$subscribedCategories = $statement->fetchAll(\PDO::FETCH_COLUMN);
+                                       
+                                       // update storage data
+                                       UserStorageHandler::getInstance()->update(WCF::getUser()->userID, 'articleSubscribedCategories', serialize(self::$subscribedCategories));
+                               }
+                               else {
+                                       self::$subscribedCategories = unserialize($data);
+                               }
+                       }
+               }
+               
+               return self::$subscribedCategories;
+       }
 }
diff --git a/wcfsetup/install/files/lib/system/user/object/watch/ArticleCategoryUserObjectWatch.class.php b/wcfsetup/install/files/lib/system/user/object/watch/ArticleCategoryUserObjectWatch.class.php
new file mode 100644 (file)
index 0000000..3341b8e
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+namespace wcf\system\user\object\watch;
+use wcf\data\article\category\ArticleCategory;
+use wcf\data\object\type\AbstractObjectTypeProcessor;
+use wcf\system\user\storage\UserStorageHandler;
+use wcf\system\exception\IllegalLinkException;
+use wcf\system\exception\PermissionDeniedException;
+
+/**
+ * Implementation of IUserObjectWatch for watched article categories.
+ *
+ * @author     Joshua Ruesweg
+ * @copyright  2001-2018 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\User\Object\Watch
+ */
+class ArticleCategoryUserObjectWatch extends AbstractObjectTypeProcessor implements IUserObjectWatch {
+       /**
+        * @inheritDoc
+        */
+       public function validateObjectID($objectID) {
+               $category = ArticleCategory::getCategory($objectID);
+               if ($category === null) {
+                       throw new IllegalLinkException();
+               }
+               if (!$category->isAccessible()) {
+                       throw new PermissionDeniedException();
+               }
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function resetUserStorage(array $userIDs) {
+               UserStorageHandler::getInstance()->reset($userIDs, 'unreadWatchedArticles');
+               UserStorageHandler::getInstance()->reset($userIDs, 'articleSubscribedCategories');
+       }
+}
index 1e78d63c051b741b675468df51bcd320ee507911..9f9d79adfe1f34afe820904993fdd5910ee2a218 100644 (file)
@@ -4295,6 +4295,9 @@ Benachrichtigungen auf <a href="{link isEmail=true}{/link}">{PAGE_TITLE|language
        
        <category name="wcf.user.objectWatch">
                <item name="wcf.user.objectWatch.manageSubscription"><![CDATA[Abonnement verwalten]]></item>
+               <item name="wcf.user.objectWatch.subscribe.com.woltlab.wcf.article.category"><![CDATA[Kategorie abonnieren]]></item>
+               <item name="wcf.user.objectWatch.enableNotification.com.woltlab.wcf.article.category"><![CDATA[Benachrichtigung über neue Artikel aus dieser Kategorie aktivieren]]></item>
+               <item name="wcf.user.objectWatch.unsubscribe.com.woltlab.wcf.article.category"><![CDATA[Kategorie nicht abonnieren]]></item>
        </category>
        
        <category name="wcf.user.option">
index 809ab2b974695d9224859ef1aae2809eb3aa416e..fbb932d8fdffdc70e7faf4489a9949295ccc9152 100644 (file)
@@ -4291,6 +4291,9 @@ your notifications on <a href="{link isEmail=true}{/link}">{PAGE_TITLE|language}
        
        <category name="wcf.user.objectWatch">
                <item name="wcf.user.objectWatch.manageSubscription"><![CDATA[Manage Subscription]]></item>
+               <item name="wcf.user.objectWatch.subscribe.com.woltlab.wcf.article.category"><![CDATA[Watch this category]]></item>
+               <item name="wcf.user.objectWatch.enableNotification.com.woltlab.wcf.article.category"><![CDATA[Notify me of new articles.]]></item>
+               <item name="wcf.user.objectWatch.unsubscribe.com.woltlab.wcf.article.category"><![CDATA[Unwatch this category]]></item>
        </category>
        
        <category name="wcf.user.option">