diff --git a/composer.json b/composer.json index 1a3e841fe2..46f3f3bf3a 100644 --- a/composer.json +++ b/composer.json @@ -85,7 +85,6 @@ "Friendica\\Addon\\": "addon/" }, "files": [ - "include/enotify.php", "boot.php" ] }, diff --git a/include/enotify.php b/include/enotify.php deleted file mode 100644 index c30b6de86e..0000000000 --- a/include/enotify.php +++ /dev/null @@ -1,591 +0,0 @@ -. - * - */ - -use Friendica\Content\Text\Plaintext; -use Friendica\Core\Hook; -use Friendica\Core\Logger; -use Friendica\Core\System; -use Friendica\Database\DBA; -use Friendica\DI; -use Friendica\Model\Contact; -use Friendica\Model\Item; -use Friendica\Model\Notification; -use Friendica\Model\Post; -use Friendica\Model\User; -use Friendica\Navigation\Notifications; -use Friendica\Protocol\Activity; - -/** - * Creates a notification entry and possibly sends a mail - * - * @param array $params Array with the elements: - * type, event, otype, activity, verb, uid, cid, item, link, - * source_name, source_mail, source_nick, source_link, source_photo, - * show_in_notification_page - * - * @return bool - * @throws \Friendica\Network\HTTPException\InternalServerErrorException - */ -function notification($params) -{ - /** @var string the common prefix of a notification subject */ - $subjectPrefix = DI::l10n()->t('[Friendica:Notify]'); - - // Temporary logging for finding the origin - if (!isset($params['uid'])) { - Logger::notice('Missing parameters "uid".', ['params' => $params, 'callstack' => System::callstack()]); - } - - // Ensure that the important fields are set at any time - $fields = ['nickname', 'page-flags', 'notify-flags', 'language', 'username', 'email']; - $user = DBA::selectFirst('user', $fields, ['uid' => $params['uid']]); - - if (!DBA::isResult($user)) { - Logger::error('Unknown user', ['uid' => $params['uid']]); - return false; - } - - // There is no need to create notifications for forum accounts - if (in_array($user['page-flags'], [User::PAGE_FLAGS_COMMUNITY, User::PAGE_FLAGS_PRVGROUP])) { - return false; - } - - $params['notify_flags'] = $user['notify-flags']; - $params['language'] = $user['language']; - $params['to_name'] = $user['username']; - $params['to_email'] = $user['email']; - - // from here on everything is in the recipients language - $l10n = DI::l10n()->withLang($params['language']); - - if (!empty($params['cid'])) { - $contact = Contact::getById($params['cid'], ['url', 'name', 'photo']); - if (DBA::isResult($contact)) { - $params['source_link'] = $contact['url']; - $params['source_name'] = $contact['name']; - $params['source_photo'] = $contact['photo']; - } - } - - $siteurl = DI::baseUrl()->get(true); - $sitename = DI::config()->get('config', 'sitename'); - - // with $params['show_in_notification_page'] == false, the notification isn't inserted into - // the database, and an email is sent if applicable. - // default, if not specified: true - $show_in_notification_page = isset($params['show_in_notification_page']) ? $params['show_in_notification_page'] : true; - - $title = $params['item']['title'] ?? ''; - $body = $params['item']['body'] ?? ''; - - $parent_id = $params['item']['parent'] ?? 0; - $parent_uri_id = $params['item']['parent-uri-id'] ?? 0; - - $epreamble = ''; - $preamble = ''; - $subject = ''; - $sitelink = ''; - $tsitelink = ''; - $hsitelink = ''; - $itemlink = ''; - - switch ($params['type']) { - case Notification\Type::MAIL: - $itemlink = $params['link']; - - $subject = $l10n->t('%s New mail received at %s', $subjectPrefix, $sitename); - - $preamble = $l10n->t('%1$s sent you a new private message at %2$s.', $params['source_name'], $sitename); - $epreamble = $l10n->t('%1$s sent you %2$s.', '[url='.$params['source_link'].']'.$params['source_name'].'[/url]', '[url=' . $itemlink . ']' . $l10n->t('a private message').'[/url]'); - - $sitelink = $l10n->t('Please visit %s to view and/or reply to your private messages.'); - $tsitelink = sprintf($sitelink, $itemlink); - $hsitelink = sprintf($sitelink, '' . $sitename . ''); - - // Mail notifications aren't using the "notify" table entry - $show_in_notification_page = false; - break; - - case Notification\Type::COMMENT: - if (Post\ThreadUser::getIgnored($parent_uri_id, $params['uid'])) { - Logger::info('Thread is ignored', ['parent' => $parent_id, 'parent-uri-id' => $parent_uri_id]); - return false; - } - - $item = Post::selectFirstForUser($params['uid'], Item::ITEM_FIELDLIST, ['id' => $parent_id, 'deleted' => false]); - if (empty($item)) { - return false; - } - - $item_post_type = Item::postType($item, $l10n); - - $content = Plaintext::getPost($item, 70); - if (!empty($content['text'])) { - $title = '"' . trim(str_replace("\n", " ", $content['text'])) . '"'; - } else { - $title = ''; - } - - // First go for the general message - - // "George Bull's post" - $message = $l10n->t('%1$s commented on %2$s\'s %3$s %4$s'); - $dest_str = sprintf($message, $params['source_name'], $item['author-name'], $item_post_type, $title); - - // "your post" - if ($item['wall']) { - $message = $l10n->t('%1$s commented on your %2$s %3$s'); - $dest_str = sprintf($message, $params['source_name'], $item_post_type, $title); - // "their post" - } elseif ($item['author-link'] == $params['source_link']) { - $message = $l10n->t('%1$s commented on their %2$s %3$s'); - $dest_str = sprintf($message, $params['source_name'], $item_post_type, $title); - } - - $subject = $l10n->t('%1$s Comment to conversation #%2$d by %3$s', $subjectPrefix, $parent_id, $params['source_name']); - - $preamble = $l10n->t('%s commented on an item/conversation you have been following.', $params['source_name']); - - $epreamble = $dest_str; - - $sitelink = $l10n->t('Please visit %s to view and/or reply to the conversation.'); - $tsitelink = sprintf($sitelink, $siteurl); - $hsitelink = sprintf($sitelink, '' . $sitename . ''); - $itemlink = $params['link']; - break; - - case Notification\Type::WALL: - $subject = $l10n->t('%s %s posted to your profile wall', $subjectPrefix, $params['source_name']); - - $preamble = $l10n->t('%1$s posted to your profile wall at %2$s', $params['source_name'], $sitename); - $epreamble = $l10n->t('%1$s posted to [url=%2$s]your wall[/url]', - '[url='.$params['source_link'].']'.$params['source_name'].'[/url]', - $params['link'] - ); - - $sitelink = $l10n->t('Please visit %s to view and/or reply to the conversation.'); - $tsitelink = sprintf($sitelink, $siteurl); - $hsitelink = sprintf($sitelink, ''.$sitename.''); - $itemlink = $params['link']; - break; - - case Notification\Type::POKE: - $subject = $l10n->t('%1$s %2$s poked you', $subjectPrefix, $params['source_name']); - - $preamble = $l10n->t('%1$s poked you at %2$s', $params['source_name'], $sitename); - $epreamble = $l10n->t('%1$s [url=%2$s]poked you[/url].', - '[url='.$params['source_link'].']'.$params['source_name'].'[/url]', - $params['link'] - ); - - $subject = str_replace('poked', $l10n->t($params['activity']), $subject); - $preamble = str_replace('poked', $l10n->t($params['activity']), $preamble); - $epreamble = str_replace('poked', $l10n->t($params['activity']), $epreamble); - - $sitelink = $l10n->t('Please visit %s to view and/or reply to the conversation.'); - $tsitelink = sprintf($sitelink, $siteurl); - $hsitelink = sprintf($sitelink, ''.$sitename.''); - $itemlink = $params['link']; - break; - - case Notification\Type::INTRO: - $itemlink = $params['link']; - $subject = $l10n->t('%s Introduction received', $subjectPrefix); - - $preamble = $l10n->t('You\'ve received an introduction from \'%1$s\' at %2$s', $params['source_name'], $sitename); - $epreamble = $l10n->t('You\'ve received [url=%1$s]an introduction[/url] from %2$s.', - $itemlink, - '[url='.$params['source_link'].']'.$params['source_name'].'[/url]' - ); - - $body = $l10n->t('You may visit their profile at %s', $params['source_link']); - - $sitelink = $l10n->t('Please visit %s to approve or reject the introduction.'); - $tsitelink = sprintf($sitelink, $siteurl); - $hsitelink = sprintf($sitelink, ''.$sitename.''); - - switch ($params['verb']) { - case Activity::FRIEND: - // someone started to share with user (mostly OStatus) - $subject = $l10n->t('%s A new person is sharing with you', $subjectPrefix); - - $preamble = $l10n->t('%1$s is sharing with you at %2$s', $params['source_name'], $sitename); - $epreamble = $l10n->t('%1$s is sharing with you at %2$s', - '[url='.$params['source_link'].']'.$params['source_name'].'[/url]', - $sitename - ); - break; - case Activity::FOLLOW: - // someone started to follow the user (mostly OStatus) - $subject = $l10n->t('%s You have a new follower', $subjectPrefix); - - $preamble = $l10n->t('You have a new follower at %2$s : %1$s', $params['source_name'], $sitename); - $epreamble = $l10n->t('You have a new follower at %2$s : %1$s', - '[url='.$params['source_link'].']'.$params['source_name'].'[/url]', - $sitename - ); - break; - default: - // ACTIVITY_REQ_FRIEND is default activity for notifications - break; - } - break; - - case Notification\Type::SUGGEST: - $itemlink = $params['link']; - $subject = $l10n->t('%s Friend suggestion received', $subjectPrefix); - - $preamble = $l10n->t('You\'ve received a friend suggestion from \'%1$s\' at %2$s', $params['source_name'], $sitename); - $epreamble = $l10n->t('You\'ve received [url=%1$s]a friend suggestion[/url] for %2$s from %3$s.', - $itemlink, - '[url='.$params['item']['url'].']'.$params['item']['name'].'[/url]', - '[url='.$params['source_link'].']'.$params['source_name'].'[/url]' - ); - - $body = $l10n->t('Name:').' '.$params['item']['name']."\n"; - $body .= $l10n->t('Photo:').' '.$params['item']['photo']."\n"; - $body .= $l10n->t('You may visit their profile at %s', $params['item']['url']); - - $sitelink = $l10n->t('Please visit %s to approve or reject the suggestion.'); - $tsitelink = sprintf($sitelink, $siteurl); - $hsitelink = sprintf($sitelink, ''.$sitename.''); - break; - - case Notification\Type::CONFIRM: - if ($params['verb'] == Activity::FRIEND) { // mutual connection - $itemlink = $params['link']; - $subject = $l10n->t('%s Connection accepted', $subjectPrefix); - - $preamble = $l10n->t('\'%1$s\' has accepted your connection request at %2$s', $params['source_name'], $sitename); - $epreamble = $l10n->t('%2$s has accepted your [url=%1$s]connection request[/url].', - $itemlink, - '[url='.$params['source_link'].']'.$params['source_name'].'[/url]' - ); - - $body = $l10n->t('You are now mutual friends and may exchange status updates, photos, and email without restriction.'); - - $sitelink = $l10n->t('Please visit %s if you wish to make any changes to this relationship.'); - $tsitelink = sprintf($sitelink, $siteurl); - $hsitelink = sprintf($sitelink, ''.$sitename.''); - } else { // ACTIVITY_FOLLOW - $itemlink = $params['link']; - $subject = $l10n->t('%s Connection accepted', $subjectPrefix); - - $preamble = $l10n->t('\'%1$s\' has accepted your connection request at %2$s', $params['source_name'], $sitename); - $epreamble = $l10n->t('%2$s has accepted your [url=%1$s]connection request[/url].', - $itemlink, - '[url='.$params['source_link'].']'.$params['source_name'].'[/url]' - ); - - $body = $l10n->t('\'%1$s\' has chosen to accept you a fan, which restricts some forms of communication - such as private messaging and some profile interactions. If this is a celebrity or community page, these settings were applied automatically.', $params['source_name']); - $body .= "\n\n"; - $body .= $l10n->t('\'%1$s\' may choose to extend this into a two-way or more permissive relationship in the future.', $params['source_name']); - - $sitelink = $l10n->t('Please visit %s if you wish to make any changes to this relationship.'); - $tsitelink = sprintf($sitelink, $siteurl); - $hsitelink = sprintf($sitelink, ''.$sitename.''); - } - break; - - case Notification\Type::SYSTEM: - switch($params['event']) { - case "SYSTEM_REGISTER_REQUEST": - $itemlink = $params['link']; - $subject = $l10n->t('[Friendica System Notify]') . ' ' . $l10n->t('registration request'); - - $preamble = $l10n->t('You\'ve received a registration request from \'%1$s\' at %2$s', $params['source_name'], $sitename); - $epreamble = $l10n->t('You\'ve received a [url=%1$s]registration request[/url] from %2$s.', - $itemlink, - '[url='.$params['source_link'].']'.$params['source_name'].'[/url]' - ); - - $body = $l10n->t("Full Name: %s\nSite Location: %s\nLogin Name: %s (%s)", - $params['source_name'], - $siteurl, $params['source_mail'], - $params['source_nick'] - ); - - $sitelink = $l10n->t('Please visit %s to approve or reject the request.'); - $tsitelink = sprintf($sitelink, $params['link']); - $hsitelink = sprintf($sitelink, ''.$sitename.'

'); - break; - case "SYSTEM_DB_UPDATE_FAIL": - break; - } - break; - - default: - Logger::notice('Unhandled type', ['type' => $params['type']]); - return false; - } - - return notification_store_and_send($params, $sitelink, $tsitelink, $hsitelink, $title, $subject, $preamble, $epreamble, $body, $itemlink, $show_in_notification_page); -} - -function notification_store_and_send($params, $sitelink, $tsitelink, $hsitelink, $title, $subject, $preamble, $epreamble, $body, $itemlink, $show_in_notification_page) -{ - $item_id = $params['item']['id'] ?? 0; - $uri_id = $params['item']['uri-id'] ?? 0; - $parent_id = $params['item']['parent'] ?? 0; - $parent_uri_id = $params['item']['parent-uri-id'] ?? 0; - - // Ensure that the important fields are set at any time - $fields = ['nickname']; - $user = User::getById($params['uid'], $fields); - - $sitename = DI::config()->get('config', 'sitename'); - - $nickname = $user['nickname']; - - $hostname = DI::baseUrl()->getHostname(); - if (strpos($hostname, ':')) { - $hostname = substr($hostname, 0, strpos($hostname, ':')); - } - - // Creates a new email builder for the notification email - $emailBuilder = DI::emailer()->newNotifyMail(); - - $emailBuilder->setHeader('X-Friendica-Account', '<' . $nickname . '@' . $hostname . '>'); - - $subject .= " (".$nickname."@".$hostname.")"; - - $h = [ - 'params' => $params, - 'subject' => $subject, - 'preamble' => $preamble, - 'epreamble' => $epreamble, - 'body' => $body, - 'sitelink' => $sitelink, - 'tsitelink' => $tsitelink, - 'hsitelink' => $hsitelink, - 'itemlink' => $itemlink - ]; - - Hook::callAll('enotify', $h); - - $subject = $h['subject']; - - $preamble = $h['preamble']; - $epreamble = $h['epreamble']; - - $body = $h['body']; - - $tsitelink = $h['tsitelink']; - $hsitelink = $h['hsitelink']; - $itemlink = $h['itemlink']; - - $notify_id = 0; - - if ($show_in_notification_page) { - $Notify = DI::notifyFactory()->createFromParams($params, $itemlink, $item_id, $uri_id, $parent_id, $parent_uri_id); - try { - $Notify = DI::notify()->save($Notify); - } catch (Notifications\Exception\NotificationCreationInterceptedException $e) { - // Notification insertion can be intercepted by an addon registering the 'enotify_store' hook - return false; - } - - $Notify->updateMsgFromPreamble($epreamble); - $Notify = DI::notify()->save($Notify); - - $itemlink = DI::baseUrl() . '/notification/' . $Notify->id; - $notify_id = $Notify->id; - } - - // send email notification if notification preferences permit - if ((intval($params['notify_flags']) & intval($params['type'])) - || $params['type'] == Notification\Type::SYSTEM) { - - Logger::log('sending notification email'); - - if (isset($params['parent']) && (intval($params['parent']) != 0)) { - $parent = Post::selectFirst(['guid'], ['id' => $params['parent']]); - $message_id = "<" . $parent['guid'] . "@" . gethostname() . ">"; - - // Is this the first email notification for this parent item and user? - if (!DBA::exists('notify-threads', ['master-parent-uri-id' => $parent_uri_id, 'receiver-uid' => $params['uid']])) { - Logger::log("notify_id:" . intval($notify_id) . ", parent: " . intval($params['parent']) . "uid: " . intval($params['uid']), Logger::DEBUG); - - $fields = ['notify-id' => $notify_id, 'master-parent-uri-id' => $parent_uri_id, - 'receiver-uid' => $params['uid'], 'parent-item' => 0]; - DBA::insert('notify-threads', $fields); - - $emailBuilder->setHeader('Message-ID', $message_id); - $log_msg = "include/enotify: No previous notification found for this parent:\n" . - " parent: ${params['parent']}\n" . " uid : ${params['uid']}\n"; - Logger::log($log_msg, Logger::DEBUG); - } else { - // If not, just "follow" the thread. - $emailBuilder->setHeader('References', $message_id); - $emailBuilder->setHeader('In-Reply-To', $message_id); - Logger::log("There's already a notification for this parent.", Logger::DEBUG); - } - } - - $datarray = [ - 'preamble' => $preamble, - 'type' => $params['type'], - 'parent' => $parent_id, - 'source_name' => $params['source_name'] ?? null, - 'source_link' => $params['source_link'] ?? null, - 'source_photo' => $params['source_photo'] ?? null, - 'uid' => $params['uid'], - 'hsitelink' => $hsitelink, - 'tsitelink' => $tsitelink, - 'itemlink' => $itemlink, - 'title' => $title, - 'body' => $body, - 'subject' => $subject, - 'headers' => $emailBuilder->getHeaders(), - ]; - - Hook::callAll('enotify_mail', $datarray); - - $emailBuilder - ->withHeaders($datarray['headers']) - ->withRecipient($params['to_email']) - ->forUser([ - 'uid' => $datarray['uid'], - 'language' => $params['language'], - ]) - ->withNotification($datarray['subject'], $datarray['preamble'], $datarray['title'], $datarray['body']) - ->withSiteLink($datarray['tsitelink'], $datarray['hsitelink']) - ->withItemLink($datarray['itemlink']); - - // If a photo is present, add it to the email - if (!empty($datarray['source_photo'])) { - $emailBuilder->withPhoto( - $datarray['source_photo'], - $datarray['source_link'] ?? $sitelink, - $datarray['source_name'] ?? $sitename); - } - - $email = $emailBuilder->build(); - - // use the Emailer class to send the message - return DI::emailer()->send($email); - } - - return false; -} - -function notification_from_array(Notifications\Entity\Notification $Notification) -{ - 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]); - return false; - } - - $params = []; - $params['verb'] = $Notification->verb; - $params['uid'] = $Notification->uid; - $params['otype'] = Notification\ObjectType::ITEM; - - $user = User::getById($Notification->uid); - - $params['notify_flags'] = $user['notify-flags']; - $params['language'] = $user['language']; - $params['to_name'] = $user['username']; - $params['to_email'] = $user['email']; - - // from here on everything is in the recipients language - $l10n = DI::l10n()->withLang($user['language']); - - $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->targetUriId, 'deleted' => false], - ['order' => ['uid' => true]]); - if (empty($item)) { - Logger::info('Item not found', ['uri-id' => $Notification->targetUriId, 'type' => $Notification->type]); - return false; - } - - $params['item'] = $item; - $params['parent'] = $item['parent']; - $params['link'] = DI::baseUrl() . '/display/' . urlencode($item['guid']); - - $subjectPrefix = $l10n->t('[Friendica:Notify]'); - - if (Post\ThreadUser::getIgnored($Notification->parentUriId, $Notification->uid)) { - Logger::info('Thread is ignored', ['parent-uri-id' => $Notification->parentUriId, 'type' => $Notification->type]); - return false; - } - - // Check to see if there was already a tag notify or comment notify for this post. - // 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]); - return false; - } - - $content = Plaintext::getPost($item, 70); - if (!empty($content['text'])) { - $title = '"' . trim(str_replace("\n", " ", $content['text'])) . '"'; - } else { - $title = $item['title']; - } - - // Some mail software relies on subject field for threading. - // 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) { - $params['type'] = Notification\Type::TAG_SELF; - $subject = $l10n->t('%s %s tagged you', $subjectPrefix, $contact['name']); - } 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 { - $params['type'] = Notification\Type::COMMENT; - $subject = $l10n->t('%1$s Comment to conversation #%2$d by %3$s', $subjectPrefix, $item['parent'], $contact['name']); - } - - $msg = DI::notificationFactory()->getMessageFromNotification($Notification, DI::baseUrl(), $l10n); - if (empty($msg)) { - Logger::info('No notification message, quitting', ['uid' => $Notification->uid, 'id' => $Notification->id, 'type' => $Notification->type]); - return false; - } - - $preamble = $msg['plain']; - $epreamble = $msg['rich']; - - $sitename = DI::config()->get('config', 'sitename'); - $siteurl = DI::baseUrl()->get(true); - - $sitelink = $l10n->t('Please visit %s to view and/or reply to the conversation.'); - $tsitelink = sprintf($sitelink, $siteurl); - $hsitelink = sprintf($sitelink, '' . $sitename . ''); - $itemlink = $params['link']; - - 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); -} diff --git a/mod/item.php b/mod/item.php index bfb865b790..1309dce47e 100644 --- a/mod/item.php +++ b/mod/item.php @@ -777,7 +777,7 @@ function item_post(App $a) { // These notifications are sent if someone else is commenting other your wall if ($contact_record != $author) { if ($toplevel_item_id) { - notification([ + DI::notify()->createFromArray([ 'type' => Notification\Type::COMMENT, 'otype' => Notification\ObjectType::ITEM, 'verb' => Activity::POST, @@ -787,7 +787,7 @@ function item_post(App $a) { 'link' => DI::baseUrl() . '/display/' . urlencode($datarray['guid']), ]); } elseif (empty($forum_contact)) { - notification([ + DI::notify()->createFromArray([ 'type' => Notification\Type::WALL, 'otype' => Notification\ObjectType::ITEM, 'verb' => Activity::POST, diff --git a/src/Model/Contact.php b/src/Model/Contact.php index f0b6eda55e..06e546d614 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -2719,7 +2719,7 @@ class Contact if (($user['notify-flags'] & Notification\Type::INTRO) && in_array($user['page-flags'], [User::PAGE_FLAGS_NORMAL])) { - notification([ + DI::notify()->createFromArray([ 'type' => Notification\Type::INTRO, 'otype' => Notification\ObjectType::INTRO, 'verb' => ($sharing ? Activity::FRIEND : Activity::FOLLOW), diff --git a/src/Model/Mail.php b/src/Model/Mail.php index 75515c5df5..f9c197ffa0 100644 --- a/src/Model/Mail.php +++ b/src/Model/Mail.php @@ -104,7 +104,7 @@ class Mail 'link' => DI::baseUrl() . '/message/' . $msg['id'], ]; - notification($notif_params); + DI::notify()->createFromArray($notif_params); Logger::info('Mail is processed, notification was sent.', ['id' => $msg['id'], 'uri' => $msg['uri']]); } diff --git a/src/Model/Subscription.php b/src/Model/Subscription.php index c6c57c7328..31048d963f 100644 --- a/src/Model/Subscription.php +++ b/src/Model/Subscription.php @@ -154,7 +154,7 @@ class Subscription } if ($desktop_notification) { - notification_from_array($Notification); + DI::notify()->createFromNotification($Notification); } if (empty($type)) { diff --git a/src/Module/Register.php b/src/Module/Register.php index 976e43a5d4..d93c8754fe 100644 --- a/src/Module/Register.php +++ b/src/Module/Register.php @@ -365,7 +365,7 @@ class Register extends BaseModule // send notification to admins while ($admin = DBA::fetch($admins_stmt)) { - \notification([ + DI::notify()->createFromArray([ 'type' => Model\Notification\Type::SYSTEM, 'event' => 'SYSTEM_REGISTER_REQUEST', 'uid' => $admin['uid'], diff --git a/src/Navigation/Notifications/Depository/Notify.php b/src/Navigation/Notifications/Depository/Notify.php index 4c7a1ef33d..31ad7af0e4 100644 --- a/src/Navigation/Notifications/Depository/Notify.php +++ b/src/Navigation/Notifications/Depository/Notify.php @@ -2,16 +2,24 @@ namespace Friendica\Navigation\Notifications\Depository; +use Friendica\App\BaseURL; use Friendica\BaseDepository; +use Friendica\Content\Text\Plaintext; +use Friendica\Core\Config\IConfig; use Friendica\Core\Hook; +use Friendica\Core\L10n; +use Friendica\Core\System; use Friendica\Database\Database; use Friendica\Database\DBA; +use Friendica\Model; use Friendica\Navigation\Notifications\Collection; use Friendica\Navigation\Notifications\Entity; use Friendica\Navigation\Notifications\Exception; use Friendica\Navigation\Notifications\Factory; use Friendica\Network\HTTPException; +use Friendica\Protocol\Activity; use Friendica\Util\DateTimeFormat; +use Friendica\Util\Emailer; use Psr\Log\LoggerInterface; class Notify extends BaseDepository @@ -19,10 +27,31 @@ class Notify extends BaseDepository /** @var Factory\Notify */ protected $factory; + /** @var L10n */ + protected $l10n; + + /** @var BaseURL */ + protected $baseUrl; + + /** @var IConfig */ + protected $config; + + /** @var Emailer */ + protected $emailer; + + /** @var Factory\Notification */ + protected $notification; + protected static $table_name = 'notify'; - public function __construct(Database $database, LoggerInterface $logger, Factory\Notify $factory = null) + public function __construct(Database $database, LoggerInterface $logger, L10n $l10n, BaseURL $baseUrl, IConfig $config, Emailer $emailer, Factory\Notification $notification, Factory\Notify $factory = null) { + $this->l10n = $l10n; + $this->baseUrl = $baseUrl; + $this->config = $config; + $this->emailer = $emailer; + $this->notification = $notification; + parent::__construct($database, $logger, $factory ?? new Factory\Notify($logger)); } @@ -145,4 +174,561 @@ class Notify extends BaseDepository ]; return $this->db->update(self::$table_name, ['seen' => true], $condition); } + + /** + * Creates a notification entry and possibly sends a mail + * + * @param array $params Array with the elements: + * type, event, otype, activity, verb, uid, cid, item, link, + * source_name, source_mail, source_nick, source_link, source_photo, + * show_in_notification_page + * + * @return bool + * @throws \Friendica\Network\HTTPException\InternalServerErrorException + */ + function createFromArray($params) + { + /** @var string the common prefix of a notification subject */ + $subjectPrefix = $this->l10n->t('[Friendica:Notify]'); + + // Temporary logging for finding the origin + if (!isset($params['uid'])) { + $this->logger->notice('Missing parameters "uid".', ['params' => $params, 'callstack' => System::callstack()]); + } + + // Ensure that the important fields are set at any time + $fields = ['nickname', 'page-flags', 'notify-flags', 'language', 'username', 'email']; + $user = DBA::selectFirst('user', $fields, ['uid' => $params['uid']]); + + if (!DBA::isResult($user)) { + $this->logger->error('Unknown user', ['uid' => $params['uid']]); + return false; + } + + // There is no need to create notifications for forum accounts + if (in_array($user['page-flags'], [Model\User::PAGE_FLAGS_COMMUNITY, Model\User::PAGE_FLAGS_PRVGROUP])) { + return false; + } + + $params['notify_flags'] = $user['notify-flags']; + $params['language'] = $user['language']; + $params['to_name'] = $user['username']; + $params['to_email'] = $user['email']; + + // from here on everything is in the recipients language + $l10n = $this->l10n->withLang($params['language']); + + if (!empty($params['cid'])) { + $contact = Model\Contact::getById($params['cid'], ['url', 'name', 'photo']); + if (DBA::isResult($contact)) { + $params['source_link'] = $contact['url']; + $params['source_name'] = $contact['name']; + $params['source_photo'] = $contact['photo']; + } + } + + $siteurl = $this->baseUrl->get(true); + $sitename = $this->config->get('config', 'sitename'); + + // with $params['show_in_notification_page'] == false, the notification isn't inserted into + // the database, and an email is sent if applicable. + // default, if not specified: true + $show_in_notification_page = isset($params['show_in_notification_page']) ? $params['show_in_notification_page'] : true; + + $title = $params['item']['title'] ?? ''; + $body = $params['item']['body'] ?? ''; + + $parent_id = $params['item']['parent'] ?? 0; + $parent_uri_id = $params['item']['parent-uri-id'] ?? 0; + + $epreamble = ''; + $preamble = ''; + $subject = ''; + $sitelink = ''; + $tsitelink = ''; + $hsitelink = ''; + $itemlink = ''; + + switch ($params['type']) { + case Model\Notification\Type::MAIL: + $itemlink = $params['link']; + + $subject = $l10n->t('%s New mail received at %s', $subjectPrefix, $sitename); + + $preamble = $l10n->t('%1$s sent you a new private message at %2$s.', $params['source_name'], $sitename); + $epreamble = $l10n->t('%1$s sent you %2$s.', '[url='.$params['source_link'].']'.$params['source_name'].'[/url]', '[url=' . $itemlink . ']' . $l10n->t('a private message').'[/url]'); + + $sitelink = $l10n->t('Please visit %s to view and/or reply to your private messages.'); + $tsitelink = sprintf($sitelink, $itemlink); + $hsitelink = sprintf($sitelink, '' . $sitename . ''); + + // Mail notifications aren't using the "notify" table entry + $show_in_notification_page = false; + break; + + case Model\Notification\Type::COMMENT: + if (Model\Post\ThreadUser::getIgnored($parent_uri_id, $params['uid'])) { + $this->logger->info('Thread is ignored', ['parent' => $parent_id, 'parent-uri-id' => $parent_uri_id]); + return false; + } + + $item = Model\Post::selectFirstForUser($params['uid'], Model\Item::ITEM_FIELDLIST, ['id' => $parent_id, 'deleted' => false]); + if (empty($item)) { + return false; + } + + $item_post_type = Model\Item::postType($item, $l10n); + + $content = Plaintext::getPost($item, 70); + if (!empty($content['text'])) { + $title = '"' . trim(str_replace("\n", " ", $content['text'])) . '"'; + } else { + $title = ''; + } + + // First go for the general message + + // "George Bull's post" + $message = $l10n->t('%1$s commented on %2$s\'s %3$s %4$s'); + $dest_str = sprintf($message, $params['source_name'], $item['author-name'], $item_post_type, $title); + + // "your post" + if ($item['wall']) { + $message = $l10n->t('%1$s commented on your %2$s %3$s'); + $dest_str = sprintf($message, $params['source_name'], $item_post_type, $title); + // "their post" + } elseif ($item['author-link'] == $params['source_link']) { + $message = $l10n->t('%1$s commented on their %2$s %3$s'); + $dest_str = sprintf($message, $params['source_name'], $item_post_type, $title); + } + + $subject = $l10n->t('%1$s Comment to conversation #%2$d by %3$s', $subjectPrefix, $parent_id, $params['source_name']); + + $preamble = $l10n->t('%s commented on an item/conversation you have been following.', $params['source_name']); + + $epreamble = $dest_str; + + $sitelink = $l10n->t('Please visit %s to view and/or reply to the conversation.'); + $tsitelink = sprintf($sitelink, $siteurl); + $hsitelink = sprintf($sitelink, '' . $sitename . ''); + $itemlink = $params['link']; + break; + + case Model\Notification\Type::WALL: + $subject = $l10n->t('%s %s posted to your profile wall', $subjectPrefix, $params['source_name']); + + $preamble = $l10n->t('%1$s posted to your profile wall at %2$s', $params['source_name'], $sitename); + $epreamble = $l10n->t('%1$s posted to [url=%2$s]your wall[/url]', + '[url='.$params['source_link'].']'.$params['source_name'].'[/url]', + $params['link'] + ); + + $sitelink = $l10n->t('Please visit %s to view and/or reply to the conversation.'); + $tsitelink = sprintf($sitelink, $siteurl); + $hsitelink = sprintf($sitelink, ''.$sitename.''); + $itemlink = $params['link']; + break; + + case Model\Notification\Type::POKE: + $subject = $l10n->t('%1$s %2$s poked you', $subjectPrefix, $params['source_name']); + + $preamble = $l10n->t('%1$s poked you at %2$s', $params['source_name'], $sitename); + $epreamble = $l10n->t('%1$s [url=%2$s]poked you[/url].', + '[url='.$params['source_link'].']'.$params['source_name'].'[/url]', + $params['link'] + ); + + $subject = str_replace('poked', $l10n->t($params['activity']), $subject); + $preamble = str_replace('poked', $l10n->t($params['activity']), $preamble); + $epreamble = str_replace('poked', $l10n->t($params['activity']), $epreamble); + + $sitelink = $l10n->t('Please visit %s to view and/or reply to the conversation.'); + $tsitelink = sprintf($sitelink, $siteurl); + $hsitelink = sprintf($sitelink, ''.$sitename.''); + $itemlink = $params['link']; + break; + + case Model\Notification\Type::INTRO: + $itemlink = $params['link']; + $subject = $l10n->t('%s Introduction received', $subjectPrefix); + + $preamble = $l10n->t('You\'ve received an introduction from \'%1$s\' at %2$s', $params['source_name'], $sitename); + $epreamble = $l10n->t('You\'ve received [url=%1$s]an introduction[/url] from %2$s.', + $itemlink, + '[url='.$params['source_link'].']'.$params['source_name'].'[/url]' + ); + + $body = $l10n->t('You may visit their profile at %s', $params['source_link']); + + $sitelink = $l10n->t('Please visit %s to approve or reject the introduction.'); + $tsitelink = sprintf($sitelink, $siteurl); + $hsitelink = sprintf($sitelink, ''.$sitename.''); + + switch ($params['verb']) { + case Activity::FRIEND: + // someone started to share with user (mostly OStatus) + $subject = $l10n->t('%s A new person is sharing with you', $subjectPrefix); + + $preamble = $l10n->t('%1$s is sharing with you at %2$s', $params['source_name'], $sitename); + $epreamble = $l10n->t('%1$s is sharing with you at %2$s', + '[url='.$params['source_link'].']'.$params['source_name'].'[/url]', + $sitename + ); + break; + case Activity::FOLLOW: + // someone started to follow the user (mostly OStatus) + $subject = $l10n->t('%s You have a new follower', $subjectPrefix); + + $preamble = $l10n->t('You have a new follower at %2$s : %1$s', $params['source_name'], $sitename); + $epreamble = $l10n->t('You have a new follower at %2$s : %1$s', + '[url='.$params['source_link'].']'.$params['source_name'].'[/url]', + $sitename + ); + break; + default: + // ACTIVITY_REQ_FRIEND is default activity for notifications + break; + } + break; + + case Model\Notification\Type::SUGGEST: + $itemlink = $params['link']; + $subject = $l10n->t('%s Friend suggestion received', $subjectPrefix); + + $preamble = $l10n->t('You\'ve received a friend suggestion from \'%1$s\' at %2$s', $params['source_name'], $sitename); + $epreamble = $l10n->t('You\'ve received [url=%1$s]a friend suggestion[/url] for %2$s from %3$s.', + $itemlink, + '[url='.$params['item']['url'].']'.$params['item']['name'].'[/url]', + '[url='.$params['source_link'].']'.$params['source_name'].'[/url]' + ); + + $body = $l10n->t('Name:').' '.$params['item']['name']."\n"; + $body .= $l10n->t('Photo:').' '.$params['item']['photo']."\n"; + $body .= $l10n->t('You may visit their profile at %s', $params['item']['url']); + + $sitelink = $l10n->t('Please visit %s to approve or reject the suggestion.'); + $tsitelink = sprintf($sitelink, $siteurl); + $hsitelink = sprintf($sitelink, ''.$sitename.''); + break; + + case Model\Notification\Type::CONFIRM: + if ($params['verb'] == Activity::FRIEND) { // mutual connection + $itemlink = $params['link']; + $subject = $l10n->t('%s Connection accepted', $subjectPrefix); + + $preamble = $l10n->t('\'%1$s\' has accepted your connection request at %2$s', $params['source_name'], $sitename); + $epreamble = $l10n->t('%2$s has accepted your [url=%1$s]connection request[/url].', + $itemlink, + '[url='.$params['source_link'].']'.$params['source_name'].'[/url]' + ); + + $body = $l10n->t('You are now mutual friends and may exchange status updates, photos, and email without restriction.'); + + $sitelink = $l10n->t('Please visit %s if you wish to make any changes to this relationship.'); + $tsitelink = sprintf($sitelink, $siteurl); + $hsitelink = sprintf($sitelink, ''.$sitename.''); + } else { // ACTIVITY_FOLLOW + $itemlink = $params['link']; + $subject = $l10n->t('%s Connection accepted', $subjectPrefix); + + $preamble = $l10n->t('\'%1$s\' has accepted your connection request at %2$s', $params['source_name'], $sitename); + $epreamble = $l10n->t('%2$s has accepted your [url=%1$s]connection request[/url].', + $itemlink, + '[url='.$params['source_link'].']'.$params['source_name'].'[/url]' + ); + + $body = $l10n->t('\'%1$s\' has chosen to accept you a fan, which restricts some forms of communication - such as private messaging and some profile interactions. If this is a celebrity or community page, these settings were applied automatically.', $params['source_name']); + $body .= "\n\n"; + $body .= $l10n->t('\'%1$s\' may choose to extend this into a two-way or more permissive relationship in the future.', $params['source_name']); + + $sitelink = $l10n->t('Please visit %s if you wish to make any changes to this relationship.'); + $tsitelink = sprintf($sitelink, $siteurl); + $hsitelink = sprintf($sitelink, ''.$sitename.''); + } + break; + + case Model\Notification\Type::SYSTEM: + switch($params['event']) { + case "SYSTEM_REGISTER_REQUEST": + $itemlink = $params['link']; + $subject = $l10n->t('[Friendica System Notify]') . ' ' . $l10n->t('registration request'); + + $preamble = $l10n->t('You\'ve received a registration request from \'%1$s\' at %2$s', $params['source_name'], $sitename); + $epreamble = $l10n->t('You\'ve received a [url=%1$s]registration request[/url] from %2$s.', + $itemlink, + '[url='.$params['source_link'].']'.$params['source_name'].'[/url]' + ); + + $body = $l10n->t("Full Name: %s\nSite Location: %s\nLogin Name: %s (%s)", + $params['source_name'], + $siteurl, $params['source_mail'], + $params['source_nick'] + ); + + $sitelink = $l10n->t('Please visit %s to approve or reject the request.'); + $tsitelink = sprintf($sitelink, $params['link']); + $hsitelink = sprintf($sitelink, ''.$sitename.'

