diff --git a/src/DI.php b/src/DI.php index 43234946cb..1283100313 100644 --- a/src/DI.php +++ b/src/DI.php @@ -487,6 +487,11 @@ abstract class DI return self::$dice->create(Contact\Introduction\Factory\Introduction::class); } + public static function localRelationship(): Contact\LocalRelationship\Repository\LocalRelationship + { + return self::$dice->create(Contact\LocalRelationship\Repository\LocalRelationship::class); + } + public static function permissionSet(): Security\PermissionSet\Repository\PermissionSet { return self::$dice->create(Security\PermissionSet\Repository\PermissionSet::class); diff --git a/src/Model/Contact.php b/src/Model/Contact.php index f0be457722..cdb347e8be 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -2665,7 +2665,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'], Activity::FOLLOW, $importer['uid']); + Post\UserNotification::insertNotification($pub_contact['id'], Activity::FOLLOW, $importer['uid']); return true; } else { @@ -2696,7 +2696,7 @@ class Contact self::updateAvatar($contact_id, $photo, true); - Post\UserNotification::insertNotification($contact_id, Activity::FOLLOW, $importer['uid']); + Post\UserNotification::insertNotification($pub_contact['id'], Activity::FOLLOW, $importer['uid']); $contact_record = DBA::selectFirst('contact', ['id', 'network', 'name', 'url', 'photo'], ['id' => $contact_id]); @@ -2716,9 +2716,7 @@ class Contact Group::addMember(User::getDefaultGroup($importer['uid']), $contact_record['id']); - if (($user['notify-flags'] & Notification\Type::INTRO) && - in_array($user['page-flags'], [User::PAGE_FLAGS_NORMAL])) { - + if (($user['notify-flags'] & Notification\Type::INTRO) && $user['page-flags'] == User::PAGE_FLAGS_NORMAL) { DI::notify()->createFromArray([ 'type' => Notification\Type::INTRO, 'otype' => Notification\ObjectType::INTRO, diff --git a/src/Model/Post/UserNotification.php b/src/Model/Post/UserNotification.php index d9bd2256f2..0873646a41 100644 --- a/src/Model/Post/UserNotification.php +++ b/src/Model/Post/UserNotification.php @@ -308,7 +308,7 @@ class UserNotification return; } - $notification = (new Notifications\Factory\Notification(DI::logger()))->createForUser( + $notification = (new Notifications\Factory\Notification(DI::baseUrl(), DI::l10n(), DI::localRelationship(), DI::logger()))->createForUser( $uid, $item['vid'], $type, @@ -328,7 +328,7 @@ class UserNotification /** * Add a notification entry * - * @param int $actor Contact ID of the actor + * @param int $actor Public contact ID of the actor * @param string $verb One of the Activity verb constant values * @param int $uid User ID * @return boolean @@ -336,7 +336,7 @@ class UserNotification */ public static function insertNotification(int $actor, string $verb, int $uid): bool { - $notification = (new Notifications\Factory\Notification(DI::logger()))->createForRelationship( + $notification = (new Notifications\Factory\Notification(DI::baseUrl(), DI::l10n(), DI::localRelationship(), DI::logger()))->createForRelationship( $uid, $actor, $verb diff --git a/src/Navigation/Notifications/Entity/Notification.php b/src/Navigation/Notifications/Entity/Notification.php index 15cf3be537..0f12bfe84f 100644 --- a/src/Navigation/Notifications/Entity/Notification.php +++ b/src/Navigation/Notifications/Entity/Notification.php @@ -34,6 +34,7 @@ use Friendica\BaseEntity; * @property-read $parentUriId * @property-read $created * @property-read $seen + * @property-read $dismissed */ class Notification extends BaseEntity { @@ -72,11 +73,11 @@ class Notification extends BaseEntity * @param int|null $parentUriId * @param DateTime|null $created * @param bool $seen - * @param int|null $id * @param bool $dismissed + * @param int|null $id * @see \Friendica\Navigation\Notifications\Factory\Notification */ - public function __construct(int $uid, string $verb, int $type, int $actorId, int $targetUriId = null, int $parentUriId = null, DateTime $created = null, bool $seen = false, int $id = null, bool $dismissed = false) + public function __construct(int $uid, string $verb, int $type, int $actorId, int $targetUriId = null, int $parentUriId = null, DateTime $created = null, bool $seen = false, bool $dismissed = false, int $id = null) { $this->uid = $uid; $this->verb = $verb; @@ -86,8 +87,9 @@ class Notification extends BaseEntity $this->parentUriId = $parentUriId ?: $targetUriId; $this->created = $created; $this->seen = $seen; - $this->id = $id; $this->dismissed = $dismissed; + + $this->id = $id; } public function setSeen() diff --git a/src/Navigation/Notifications/Factory/Notification.php b/src/Navigation/Notifications/Factory/Notification.php index 7cc17f8fe3..50180a9203 100644 --- a/src/Navigation/Notifications/Factory/Notification.php +++ b/src/Navigation/Notifications/Factory/Notification.php @@ -24,16 +24,35 @@ namespace Friendica\Navigation\Notifications\Factory; use Friendica\App\BaseURL; use Friendica\BaseFactory; use Friendica\Capabilities\ICanCreateFromTableRow; +use Friendica\Contact\LocalRelationship\Repository\LocalRelationship; use Friendica\Content\Text\Plaintext; use Friendica\Core\L10n; use Friendica\Model\Contact; use Friendica\Model\Post; use Friendica\Model\Verb; use Friendica\Navigation\Notifications\Entity; +use Friendica\Network\HTTPException; use Friendica\Protocol\Activity; +use Psr\Log\LoggerInterface; class Notification extends BaseFactory implements ICanCreateFromTableRow { + /** @var BaseURL */ + private $baseUrl; + /** @var L10n */ + private $l10n; + /** @var LocalRelationship */ + private $localRelationshipRepo; + + public function __construct(\Friendica\App\BaseURL $baseUrl, \Friendica\Core\L10n $l10n, \Friendica\Contact\LocalRelationship\Repository\LocalRelationship $localRelationshipRepo, LoggerInterface $logger) + { + parent::__construct($logger); + + $this->baseUrl = $baseUrl; + $this->l10n = $l10n; + $this->localRelationshipRepo = $localRelationshipRepo; + } + public function createFromTableRow(array $row): Entity\Notification { return new Entity\Notification( @@ -45,7 +64,8 @@ class Notification extends BaseFactory implements ICanCreateFromTableRow $row['parent-uri-id'], new \DateTime($row['created'], new \DateTimeZone('UTC')), $row['seen'], - $row['id'] + $row['dismissed'], + $row['id'], ); } @@ -61,6 +81,12 @@ class Notification extends BaseFactory implements ICanCreateFromTableRow ); } + /** + * @param int $uid + * @param int $contactId Public contact id + * @param string $verb + * @return Entity\Notification + */ public function createForRelationship(int $uid, int $contactId, string $verb): Entity\Notification { return new Entity\Notification( @@ -73,12 +99,11 @@ class Notification extends BaseFactory implements ICanCreateFromTableRow /** * @param Entity\Notification $Notification - * @param BaseURL $baseUrl - * @param L10n $userL10n Seeded with the language of the user we mean the notification for * @return array - * @throws \Friendica\Network\HTTPException\InternalServerErrorException + * @throws HTTPException\InternalServerErrorException + * @throws HTTPException\NotFoundException */ - public function getMessageFromNotification(Entity\Notification $Notification, BaseURL $baseUrl, L10n $userL10n) + public function getMessageFromNotification(Entity\Notification $Notification): array { $message = []; @@ -89,37 +114,41 @@ class Notification extends BaseFactory implements ICanCreateFromTableRow } if ($Notification->type === Post\UserNotification::TYPE_NONE) { - if ($causer['pending']) { - $msg = $userL10n->t('%1$s wants to follow you'); + $localRelationship = $this->localRelationshipRepo->getForUserContact($Notification->uid, $Notification->actorId); + if ($localRelationship->pending) { + $msg = $this->l10n->t('%1$s wants to follow you'); } else { - $msg = $userL10n->t('%1$s had started following you'); + $msg = $this->l10n->t('%1$s had started following you'); } + $title = $causer['name']; - $link = $baseUrl . '/contact/' . $causer['id']; + $link = $this->baseUrl . '/contact/' . $causer['id']; } else { if (!$Notification->targetUriId) { return $message; } - 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->parentUriId, 'uid' => [0, $Notification->uid]], ['order' => ['uid' => true]]); - if (empty($item)) { - $this->logger->info('Parent post not found', ['uri-id' => $Notification->parentUriId]); - return $message; - } - } else { - $item = Post::selectFirst([], ['uri-id' => $Notification->targetUriId, 'uid' => [0, $Notification->uid]], ['order' => ['uid' => true]]); - if (empty($item)) { - $this->logger->info('Post not found', ['uri-id' => $Notification->targetUriId]); - return $message; - } + $item = Post::selectFirst([], ['uri-id' => $Notification->targetUriId, 'uid' => [0, $Notification->uid]], ['order' => ['uid' => true]]); + if (empty($item)) { + $this->logger->info('Post not found', ['uri-id' => $Notification->targetUriId]); + return $message; + } - if (($Notification->verb == Activity::POST) || ($Notification->type === Post\UserNotification::TYPE_SHARED)) { - $item = Post::selectFirst([], ['uri-id' => $item['thr-parent-id'], 'uid' => [0, $Notification->uid]], ['order' => ['uid' => true]]); - if (empty($item)) { - $this->logger->info('Thread parent post not found', ['uri-id' => $item['thr-parent-id']]); - return $message; - } + if ($Notification->type == Post\UserNotification::TYPE_ACTIVITY_PARTICIPATION) { + $thrParentId = $item['thr-parent-id']; + $item = Post::selectFirst([], ['uri-id' => $thrParentId, 'uid' => [0, $Notification->uid]], ['order' => ['uid' => true]]); + if (empty($item)) { + $this->logger->info('Thread parent post not found', ['uri-id' => $thrParentId]); + return $message; + } + } + + $parent = $item; + if ($Notification->targetUriId != $Notification->parentUriId) { + $parent = Post::selectFirst([], ['uri-id' => $Notification->parentUriId, 'uid' => [0, $Notification->uid]], ['order' => ['uid' => true]]); + if (empty($parent)) { + $this->logger->info('Top level post not found', ['uri-id' => $Notification->parentUriId]); + return $message; } } @@ -131,9 +160,9 @@ class Notification extends BaseFactory implements ICanCreateFromTableRow } } - $link = $baseUrl . '/display/' . urlencode($item['guid']); + $link = $this->baseUrl . '/display/' . urlencode($item['guid']); - $content = Plaintext::getPost($item, 70); + $content = Plaintext::getPost($parent, 70); if (!empty($content['text'])) { $title = '"' . trim(str_replace("\n", " ", $content['text'])) . '"'; } else { @@ -146,40 +175,40 @@ class Notification extends BaseFactory implements ICanCreateFromTableRow case Activity::LIKE: switch ($Notification->type) { case Post\UserNotification::TYPE_DIRECT_COMMENT: - $msg = $userL10n->t('%1$s liked your comment %2$s'); + $msg = $this->l10n->t('%1$s liked your comment %2$s'); break; case Post\UserNotification::TYPE_DIRECT_THREAD_COMMENT: - $msg = $userL10n->t('%1$s liked your post %2$s'); + $msg = $this->l10n->t('%1$s liked your post %2$s'); break; } break; case Activity::DISLIKE: switch ($Notification->type) { case Post\UserNotification::TYPE_DIRECT_COMMENT: - $msg = $userL10n->t('%1$s disliked your comment %2$s'); + $msg = $this->l10n->t('%1$s disliked your comment %2$s'); break; case Post\UserNotification::TYPE_DIRECT_THREAD_COMMENT: - $msg = $userL10n->t('%1$s disliked your post %2$s'); + $msg = $this->l10n->t('%1$s disliked your post %2$s'); break; } break; case Activity::ANNOUNCE: switch ($Notification->type) { case Post\UserNotification::TYPE_DIRECT_COMMENT: - $msg = $userL10n->t('%1$s shared your comment %2$s'); + $msg = $this->l10n->t('%1$s shared your comment %2$s'); break; case Post\UserNotification::TYPE_DIRECT_THREAD_COMMENT: - $msg = $userL10n->t('%1$s shared your post %2$s'); + $msg = $this->l10n->t('%1$s shared your post %2$s'); break; case Post\UserNotification::TYPE_SHARED: if (($causer['id'] != $author['id']) && ($title != '')) { - $msg = $userL10n->t('%1$s shared the post %2$s from %3$s'); + $msg = $this->l10n->t('%1$s shared the post %2$s from %3$s'); } elseif ($causer['id'] != $author['id']) { - $msg = $userL10n->t('%1$s shared a post from %3$s'); + $msg = $this->l10n->t('%1$s shared a post from %3$s'); } elseif ($title != '') { - $msg = $userL10n->t('%1$s shared the post %2$s'); + $msg = $this->l10n->t('%1$s shared the post %2$s'); } else { - $msg = $userL10n->t('%1$s shared a post'); + $msg = $this->l10n->t('%1$s shared a post'); } break; } @@ -187,68 +216,68 @@ class Notification extends BaseFactory implements ICanCreateFromTableRow case Activity::ATTEND: switch ($Notification->type) { case Post\UserNotification::TYPE_DIRECT_THREAD_COMMENT: - $msg = $userL10n->t('%1$s wants to attend your event %2$s'); + $msg = $this->l10n->t('%1$s wants to attend your event %2$s'); break; } break; case Activity::ATTENDNO: switch ($Notification->type) { case Post\UserNotification::TYPE_DIRECT_THREAD_COMMENT: - $msg = $userL10n->t('%1$s does not want to attend your event %2$s'); + $msg = $this->l10n->t('%1$s does not want to attend your event %2$s'); break; } break; case Activity::ATTENDMAYBE: switch ($Notification->type) { case Post\UserNotification::TYPE_DIRECT_THREAD_COMMENT: - $msg = $userL10n->t('%1$s maybe wants to attend your event %2$s'); + $msg = $this->l10n->t('%1$s maybe wants to attend your event %2$s'); break; } break; case Activity::POST: switch ($Notification->type) { case Post\UserNotification::TYPE_EXPLICIT_TAGGED: - $msg = $userL10n->t('%1$s tagged you on %2$s'); + $msg = $this->l10n->t('%1$s tagged you on %2$s'); break; case Post\UserNotification::TYPE_IMPLICIT_TAGGED: - $msg = $userL10n->t('%1$s replied to you on %2$s'); + $msg = $this->l10n->t('%1$s replied to you on %2$s'); break; case Post\UserNotification::TYPE_THREAD_COMMENT: - $msg = $userL10n->t('%1$s commented in your thread %2$s'); + $msg = $this->l10n->t('%1$s commented in your thread %2$s'); break; case Post\UserNotification::TYPE_DIRECT_COMMENT: - $msg = $userL10n->t('%1$s commented on your comment %2$s'); + $msg = $this->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'] == $author['id']) && ($title != '')) { - $msg = $userL10n->t('%1$s commented in their thread %2$s'); + $msg = $this->l10n->t('%1$s commented in their thread %2$s'); } elseif ($causer['id'] == $author['id']) { - $msg = $userL10n->t('%1$s commented in their thread'); + $msg = $this->l10n->t('%1$s commented in their thread'); } elseif ($title != '') { - $msg = $userL10n->t('%1$s commented in the thread %2$s from %3$s'); + $msg = $this->l10n->t('%1$s commented in the thread %2$s from %3$s'); } else { - $msg = $userL10n->t('%1$s commented in the thread from %3$s'); + $msg = $this->l10n->t('%1$s commented in the thread from %3$s'); } break; case Post\UserNotification::TYPE_DIRECT_THREAD_COMMENT: - $msg = $userL10n->t('%1$s commented on your thread %2$s'); + $msg = $this->l10n->t('%1$s commented on your thread %2$s'); break; case Post\UserNotification::TYPE_SHARED: if (($causer['id'] != $author['id']) && ($title != '')) { - $msg = $userL10n->t('%1$s shared the post %2$s from %3$s'); + $msg = $this->l10n->t('%1$s shared the post %2$s from %3$s'); } elseif ($causer['id'] != $author['id']) { - $msg = $userL10n->t('%1$s shared a post from %3$s'); + $msg = $this->l10n->t('%1$s shared a post from %3$s'); } elseif ($title != '') { - $msg = $userL10n->t('%1$s shared the post %2$s'); + $msg = $this->l10n->t('%1$s shared the post %2$s'); } else { - $msg = $userL10n->t('%1$s shared a post'); + $msg = $this->l10n->t('%1$s shared a post'); } break; } @@ -268,6 +297,7 @@ class Notification extends BaseFactory implements ICanCreateFromTableRow '[url=' . $causer['url'] . ']' . $causer['name'] . '[/url]', '[url=' . $link . ']' . $title . '[/url]', '[url=' . $author['url'] . ']' . $author['name'] . '[/url]'); + $message['link'] = $link; } return $message; diff --git a/src/Navigation/Notifications/Repository/Notification.php b/src/Navigation/Notifications/Repository/Notification.php index c4035663b0..2269f5bc54 100644 --- a/src/Navigation/Notifications/Repository/Notification.php +++ b/src/Navigation/Notifications/Repository/Notification.php @@ -41,9 +41,9 @@ class Notification extends BaseRepository protected static $table_name = 'notification'; - public function __construct(Database $database, LoggerInterface $logger, Factory\Notification $factory = null) + public function __construct(Database $database, LoggerInterface $logger, Factory\Notification $factory) { - parent::__construct($database, $logger, $factory ?? new Factory\Notification($logger)); + parent::__construct($database, $logger, $factory); } /** diff --git a/src/Navigation/Notifications/Repository/Notify.php b/src/Navigation/Notifications/Repository/Notify.php index 959418bbfa..eb65ed4a41 100644 --- a/src/Navigation/Notifications/Repository/Notify.php +++ b/src/Navigation/Notifications/Repository/Notify.php @@ -732,7 +732,7 @@ class Notify extends BaseRepository $subject = $l10n->t('%1$s Comment to conversation #%2$d by %3$s', $subjectPrefix, $item['parent'], $contact['name']); } - $msg = $this->notification->getMessageFromNotification($Notification, $this->baseUrl, $l10n); + $msg = $this->notification->getMessageFromNotification($Notification); if (empty($msg)) { $this->logger->info('No notification message, quitting', ['uid' => $Notification->uid, 'id' => $Notification->id, 'type' => $Notification->type]); return false; diff --git a/src/Worker/PushSubscription.php b/src/Worker/PushSubscription.php index 7b9f5acbd9..45ecb62291 100644 --- a/src/Worker/PushSubscription.php +++ b/src/Worker/PushSubscription.php @@ -82,7 +82,7 @@ class PushSubscription } } - $message = DI::notificationFactory()->getMessageFromNotification($Notification, DI::baseUrl(), $l10n); + $message = DI::notificationFactory()->getMessageFromNotification($Notification); $title = $message['plain'] ?: ''; $push = Subscription::create([