]> git.mxchange.org Git - friendica.git/commitdiff
Move notification to the new paradigm
authorHypolite Petovan <hypolite@mrpetovan.com>
Sat, 18 Sep 2021 04:03:32 +0000 (00:03 -0400)
committerHypolite Petovan <hypolite@mrpetovan.com>
Sat, 2 Oct 2021 22:15:45 +0000 (18:15 -0400)
16 files changed:
include/api.php
include/enotify.php
mod/display.php
src/DI.php
src/Factory/Api/Mastodon/Notification.php
src/Model/Contact.php
src/Model/Notification.php [deleted file]
src/Model/Post/UserNotification.php
src/Model/Subscription.php
src/Module/Api/Mastodon/Notifications.php
src/Module/Api/Mastodon/Notifications/Clear.php
src/Module/Api/Mastodon/Notifications/Dismiss.php
src/Module/Notifications/Notification.php
src/Module/Notifications/Notifications.php
src/Object/Api/Mastodon/Notification.php
src/Worker/PushSubscription.php

index cd096c187afe33d1fb7089b0f8735b703245328b..11950f52f3cbf4d3a20cc05f2f4af1d77e8fc0c4 100644 (file)
@@ -5647,7 +5647,7 @@ function api_friendica_notification_seen($type)
                }
 
                if ($Notify->uriId) {
-                       DI::dba()->update('notification', ['seen' => true], ['uid' => $Notify->uid, 'target-uri-id' => $Notify->uriId]);
+                       DI::notification()->setAllSeenForUser($Notify->uid, ['target-uri-id' => $Notify->uriId]);
                }
 
                $Notify->setSeen();
index 623347b8b015a6685651dba97a3399fc276c5f0b..90a17ad25e5dec8481d6bfb3a745ab7ad32d6605 100644 (file)
@@ -491,22 +491,21 @@ function notification_store_and_send($params, $sitelink, $tsitelink, $hsitelink,
        return false;
 }
 