'); + break; + case "SYSTEM_DB_UPDATE_FAIL": + break; + } + break; + + default: + $this->logger->notice('Unhandled type', ['type' => $params['type']]); + return false; + } + + return $this->storeAndSend($params, $sitelink, $tsitelink, $hsitelink, $title, $subject, $preamble, $epreamble, $body, $itemlink, $show_in_notification_page); + } + + private function storeAndSend($params, $sitelink, $tsitelink, $hsitelink, $title, $subject, $preamble, $epreamble, $body, $itemlink, $show_in_notification_page) + { + $item_id = $params['item']['id'] ?? 0; + $uri_id = $params['item']['uri-id'] ?? 0; + $parent_id = $params['item']['parent'] ?? 0; + $parent_uri_id = $params['item']['parent-uri-id'] ?? 0; + + // Ensure that the important fields are set at any time + $fields = ['nickname']; + $user = Model\User::getById($params['uid'], $fields); + + $sitename = $this->config->get('config', 'sitename'); + + $nickname = $user['nickname']; + + $hostname = $this->baseUrl->getHostname(); + if (strpos($hostname, ':')) { + $hostname = substr($hostname, 0, strpos($hostname, ':')); + } + + // Creates a new email builder for the notification email + $emailBuilder = $this->emailer->newNotifyMail(); + + $emailBuilder->setHeader('X-Friendica-Account', '<' . $nickname . '@' . $hostname . '>'); + + $subject .= " (".$nickname."@".$hostname.")"; + + $h = [ + 'params' => $params, + 'subject' => $subject, + 'preamble' => $preamble, + 'epreamble' => $epreamble, + 'body' => $body, + 'sitelink' => $sitelink, + 'tsitelink' => $tsitelink, + 'hsitelink' => $hsitelink, + 'itemlink' => $itemlink + ]; + + Hook::callAll('enotify', $h); + + $subject = $h['subject']; + + $preamble = $h['preamble']; + $epreamble = $h['epreamble']; + + $body = $h['body']; + + $tsitelink = $h['tsitelink']; + $hsitelink = $h['hsitelink']; + $itemlink = $h['itemlink']; + + $notify_id = 0; + + if ($show_in_notification_page) { + $Notify = $this->factory->createFromParams($params, $itemlink, $item_id, $uri_id, $parent_id, $parent_uri_id); + try { + $Notify = $this->save($Notify); + } catch (Exception\NotificationCreationInterceptedException $e) { + // Notification insertion can be intercepted by an addon registering the 'enotify_store' hook + return false; + } + + $Notify->updateMsgFromPreamble($epreamble); + $Notify = $this->save($Notify); + + $itemlink = $this->baseUrl->get() . '/notification/' . $Notify->id; + $notify_id = $Notify->id; + } + + // send email notification if notification preferences permit + if ((intval($params['notify_flags']) & intval($params['type'])) + || $params['type'] == Model\Notification\Type::SYSTEM) { + + $this->logger->notice('sending notification email'); + + if (isset($params['parent']) && (intval($params['parent']) != 0)) { + $parent = Model\Post::selectFirst(['guid'], ['id' => $params['parent']]); + $message_id = "<" . $parent['guid'] . "@" . gethostname() . ">"; + + // Is this the first email notification for this parent item and user? + if (!DBA::exists('notify-threads', ['master-parent-uri-id' => $parent_uri_id, 'receiver-uid' => $params['uid']])) { + $this->logger->log("notify_id:" . intval($notify_id) . ", parent: " . intval($params['parent']) . "uid: " . intval($params['uid']), $this->logger->DEBUG); + + $fields = ['notify-id' => $notify_id, 'master-parent-uri-id' => $parent_uri_id, + 'receiver-uid' => $params['uid'], 'parent-item' => 0]; + DBA::insert('notify-threads', $fields); + + $emailBuilder->setHeader('Message-ID', $message_id); + $log_msg = "include/enotify: No previous notification found for this parent:\n" . + " parent: ${params['parent']}\n" . " uid : ${params['uid']}\n"; + $this->logger->log($log_msg, $this->logger->DEBUG); + } else { + // If not, just "follow" the thread. + $emailBuilder->setHeader('References', $message_id); + $emailBuilder->setHeader('In-Reply-To', $message_id); + $this->logger->log("There's already a notification for this parent.", $this->logger->DEBUG); + } + } + + $datarray = [ + 'preamble' => $preamble, + 'type' => $params['type'], + 'parent' => $parent_id, + 'source_name' => $params['source_name'] ?? null, + 'source_link' => $params['source_link'] ?? null, + 'source_photo' => $params['source_photo'] ?? null, + 'uid' => $params['uid'], + 'hsitelink' => $hsitelink, + 'tsitelink' => $tsitelink, + 'itemlink' => $itemlink, + 'title' => $title, + 'body' => $body, + 'subject' => $subject, + 'headers' => $emailBuilder->getHeaders(), + ]; + + Hook::callAll('enotify_mail', $datarray); + + $emailBuilder + ->withHeaders($datarray['headers']) + ->withRecipient($params['to_email']) + ->forUser([ + 'uid' => $datarray['uid'], + 'language' => $params['language'], + ]) + ->withNotification($datarray['subject'], $datarray['preamble'], $datarray['title'], $datarray['body']) + ->withSiteLink($datarray['tsitelink'], $datarray['hsitelink']) + ->withItemLink($datarray['itemlink']); + + // If a photo is present, add it to the email + if (!empty($datarray['source_photo'])) { + $emailBuilder->withPhoto( + $datarray['source_photo'], + $datarray['source_link'] ?? $sitelink, + $datarray['source_name'] ?? $sitename); + } + + $email = $emailBuilder->build(); + + // use the Emailer class to send the message + return $this->emailer->send($email); + } + + return false; + } + + public function createFromNotification(Entity\Notification $Notification) + { + $this->logger->info('Start', ['uid' => $Notification->uid, 'id' => $Notification->id, 'type' => $Notification->type]); + + if ($Notification->type === Model\Post\UserNotification::TYPE_NONE) { + $this->logger->info('Not an item based notification, quitting', ['uid' => $Notification->uid, 'id' => $Notification->id, 'type' => $Notification->type]); + return false; + } + + $params = []; + $params['verb'] = $Notification->verb; + $params['uid'] = $Notification->uid; + $params['otype'] = Model\Notification\ObjectType::ITEM; + + $user = Model\User::getById($Notification->uid); + + $params['notify_flags'] = $user['notify-flags']; + $params['language'] = $user['language']; + $params['to_name'] = $user['username']; + $params['to_email'] = $user['email']; + + // from here on everything is in the recipients language + $l10n = $this->l10n->withLang($user['language']); + + $contact = Model\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 = Model\Post::selectFirstForUser($Notification->uid, Model\Item::ITEM_FIELDLIST, + ['uid' => [0, $Notification->uid], 'uri-id' => $Notification->targetUriId, 'deleted' => false], + ['order' => ['uid' => true]]); + if (empty($item)) { + $this->logger->info('Item not found', ['uri-id' => $Notification->targetUriId, 'type' => $Notification->type]); + return false; + } + + $params['item'] = $item; + $params['parent'] = $item['parent']; + $params['link'] = $this->baseUrl->get() . '/display/' . urlencode($item['guid']); + + $subjectPrefix = $l10n->t('[Friendica:Notify]'); + + if (Model\Post\ThreadUser::getIgnored($Notification->parentUriId, $Notification->uid)) { + $this->logger->info('Thread is ignored', ['parent-uri-id' => $Notification->parentUriId, 'type' => $Notification->type]); + return false; + } + + // Check to see if there was already a tag notify or comment notify for this post. + // If so don't create a second notification + $condition = ['type' => [Model\Notification\Type::TAG_SELF, Model\Notification\Type::COMMENT, Model\Notification\Type::SHARE], + 'link' => $params['link'], 'verb' => Activity::POST]; + if ($this->existsForUser($Notification->uid, $condition)) { + $this->logger->info('Duplicate found, quitting', $condition + ['uid' => $Notification->uid]); + return false; + } + + $content = Plaintext::getPost($item, 70); + if (!empty($content['text'])) { + $title = '"' . trim(str_replace("\n", " ", $content['text'])) . '"'; + } else { + $title = $item['title']; + } + + // Some mail software relies on subject field for threading. + // 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 === Model\Post\UserNotification::TYPE_EXPLICIT_TAGGED) { + $params['type'] = Model\Notification\Type::TAG_SELF; + $subject = $l10n->t('%s %s tagged you', $subjectPrefix, $contact['name']); + } elseif ($Notification->type === Model\Post\UserNotification::TYPE_SHARED) { + $params['type'] = Model\Notification\Type::SHARE; + $subject = $l10n->t('%s %s shared a new post', $subjectPrefix, $contact['name']); + } else { + $params['type'] = Model\Notification\Type::COMMENT; + $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); + if (empty($msg)) { + $this->logger->info('No notification message, quitting', ['uid' => $Notification->uid, 'id' => $Notification->id, 'type' => $Notification->type]); + return false; + } + + $preamble = $msg['plain']; + $epreamble = $msg['rich']; + + $sitename = $this->config->get('config', 'sitename'); + $siteurl = $this->baseUrl->get(true); + + $sitelink = $l10n->t('Please visit %s to view and/or reply to the conversation.'); + $tsitelink = sprintf($sitelink, $siteurl); + $hsitelink = sprintf($sitelink, '' . $sitename . ''); + $itemlink = $params['link']; + + $this->logger->info('Perform notification', ['uid' => $Notification->uid, 'id' => $Notification->id, 'type' => $Notification->type]); + + return $this->storeAndSend($params, $sitelink, $tsitelink, $hsitelink, $title, $subject, $preamble, $epreamble, $item['body'], $itemlink, true); + } } diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php index 081b7f2a37..8c511c2cd5 100644 --- a/src/Protocol/DFRN.php +++ b/src/Protocol/DFRN.php @@ -1371,7 +1371,7 @@ class DFRN 'note' => $suggest['body'], 'hash' => $hash, 'datetime' => DateTimeFormat::utcNow(), 'blocked' => false]; DBA::insert('intro', $fields); - notification([ + DI::notify()->createFromArray([ 'type' => Notification\Type::SUGGEST, 'otype' => Notification\ObjectType::INTRO, 'verb' => Activity::REQ_FRIEND, @@ -1576,7 +1576,7 @@ class DFRN $item['parent'] = $parent['id']; // send a notification - notification( + DI::notify()->createFromArray( [ "type" => Notification\Type::POKE, "otype" => Notification\ObjectType::PERSON, diff --git a/view/lang/C/messages.po b/view/lang/C/messages.po index 52412965f2..95fb60457c 100644 --- a/view/lang/C/messages.po +++ b/view/lang/C/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 2021.12-dev\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-10-18 00:07+0200\n" +"POT-Creation-Date: 2021-10-19 20:03+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -37,256 +37,6 @@ msgstr[1] "" msgid "Monthly posting limit of %d post reached. The post was rejected." msgstr "" -#: include/enotify.php:50 include/enotify.php:533 -msgid "[Friendica:Notify]" -msgstr "" - -#: include/enotify.php:114 -#, php-format -msgid "%s New mail received at %s" -msgstr "" - -#: include/enotify.php:116 -#, php-format -msgid "%1$s sent you a new private message at %2$s." -msgstr "" - -#: include/enotify.php:117 -msgid "a private message" -msgstr "" - -#: include/enotify.php:117 -#, php-format -msgid "%1$s sent you %2$s." -msgstr "" - -#: include/enotify.php:119 -#, php-format -msgid "Please visit %s to view and/or reply to your private messages." -msgstr "" - -#: include/enotify.php:150 -#, php-format -msgid "%1$s commented on %2$s's %3$s %4$s" -msgstr "" - -#: include/enotify.php:155 -#, php-format -msgid "%1$s commented on your %2$s %3$s" -msgstr "" - -#: include/enotify.php:159 -#, php-format -msgid "%1$s commented on their %2$s %3$s" -msgstr "" - -#: include/enotify.php:163 include/enotify.php:568 -#, php-format -msgid "%1$s Comment to conversation #%2$d by %3$s" -msgstr "" - -#: include/enotify.php:165 -#, php-format -msgid "%s commented on an item/conversation you have been following." -msgstr "" - -#: include/enotify.php:169 include/enotify.php:184 include/enotify.php:203 -#: include/enotify.php:583 -#, php-format -msgid "Please visit %s to view and/or reply to the conversation." -msgstr "" - -#: include/enotify.php:176 -#, php-format -msgid "%s %s posted to your profile wall" -msgstr "" - -#: include/enotify.php:178 -#, php-format -msgid "%1$s posted to your profile wall at %2$s" -msgstr "" - -#: include/enotify.php:179 -#, php-format -msgid "%1$s posted to [url=%2$s]your wall[/url]" -msgstr "" - -#: include/enotify.php:191 -#, php-format -msgid "%1$s %2$s poked you" -msgstr "" - -#: include/enotify.php:193 -#, php-format -msgid "%1$s poked you at %2$s" -msgstr "" - -#: include/enotify.php:194 -#, php-format -msgid "%1$s [url=%2$s]poked you[/url]." -msgstr "" - -#: include/enotify.php:211 -#, php-format -msgid "%s Introduction received" -msgstr "" - -#: include/enotify.php:213 -#, php-format -msgid "You've received an introduction from '%1$s' at %2$s" -msgstr "" - -#: include/enotify.php:214 -#, php-format -msgid "You've received [url=%1$s]an introduction[/url] from %2$s." -msgstr "" - -#: include/enotify.php:219 include/enotify.php:265 -#, php-format -msgid "You may visit their profile at %s" -msgstr "" - -#: include/enotify.php:221 -#, php-format -msgid "Please visit %s to approve or reject the introduction." -msgstr "" - -#: include/enotify.php:228 -#, php-format -msgid "%s A new person is sharing with you" -msgstr "" - -#: include/enotify.php:230 include/enotify.php:231 -#, php-format -msgid "%1$s is sharing with you at %2$s" -msgstr "" - -#: include/enotify.php:238 -#, php-format -msgid "%s You have a new follower" -msgstr "" - -#: include/enotify.php:240 include/enotify.php:241 -#, php-format -msgid "You have a new follower at %2$s : %1$s" -msgstr "" - -#: include/enotify.php:254 -#, php-format -msgid "%s Friend suggestion received" -msgstr "" - -#: include/enotify.php:256 -#, php-format -msgid "You've received a friend suggestion from '%1$s' at %2$s" -msgstr "" - -#: include/enotify.php:257 -#, php-format -msgid "You've received [url=%1$s]a friend suggestion[/url] for %2$s from %3$s." -msgstr "" - -#: include/enotify.php:263 -msgid "Name:" -msgstr "" - -#: include/enotify.php:264 -msgid "Photo:" -msgstr "" - -#: include/enotify.php:267 -#, php-format -msgid "Please visit %s to approve or reject the suggestion." -msgstr "" - -#: include/enotify.php:275 include/enotify.php:290 -#, php-format -msgid "%s Connection accepted" -msgstr "" - -#: include/enotify.php:277 include/enotify.php:292 -#, php-format -msgid "'%1$s' has accepted your connection request at %2$s" -msgstr "" - -#: include/enotify.php:278 include/enotify.php:293 -#, php-format -msgid "%2$s has accepted your [url=%1$s]connection request[/url]." -msgstr "" - -#: include/enotify.php:283 -msgid "" -"You are now mutual friends and may exchange status updates, photos, and " -"email without restriction." -msgstr "" - -#: include/enotify.php:285 -#, php-format -msgid "Please visit %s if you wish to make any changes to this relationship." -msgstr "" - -#: include/enotify.php:298 -#, php-format -msgid "" -"'%1$s' has chosen to accept you a fan, which restricts some forms of " -"communication - such as private messaging and some profile interactions. If " -"this is a celebrity or community page, these settings were applied " -"automatically." -msgstr "" - -#: include/enotify.php:300 -#, php-format -msgid "" -"'%1$s' may choose to extend this into a two-way or more permissive " -"relationship in the future." -msgstr "" - -#: include/enotify.php:302 -#, php-format -msgid "Please visit %s if you wish to make any changes to this relationship." -msgstr "" - -#: include/enotify.php:312 mod/removeme.php:63 -msgid "[Friendica System Notify]" -msgstr "" - -#: include/enotify.php:312 -msgid "registration request" -msgstr "" - -#: include/enotify.php:314 -#, php-format -msgid "You've received a registration request from '%1$s' at %2$s" -msgstr "" - -#: include/enotify.php:315 -#, php-format -msgid "You've received a [url=%1$s]registration request[/url] from %2$s." -msgstr "" - -#: include/enotify.php:320 -#, php-format -msgid "" -"Full Name:\t%s\n" -"Site Location:\t%s\n" -"Login Name:\t%s (%s)" -msgstr "" - -#: include/enotify.php:326 -#, php-format -msgid "Please visit %s to approve or reject the request." -msgstr "" - -#: include/enotify.php:562 -#, php-format -msgid "%s %s tagged you" -msgstr "" - -#: include/enotify.php:565 -#, php-format -msgid "%s %s shared a new post" -msgstr "" - #: mod/api.php:30 mod/editpost.php:38 mod/events.php:220 mod/follow.php:56 #: mod/follow.php:130 mod/item.php:185 mod/item.php:190 mod/item.php:936 #: mod/message.php:69 mod/message.php:111 mod/notes.php:44 @@ -1368,6 +1118,10 @@ msgstr "" msgid "Contact not found." msgstr "" +#: mod/removeme.php:63 src/Navigation/Notifications/Depository/Notify.php:454 +msgid "[Friendica System Notify]" +msgstr "" + #: mod/removeme.php:63 msgid "User deleted their account" msgstr "" @@ -3312,8 +3066,8 @@ msgstr "" msgid "last" msgstr "" -#: src/Content/Text/BBCode.php:987 src/Content/Text/BBCode.php:1775 -#: src/Content/Text/BBCode.php:1776 +#: src/Content/Text/BBCode.php:987 src/Content/Text/BBCode.php:1781 +#: src/Content/Text/BBCode.php:1782 msgid "Image/photo" msgstr "" @@ -3328,23 +3082,23 @@ msgstr "" msgid "Link to source" msgstr "" -#: src/Content/Text/BBCode.php:1693 src/Content/Text/HTML.php:943 +#: src/Content/Text/BBCode.php:1699 src/Content/Text/HTML.php:943 msgid "Click to open/close" msgstr "" -#: src/Content/Text/BBCode.php:1724 +#: src/Content/Text/BBCode.php:1730 msgid "$1 wrote:" msgstr "" -#: src/Content/Text/BBCode.php:1780 src/Content/Text/BBCode.php:1781 +#: src/Content/Text/BBCode.php:1786 src/Content/Text/BBCode.php:1787 msgid "Encrypted content" msgstr "" -#: src/Content/Text/BBCode.php:1996 +#: src/Content/Text/BBCode.php:2002 msgid "Invalid source protocol" msgstr "" -#: src/Content/Text/BBCode.php:2011 +#: src/Content/Text/BBCode.php:2017 msgid "Invalid link protocol" msgstr "" @@ -10159,6 +9913,262 @@ msgid "" "features and resources." msgstr "" +#: src/Navigation/Notifications/Depository/Notify.php:192 +#: src/Navigation/Notifications/Depository/Notify.php:675 +msgid "[Friendica:Notify]" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:256 +#, php-format +msgid "%s New mail received at %s" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:258 +#, php-format +msgid "%1$s sent you a new private message at %2$s." +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:259 +msgid "a private message" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:259 +#, php-format +msgid "%1$s sent you %2$s." +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:261 +#, php-format +msgid "Please visit %s to view and/or reply to your private messages." +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:292 +#, php-format +msgid "%1$s commented on %2$s's %3$s %4$s" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:297 +#, php-format +msgid "%1$s commented on your %2$s %3$s" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:301 +#, php-format +msgid "%1$s commented on their %2$s %3$s" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:305 +#: src/Navigation/Notifications/Depository/Notify.php:710 +#, php-format +msgid "%1$s Comment to conversation #%2$d by %3$s" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:307 +#, php-format +msgid "%s commented on an item/conversation you have been following." +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:311 +#: src/Navigation/Notifications/Depository/Notify.php:326 +#: src/Navigation/Notifications/Depository/Notify.php:345 +#: src/Navigation/Notifications/Depository/Notify.php:725 +#, php-format +msgid "Please visit %s to view and/or reply to the conversation." +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:318 +#, php-format +msgid "%s %s posted to your profile wall" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:320 +#, php-format +msgid "%1$s posted to your profile wall at %2$s" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:321 +#, php-format +msgid "%1$s posted to [url=%2$s]your wall[/url]" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:333 +#, php-format +msgid "%1$s %2$s poked you" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:335 +#, php-format +msgid "%1$s poked you at %2$s" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:336 +#, php-format +msgid "%1$s [url=%2$s]poked you[/url]." +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:353 +#, php-format +msgid "%s Introduction received" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:355 +#, php-format +msgid "You've received an introduction from '%1$s' at %2$s" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:356 +#, php-format +msgid "You've received [url=%1$s]an introduction[/url] from %2$s." +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:361 +#: src/Navigation/Notifications/Depository/Notify.php:407 +#, php-format +msgid "You may visit their profile at %s" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:363 +#, php-format +msgid "Please visit %s to approve or reject the introduction." +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:370 +#, php-format +msgid "%s A new person is sharing with you" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:372 +#: src/Navigation/Notifications/Depository/Notify.php:373 +#, php-format +msgid "%1$s is sharing with you at %2$s" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:380 +#, php-format +msgid "%s You have a new follower" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:382 +#: src/Navigation/Notifications/Depository/Notify.php:383 +#, php-format +msgid "You have a new follower at %2$s : %1$s" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:396 +#, php-format +msgid "%s Friend suggestion received" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:398 +#, php-format +msgid "You've received a friend suggestion from '%1$s' at %2$s" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:399 +#, php-format +msgid "You've received [url=%1$s]a friend suggestion[/url] for %2$s from %3$s." +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:405 +msgid "Name:" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:406 +msgid "Photo:" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:409 +#, php-format +msgid "Please visit %s to approve or reject the suggestion." +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:417 +#: src/Navigation/Notifications/Depository/Notify.php:432 +#, php-format +msgid "%s Connection accepted" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:419 +#: src/Navigation/Notifications/Depository/Notify.php:434 +#, php-format +msgid "'%1$s' has accepted your connection request at %2$s" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:420 +#: src/Navigation/Notifications/Depository/Notify.php:435 +#, php-format +msgid "%2$s has accepted your [url=%1$s]connection request[/url]." +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:425 +msgid "" +"You are now mutual friends and may exchange status updates, photos, and " +"email without restriction." +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:427 +#, php-format +msgid "Please visit %s if you wish to make any changes to this relationship." +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:440 +#, php-format +msgid "" +"'%1$s' has chosen to accept you a fan, which restricts some forms of " +"communication - such as private messaging and some profile interactions. If " +"this is a celebrity or community page, these settings were applied " +"automatically." +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:442 +#, php-format +msgid "" +"'%1$s' may choose to extend this into a two-way or more permissive " +"relationship in the future." +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:444 +#, php-format +msgid "Please visit %s if you wish to make any changes to this relationship." +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:454 +msgid "registration request" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:456 +#, php-format +msgid "You've received a registration request from '%1$s' at %2$s" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:457 +#, php-format +msgid "You've received a [url=%1$s]registration request[/url] from %2$s." +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:462 +#, php-format +msgid "" +"Full Name:\t%s\n" +"Site Location:\t%s\n" +"Login Name:\t%s (%s)" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:468 +#, php-format +msgid "Please visit %s to approve or reject the request." +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:704 +#, php-format +msgid "%s %s tagged you" +msgstr "" + +#: src/Navigation/Notifications/Depository/Notify.php:707 +#, php-format +msgid "%s %s shared a new post" +msgstr "" + #: src/Navigation/Notifications/Factory/FormattedNotification.php:89 #, php-format msgid "%s liked %s's post"