Add notifications for article reactions
authorMatthias Schmidt <gravatronics@live.com>
Sun, 10 May 2020 14:28:33 +0000 (16:28 +0200)
committerMatthias Schmidt <gravatronics@live.com>
Sun, 10 May 2020 14:28:33 +0000 (16:28 +0200)
Close #3269

com.woltlab.wcf/objectType.xml
com.woltlab.wcf/userNotificationEvent.xml
wcfsetup/install/files/lib/data/article/LikeableArticle.class.php
wcfsetup/install/files/lib/system/user/notification/event/ArticleLikeUserNotificationEvent.class.php [new file with mode: 0644]
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index ff97471cf8c234357e3014321b67b8390a66abd1..98963f777ecd672789c1ff741ef423d3c4839728 100644 (file)
                        <classname>wcf\system\user\notification\object\type\ArticleUserNotificationObjectType</classname>
                        <category>com.woltlab.wcf.page</category>
                </type>
+               <type>
+                       <name>com.woltlab.wcf.likeableArticle.notification</name>
+                       <definitionname>com.woltlab.wcf.notification.objectType</definitionname>
+                       <classname>wcf\system\user\notification\object\type\LikeUserNotificationObjectType</classname>
+                       <category>com.woltlab.wcf.page</category>
+               </type>
                <type>
                        <name>com.woltlab.wcf.article.recentActivityEvent</name>
                        <definitionname>com.woltlab.wcf.user.recentActivityEvent</definitionname>
index 1af648de6da5c8de8fd6a3c58cd035a0a41a119d..3a6d8bb871438ade2e367c5dca1183f5d8cb2a37 100644 (file)
                        <classname>wcf\system\user\notification\event\ArticleUserNotificationEvent</classname>
                        <preset>1</preset>
                </event>
+               <event>
+                       <name>like</name>
+                       <objecttype>com.woltlab.wcf.likeableArticle.notification</objecttype>
+                       <classname>wcf\system\user\notification\event\ArticleLikeUserNotificationEvent</classname>
+                       <options>module_like</options>
+                       <preset>1</preset>
+               </event>
                
                <event>
                        <name>registration</name>
index 1661cc337ba76d688ba1efc4c8797bce51ba5318..5b6f0ea1498e3550377c0574ff6780cb884c5d70 100644 (file)
@@ -1,6 +1,11 @@
 <?php
 namespace wcf\data\article;
+use wcf\data\like\Like;
 use wcf\data\like\object\AbstractLikeObject;
+use wcf\data\reaction\object\IReactionObject;
+use wcf\system\user\notification\object\LikeUserNotificationObject;
+use wcf\system\user\notification\UserNotificationHandler;
+use wcf\system\WCF;
 
 /**
  * Likeable object implementation for cms articles.
@@ -14,7 +19,7 @@ use wcf\data\like\object\AbstractLikeObject;
  * @method     Article getDecoratedObject()
  * @mixin      Article
  */
