Path: blob/master/src/applications/notification/controller/PhabricatorNotificationPanelController.php
12256 views
<?php12final class PhabricatorNotificationPanelController3extends PhabricatorNotificationController {45public function handleRequest(AphrontRequest $request) {6$viewer = $request->getViewer();78$unread_count = $viewer->getUnreadNotificationCount();910$warning = $this->prunePhantomNotifications($unread_count);1112$query = id(new PhabricatorNotificationQuery())13->setViewer($viewer)14->withUserPHIDs(array($viewer->getPHID()))15->setLimit(10);1617$stories = $query->execute();1819$clear_ui_class = 'phabricator-notification-clear-all';20$clear_uri = id(new PhutilURI('/notification/clear/'));21if ($stories) {22$builder = id(new PhabricatorNotificationBuilder($stories))23->setUser($viewer);2425$notifications_view = $builder->buildView();26$content = $notifications_view->render();27$clear_uri->replaceQueryParam(28'chronoKey',29head($stories)->getChronologicalKey());30} else {31$content = phutil_tag_div(32'phabricator-notification no-notifications',33pht('You have no notifications.'));34$clear_ui_class .= ' disabled';35}36$clear_ui = javelin_tag(37'a',38array(39'sigil' => 'workflow',40'href' => (string)$clear_uri,41'class' => $clear_ui_class,42),43pht('Mark All Read'));4445$notifications_link = phutil_tag(46'a',47array(48'href' => '/notification/',49),50pht('Notifications'));5152$connection_status = new PhabricatorNotificationStatusView();5354$connection_ui = phutil_tag(55'div',56array(57'class' => 'phabricator-notification-footer',58),59$connection_status);6061$header = phutil_tag(62'div',63array(64'class' => 'phabricator-notification-header',65),66array(67$notifications_link,68$clear_ui,69));7071$content = hsprintf(72'%s%s%s%s',73$header,74$warning,75$content,76$connection_ui);7778$json = array(79'content' => $content,80'number' => (int)$unread_count,81);8283return id(new AphrontAjaxResponse())->setContent($json);84}8586private function prunePhantomNotifications($unread_count) {87// See T8953. If you have an unread notification about an object you88// do not have permission to view, it isn't possible to clear it by89// visiting the object. Identify these notifications and mark them as90// read.9192$viewer = $this->getViewer();9394if (!$unread_count) {95return null;96}9798$table = new PhabricatorFeedStoryNotification();99$conn = $table->establishConnection('r');100101$rows = queryfx_all(102$conn,103'SELECT chronologicalKey, primaryObjectPHID FROM %T104WHERE userPHID = %s AND hasViewed = 0',105$table->getTableName(),106$viewer->getPHID());107if (!$rows) {108return null;109}110111$map = array();112foreach ($rows as $row) {113$map[$row['primaryObjectPHID']][] = $row['chronologicalKey'];114}115116$handles = $viewer->loadHandles(array_keys($map));117$purge_keys = array();118foreach ($handles as $handle) {119$phid = $handle->getPHID();120if ($handle->isComplete()) {121continue;122}123124foreach ($map[$phid] as $chronological_key) {125$purge_keys[] = $chronological_key;126}127}128129if (!$purge_keys) {130return null;131}132133$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();134135$conn = $table->establishConnection('w');136queryfx(137$conn,138'UPDATE %T SET hasViewed = 1139WHERE userPHID = %s AND chronologicalKey IN (%Ls)',140$table->getTableName(),141$viewer->getPHID(),142$purge_keys);143144PhabricatorUserCache::clearCache(145PhabricatorUserNotificationCountCacheType::KEY_COUNT,146$viewer->getPHID());147148unset($unguarded);149150return phutil_tag(151'div',152array(153'class' => 'phabricator-notification phabricator-notification-warning',154),155pht(156'%s notification(s) about objects which no longer exist or which '.157'you can no longer see were discarded.',158phutil_count($purge_keys)));159}160161162}163164165