2012-06-11 09:37:06 -07:00
|
|
|
<?php
|
|
|
|
|
|
|
|
final class PhabricatorNotificationPanelController
|
|
|
|
extends PhabricatorNotificationController {
|
|
|
|
|
2015-08-04 09:32:56 -07:00
|
|
|
public function handleRequest(AphrontRequest $request) {
|
|
|
|
$viewer = $request->getViewer();
|
2012-06-11 09:37:06 -07:00
|
|
|
|
Fix the most significant "phantom notification" badness
Summary:
Ref T13124. Ref T13131. Fixes T8953. See PHI512.
When you receieve a notification about an object and then someone hides that object from you (or deletes it), you get a phantom notification which is very difficult to clear.
For now, test that notifications are visible when you open the menu and clear any that are not.
This could be a little more elegant than it is, but the current behavior is very clearly broken. This unbreaks it, at least.
Test Plan:
- As Alice, configured task stuff to notify me (instead of sending email).
- As Bailey, added Alice as a subscriber to a task, then commented on it.
- As Alice, loaded home and saw a notification count. Didn't click it yet.
- As Bailey, set the task to private.
- As Alice, clicked the notification bell menu icon.
- Before change: no unread notifications, bell menu is semi-stuck in a phantom state which you can't clear.
- After change: bad notifications automatically cleared.
{F5530005}
Reviewers: amckinley
Reviewed By: amckinley
Maniphest Tasks: T13131, T13124, T8953
Differential Revision: https://secure.phabricator.com/D19384
2018-04-19 10:49:30 -07:00
|
|
|
$unread_count = $viewer->getUnreadNotificationCount();
|
|
|
|
|
|
|
|
$warning = $this->prunePhantomNotifications($unread_count);
|
|
|
|
|
2014-08-16 11:14:32 -07:00
|
|
|
$query = id(new PhabricatorNotificationQuery())
|
2015-08-04 09:32:56 -07:00
|
|
|
->setViewer($viewer)
|
|
|
|
->withUserPHIDs(array($viewer->getPHID()))
|
2017-08-28 15:10:25 -07:00
|
|
|
->setLimit(10);
|
2012-06-11 09:37:06 -07:00
|
|
|
|
|
|
|
$stories = $query->execute();
|
|
|
|
|
2014-08-01 16:39:05 -07:00
|
|
|
$clear_ui_class = 'phabricator-notification-clear-all';
|
|
|
|
$clear_uri = id(new PhutilURI('/notification/clear/'));
|
2012-06-17 11:35:18 -07:00
|
|
|
if ($stories) {
|
2016-06-04 15:01:28 -07:00
|
|
|
$builder = id(new PhabricatorNotificationBuilder($stories))
|
|
|
|
->setUser($viewer);
|
|
|
|
|
2012-06-17 11:35:18 -07:00
|
|
|
$notifications_view = $builder->buildView();
|
|
|
|
$content = $notifications_view->render();
|
2014-08-01 16:39:05 -07:00
|
|
|
$clear_uri->setQueryParam(
|
|
|
|
'chronoKey',
|
|
|
|
head($stories)->getChronologicalKey());
|
2012-06-17 11:35:18 -07:00
|
|
|
} else {
|
2013-11-11 09:23:23 -08:00
|
|
|
$content = phutil_tag_div(
|
|
|
|
'phabricator-notification no-notifications',
|
2013-02-13 14:50:15 -08:00
|
|
|
pht('You have no notifications.'));
|
2014-08-01 16:39:05 -07:00
|
|
|
$clear_ui_class .= ' disabled';
|
2012-06-11 17:49:32 -07:00
|
|
|
}
|
2014-08-01 16:39:05 -07:00
|
|
|
$clear_ui = javelin_tag(
|
|
|
|
'a',
|
|
|
|
array(
|
|
|
|
'sigil' => 'workflow',
|
2015-05-20 07:06:07 +10:00
|
|
|
'href' => (string)$clear_uri,
|
2014-08-01 16:39:05 -07:00
|
|
|
'class' => $clear_ui_class,
|
|
|
|
),
|
|
|
|
pht('Mark All Read'));
|
2012-06-11 17:49:32 -07:00
|
|
|
|
2014-06-23 16:26:16 -07:00
|
|
|
$notifications_link = phutil_tag(
|
|
|
|
'a',
|
|
|
|
array(
|
|
|
|
'href' => '/notification/',
|
|
|
|
),
|
|
|
|
pht('Notifications'));
|
|
|
|
|
2016-04-13 12:07:48 -07:00
|
|
|
$connection_status = new PhabricatorNotificationStatusView();
|
|
|
|
|
2014-08-14 17:19:01 -07:00
|
|
|
$connection_ui = phutil_tag(
|
|
|
|
'div',
|
|
|
|
array(
|
2014-10-08 00:01:04 +11:00
|
|
|
'class' => 'phabricator-notification-footer',
|
2014-08-14 17:19:01 -07:00
|
|
|
),
|
|
|
|
$connection_status);
|
2014-06-23 16:26:16 -07:00
|
|
|
|
|
|
|
$header = phutil_tag(
|
|
|
|
'div',
|
|
|
|
array(
|
|
|
|
'class' => 'phabricator-notification-header',
|
|
|
|
),
|
|
|
|
array(
|
|
|
|
$notifications_link,
|
2014-08-14 17:19:01 -07:00
|
|
|
$clear_ui,
|
2014-06-23 16:26:16 -07:00
|
|
|
));
|
|
|
|
|
2013-02-13 14:50:15 -08:00
|
|
|
$content = hsprintf(
|
Fix the most significant "phantom notification" badness
Summary:
Ref T13124. Ref T13131. Fixes T8953. See PHI512.
When you receieve a notification about an object and then someone hides that object from you (or deletes it), you get a phantom notification which is very difficult to clear.
For now, test that notifications are visible when you open the menu and clear any that are not.
This could be a little more elegant than it is, but the current behavior is very clearly broken. This unbreaks it, at least.
Test Plan:
- As Alice, configured task stuff to notify me (instead of sending email).
- As Bailey, added Alice as a subscriber to a task, then commented on it.
- As Alice, loaded home and saw a notification count. Didn't click it yet.
- As Bailey, set the task to private.
- As Alice, clicked the notification bell menu icon.
- Before change: no unread notifications, bell menu is semi-stuck in a phantom state which you can't clear.
- After change: bad notifications automatically cleared.
{F5530005}
Reviewers: amckinley
Reviewed By: amckinley
Maniphest Tasks: T13131, T13124, T8953
Differential Revision: https://secure.phabricator.com/D19384
2018-04-19 10:49:30 -07:00
|
|
|
'%s%s%s%s',
|
2014-06-23 16:26:16 -07:00
|
|
|
$header,
|
Fix the most significant "phantom notification" badness
Summary:
Ref T13124. Ref T13131. Fixes T8953. See PHI512.
When you receieve a notification about an object and then someone hides that object from you (or deletes it), you get a phantom notification which is very difficult to clear.
For now, test that notifications are visible when you open the menu and clear any that are not.
This could be a little more elegant than it is, but the current behavior is very clearly broken. This unbreaks it, at least.
Test Plan:
- As Alice, configured task stuff to notify me (instead of sending email).
- As Bailey, added Alice as a subscriber to a task, then commented on it.
- As Alice, loaded home and saw a notification count. Didn't click it yet.
- As Bailey, set the task to private.
- As Alice, clicked the notification bell menu icon.
- Before change: no unread notifications, bell menu is semi-stuck in a phantom state which you can't clear.
- After change: bad notifications automatically cleared.
{F5530005}
Reviewers: amckinley
Reviewed By: amckinley
Maniphest Tasks: T13131, T13124, T8953
Differential Revision: https://secure.phabricator.com/D19384
2018-04-19 10:49:30 -07:00
|
|
|
$warning,
|
2014-06-23 16:26:16 -07:00
|
|
|
$content,
|
2014-08-14 17:19:01 -07:00
|
|
|
$connection_ui);
|
2012-06-18 14:07:38 -07:00
|
|
|
|
2012-06-11 09:37:06 -07:00
|
|
|
$json = array(
|
2012-06-17 11:35:18 -07:00
|
|
|
'content' => $content,
|
2013-05-21 15:44:44 -07:00
|
|
|
'number' => (int)$unread_count,
|
2012-06-11 09:37:06 -07:00
|
|
|
);
|
|
|
|
|
|
|
|
return id(new AphrontAjaxResponse())->setContent($json);
|
|
|
|
}
|
Fix the most significant "phantom notification" badness
Summary:
Ref T13124. Ref T13131. Fixes T8953. See PHI512.
When you receieve a notification about an object and then someone hides that object from you (or deletes it), you get a phantom notification which is very difficult to clear.
For now, test that notifications are visible when you open the menu and clear any that are not.
This could be a little more elegant than it is, but the current behavior is very clearly broken. This unbreaks it, at least.
Test Plan:
- As Alice, configured task stuff to notify me (instead of sending email).
- As Bailey, added Alice as a subscriber to a task, then commented on it.
- As Alice, loaded home and saw a notification count. Didn't click it yet.
- As Bailey, set the task to private.
- As Alice, clicked the notification bell menu icon.
- Before change: no unread notifications, bell menu is semi-stuck in a phantom state which you can't clear.
- After change: bad notifications automatically cleared.
{F5530005}
Reviewers: amckinley
Reviewed By: amckinley
Maniphest Tasks: T13131, T13124, T8953
Differential Revision: https://secure.phabricator.com/D19384
2018-04-19 10:49:30 -07:00
|
|
|
|
|
|
|
private function prunePhantomNotifications($unread_count) {
|
|
|
|
// See T8953. If you have an unread notification about an object you
|
|
|
|
// do not have permission to view, it isn't possible to clear it by
|
|
|
|
// visiting the object. Identify these notifications and mark them as
|
|
|
|
// read.
|
|
|
|
|
|
|
|
$viewer = $this->getViewer();
|
|
|
|
|
|
|
|
if (!$unread_count) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
$table = new PhabricatorFeedStoryNotification();
|
|
|
|
$conn = $table->establishConnection('r');
|
|
|
|
|
|
|
|
$rows = queryfx_all(
|
|
|
|
$conn,
|
|
|
|
'SELECT chronologicalKey, primaryObjectPHID FROM %T
|
|
|
|
WHERE userPHID = %s AND hasViewed = 0',
|
|
|
|
$table->getTableName(),
|
|
|
|
$viewer->getPHID());
|
|
|
|
if (!$rows) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
$map = array();
|
|
|
|
foreach ($rows as $row) {
|
|
|
|
$map[$row['primaryObjectPHID']][] = $row['chronologicalKey'];
|
|
|
|
}
|
|
|
|
|
|
|
|
$handles = $viewer->loadHandles(array_keys($map));
|
|
|
|
$purge_keys = array();
|
|
|
|
foreach ($handles as $handle) {
|
|
|
|
$phid = $handle->getPHID();
|
|
|
|
if ($handle->isComplete()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($map[$phid] as $chronological_key) {
|
|
|
|
$purge_keys[] = $chronological_key;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$purge_keys) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
|
|
|
|
|
|
|
$conn = $table->establishConnection('w');
|
|
|
|
queryfx(
|
|
|
|
$conn,
|
|
|
|
'UPDATE %T SET hasViewed = 1
|
|
|
|
WHERE userPHID = %s AND chronologicalKey IN (%Ls)',
|
|
|
|
$table->getTableName(),
|
|
|
|
$viewer->getPHID(),
|
|
|
|
$purge_keys);
|
|
|
|
|
|
|
|
PhabricatorUserCache::clearCache(
|
|
|
|
PhabricatorUserNotificationCountCacheType::KEY_COUNT,
|
|
|
|
$viewer->getPHID());
|
|
|
|
|
|
|
|
unset($unguarded);
|
|
|
|
|
|
|
|
return phutil_tag(
|
|
|
|
'div',
|
|
|
|
array(
|
|
|
|
'class' => 'phabricator-notification phabricator-notification-warning',
|
|
|
|
),
|
|
|
|
pht(
|
|
|
|
'%s notification(s) about objects which no longer exist or which '.
|
|
|
|
'you can no longer see were discarded.',
|
|
|
|
phutil_count($purge_keys)));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-06-11 09:37:06 -07:00
|
|
|
}
|