-function notification_from_array(array $notification)
+function notification_from_array(Notifications\Entity\Notification $Notification)
 {
-       Logger::info('Start', ['uid' => $notification['uid'], 'id' => $notification['id'], 'type' => $notification['type']]);
+       Logger::info('Start', ['uid' => $Notification->uid, 'id' => $Notification->id, 'type' => $Notification->type]);
 
-       if ($notification['type'] == Post\UserNotification::TYPE_NONE) {
-               Logger::info('Not an item based notification, quitting', ['uid' => $notification['uid'], 'id' => $notification['id'], 'type' => $notification['type']]);
+       if ($Notification->type === Post\UserNotification::TYPE_NONE) {
+               Logger::info('Not an item based notification, quitting', ['uid' => $Notification->uid, 'id' => $Notification->id, 'type' => $Notification->type]);
                return false;
        }
 
        $params = [];
-       $params['verb'] = Verb::getByID($notification['vid']);
-
-       $params['uid']   = $notification['uid'];
+       $params['verb']  = $Notification->verb;
+       $params['uid']   = $Notification->uid;
        $params['otype'] = Notification\ObjectType::ITEM;
 
-       $user = User::getById($notification['uid']);
+       $user = User::getById($Notification->uid);
 
        $params['notify_flags'] = $user['notify-flags'];
        $params['language']     = $user['language'];
@@ -516,18 +515,18 @@ function notification_from_array(array $notification)
        // from here on everything is in the recipients language
        $l10n = DI::l10n()->withLang($user['language']);
 
-       $contact = Contact::getById($notification['actor-id'], ['url', 'name', 'photo']);
+       $contact = Contact::getById($Notification->actorId, ['url', 'name', 'photo']);
        if (DBA::isResult($contact)) {
                $params['source_link']  = $contact['url'];
                $params['source_name']  = $contact['name'];
                $params['source_photo'] = $contact['photo'];
        }
 
-       $item = Post::selectFirstForUser($notification['uid'], Item::ITEM_FIELDLIST,
-               ['uid' => [0, $notification['uid']], 'uri-id' => $notification['target-uri-id'], 'deleted' => false],
+       $item = Post::selectFirstForUser($Notification->uid, Item::ITEM_FIELDLIST,
+               ['uid' => [0, $Notification->uid], 'uri-id' => $Notification->targetUriId, 'deleted' => false],
                ['order' => ['uid' => true]]);
        if (empty($item)) {
-               Logger::info('Item not found', ['uri-id' => $notification['target-uri-id'], 'type' => $notification['type']]);
+               Logger::info('Item not found', ['uri-id' => $Notification->targetUriId, 'type' => $Notification->type]);
                return false;
        }
 
@@ -537,8 +536,8 @@ function notification_from_array(array $notification)
 
        $subjectPrefix = $l10n->t('[Friendica:Notify]');
 
-       if (Post\ThreadUser::getIgnored($notification['parent-uri-id'], $notification['uid'])) {
-               Logger::info('Thread is ignored', ['parent-uri-id' => $notification['parent-uri-id'], 'type' => $notification['type']]);
+       if (Post\ThreadUser::getIgnored($Notification->parentUriId, $Notification->uid)) {
+               Logger::info('Thread is ignored', ['parent-uri-id' => $Notification->parentUriId, 'type' => $Notification->type]);
                return false;
        }
 
@@ -546,8 +545,8 @@ function notification_from_array(array $notification)
        // If so don't create a second notification
        $condition = ['type' => [Notification\Type::TAG_SELF, Notification\Type::COMMENT, Notification\Type::SHARE],
                'link' => $params['link'], 'verb' => Activity::POST];
-       if (DI::notify()->existsForUser($notification['uid'], $condition)) {
-               Logger::info('Duplicate found, quitting', $condition + ['uid' => $notification['uid']]);
+       if (DI::notify()->existsForUser($Notification->uid, $condition)) {
+               Logger::info('Duplicate found, quitting', $condition + ['uid' => $Notification->uid]);
                return false;
        }
 
@@ -562,10 +561,10 @@ function notification_from_array(array $notification)
        // So, we cannot have different subjects for notifications of the same thread.
        // Before this we have the name of the replier on the subject rendering
        // different subjects for messages on the same thread.
-       if ($notification['type'] == Post\UserNotification::TYPE_EXPLICIT_TAGGED) {
+       if ($Notification->type === Post\UserNotification::TYPE_EXPLICIT_TAGGED) {
                $params['type'] = Notification\Type::TAG_SELF;
                $subject        = $l10n->t('%s %s tagged you', $subjectPrefix, $contact['name']);
-       } elseif ($notification['type'] == Post\UserNotification::TYPE_SHARED) {
+       } elseif ($Notification->type === Post\UserNotification::TYPE_SHARED) {
                $params['type'] = Notification\Type::SHARE;
                $subject        = $l10n->t('%s %s shared a new post', $subjectPrefix, $contact['name']);
        } else {
@@ -573,9 +572,9 @@ function notification_from_array(array $notification)
                $subject        = $l10n->t('%1$s Comment to conversation #%2$d by %3$s', $subjectPrefix, $item['parent'], $contact['name']);
        }
 
-       $msg = Notification::getMessage($notification);
+       $msg = (new Notifications\Factory\Notification(DI::logger()))->getMessageFromNotification($Notification, DI::baseUrl(), $l10n);
        if (empty($msg)) {
-               Logger::info('No notification message, quitting', ['uid' => $notification['uid'], 'id' => $notification['id'], 'type' => $notification['type']]);
+               Logger::info('No notification message, quitting', ['uid' => $Notification->uid, 'id' => $Notification->id, 'type' => $Notification->type]);
                return false;
        }
 
@@ -590,7 +589,7 @@ function notification_from_array(array $notification)
        $hsitelink = sprintf($sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
        $itemlink  = $params['link'];
 
-       Logger::info('Perform notification', ['uid' => $notification['uid'], 'id' => $notification['id'], 'type' => $notification['type']]);
+       Logger::info('Perform notification', ['uid' => $Notification->uid, 'id' => $Notification->id, 'type' => $Notification->type]);
 
        return notification_store_and_send($params, $sitelink, $tsitelink, $hsitelink, $title, $subject, $preamble, $epreamble, $item['body'], $itemlink, true);
 }
index 26f6eae368d310fb7279b84dca02147e1390c163..a349a552c30c088a12074ce1f0bd0dc27764424e 100644 (file)
@@ -222,7 +222,7 @@ function display_content(App $a, $update = false, $update_uid = 0)
        }
 
        if (!DI::pConfig()->get(local_user(), 'system', 'detailed_notif')) {
-               DBA::update('notification', ['seen' => true], ['parent-uri-id' => $item['parent-uri-id'], 'uid' => local_user()]);
+               DI::notification()->setAllSeenForUser(local_user(), ['parent-uri-id' => $item['parent-uri-id']]);
                DI::notify()->setAllSeenForUser(local_user(), ['parent-uri-id' => $item['parent-uri-id']]);
        }
 
index ed73ab767c335b0e79283a4d3c64012a1af12f6c..4168997d4be0a13681aade5321131e2a95c1a6d4 100644 (file)
@@ -458,6 +458,11 @@ abstract class DI
                return self::$dice->create(Repository\ProfileField::class);
        }
 
+       public static function notification(): Navigation\Notifications\Depository\Notification
+       {
+               return self::$dice->create(Navigation\Notifications\Depository\Notification::class);
+       }
+
        public static function notify(): Navigation\Notifications\Depository\Notify
        {
                return self::$dice->create(Navigation\Notifications\Depository\Notify::class);
index 03d102b503446ff7f5ce8c01aa6a012762982f9d..bdc5717f89f9f8f80b09757ec08ee5bfa5dd0739 100644 (file)
 namespace Friendica\Factory\Api\Mastodon;
 
 use Friendica\BaseFactory;
-use Friendica\Database\Database;
-use Friendica\Model\Notification as ModelNotification;
+use Friendica\Model\Contact;
+use Friendica\Navigation\Notifications;
+use Friendica\Navigation\Notifications\Exception\UnexpectedNotificationTypeException;
+use Friendica\Object\Api\Mastodon\Notification as MstdnNotification;
+use Friendica\Protocol\Activity;
 use Psr\Log\LoggerInterface;
+use Friendica\Navigation\Notifications\Entity;
+use Friendica\Model\Post;
 
 class Notification extends BaseFactory
 {
-       /** @var Database */
-       private $dba;
        /** @var Account */
        private $mstdnAccountFactory;
        /** @var Status */
        private $mstdnStatusFactory;
 
-       public function __construct(LoggerInterface $logger, Database $dba, Account $mstdnAccountFactory, Status $mstdnStatusFactoryFactory)
+       public function __construct(LoggerInterface $logger, Account $mstdnAccountFactory, Status $mstdnStatusFactoryFactory)
        {
                parent::__construct($logger);
-               $this->dba                 = $dba;
                $this->mstdnAccountFactory = $mstdnAccountFactory;
                $this->mstdnStatusFactory  = $mstdnStatusFactoryFactory;
        }
 
-       public function createFromNotificationId(int $id)
+       public function createFromNotification(Notifications\Entity\Notification $Notification): MstdnNotification
        {
-               $notification = $this->dba->selectFirst('notification', [], ['id' => $id]);
-               if (!$this->dba->isResult($notification)) {
-                       return null;
-               }
-
-               $type = ModelNotification::getType($notification);
+               $type = self::getType($Notification);
                if (empty($type)) {
-                       return null;
+                       throw new UnexpectedNotificationTypeException();
                }
 
-               $account = $this->mstdnAccountFactory->createFromContactId($notification['actor-id'], $notification['uid']);
+               $account = $this->mstdnAccountFactory->createFromContactId($Notification->actorId, $Notification->uid);
 
-               if (!empty($notification['target-uri-id'])) {
+               if ($Notification->targetUriId) {
                        try {
-                               $status = $this->mstdnStatusFactory->createFromUriId($notification['target-uri-id'], $notification['uid']);
+                               $status = $this->mstdnStatusFactory->createFromUriId($Notification->targetUriId, $Notification->uid);
                        } catch (\Throwable $th) {
                                $status = null;
                        }
@@ -67,6 +64,41 @@ class Notification extends BaseFactory
                        $status = null;
                }
 
-               return new \Friendica\Object\Api\Mastodon\Notification($id, $type, $notification['created'], $account, $status);
+               return new MstdnNotification($Notification->id, $type, $Notification->created, $account, $status);
+       }
+
+       /**
+        * Computes the Mastodon notification type from the given local notification
+        *
+        * @param Entity\Notification $Notification
+        * @return string
+        * @throws \Exception
+        */
+       public static function getType(Entity\Notification $Notification): string
+       {
+               if (($Notification->verb == Activity::FOLLOW) && ($Notification->type === Post\UserNotification::TYPE_NONE)) {
+                       $contact = Contact::getById($Notification->actorId, ['pending']);
+                       $type = $contact['pending'] ? MstdnNotification::TYPE_INTRODUCTION : MstdnNotification::TYPE_FOLLOW;
+               } elseif (($Notification->verb == Activity::ANNOUNCE) &&
+                       in_array($Notification->type, [Post\UserNotification::TYPE_DIRECT_COMMENT, Post\UserNotification::TYPE_DIRECT_THREAD_COMMENT])) {
+                       $type = MstdnNotification::TYPE_RESHARE;
+               } elseif (in_array($Notification->verb, [Activity::LIKE, Activity::DISLIKE]) &&
+                       in_array($Notification->type, [Post\UserNotification::TYPE_DIRECT_COMMENT, Post\UserNotification::TYPE_DIRECT_THREAD_COMMENT])) {
+                       $type = MstdnNotification::TYPE_LIKE;
+               } elseif ($Notification->type === Post\UserNotification::TYPE_SHARED) {
+                       $type = MstdnNotification::TYPE_POST;
+               } elseif (in_array($Notification->type, [
+                       Post\UserNotification::TYPE_EXPLICIT_TAGGED,
+                       Post\UserNotification::TYPE_IMPLICIT_TAGGED,
+                       Post\UserNotification::TYPE_DIRECT_COMMENT,
+                       Post\UserNotification::TYPE_DIRECT_THREAD_COMMENT,
+                       Post\UserNotification::TYPE_THREAD_COMMENT
+               ])) {
+                       $type = MstdnNotification::TYPE_MENTION;
+               } else {
+                       return '';
+               }
+
+               return $type;
        }
 }
index 18e041ab9849c1f18611f925b81e0e534deef8f1..ddf541b70e5afcd95d8640c8f33dbe0b30aed87e 100644 (file)
@@ -2705,7 +2705,7 @@ class Contact
                        // Ensure to always have the correct network type, independent from the connection request method
                        self::updateFromProbe($contact['id']);
 
-                       Post\UserNotification::insertNotification($contact['id'], Verb::getID(Activity::FOLLOW), $importer['uid']);
+                       Post\UserNotification::insertNotification($contact['id'], Activity::FOLLOW, $importer['uid']);
 
                        return true;
                } else {
@@ -2736,7 +2736,7 @@ class Contact
 
                        self::updateAvatar($contact_id, $photo, true);
 
-                       Post\UserNotification::insertNotification($contact_id, Verb::getID(Activity::FOLLOW), $importer['uid']);
+                       Post\UserNotification::insertNotification($contact_id, Activity::FOLLOW, $importer['uid']);
 
                        $contact_record = DBA::selectFirst('contact', ['id', 'network', 'name', 'url', 'photo'], ['id' => $contact_id]);
 
diff --git a/src/Model/Notification.php b/src/Model/Notification.php
deleted file mode 100644 (file)
index 284b3e7..0000000
+++ /dev/null
@@ -1,266 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Model;
-
-use Friendica\BaseModel;
-use Friendica\Content\Text\BBCode;
-use Friendica\Content\Text\Plaintext;
-use Friendica\Core\Logger;
-use Friendica\Database\Database;
-use Friendica\DI;
-use Friendica\Network\HTTPException\InternalServerErrorException;
-use Friendica\Object\Api\Mastodon\Notification as MstdnNotification;
-use Friendica\Protocol\Activity;
-use Psr\Log\LoggerInterface;
-
-/**
- * Model for an entry in the notify table
- */
-class Notification extends BaseModel
-{
-       /**
-        * Fetch the notification type for the given notification
-        *
-        * @param array $notification
-        * @return string
-        */
-       public static function getType(array $notification): string
-       {
-               if (($notification['vid'] == Verb::getID(Activity::FOLLOW)) && ($notification['type'] == Post\UserNotification::TYPE_NONE)) {
-                       $contact = Contact::getById($notification['actor-id'], ['pending']);
-                       $type = $contact['pending'] ? MstdnNotification::TYPE_INTRODUCTION : MstdnNotification::TYPE_FOLLOW;
-               } elseif (($notification['vid'] == Verb::getID(Activity::ANNOUNCE)) &&
-                       in_array($notification['type'], [Post\UserNotification::TYPE_DIRECT_COMMENT, Post\UserNotification::TYPE_DIRECT_THREAD_COMMENT])) {
-                       $type = MstdnNotification::TYPE_RESHARE;
-               } elseif (in_array($notification['vid'], [Verb::getID(Activity::LIKE), Verb::getID(Activity::DISLIKE)]) &&
-                       in_array($notification['type'], [Post\UserNotification::TYPE_DIRECT_COMMENT, Post\UserNotification::TYPE_DIRECT_THREAD_COMMENT])) {
-                       $type = MstdnNotification::TYPE_LIKE;
-               } elseif ($notification['type'] == Post\UserNotification::TYPE_SHARED) {
-                       $type = MstdnNotification::TYPE_POST;
-               } elseif (in_array($notification['type'], [
-                       Post\UserNotification::TYPE_EXPLICIT_TAGGED,
-            Post\UserNotification::TYPE_IMPLICIT_TAGGED,
-                       Post\UserNotification::TYPE_DIRECT_COMMENT,
-                       Post\UserNotification::TYPE_DIRECT_THREAD_COMMENT,
-                       Post\UserNotification::TYPE_THREAD_COMMENT
-               ])) {
-                       $type = MstdnNotification::TYPE_MENTION;
-               } else {
-                       return '';
-               }
-
-               return $type;
-       }
-
-       /**
-        * Create a notification message for the given notification
-        *
-        * @param array $notification
-        * @return array with the elements "causer", "notification", "plain" and "rich"
-        */
-       public static function getMessage(array $notification)
-       {
-               $message = [];
-
-               $user = User::getById($notification['uid']);
-               if (empty($user)) {
-                       Logger::info('User not found', ['application' => $notification['uid']]);
-                       return $message;
-               }
-
-               $l10n = DI::l10n()->withLang($user['language']);
-
-               $causer = $contact = Contact::getById($notification['actor-id'], ['id', 'name', 'url', 'pending']);
-               if (empty($contact)) {
-                       Logger::info('Contact not found', ['contact' => $notification['actor-id']]);
-                       return $message;
-               }
-
-               if ($notification['type'] == Post\UserNotification::TYPE_NONE) {
-                       if ($contact['pending']) {
-                               $msg = $l10n->t('%1$s wants to follow you');
-                       } else {
-                               $msg = $l10n->t('%1$s had started following you');
-                       }
-                       $title = $contact['name'];
-                       $link = DI::baseUrl() . '/contact/' . $contact['id'];
-               } else {
-                       if (empty($notification['target-uri-id'])) {
-                               return $message;
-                       }
-
-                       $like     = Verb::getID(Activity::LIKE);
-                       $dislike  = Verb::getID(Activity::DISLIKE);
-                       $announce = Verb::getID(Activity::ANNOUNCE);
-                       $post     = Verb::getID(Activity::POST);
-
-                       if (in_array($notification['type'], [Post\UserNotification::TYPE_THREAD_COMMENT, Post\UserNotification::TYPE_COMMENT_PARTICIPATION, Post\UserNotification::TYPE_ACTIVITY_PARTICIPATION, Post\UserNotification::TYPE_EXPLICIT_TAGGED])) {
-                               $item = Post::selectFirst([], ['uri-id' => $notification['parent-uri-id'], 'uid' => [0, $notification['uid']]], ['order' => ['uid' => true]]);
-                               if (empty($item)) {
-                                       Logger::info('Parent post not found', ['uri-id' => $notification['parent-uri-id']]);
-                                       return $message;
-                               }
-                       } else {
-                               $item = Post::selectFirst([], ['uri-id' => $notification['target-uri-id'], 'uid' => [0, $notification['uid']]], ['order' => ['uid' => true]]);
-                               if (empty($item)) {
-                                       Logger::info('Post not found', ['uri-id' => $notification['target-uri-id']]);
-                                       return $message;
-                               }
-
-                               if ($notification['vid'] == $post) {
-                                       $item = Post::selectFirst([], ['uri-id' => $item['thr-parent-id'], 'uid' => [0, $notification['uid']]], ['order' => ['uid' => true]]);
-                                       if (empty($item)) {
-                                               Logger::info('Thread parent post not found', ['uri-id' => $item['thr-parent-id']]);
-                                               return $message;
-                                       }
-                               }
-                       }
-
-                       if ($item['owner-id'] != $item['author-id']) {
-                               $cid = $item['owner-id'];
-                       }
-                       if (!empty($item['causer-id']) && ($item['causer-id'] != $item['author-id'])) {
-                               $cid = $item['causer-id'];
-                       }
-
-                       if (($notification['type'] == Post\UserNotification::TYPE_SHARED) && !empty($cid)) {
-                               $causer = Contact::getById($cid, ['id', 'name', 'url']);
-                               if (empty($contact)) {
-                                       Logger::info('Causer not found', ['causer' => $cid]);
-                                       return $message;
-                               }
-                       } elseif (in_array($notification['type'], [Post\UserNotification::TYPE_COMMENT_PARTICIPATION, Post\UserNotification::TYPE_ACTIVITY_PARTICIPATION])) {
-                               $contact = Contact::getById($item['author-id'], ['id', 'name', 'url']);
-                               if (empty($contact)) {
-                                       Logger::info('Author not found', ['author' => $item['author-id']]);
-                                       return $message;
-                               }
-                       }
-
-                       $link = DI::baseUrl() . '/display/' . urlencode($item['guid']);
-
-                       $content = Plaintext::getPost($item, 70);
-                       if (!empty($content['text'])) {
-                               $title = '"' . trim(str_replace("\n", " ", $content['text'])) . '"';
-                       } else {
-                               $title = '';
-                       }
-
-                       switch ($notification['vid']) {
-                               case $like:
-                                       switch ($notification['type']) {
-                                               case Post\UserNotification::TYPE_DIRECT_COMMENT:
-                                                       $msg = $l10n->t('%1$s liked your comment %2$s');
-                                                       break;
-                                               case Post\UserNotification::TYPE_DIRECT_THREAD_COMMENT:
-                                                       $msg = $l10n->t('%1$s liked your post %2$s');
-                                                       break;
-                                               }
-                                       break;
-                               case $dislike:
-                                       switch ($notification['type']) {
-                                               case Post\UserNotification::TYPE_DIRECT_COMMENT:
-                                                       $msg = $l10n->t('%1$s disliked your comment %2$s');
-                                                       break;
-                                               case Post\UserNotification::TYPE_DIRECT_THREAD_COMMENT:
-                                                       $msg = $l10n->t('%1$s disliked your post %2$s');
-                                                       break;
-                                       }
-                                       break;
-                               case $announce:
-                                       switch ($notification['type']) {
-                                               case Post\UserNotification::TYPE_DIRECT_COMMENT:
-                                                       $msg = $l10n->t('%1$s shared your comment %2$s');
-                                                       break;
-                                               case Post\UserNotification::TYPE_DIRECT_THREAD_COMMENT:
-                                                       $msg = $l10n->t('%1$s shared your post %2$s');
-                                                       break;
-                                               }
-                                       break;
-                               case $post:
-                                       switch ($notification['type']) {
-                                               case Post\UserNotification::TYPE_EXPLICIT_TAGGED:
-                                                       $msg = $l10n->t('%1$s tagged you on %2$s');
-                                                       break;
-
-                                               case Post\UserNotification::TYPE_IMPLICIT_TAGGED:
-                                                       $msg = $l10n->t('%1$s replied to you on %2$s');
-                                                       break;
-
-                                               case Post\UserNotification::TYPE_THREAD_COMMENT:
-                                                       $msg = $l10n->t('%1$s commented in your thread %2$s');
-                                                       break;
-
-                                               case Post\UserNotification::TYPE_DIRECT_COMMENT:
-                                                       $msg = $l10n->t('%1$s commented on your comment %2$s');
-                                                       break;
-
-                                               case Post\UserNotification::TYPE_COMMENT_PARTICIPATION:
-                                               case Post\UserNotification::TYPE_ACTIVITY_PARTICIPATION:
-                                                       if (($causer['id'] == $contact['id']) && ($title != '')) {
-                                                               $msg = $l10n->t('%1$s commented in their thread %2$s');
-                                                       } elseif ($causer['id'] == $contact['id']) {
-                                                               $msg = $l10n->t('%1$s commented in their thread');
-                                                       } elseif ($title != '') {
-                                                               $msg = $l10n->t('%1$s commented in the thread %2$s from %3$s');
-                                                       } else {
-                                                               $msg = $l10n->t('%1$s commented in the thread from %3$s');
-                                                       }
-                                                       break;
-
-                                               case Post\UserNotification::TYPE_DIRECT_THREAD_COMMENT:
-                                                       $msg = $l10n->t('%1$s commented on your thread %2$s');
-                                                       break;
-
-                                               case Post\UserNotification::TYPE_SHARED:
-                                                       if (($causer['id'] != $contact['id']) && ($title != '')) {
-                                                               $msg = $l10n->t('%1$s shared the post %2$s from %3$s');
-                                                       } elseif ($causer['id'] != $contact['id']) {
-                                                               $msg = $l10n->t('%1$s shared a post from %3$s');
-                                                       } elseif ($title != '') {
-                                                               $msg = $l10n->t('%1$s shared the post %2$s');
-                                                       } else {
-                                                               $msg = $l10n->t('%1$s shared a post');
-                                                       }
-                                                       break;
-                                       }
-                                       break;
-                       }
-               }
-
-               if (!empty($msg)) {
-                       // Name of the notification's causer
-                       $message['causer'] = $causer['name'];
-                       // Format for the "ping" mechanism
-                       $message['notification'] = sprintf($msg, '{0}', $title, $contact['name']);
-                       // Plain text for the web push api
-                       $message['plain']        = sprintf($msg, $causer['name'], $title, $contact['name']);
-                       // Rich text for other purposes
-                       $message['rich']         = sprintf($msg,
-                               '[url=' . $causer['url'] . ']' . $causer['name'] . '[/url]',
-                               '[url=' . $link . ']' . $title . '[/url]',
-                               '[url=' . $contact['url'] . ']' . $contact['name'] . '[/url]');
-               }
-
-               return $message;
-       }
-}
index 065cba44ca706f72f3e034a2b4b6eee64fda54d8..d14eb7f3be556a9c7b1cd94ecee028367bbc4337 100644 (file)
@@ -33,9 +33,9 @@ use Friendica\Model\Contact;
 use Friendica\Model\Post;
 use Friendica\Model\Subscription;
 use Friendica\Model\Tag;
+use Friendica\Navigation\Notifications;
 use Friendica\Network\HTTPException;
 use Friendica\Protocol\Activity;
-use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Strings;
 
 class UserNotification
@@ -286,56 +286,46 @@ class UserNotification
                        return;
                }
 
-               $fields = [
-                       'uid' => $uid,
-                       'vid' => $item['vid'],
-                       'type' => $type,
-                       'actor-id' => $item['author-id'],
-                       'parent-uri-id' => $item['parent-uri-id'],
-                       'created' => DateTimeFormat::utcNow(),
-               ];
+               $notification = (new Notifications\Factory\Notification(DI::logger()))->createForUser(
+                       $uid,
+                       $item['vid'],
+                       $type,
+                       $item['author-id'],
+                       $item['gravity'] == GRAVITY_ACTIVITY ? $item['thr-parent-id'] : $item['uri-id'],
+                       $item['parent-uri-id']
+               );
 
-               if ($item['gravity'] == GRAVITY_ACTIVITY) {
-                       $fields['target-uri-id'] = $item['thr-parent-id'];
-               } else {
-                       $fields['target-uri-id'] = $item['uri-id'];
-               }
+               try {
+                       $notification = DI::notification()->save($notification);
+                       Subscription::pushByNotification($notification);
+               } catch (Exception $e) {
 
-               if (DBA::insert('notification', $fields, Database::INSERT_IGNORE)) {
-                       $id = DBA::lastInsertId();
-                       if (!empty($id)) {
-                               Subscription::pushByNotificationId($id);
-                       }
                }
        }
 
        /**
         * Add a notification entry
         *
-        * @param int $actor Contact ID of the actor
-        * @param int $vid   Verb ID
-        * @param int $uid   User ID
+        * @param int    $actor Contact ID of the actor
+        * @param string $verb  One of the Activity verb constant values
+        * @param int    $uid   User ID
         * @return boolean
         * @throws Exception
         */
-       public static function insertNotification(int $actor, int $vid, int $uid): bool
+       public static function insertNotification(int $actor, string $verb, int $uid): bool
        {
-               $fields = [
-                       'uid' => $uid,
-                       'vid' => $vid,
-                       'type' => self::TYPE_NONE,
-                       'actor-id' => $actor,
-                       'created' => DateTimeFormat::utcNow(),
-               ];
-
-               $ret = DBA::insert('notification', $fields, Database::INSERT_IGNORE);
-               if ($ret) {
-                       $id = DBA::lastInsertId();
-                       if (!empty($id)) {
-                               Subscription::pushByNotificationId($id);
-                       }
+               $notification = (new Notifications\Factory\Notification(DI::logger()))->createForRelationship(
+                       $uid,
+                       $actor,
+                       $verb
+               );
+               try {
+                       $notification = DI::notification()->save($notification);
+                       Subscription::pushByNotification($notification);
+                       return true;
+               } catch (Exception $e) {
+                       return false;
                }
-               return $ret;
        }
 
        /**
index f9498af986a5b5fb2205c84b76bc8c3c5d2968b3..c6c57c732835da504b97cb9c6f95215636456b5a 100644 (file)
@@ -25,6 +25,7 @@ use Friendica\Core\Logger;
 use Friendica\Core\Worker;
 use Friendica\Database\DBA;
 use Friendica\DI;
+use Friendica\Navigation\Notifications\Entity;
 use Friendica\Object\Api\Mastodon\Notification;
 use Minishlink\WebPush\VAPID;
 
@@ -138,34 +139,32 @@ class Subscription
         * @param int $nid
         * @return void
         */
-       public static function pushByNotificationId(int $nid)
+       public static function pushByNotification(Entity\Notification $Notification)
        {
-               $notification = DBA::selectFirst('notification', [], ['id' => $nid]);
+               $type = \Friendica\Factory\Api\Mastodon\Notification::getType($Notification);
 
-               $type = Notification::getType($notification);
                $desktop_notification = !in_array($type, [Notification::TYPE_RESHARE, Notification::TYPE_LIKE]);
 
-
-               if (DI::pConfig()->get($notification['uid'], 'system', 'notify_like') && ($type == 'favourite')) {
+               if (DI::pConfig()->get($Notification->uid, 'system', 'notify_like') && ($type == Notification::TYPE_LIKE)) {
                        $desktop_notification = true;
                }
 
-               if (DI::pConfig()->get($notification['uid'], 'system', 'notify_announce') && ($type == 'reblog')) {
+               if (DI::pConfig()->get($Notification->uid, 'system', 'notify_announce') && ($type == Notification::TYPE_RESHARE)) {
                        $desktop_notification = true;
                }
 
                if ($desktop_notification) {
-                       notification_from_array($notification);
+                       notification_from_array($Notification);
                }
 
                if (empty($type)) {
                        return;
                }
 
-               $subscriptions = DBA::select('subscription', [], ['uid' => $notification['uid'], $type => true]);
+               $subscriptions = DBA::select('subscription', [], ['uid' => $Notification->uid, $type => true]);
                while ($subscription = DBA::fetch($subscriptions)) {
                        Logger::info('Push notification', ['id' => $subscription['id'], 'uid' => $subscription['uid'], 'type' => $type]);
-                       Worker::add(PRIORITY_HIGH, 'PushSubscription', $subscription['id'], $nid);
+                       Worker::add(PRIORITY_HIGH, 'PushSubscription', $subscription['id'], $Notification->id);
                }
                DBA::close($subscriptions);
        }
index a04a9ae69ac1e56a00d088c457ff31c4f27addc4..28166e6ed7fff66eddce3a927292f71e715e58ed 100644 (file)
@@ -28,6 +28,8 @@ use Friendica\Model\Contact;
 use Friendica\Model\Post;
 use Friendica\Model\Verb;
 use Friendica\Module\BaseApi;
+use Friendica\Navigation\Notifications\Entity;
+use Friendica\Object\Api\Mastodon\Notification;
 use Friendica\Protocol\Activity;
 
 /**
@@ -46,10 +48,12 @@ class Notifications extends BaseApi
 
                if (!empty($parameters['id'])) {
                        $id = $parameters['id'];
-                       if (!DBA::exists('notification', ['id' => $id, 'uid' => $uid])) {
+                       try {
+                               $notification = DI::notification()->selectOneForUser($uid, ['id' => $id]);
+                               System::jsonExit(DI::mstdnNotification()->createFromNotification($notification));
+                       } catch (\Exception $e) {
                                DI::mstdnError()->RecordNotFound();
                        }
-                       System::jsonExit(DI::mstdnNotification()->createFromNotificationId($id));
                }
 
                $request = self::getRequest([
@@ -63,7 +67,7 @@ class Notifications extends BaseApi
                        'count'         => 0,     // Unknown parameter
                ]);
 
-               $params = ['order' => ['id' => true], 'limit' => $request['limit']];
+               $params = ['order' => ['id' => true]];
 
                $condition = ['uid' => $uid, 'seen' => false];
 
@@ -115,36 +119,26 @@ class Notifications extends BaseApi
                                Verb::getID(Activity::POST), Post\UserNotification::TYPE_SHARED]);
                }
 
-               if (!empty($request['max_id'])) {
-                       $condition = DBA::mergeConditions($condition, ["`id` < ?", $request['max_id']]);
-               }
-
-               if (!empty($request['since_id'])) {
-                       $condition = DBA::mergeConditions($condition, ["`id` > ?", $request['since_id']]);
-               }
-
-               if (!empty($request['min_id'])) {
-                       $condition = DBA::mergeConditions($condition, ["`id` > ?", $request['min_id']]);
-
-                       $params['order'] = ['id'];
-               }
-
-               $notifications = [];
-
-               $notify = DBA::select('notification', ['id'], $condition, $params);
-               while ($notification = DBA::fetch($notify)) {
-                       self::setBoundaries($notification['id']);
-                       $entry = DI::mstdnNotification()->createFromNotificationId($notification['id']);
-                       if (!empty($entry)) {
-                               $notifications[] = $entry;
+               $mstdnNotifications = [];
+
+               $Notifications = DI::notification()->selectByBoundaries(
+                       $condition,
+                       $params,
+                       $request['min_id'] ?? null,
+                       $request['min_id'] ?? $request['since_id'] ?? null,
+                       $request['limit']
+               );
+
+               foreach($Notifications as $Notification) {
+                       try {
+                               $mstdnNotifications[] = DI::mstdnNotification()->createFromNotification($Notification);
+                               self::setBoundaries($Notification->id);
+                       } catch (\Exception $e) {
+                               // Skip this notification
                        }
                }
 
-               if (!empty($request['min_id'])) {
-                       array_reverse($notifications);
-               }
-
                self::setLinkHeader();
-               System::jsonExit($notifications);
+               System::jsonExit($mstdnNotifications);
        }
 }
index 5471dc24e6084197d25fdafc84836a6dec6193e2..9dca0bf65545d3a642d0222e8f6e2ed96d818b40 100644 (file)
@@ -22,7 +22,7 @@
 namespace Friendica\Module\Api\Mastodon\Notifications;
 
 use Friendica\Core\System;
-use Friendica\Database\DBA;
+use Friendica\DI;
 use Friendica\Module\BaseApi;
 
 /**
@@ -35,7 +35,7 @@ class Clear extends BaseApi
                self::checkAllowedScope(self::SCOPE_WRITE);
                $uid = self::getCurrentUserID();
 
-               DBA::update('notification', ['seen' => true], ['uid' => $uid]);
+               DI::notification()->setAllSeenForUser($uid);
 
                System::jsonExit([]);
        }
index 8900a2d43f9eff288595e0b76259b0583962851e..b615c5e890d17aa53dd71bf8679091619eb58727 100644 (file)
@@ -25,6 +25,7 @@ use Friendica\Core\System;
 use Friendica\Database\DBA;
 use Friendica\DI;
 use Friendica\Module\BaseApi;
+use Friendica\Network\HTTPException\ForbiddenException;
 
 /**
  * @see https://docs.joinmastodon.org/methods/notifications/
@@ -40,7 +41,9 @@ class Dismiss extends BaseApi
                        DI::mstdnError()->UnprocessableEntity();
                }
 
-               DBA::update('notification', ['seen' => true], ['uid' => $uid, 'id' => $parameters['id']]);
+               $Notification = DI::notification()->selectOneForUser($uid, $parameters['id']);
+               $Notification->setSeen();
+               DI::notification()->save($Notification);
 
                System::jsonExit([]);
        }
index 6f032772c7dec6f35b227b97822656c86c3e2e3f..2480e63b0bab005a1bae3392cc74c00a45a33842 100644 (file)
@@ -78,7 +78,7 @@ class Notification extends BaseModule
 
                if (DI::args()->get(1) === 'mark' && DI::args()->get(2) === 'all') {
                        try {
-                               DI::dba()->update('notification', ['seen' => true], ['uid' => local_user()]);
+                               DI::notification()->setAllSeenForUser(local_user());
                                $success = DI::notify()->setAllSeenForUser(local_user());
                        } catch (\Exception $e) {
                                DI::logger()->warning('set all seen failed.', ['exception' => $e]);
@@ -118,7 +118,7 @@ class Notification extends BaseModule
                                DI::notify()->save($Notify);
                        } else {
                                if ($Notify->uriId) {
-                                       DI::dba()->update('notification', ['seen' => true], ['uid' => $Notify->uid, 'target-uri-id' => $Notify->uriId]);
+                                       DI::notification()->setAllSeenForUser($Notify->uid, ['target-uri-id' => $Notify->uriId]);
                                }
 
                                DI::notify()->setAllSeenForRelatedNotify($Notify);
index 79f1596f9596c29b10b2f47e8fe268b8534f680f..af8b14512b35795515aaef0ff9e5ad254e82c166 100644 (file)
@@ -95,25 +95,24 @@ class Notifications extends BaseNotifications
                $notificationHeader = $notificationResult['header'] ?? '';
 
                if (!empty($notifications['notifications'])) {
+                       $notificationTemplates = [
+                               'like'         => 'notifications/likes_item.tpl',
+                               'dislike'      => 'notifications/dislikes_item.tpl',
+                               'attend'       => 'notifications/attend_item.tpl',
+                               'attendno'     => 'notifications/attend_item.tpl',
+                               'attendmaybe'  => 'notifications/attend_item.tpl',
+                               'friend'       => 'notifications/friends_item.tpl',
+                               'comment'      => 'notifications/comments_item.tpl',
+                               'post'         => 'notifications/posts_item.tpl',
+                               'notification' => 'notifications/notification.tpl',
+                       ];
                        // Loop trough ever notification This creates an array with the output html for each
                        // notification and apply the correct template according to the notificationtype (label).
-                       /** @var FormattedNotification $notification */
-                       foreach ($notifications['notifications'] as $notification) {
-                               $notification_templates = [
-                                       'like'         => 'notifications/likes_item.tpl',
-                                       'dislike'      => 'notifications/dislikes_item.tpl',
-                                       'attend'       => 'notifications/attend_item.tpl',
-                                       'attendno'     => 'notifications/attend_item.tpl',
-                                       'attendmaybe'  => 'notifications/attend_item.tpl',
-                                       'friend'       => 'notifications/friends_item.tpl',
-                                       'comment'      => 'notifications/comments_item.tpl',
-                                       'post'         => 'notifications/posts_item.tpl',
-                                       'notification' => 'notifications/notification.tpl',
-                               ];
-
-                               $notificationArray = $notification->toArray();
+                       /** @var FormattedNotification $Notification */
+                       foreach ($notifications['notifications'] as $Notification) {
+                               $notificationArray = $Notification->toArray();
 
-                               $notificationTemplate = Renderer::getMarkupTemplate($notification_templates[$notificationArray['label']]);
+                               $notificationTemplate = Renderer::getMarkupTemplate($notificationTemplates[$notificationArray['label']]);
 
                                $notificationContent[] = Renderer::replaceMacros($notificationTemplate, [
                                        '$notification' => $notificationArray
index d660baa083727016cc07afe1bb3d6fe2049c3612..d912dc894d2ef66e6d27cd511978b841ec48110f 100644 (file)
@@ -66,11 +66,11 @@ class Notification extends BaseDataTransferObject
         *
         * @throws HttpException\InternalServerErrorException|Exception
         */
-       public function __construct(int $id, string $type, string $created_at, Account $account = null, Status $status = null)
+       public function __construct(int $id, string $type, \DateTime $created_at, Account $account = null, Status $status = null)
        {
                $this->id         = (string)$id;
                $this->type       = $type;
-               $this->created_at = DateTimeFormat::utc($created_at, DateTimeFormat::JSON);
+               $this->created_at = $created_at->format(DateTimeFormat::JSON);
                $this->account    = $account->toArray();
 
                if (!empty($status)) {
index eaf2adb32d53a86fef59b9952d034a895874a556..ae34abc8775c56377215075eb9fd83da7a46fa67 100644 (file)
@@ -27,10 +27,11 @@ use Friendica\Core\Logger;
 use Friendica\Database\DBA;
 use Friendica\DI;
 use Friendica\Model\Contact;
-use Friendica\Model\Notification;
 use Friendica\Model\Post;
 use Friendica\Model\Subscription as ModelSubscription;
 use Friendica\Model\User;
+use Friendica\Navigation\Notifications;
+use Friendica\Network\HTTPException\NotFoundException;
 use Minishlink\WebPush\WebPush;
 use Minishlink\WebPush\Subscription;
 
@@ -46,8 +47,9 @@ class PushSubscription
                        return;
                }
 
-               $notification = DBA::selectFirst('notification', [], ['id' => $nid]);
-               if (empty($notification)) {
+               try {
+                       $Notification = DI::notification()->selectOneById($nid);
+               } catch (NotFoundException $e) {
                        Logger::info('Notification not found', ['notification' => $nid]);
                        return;
                }
@@ -58,7 +60,7 @@ class PushSubscription
                        return;
                }
 
-               $user = User::getById($notification['uid']);
+               $user = User::getById($Notification->uid);
                if (empty($user)) {
                        Logger::info('User not found', ['application' => $subscription['uid']]);
                        return;
@@ -66,23 +68,21 @@ class PushSubscription
 
                $l10n = DI::l10n()->withLang($user['language']);
 
-               $type = Notification::getType($notification);
-
-               if (!empty($notification['actor-id'])) {
-                       $actor = Contact::getById($notification['actor-id']);
+               if ($Notification->actorId) {
+                       $actor = Contact::getById($Notification->actorId);
                }
 
                $body = '';
 
-               if (!empty($notification['target-uri-id'])) {
-                       $post = Post::selectFirst([], ['uri-id' => $notification['target-uri-id'], 'uid' => [0, $notification['uid']]]);
+               if ($Notification->targetUriId) {
+                       $post = Post::selectFirst([], ['uri-id' => $Notification->targetUriId, 'uid' => [0, $Notification->uid]]);
                        if (!empty($post['body'])) {
                                $body = BBCode::toPlaintext($post['body'], false);
-                               $body = Plaintext::shorten($body, 160, $notification['uid']);
+                               $body = Plaintext::shorten($body, 160, $Notification->uid);
                        }
                }
 
-               $message = Notification::getMessage($notification);
+               $message = (new Notifications\Factory\Notification(DI::logger()))->getMessageFromNotification($Notification, DI::baseUrl(), $l10n);
                $title = $message['plain'] ?: '';
 
                $push = Subscription::create([
@@ -98,7 +98,7 @@ class PushSubscription
                        'access_token'      => $application_token['access_token'],
                        'preferred_locale'  => $user['language'],
                        'notification_id'   => $nid,
-                       'notification_type' => $type,
+                       'notification_type' => \Friendica\Factory\Api\Mastodon\Notification::getType($Notification),
                        'icon'              => $actor['thumb'] ?? '',
                        'title'             => $title ?: $l10n->t('Notification from Friendica'),
                        'body'              => $body ?: $l10n->t('Empty Post'),