X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FModule%2FNotifications%2FPing.php;h=3cd4d702010dc9e61c1e702618649e15014aaffa;hb=f0743e4e128dfcb5d6305f4ed09e969573ba6b15;hp=6faea810e23649a046740cdc16f146aba0ec26a3;hpb=1ae7cac23667a7e43a0ca5e66ad6fd58011542d0;p=friendica.git diff --git a/src/Module/Notifications/Ping.php b/src/Module/Notifications/Ping.php index 6faea810e2..3cd4d70201 100644 --- a/src/Module/Notifications/Ping.php +++ b/src/Module/Notifications/Ping.php @@ -1,6 +1,6 @@ systemMessages = $systemMessages; + $this->notificationRepo = $notificationRepo; + $this->introductionRepo = $introductionRepo; + $this->formattedNavNotification = $formattedNavNotification; + $this->session = $session; + $this->config = $config; + $this->pconfig = $pconfig; + $this->database = $database; + $this->cache = $cache; + $this->notify = $notify; + $this->app = $app; + } + protected function rawContent(array $request = []) { - $regs = []; - $notifications = []; - - $intro_count = 0; - $mail_count = 0; - $home_count = 0; - $network_count = 0; - $register_count = 0; + $registrations = []; + $navNotifications = []; + + $intro_count = 0; + $mail_count = 0; + $home_count = 0; + $network_count = 0; + $register_count = 0; $sysnotify_count = 0; - $groups_unseen = []; - $forums_unseen = []; - - $all_events = 0; - $all_events_today = 0; - $events = 0; - $events_today = 0; - $birthdays = 0; - $birthdays_today = 0; - - - if (local_user()) { - $notifications = $this->getNotificationList(local_user()); + $groups_unseen = []; + $forums_unseen = []; + + $event_count = 0; + $today_event_count = 0; + $birthday_count = 0; + $today_birthday_count = 0; + + // Suppress notification display for forum accounts + if ($this->session->getLocalUserId() && $this->session->get('page_flags', '') != User::PAGE_FLAGS_COMMUNITY) { + if ($this->pconfig->get($this->session->getLocalUserId(), 'system', 'detailed_notif')) { + $notifications = $this->notificationRepo->selectDetailedForUser($this->session->getLocalUserId()); + } else { + $notifications = $this->notificationRepo->selectDigestForUser($this->session->getLocalUserId()); + } $condition = [ "`unseen` AND `uid` = ? AND NOT `origin` AND (`vid` != ? OR `vid` IS NULL)", - local_user(), Verb::getID(Activity::FOLLOW) + $this->session->getLocalUserId(), Verb::getID(Activity::FOLLOW) ]; - $items = Post::selectForUser(local_user(), ['wall', 'uid', 'uri-id'], $condition, ['limit' => 1000]); - if (DBA::isResult($items)) { - $items_unseen = Post::toArray($items, false); - $arr = ['items' => $items_unseen]; - Hook::callAll('network_ping', $arr); - - foreach ($items_unseen as $item) { - if ($item['wall']) { - $home_count++; - } else { - $network_count++; - } + + // No point showing counts for non-top-level posts when the network page is ordered by received field + if (Network::getTimelineOrderBySession($this->session, $this->pconfig) == 'received') { + $condition = DBA::mergeConditions($condition, ["`parent` = `id`"]); + } + + $items_unseen = $this->database->toArray(Post::selectForUser( + $this->session->getLocalUserId(), + ['wall', 'uid', 'uri-id'], + $condition, + ['limit' => 1000], + )); + $arr = ['items' => $items_unseen]; + Hook::callAll('network_ping', $arr); + + foreach ($items_unseen as $item) { + if ($item['wall']) { + $home_count++; + } else { + $network_count++; } } - DBA::close($items); - if ($network_count) { + $compute_group_counts = $this->config->get('system','compute_group_counts'); + if ($network_count && $compute_group_counts) { // Find out how unseen network posts are spread across groups - $group_counts = Group::countUnseen(); - if (DBA::isResult($group_counts)) { - foreach ($group_counts as $group_count) { - if ($group_count['count'] > 0) { - $groups_unseen[] = $group_count; - } + foreach (Group::countUnseen() as $group_count) { + if ($group_count['count'] > 0) { + $groups_unseen[] = $group_count; } } - $forum_counts = ForumManager::countUnseenItems(); - if (DBA::isResult($forum_counts)) { - foreach ($forum_counts as $forum_count) { - if ($forum_count['count'] > 0) { - $forums_unseen[] = $forum_count; - } + foreach (ForumManager::countUnseenItems() as $forum_count) { + if ($forum_count['count'] > 0) { + $forums_unseen[] = $forum_count; } } } - $intros1 = DBA::toArray(DBA::p( - "SELECT `intro`.`id`, `intro`.`datetime`, - `contact`.`name`, `contact`.`url`, `contact`.`photo` - FROM `intro` INNER JOIN `contact` ON `intro`.`suggest-cid` = `contact`.`id` - WHERE `intro`.`uid` = ? AND NOT `intro`.`blocked` AND NOT `intro`.`ignore` AND `intro`.`suggest-cid` != 0", - local_user() - )); - $intros2 = DBA::toArray(DBA::p( - "SELECT `intro`.`id`, `intro`.`datetime`, - `contact`.`name`, `contact`.`url`, `contact`.`photo` - FROM `intro` INNER JOIN `contact` ON `intro`.`contact-id` = `contact`.`id` - WHERE `intro`.`uid` = ? AND NOT `intro`.`blocked` AND NOT `intro`.`ignore` AND `intro`.`contact-id` != 0 AND (`intro`.`suggest-cid` = 0 OR `intro`.`suggest-cid` IS NULL)", - local_user() - )); - - $intro_count = count($intros1) + count($intros2); - $intros = $intros1 + $intros2; + $intros = $this->introductionRepo->selectForUser($this->session->getLocalUserId()); - $myurl = DI::baseUrl() . '/profile/' . DI::app()->getLoggedInUserNickname(); - $mail_count = DBA::count('mail', ["`uid` = ? AND NOT `seen` AND `from-url` != ?", local_user(), $myurl]); + $intro_count = $intros->count(); - if (intval(DI::config()->get('config', 'register_policy')) === Register::APPROVE && DI::app()->isSiteAdmin()) { - $regs = \Friendica\Model\Register::getPending(); + $myurl = $this->session->getMyUrl(); + $mail_count = $this->database->count('mail', ["`uid` = ? AND NOT `seen` AND `from-url` != ?", $this->session->getLocalUserId(), $myurl]); - if (DBA::isResult($regs)) { - $register_count = count($regs); - } + if (intval($this->config->get('config', 'register_policy')) === Register::APPROVE && $this->app->isSiteAdmin()) { + $registrations = \Friendica\Model\Register::getPending(); + $register_count = count($registrations); } - $cachekey = "ping_init:" . local_user(); - $ev = DI::cache()->get($cachekey); - if (is_null($ev)) { - $ev = DBA::selectToArray('event', ['type', 'start'], + $cachekey = 'ping:events:' . $this->session->getLocalUserId(); + $events = $this->cache->get($cachekey); + if (is_null($events)) { + $events = $this->database->selectToArray('event', ['type', 'start'], ["`uid` = ? AND `start` < ? AND `finish` > ? AND NOT `ignore`", - local_user(), DateTimeFormat::utc('now + 7 days'), DateTimeFormat::utcNow()]); - if (DBA::isResult($ev)) { - DI::cache()->set($cachekey, $ev, Duration::HOUR); - } + $this->session->getLocalUserId(), DateTimeFormat::utc('now + 7 days'), DateTimeFormat::utcNow()]); + $this->cache->set($cachekey, $events, Duration::HOUR); } - if (DBA::isResult($ev)) { - $all_events = count($ev); - - if ($all_events) { - $str_now = DateTimeFormat::localNow('Y-m-d'); - foreach ($ev as $x) { - $bd = false; - if ($x['type'] === 'birthday') { - $birthdays ++; - $bd = true; - } else { - $events ++; - } - if (DateTimeFormat::local($x['start'], 'Y-m-d') === $str_now) { - $all_events_today ++; - if ($bd) { - $birthdays_today ++; - } else { - $events_today ++; - } - } + $now_date = DateTimeFormat::localNow('Y-m-d'); + foreach ($events as $event) { + $is_birthday = false; + if ($event['type'] === 'birthday') { + $birthday_count++; + $is_birthday = true; + } else { + $event_count++; + } + + if (DateTimeFormat::local($event['start'], 'Y-m-d') === $now_date) { + if ($is_birthday) { + $today_birthday_count++; + } else { + $today_event_count++; } } } + $owner = User::getOwnerDataById($this->session->getLocalUserId()); - foreach ($notifications as $notification) { - if ($notification['seen'] == 0) { - $sysnotify_count ++; + $navNotifications = array_map(function (Entity\Notification $notification) use ($owner) { + if (!$this->notify->shouldShowOnDesktop($notification)) { + return null; } - } + if (($notification->type == Post\UserNotification::TYPE_NONE) && in_array($owner['page-flags'], [User::PAGE_FLAGS_NORMAL, User::PAGE_FLAGS_PRVGROUP])) { + return null; + } + try { + return $this->formattedNavNotification->createFromNotification($notification); + } catch (NoMessageException $e) { + return null; + } + }, $notifications->getArrayCopy()); + $navNotifications = array_filter($navNotifications); + + $sysnotify_count = array_reduce($navNotifications, function (int $carry, ValueObject\FormattedNavNotification $navNotification) { + return $carry + ($navNotification->seen ? 0 : 1); + }, 0); // merge all notification types in one array - if (DBA::isResult($intros)) { - foreach ($intros as $intro) { - $notifications[] = [ - 'href' => DI::baseUrl() . '/notifications/intros/' . $intro['id'], - 'contact' => [ - 'name' => strip_tags(BBCode::convert($intro['name'])), - 'url' => $intro['url'], - ], - 'message' => DI::l10n()->t('{0}} wants to follow you'), - 'date' => $intro['datetime'], - 'seen' => false, - ]; + foreach ($intros as $intro) { + try { + $navNotifications[] = $this->formattedNavNotification->createFromIntro($intro); + } catch (HTTPException\NotFoundException $e) { + $this->introductionRepo->delete($intro); } } - if (DBA::isResult($regs)) { - if (count($regs) <= 1 || DI::pConfig()->get(local_user(), 'system', 'detailed_notif')) { - foreach ($regs as $reg) { - $notifications[] = [ - 'href' => DI::baseUrl()->get(true) . '/admin/users/pending', - 'contact' => [ - 'name' => $reg['name'], - 'url' => $reg['url'], - ], - 'message' => DI::l10n()->t('{0} requested registration'), - 'date' => $reg['created'], - 'seen' => false, - ]; - } - } else { - $notifications[] = [ - 'href' => DI::baseUrl()->get(true) . '/admin/users/pending', - 'contact' => [ - 'name' => $regs[0]['name'], - 'url' => $regs[0]['url'], - ], - 'message' => DI::l10n()->t('{0} and %d others requested registration', count($regs) - 1), - 'date' => $regs[0]['created'], - 'seen' => false, - ]; + if (count($registrations) <= 1 || $this->pconfig->get($this->session->getLocalUserId(), 'system', 'detailed_notif')) { + foreach ($registrations as $registration) { + $navNotifications[] = $this->formattedNavNotification->createFromParams( + $registration['name'], + $registration['url'], + $this->l10n->t('{0} requested registration'), + new \DateTime($registration['created'], new \DateTimeZone('UTC')), + new Uri($this->baseUrl . '/moderation/users/pending') + ); } + } else { + $navNotifications[] = $this->formattedNavNotification->createFromParams( + $registrations[0]['name'], + $registrations[0]['url'], + $this->l10n->t('{0} and %d others requested registration', count($registrations) - 1), + new \DateTime($registrations[0]['created'], new \DateTimeZone('UTC')), + new Uri($this->baseUrl . '/moderation/users/pending') + ); } // sort notifications by $[]['date'] - $sort_function = function ($a, $b) { - $adate = strtotime($a['date']); - $bdate = strtotime($b['date']); + $sort_function = function (ValueObject\FormattedNavNotification $a, ValueObject\FormattedNavNotification $b) { + $a = $a->toArray(); + $b = $b->toArray(); // Unseen messages are kept at the top - // The value 31536000 means one year. This should be enough :-) - if (!$a['seen']) { - $adate += 31536000; - } - if (!$b['seen']) { - $bdate += 31536000; - } - - if ($adate == $bdate) { - return 0; + if ($a['seen'] == $b['seen']) { + if ($a['timestamp'] == $b['timestamp']) { + return 0; + } else { + return $a['timestamp'] < $b['timestamp'] ? 1 : -1; + } + } else { + return $a['seen'] ? 1 : -1; } - return ($adate < $bdate) ? 1 : -1; }; - usort($notifications, $sort_function); - } - - $sysmsgs = []; - $sysmsgs_info = []; - - if (!empty($_SESSION['sysmsg'])) { - $sysmsgs = $_SESSION['sysmsg']; - unset($_SESSION['sysmsg']); - } - - if (!empty($_SESSION['sysmsg_info'])) { - $sysmsgs_info = $_SESSION['sysmsg_info']; - unset($_SESSION['sysmsg_info']); + usort($navNotifications, $sort_function); } $notification_count = $sysnotify_count + $intro_count + $register_count; - $tpl = Renderer::getMarkupTemplate('notifications/nav/notify.tpl'); - - $data = []; + $data = []; $data['intro'] = $intro_count; $data['mail'] = $mail_count; $data['net'] = ($network_count < 1000) ? $network_count : '999+'; $data['home'] = ($home_count < 1000) ? $home_count : '999+'; $data['register'] = $register_count; - $data['all-events'] = $all_events; - $data['all-events-today'] = $all_events_today; - $data['events'] = $events; - $data['events-today'] = $events_today; - $data['birthdays'] = $birthdays; - $data['birthdays-today'] = $birthdays_today; - $data['groups'] = $groups_unseen; - $data['forums'] = $forums_unseen; - $data['notification'] = ($notification_count < 50) ? $notification_count : '49+'; - $data['notifications'] = array_map(function ($navNotification) use ($tpl) { - $navNotification['contact']['photo'] = Contact::getAvatarUrlForUrl($navNotification['contact']['url'], local_user(), Proxy::SIZE_MICRO); - - $navNotification['timestamp'] = strtotime($navNotification['date']); - $navNotification['localdate'] = DateTimeFormat::local($navNotification['date']); - $navNotification['ago'] = Temporal::getRelativeDate($navNotification['date']); - $navNotification['richtext'] = Entity\Notify::formatMessage($navNotification['contact']['name'], $navNotification['message']); - $navNotification['plaintext'] = strip_tags($navNotification['richtext']); - $navNotification['html'] = Renderer::replaceMacros($tpl, [ - 'notify' => $navNotification, - ]); - - return $navNotification; - }, $notifications); + $data['events'] = $event_count; + $data['events-today'] = $today_event_count; + $data['birthdays'] = $birthday_count; + $data['birthdays-today'] = $today_birthday_count; + $data['groups'] = $groups_unseen; + $data['forums'] = $forums_unseen; + $data['notification'] = ($notification_count < 50) ? $notification_count : '49+'; + + $data['notifications'] = $navNotifications; + $data['sysmsgs'] = [ - 'notice' => $sysmsgs, - 'info' => $sysmsgs_info + 'notice' => $this->systemMessages->flushNotices(), + 'info' => $this->systemMessages->flushInfos(), ]; - $json_payload = json_encode(["result" => $data]); - if (isset($_GET['callback'])) { // JSONP support - header("Content-type: application/javascript"); - echo $_GET['callback'] . '(' . $json_payload . ')'; + System::httpExit($_GET['callback'] . '(' . json_encode(['result' => $data]) . ')', Response::TYPE_BLANK, 'application/javascript'); } else { - header("Content-type: application/json"); - echo $json_payload; + System::jsonExit(['result' => $data]); } - - exit(); - } - - /** - * Retrieves the notifications array for the given user ID - * - * @param int $uid User id - * @return array Associative array of notifications - * @throws HTTPException\InternalServerErrorException - */ - private function getNotificationList(int $uid): array - { - $result = []; - $offset = 0; - $seen = false; - $seensql = 'NOT'; - $order = 'DESC'; - $quit = false; - - do { - $notifies = DBA::toArray(DBA::p( - "SELECT `notify`.*, `post`.`visible`, `post`.`deleted` - FROM `notify` - LEFT JOIN `post` ON `post`.`uri-id` = `notify`.`uri-id` - WHERE `notify`.`uid` = ? AND `notify`.`msg` != '' - AND NOT (`notify`.`type` IN (?, ?)) - AND $seensql `notify`.`seen` ORDER BY `notify`.`date` $order LIMIT ?, 50", - $uid, - Notification\Type::INTRO, - Notification\Type::MAIL, - $offset - )); - - if (!$notifies && !$seen) { - $seen = true; - $seensql = ''; - $order = 'DESC'; - $offset = 0; - } elseif (!$notifies) { - $quit = true; - } else { - $offset += 50; - } - - foreach ($notifies as $notify) { - $notify['visible'] = $notify['visible'] ?? true; - $notify['deleted'] = $notify['deleted'] ?? 0; - - if ($notify['msg_cache']) { - $notify['name'] = $notify['name_cache']; - $notify['message'] = $notify['msg_cache']; - } else { - $notify['name'] = strip_tags(BBCode::convert($notify['name'])); - $notify['message'] = BBCode::toPlaintext($notify['msg']); - - // @todo Replace this with a call of the Notify model class - DBA::update('notify', ['name_cache' => $notify['name'], 'msg_cache' => $notify['message']], ['id' => $notify['id']]); - } - - if ($notify['visible'] - && !$notify['deleted'] - && empty($result['p:' . $notify['parent']]) - ) { - $notification = [ - 'href' => DI::baseUrl() . '/notify/' . $notify['id'], - 'contact' => [ - 'name' => $notify['name'], - 'url' => $notify['url'], - ], - 'message' => $notify['message'], - 'date' => $notify['date'], - 'seen' => $notify['seen'], - ]; - - // Should we condense the notifications or show them all? - if (($notify['verb'] != Activity::POST) || DI::pConfig()->get(local_user(), 'system', 'detailed_notif')) { - $result[] = $notification; - } else { - $result['p:' . $notify['parent']] = $notification; - } - } - } - } while ((count($result) < 50) && !$quit); - - return($result); } }