-class LikeableArticle extends AbstractLikeObject {
+class LikeableArticle extends AbstractLikeObject implements IReactionObject {
        /**
         * @inheritDoc
         */
@@ -65,4 +70,19 @@ class LikeableArticle extends AbstractLikeObject {
        public function getLanguageID() {
                return null;
        }
+       
+       /**
+        * @inheritDoc
+        */
+       public function sendNotification(Like $like) {
+               if ($this->getDecoratedObject()->userID != WCF::getUser()->userID) {
+                       $notificationObject = new LikeUserNotificationObject($like);
+                       UserNotificationHandler::getInstance()->fireEvent(
+                               'like',
+                               'com.woltlab.wcf.likeableArticle.notification',
+                               $notificationObject,
+                               [$this->getDecoratedObject()->userID]
+                       );
+               }
+       }
 }
diff --git a/wcfsetup/install/files/lib/system/user/notification/event/ArticleLikeUserNotificationEvent.class.php b/wcfsetup/install/files/lib/system/user/notification/event/ArticleLikeUserNotificationEvent.class.php
new file mode 100644 (file)
index 0000000..85644c1
--- /dev/null
@@ -0,0 +1,138 @@
+<?php
+namespace wcf\system\user\notification\event;
+use wcf\data\article\category\ArticleCategory;
+use wcf\data\article\LikeableArticle;
+use wcf\data\user\UserProfile;
+use wcf\system\cache\runtime\ViewableArticleRuntimeCache;
+use wcf\system\user\notification\object\LikeUserNotificationObject;
+use wcf\system\user\storage\UserStorageHandler;
+use wcf\system\WCF;
+
+/**
+ * User notification event for post likes.
+ * 
+ * @author     Matthias Schmidt
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    WoltLab License <http://www.woltlab.com/license-agreement.html>
+ * @package    WoltLabSuite\Core\System\User\Notification\Event
+ * @since      5.3
+ * 
+ * @method     LikeUserNotificationObject      getUserNotificationObject()
+ */
+class ArticleLikeUserNotificationEvent extends AbstractSharedUserNotificationEvent implements ITestableUserNotificationEvent {
+       use TTestableLikeUserNotificationEvent {
+               TTestableLikeUserNotificationEvent::canBeTriggeredByGuests insteadof TTestableUserNotificationEvent;
+       }
+       use TTestableArticleUserNotificationEvent;
+       use TTestableCategorizedUserNotificationEvent;
+       use TTestableUserNotificationEvent;
+       use TReactionUserNotificationEvent;
+       
+       /**
+        * @inheritDoc
+        */
+       protected $stackable = true;
+       
+       /**
+        * @inheritDoc
+        */
+       protected function prepare() {
+               ViewableArticleRuntimeCache::getInstance()->cacheObjectID($this->getUserNotificationObject()->objectID);
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function getTitle() {
+               $count = count($this->getAuthors());
+               if ($count > 1) {
+                       return $this->getLanguage()->getDynamicVariable('wcf.article.like.notification.title.stacked', [
+                               'count' => $count,
+                               'timesTriggered' => $this->notification->timesTriggered
+                       ]);
+               }
+               
+               return $this->getLanguage()->getDynamicVariable('wcf.article.like.notification.title');
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function getMessage() {
+               $article = ViewableArticleRuntimeCache::getInstance()->getObject($this->getUserNotificationObject()->objectID);
+               $authors = array_values($this->getAuthors());
+               $count = count($authors);
+               
+               if ($count > 1) {
+                       return $this->getLanguage()->getDynamicVariable('wcf.article.like.notification.message.stacked', [
+                               'author' => $this->author,
+                               'authors' => $authors,
+                               'count' => $count,
+                               'others' => $count - 1,
+                               'article' => $article,
+                               'reactions' => $this->getReactionsForAuthors(),
+                       ]);
+               }
+               
+               return $this->getLanguage()->getDynamicVariable('wcf.article.like.notification.message', [
+                       'author' => $this->author,
+                       'article' => $article,
+                       'userNotificationObject' => $this->getUserNotificationObject(),
+                       'reactions' => $this->getReactionsForAuthors(),
+               ]);
+       }
+       
+       /** @noinspection PhpMissingParentCallCommonInspection */
+       /**
+        * @inheritDoc
+        */
+       public function getEmailMessage($notificationType = 'instant') {
+               // not supported
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function getLink() {
+               return ViewableArticleRuntimeCache::getInstance()->getObject($this->getUserNotificationObject()->objectID)->getLink();
+       }
+       
+       /** @noinspection PhpMissingParentCallCommonInspection */
+       /**
+        * @inheritDoc
+        */
+       public function supportsEmailNotification() {
+               return false;
+       }
+       
+       /** @noinspection PhpMissingParentCallCommonInspection */
+       /**
+        * @inheritDoc
+        */
+       public function checkAccess() {
+               if (!ViewableArticleRuntimeCache::getInstance()->getObject($this->getUserNotificationObject()->objectID)->canRead()) {
+                       UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'wbbUnreadWatchedThreads');
+                       UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'unreadArticles');
+                       UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'unreadWatchedArticles');
+                       UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'unreadArticlesByCategory');
+                       
+                       return false;
+               }
+               
+               return true;
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       protected static function createTestLikeObject(UserProfile $recipient, UserProfile $author) {
+               return new LikeableArticle(self::getTestArticle(self::createTestCategory(ArticleCategory::OBJECT_TYPE_NAME), $author));
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       protected static function getTestLikeableObjectTypeName() {
+               return 'com.woltlab.wcf.likeableArticle';
+       }
+}
index 04fc630d73c9bd3a6cb8a472970b7da22a50c5e7..587080849a38eb3b5905acef4fb2062f7b8052cd 100644 (file)
@@ -3251,6 +3251,10 @@ Benutzerkontos nun in vollem Umfang nutzen.]]></item>
                <item name="wcf.article.search.results"><![CDATA[Suchergebnisse]]></item>
                <item name="wcf.article.publicationStatus.0"><![CDATA[Dieser Artikel wurde noch nicht veröffentlicht.]]></item>
                <item name="wcf.article.publicationStatus.2"><![CDATA[Dieser Artikel wird am {@$publicationDate|plainTime} veröffentlicht.]]></item>
+               <item name="wcf.article.like.notification.title"><![CDATA[Reaktion auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Artikel]]></item>
+               <item name="wcf.article.like.notification.title.stacked"><![CDATA[{#$count} Benutzer haben auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Artikel reagiert]]></item>
+               <item name="wcf.article.like.notification.message"><![CDATA[{@$author->getAnchorTag()} hat auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Artikel <a href="{$article->getLink()}">{$article->getTitle()}</a> reagiert ({implode from=$reactions key=reactionID item=count}{@$__wcf->getReactionHandler()->getReactionTypeByID($reactionID)->renderIcon()}×{#$count}{/implode}).]]></item>
+               <item name="wcf.article.like.notification.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count == 2} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} und {@$authors[2]->getAnchorTag()}{/if}{else}{@$authors[0]->getAnchorTag()} und {#$others} weitere{/if} haben auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Artikel <a href="{$article->getLink()}">{$article->getTitle()}</a> reagiert ({implode from=$reactions key=reactionID item=count}{@$__wcf->getReactionHandler()->getReactionTypeByID($reactionID)->renderIcon()}×{#$count}{/implode}).]]></item>
        </category>
        <category name="wcf.attachment">
                <item name="wcf.attachment.file.info"><![CDATA[({@$attachment->filesize|filesize}, <b>{#$attachment->downloads}</b> Mal heruntergeladen{if $attachment->downloads > 0}, zuletzt: {@$attachment->lastDownloadTime|time}{/if})]]></item>
@@ -5089,6 +5093,7 @@ Benachrichtigungen auf <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|lang
                <item name="wcf.user.notification.com.woltlab.wcf.page.notification.comment"><![CDATA[Neuer Kommentar auf einer Seite]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.page.response.notification.commentResponse"><![CDATA[Neue Antwort auf einen Kommentar auf einer Seite]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.page.response.notification.commentResponseOwner"><![CDATA[Neue Antwort auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Kommentar auf einer Seite]]></item>
+               <item name="wcf.user.notification.com.woltlab.wcf.likeableArticle.notification.like"><![CDATA[Jemand hat auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Artikel reagiert]]></item>
                <item name="wcf.user.notification.pageComment.title"><![CDATA[Neuer Kommentar (Seite)]]></item>
                <item name="wcf.user.notification.pageComment.title.stacked"><![CDATA[{#$timesTriggered} neue Kommentare (Seite)]]></item>
                <item name="wcf.user.notification.pageComment.message"><![CDATA[{if !$author->userID}Ein Gast{else}{@$author->getAnchorTag()}{/if} hat einen Kommentar auf der Seite <a href="{$page->getLink()}#comment{@$commentID}">{$page->getTitle()}</a> verfasst.]]></item>
index 7a869322d5baf70a04c768bb5dc498175112c072..4fa21cdece8dc81538ba2d083bc4ca982ad35444 100644 (file)
@@ -3174,6 +3174,10 @@ full extend.]]></item>
                <item name="wcf.article.search.results"><![CDATA[Search Results]]></item>
                <item name="wcf.article.publicationStatus.0"><![CDATA[This article has not been published yet.]]></item>
                <item name="wcf.article.publicationStatus.2"><![CDATA[This article will be published on {@$publicationDate|plainTime}.]]></item>
+               <item name="wcf.article.like.notification.title"><![CDATA[Reaction to your article]]></item>
+               <item name="wcf.article.like.notification.title.stacked"><![CDATA[{#$count} users reacted to your article]]></item>
+               <item name="wcf.article.like.notification.message"><![CDATA[{@$author->getAnchorTag()} reacted to your article <a href="{$article->getLink()}">{$article->getTitle()}</a> ({implode from=$reactions key=reactionID item=count}{@$__wcf->getReactionHandler()->getReactionTypeByID($reactionID)->renderIcon()}×{#$count}{/implode}).]]></item>
+               <item name="wcf.article.like.notification.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count == 2} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} and {@$authors[2]->getAnchorTag()}{/if}{else}{@$authors[0]->getAnchorTag()} and {#$others} other users{/if} reacted to article <a href="{$article->getLink()}">{$article->getTitle()}</a> ({implode from=$reactions key=reactionID item=count}{@$__wcf->getReactionHandler()->getReactionTypeByID($reactionID)->renderIcon()}×{#$count}{/implode}).]]></item>
        </category>
        <category name="wcf.attachment">
                <item name="wcf.attachment.file.info"><![CDATA[({@$attachment->filesize|filesize}, downloaded <b>{#$attachment->downloads}</b> times{if $attachment->downloads > 0}, last: {@$attachment->lastDownloadTime|time}{/if})]]></item>
@@ -5086,6 +5090,7 @@ your notifications on <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|langu
                <item name="wcf.user.notification.com.woltlab.wcf.page.notification.comment"><![CDATA[Notify me when new comments are written on pages]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.page.response.notification.commentResponse"><![CDATA[Notify me when new replies to comments are written on pages]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.page.response.notification.commentResponseOwner"><![CDATA[Notify me when someone replies to my comments on pages]]></item>
+               <item name="wcf.user.notification.com.woltlab.wcf.likeableArticle.notification.like"><![CDATA[Notify me when someone reacted to my articles]]></item>
                <item name="wcf.user.notification.pageComment.title"><![CDATA[New Comment (Page)]]></item>
                <item name="wcf.user.notification.pageComment.title.stacked"><![CDATA[{#$timesTriggered} new comments (Page)]]></item>
                <item name="wcf.user.notification.pageComment.message"><![CDATA[{if !$author->userID}A guest{else}{@$author->getAnchorTag()}{/if} commented on the page <a href="{$page->getLink()}#comment{@$commentID}">{$page->getTitle()}</a>.]]></item>