X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FModel%2FNotification.php;h=880fa784a61ff1b2acde436be14cb815772fe870;hb=c0d187f2818bcdcb12bbde239f7ce213adaedd02;hp=254aaf5f6bad125014347e99ce41b9d981a07a21;hpb=74f3a2f90c6b92aafdaa7be6dcfb672fa7757586;p=friendica.git diff --git a/src/Model/Notification.php b/src/Model/Notification.php index 254aaf5f6b..880fa784a6 100644 --- a/src/Model/Notification.php +++ b/src/Model/Notification.php @@ -1,23 +1,38 @@ . + * + */ namespace Friendica\Model; -use Exception; use Friendica\BaseModel; use Friendica\Content\Text\BBCode; -use Friendica\Content\Text\HTML; +use Friendica\Content\Text\Plaintext; +use Friendica\Core\Logger; use Friendica\Database\Database; +use Friendica\DI; use Friendica\Network\HTTPException\InternalServerErrorException; -use Friendica\Util\DateTimeFormat; -use Friendica\Util\Temporal; +use Friendica\Protocol\Activity; use Psr\Log\LoggerInterface; /** * Model for an entry in the notify table - * - Including additional, calculated properties - * - * Is used either for frontend interactions or for API-based interaction - * @see https://github.com/friendica/friendica/blob/develop/doc/API-Entities.md#notification * * @property string hash * @property integer type @@ -32,15 +47,10 @@ use Psr\Log\LoggerInterface; * @property integer parent Parent Item Id * @property boolean seen Whether the notification was read or not. * @property string verb Verb URL (@see http://activitystrea.ms) - * @property string otype Subject type (`item`, `intro` or `mail`) + * @property string otype Subject type ('item', 'intro' or 'mail') * * @property-read string name_cache Full name of the contact subject * @property-read string msg_cache Plaintext version of the notification text with a placeholder (`{0}`) for the subject contact's name. - * - * @property-read integer timestamp Unix timestamp - * @property-read string dateRel Time since the note was posted, eg "1 hour ago" - * @property-read string $msg_html - * @property-read string $msg_plain */ class Notification extends BaseModel { @@ -54,63 +64,26 @@ class Notification extends BaseModel $this->repo = $repo; $this->setNameCache(); - $this->setTimestamp(); - $this->setMsg(); - } - - /** - * Set the notification as seen - * - * @param bool $seen true, if seen - * - * @return bool True, if the seen state could be saved - */ - public function setSeen(bool $seen = true) - { - $this->seen = $seen; - try { - return $this->repo->update($this); - } catch (Exception $e) { - $this->logger->warning('Update failed.', ['$this' => $this, 'exception' => $e]); - return false; - } - } - - /** - * Set some extra properties to the notification from db: - * - timestamp as int in default TZ - * - date_rel : relative date string - */ - private function setTimestamp() - { - try { - $this->timestamp = strtotime(DateTimeFormat::local($this->date)); - } catch (Exception $e) { - } - $this->dateRel = Temporal::getRelativeDate($this->date); + $this->setMsgCache(); } /** * Sets the pre-formatted name (caching) - * - * @throws InternalServerErrorException */ private function setNameCache() { - $this->name_cache = strip_tags(BBCode::convert($this->source_name ?? '')); + try { + $this->name_cache = strip_tags(BBCode::convert($this->source_name)); + } catch (InternalServerErrorException $e) { + } } /** - * Set some extra properties to the notification from db: - * - msg_html: message as html string - * - msg_plain: message as plain text string - * - msg_cache: The pre-formatted message (caching) + * Sets the pre-formatted msg (caching) */ - private function setMsg() + private function setMsgCache() { try { - $this->msg_html = BBCode::convert($this->msg, false); - $this->msg_plain = explode("\n", trim(HTML::toPlaintext($this->msg_html, 0)))[0]; $this->msg_cache = self::formatMessage($this->name_cache, strip_tags(BBCode::convert($this->msg))); } catch (InternalServerErrorException $e) { } @@ -120,12 +93,8 @@ class Notification extends BaseModel { parent::__set($name, $value); - if ($name == 'date') { - $this->setTimestamp(); - } - if ($name == 'msg') { - $this->setMsg(); + $this->setMsgCache(); } if ($name == 'source_name') { @@ -158,4 +127,190 @@ class Notification extends BaseModel return $message; } + + /** + * 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::NOTIF_NONE)) { + $contact = Contact::getById($notification['actor-id'], ['pending']); + $type = $contact['pending'] ? 'follow_request' : 'follow'; + } elseif (($notification['vid'] == Verb::getID(Activity::ANNOUNCE)) && + in_array($notification['type'], [Post\UserNotification::NOTIF_DIRECT_COMMENT, Post\UserNotification::NOTIF_DIRECT_THREAD_COMMENT])) { + $type = 'reblog'; + } elseif (in_array($notification['vid'], [Verb::getID(Activity::LIKE), Verb::getID(Activity::DISLIKE)]) && + in_array($notification['type'], [Post\UserNotification::NOTIF_DIRECT_COMMENT, Post\UserNotification::NOTIF_DIRECT_THREAD_COMMENT])) { + $type = 'favourite'; + } elseif ($notification['type'] == Post\UserNotification::NOTIF_SHARED) { + $type = 'status'; + } elseif (in_array($notification['type'], [Post\UserNotification::NOTIF_EXPLICIT_TAGGED, + Post\UserNotification::NOTIF_IMPLICIT_TAGGED, Post\UserNotification::NOTIF_DIRECT_COMMENT, + Post\UserNotification::NOTIF_DIRECT_THREAD_COMMENT, Post\UserNotification::NOTIF_THREAD_COMMENT])) { + $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 = []; + + if ($notification['type'] == Post\UserNotification::NOTIF_NONE) { + return $message; + } + + if (empty($notification['target-uri-id'])) { + return $message; + } + + $user = User::getById($notification['uid']); + if (empty($user)) { + Logger::info('User not found', ['application' => $notification['uid']]); + return $message; + } + + $contact = Contact::getById($notification['actor-id']); + if (empty($contact)) { + Logger::info('Contact not found', ['contact' => $notification['actor-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::NOTIF_THREAD_COMMENT, Post\UserNotification::NOTIF_COMMENT_PARTICIPATION])) { + $item = Post::selectFirst([], ['uri-id' => $notification['parent-uri-id'], 'uid' => [0, $notification['uid']]]); + 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']]]); + 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']]]); + if (empty($item)) { + Logger::info('Thread parent post not found', ['uri-id' => $item['thr-parent-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 = ''; + } + + $l10n = DI::l10n()->withLang($user['language']); + + switch ($notification['vid']) { + case $like: + switch ($notification['type']) { + case Post\UserNotification::NOTIF_DIRECT_COMMENT: + $msg = $l10n->t('%1$s liked your comment %2$s'); + break; + case Post\UserNotification::NOTIF_DIRECT_THREAD_COMMENT: + $msg = $l10n->t('%1$s liked your post %2$s'); + break; + } + break; + case $dislike: + switch ($notification['type']) { + case Post\UserNotification::NOTIF_DIRECT_COMMENT: + $msg = $l10n->t('%1$s disliked your comment %2$s'); + break; + case Post\UserNotification::NOTIF_DIRECT_THREAD_COMMENT: + $msg = $l10n->t('%1$s disliked your post %2$s'); + break; + } + break; + case $announce: + switch ($notification['type']) { + case Post\UserNotification::NOTIF_DIRECT_COMMENT: + $msg = $l10n->t('%1$s shared your comment %2$s'); + break; + case Post\UserNotification::NOTIF_DIRECT_THREAD_COMMENT: + $msg = $l10n->t('%1$s shared your post %2$s'); + break; + } + break; + case $post: + switch ($notification['type']) { + case Post\UserNotification::NOTIF_EXPLICIT_TAGGED: + $msg = $l10n->t('%1$s tagged you on %2$s'); + break; + + case Post\UserNotification::NOTIF_IMPLICIT_TAGGED: + $msg = $l10n->t('%1$s replied to you on %2$s'); + break; + + case Post\UserNotification::NOTIF_THREAD_COMMENT: + $msg = $l10n->t('%1$s commented in your thread %2$s'); + break; + + case Post\UserNotification::NOTIF_DIRECT_COMMENT: + $msg = $l10n->t('%1$s commented on your comment %2$s'); + break; + + case Post\UserNotification::NOTIF_COMMENT_PARTICIPATION: + $msg = $l10n->t('%1$s commented in the thread %2$s'); + break; + + case Post\UserNotification::NOTIF_ACTIVITY_PARTICIPATION: + // Unhandled + break; + + case Post\UserNotification::NOTIF_DIRECT_THREAD_COMMENT: + $msg = $l10n->t('%1$s commented on your thread %2$s'); + break; + + case Post\UserNotification::NOTIF_SHARED: + if ($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'] = $contact['name']; + // Format for the "ping" mechanism + $message['notification'] = sprintf($msg, '{0}', $title); + // Plain text for the web push api + $message['plain'] = sprintf($msg, $contact['name'], $title); + // Rich text for other purposes + $message['rich'] = sprintf($msg, + '[url=' . $contact['url'] . ']' . $contact['name'] . '[/url]', + '[url=' . $link . ']' . $title . '[/url]'); + } + + return $message; + } }