3 namespace Friendica\Navigation\Notifications\Factory;
5 use Friendica\App\BaseURL;
6 use Friendica\BaseFactory;
7 use Friendica\Capabilities\ICanCreateFromTableRow;
8 use Friendica\Content\Text\Plaintext;
9 use Friendica\Core\L10n;
10 use Friendica\Model\Contact;
11 use Friendica\Model\Post;
12 use Friendica\Model\Verb;
13 use Friendica\Navigation\Notifications\Entity;
14 use Friendica\Protocol\Activity;
16 class Notification extends BaseFactory implements ICanCreateFromTableRow
18 public function createFromTableRow(array $row): Entity\Notification
20 return new Entity\Notification(
22 Verb::getByID($row['vid']),
25 $row['target-uri-id'],
26 $row['parent-uri-id'],
27 new \DateTime($row['created'], new \DateTimeZone('UTC')),
33 public function createForUser(int $uid, int $vid, int $type, int $actorId, int $targetUriId, int $parentUriId): Entity\Notification
35 return new Entity\Notification(
45 public function createForRelationship(int $uid, int $contactId, string $verb): Entity\Notification
47 return new Entity\Notification(
50 Post\UserNotification::TYPE_NONE,
56 * @param Entity\Notification $Notification
57 * @param BaseURL $baseUrl
58 * @param L10n $userL10n Seeded with the language of the user we mean the notification for
60 * @throws \Friendica\Network\HTTPException\InternalServerErrorException
62 public function getMessageFromNotification(Entity\Notification $Notification, BaseURL $baseUrl, L10n $userL10n)
66 $causer = $author = Contact::getById($Notification->actorId, ['id', 'name', 'url', 'pending']);
68 $this->logger->info('Causer not found', ['contact' => $Notification->actorId]);
72 if ($Notification->type === Post\UserNotification::TYPE_NONE) {
73 if ($causer['pending']) {
74 $msg = $userL10n->t('%1$s wants to follow you');
76 $msg = $userL10n->t('%1$s had started following you');
78 $title = $causer['name'];
79 $link = $baseUrl . '/contact/' . $causer['id'];
81 if (!$Notification->targetUriId) {
85 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])) {
86 $item = Post::selectFirst([], ['uri-id' => $Notification->parentUriId, 'uid' => [0, $Notification->uid]], ['order' => ['uid' => true]]);
88 $this->logger->info('Parent post not found', ['uri-id' => $Notification->parentUriId]);
92 $item = Post::selectFirst([], ['uri-id' => $Notification->targetUriId, 'uid' => [0, $Notification->uid]], ['order' => ['uid' => true]]);
94 $this->logger->info('Post not found', ['uri-id' => $Notification->targetUriId]);
98 if ($Notification->verb == Activity::POST) {
99 $item = Post::selectFirst([], ['uri-id' => $item['thr-parent-id'], 'uid' => [0, $Notification->uid]], ['order' => ['uid' => true]]);
101 $this->logger->info('Thread parent post not found', ['uri-id' => $item['thr-parent-id']]);
107 if ($item['owner-id'] != $item['author-id']) {
108 $cid = $item['owner-id'];
110 if (!empty($item['causer-id']) && ($item['causer-id'] != $item['author-id'])) {
111 $cid = $item['causer-id'];
114 if (($Notification->type === Post\UserNotification::TYPE_SHARED) && !empty($cid)) {
115 $causer = Contact::getById($cid, ['id', 'name', 'url']);
116 if (empty($causer)) {
117 $this->logger->info('Causer not found', ['causer' => $cid]);
120 } elseif (in_array($Notification->type, [Post\UserNotification::TYPE_COMMENT_PARTICIPATION, Post\UserNotification::TYPE_ACTIVITY_PARTICIPATION])) {
121 $author = Contact::getById($item['author-id'], ['id', 'name', 'url']);
122 if (empty($author)) {
123 $this->logger->info('Author not found', ['author' => $item['author-id']]);
128 $link = $baseUrl . '/display/' . urlencode($item['guid']);
130 $content = Plaintext::getPost($item, 70);
131 if (!empty($content['text'])) {
132 $title = '"' . trim(str_replace("\n", " ", $content['text'])) . '"';
137 switch ($Notification->verb) {
139 switch ($Notification->type) {
140 case Post\UserNotification::TYPE_DIRECT_COMMENT:
141 $msg = $userL10n->t('%1$s liked your comment %2$s');
143 case Post\UserNotification::TYPE_DIRECT_THREAD_COMMENT:
144 $msg = $userL10n->t('%1$s liked your post %2$s');
148 case Activity::DISLIKE:
149 switch ($Notification->type) {
150 case Post\UserNotification::TYPE_DIRECT_COMMENT:
151 $msg = $userL10n->t('%1$s disliked your comment %2$s');
153 case Post\UserNotification::TYPE_DIRECT_THREAD_COMMENT:
154 $msg = $userL10n->t('%1$s disliked your post %2$s');
158 case Activity::ANNOUNCE:
159 switch ($Notification->type) {
160 case Post\UserNotification::TYPE_DIRECT_COMMENT:
161 $msg = $userL10n->t('%1$s shared your comment %2$s');
163 case Post\UserNotification::TYPE_DIRECT_THREAD_COMMENT:
164 $msg = $userL10n->t('%1$s shared your post %2$s');
169 switch ($Notification->type) {
170 case Post\UserNotification::TYPE_EXPLICIT_TAGGED:
171 $msg = $userL10n->t('%1$s tagged you on %2$s');
174 case Post\UserNotification::TYPE_IMPLICIT_TAGGED:
175 $msg = $userL10n->t('%1$s replied to you on %2$s');
178 case Post\UserNotification::TYPE_THREAD_COMMENT:
179 $msg = $userL10n->t('%1$s commented in your thread %2$s');
182 case Post\UserNotification::TYPE_DIRECT_COMMENT:
183 $msg = $userL10n->t('%1$s commented on your comment %2$s');
186 case Post\UserNotification::TYPE_COMMENT_PARTICIPATION:
187 case Post\UserNotification::TYPE_ACTIVITY_PARTICIPATION:
188 if (($causer['id'] == $author['id']) && ($title != '')) {
189 $msg = $userL10n->t('%1$s commented in their thread %2$s');
190 } elseif ($causer['id'] == $author['id']) {
191 $msg = $userL10n->t('%1$s commented in their thread');
192 } elseif ($title != '') {
193 $msg = $userL10n->t('%1$s commented in the thread %2$s from %3$s');
195 $msg = $userL10n->t('%1$s commented in the thread from %3$s');
199 case Post\UserNotification::TYPE_DIRECT_THREAD_COMMENT:
200 $msg = $userL10n->t('%1$s commented on your thread %2$s');
203 case Post\UserNotification::TYPE_SHARED:
204 if (($causer['id'] != $author['id']) && ($title != '')) {
205 $msg = $userL10n->t('%1$s shared the post %2$s from %3$s');
206 } elseif ($causer['id'] != $author['id']) {
207 $msg = $userL10n->t('%1$s shared a post from %3$s');
208 } elseif ($title != '') {
209 $msg = $userL10n->t('%1$s shared the post %2$s');
211 $msg = $userL10n->t('%1$s shared a post');
220 // Name of the notification's causer
221 $message['causer'] = $causer['name'];
222 // Format for the "ping" mechanism
223 $message['notification'] = sprintf($msg, '{0}', $title, $author['name']);
224 // Plain text for the web push api
225 $message['plain'] = sprintf($msg, $causer['name'], $title, $author['name']);
226 // Rich text for other purposes
227 $message['rich'] = sprintf($msg,
228 '[url=' . $causer['url'] . ']' . $causer['name'] . '[/url]',
229 '[url=' . $link . ']' . $title . '[/url]',
230 '[url=' . $author['url'] . ']' . $author['name'] . '[/url]');