diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -4623,6 +4623,7 @@ 'PhabricatorUserLogView' => 'applications/people/view/PhabricatorUserLogView.php', 'PhabricatorUserMessageCountCacheType' => 'applications/people/cache/PhabricatorUserMessageCountCacheType.php', 'PhabricatorUserNotificationCountCacheType' => 'applications/people/cache/PhabricatorUserNotificationCountCacheType.php', + 'PhabricatorUserNotifyTransaction' => 'applications/people/xaction/PhabricatorUserNotifyTransaction.php', 'PhabricatorUserPHIDResolver' => 'applications/phid/resolver/PhabricatorUserPHIDResolver.php', 'PhabricatorUserPreferences' => 'applications/settings/storage/PhabricatorUserPreferences.php', 'PhabricatorUserPreferencesCacheType' => 'applications/people/cache/PhabricatorUserPreferencesCacheType.php', @@ -10676,6 +10677,7 @@ 'PhabricatorUserLogView' => 'AphrontView', 'PhabricatorUserMessageCountCacheType' => 'PhabricatorUserCacheType', 'PhabricatorUserNotificationCountCacheType' => 'PhabricatorUserCacheType', + 'PhabricatorUserNotifyTransaction' => 'PhabricatorUserTransactionType', 'PhabricatorUserPHIDResolver' => 'PhabricatorPHIDResolver', 'PhabricatorUserPreferences' => array( 'PhabricatorUserDAO', diff --git a/src/applications/notification/controller/PhabricatorNotificationTestController.php b/src/applications/notification/controller/PhabricatorNotificationTestController.php --- a/src/applications/notification/controller/PhabricatorNotificationTestController.php +++ b/src/applications/notification/controller/PhabricatorNotificationTestController.php @@ -6,34 +6,31 @@ public function handleRequest(AphrontRequest $request) { $viewer = $request->getViewer(); - $story_type = 'PhabricatorNotificationTestFeedStory'; - $story_data = array( - 'title' => pht( + if ($request->validateCSRF()) { + $message_text = pht( 'This is a test notification, sent at %s.', - phabricator_datetime(time(), $viewer)), - ); + phabricator_datetime(time(), $viewer)); - $viewer_phid = $viewer->getPHID(); + // NOTE: Currently, the FeedStoryPublisher explicitly filters out + // notifications about your own actions. Send this notification from + // a different actor to get around this. + $application_phid = id(new PhabricatorNotificationsApplication()) + ->getPHID(); - // NOTE: Because we don't currently show you your own notifications, make - // sure this comes from a different PHID. - $application_phid = id(new PhabricatorNotificationsApplication()) - ->getPHID(); + $xactions = array(); - // TODO: When it's easier to get these buttons to render as forms, this - // would be slightly nicer as a more standard isFormPost() check. + $xactions[] = id(new PhabricatorUserTransaction()) + ->setTransactionType( + PhabricatorUserNotifyTransaction::TRANSACTIONTYPE) + ->setNewValue($message_text) + ->setForceNotifyPHIDs(array($viewer->getPHID())); - if ($request->validateCSRF()) { - id(new PhabricatorFeedStoryPublisher()) - ->setStoryType($story_type) - ->setStoryData($story_data) - ->setStoryTime(time()) - ->setStoryAuthorPHID($application_phid) - ->setRelatedPHIDs(array($viewer_phid)) - ->setPrimaryObjectPHID($viewer_phid) - ->setSubscribedPHIDs(array($viewer_phid)) - ->setNotifyAuthor(true) - ->publish(); + $editor = id(new PhabricatorUserTransactionEditor()) + ->setActor($viewer) + ->setActingAsPHID($application_phid) + ->setContentSourceFromRequest($request); + + $editor->applyTransactions($viewer, $xactions); } return id(new AphrontAjaxResponse()); diff --git a/src/applications/people/controller/PhabricatorPeopleProfileManageController.php b/src/applications/people/controller/PhabricatorPeopleProfileManageController.php --- a/src/applications/people/controller/PhabricatorPeopleProfileManageController.php +++ b/src/applications/people/controller/PhabricatorPeopleProfileManageController.php @@ -43,6 +43,11 @@ ->setCurtain($curtain) ->addPropertySection(pht('Details'), $properties); + $timeline = $this->buildTransactionTimeline( + $user, + new PhabricatorPeopleTransactionQuery()); + $timeline->setShouldTerminate(true); + return $this->newPage() ->setTitle( array( @@ -54,6 +59,7 @@ ->appendChild( array( $manage, + $timeline, )); } diff --git a/src/applications/people/editor/PhabricatorUserTransactionEditor.php b/src/applications/people/editor/PhabricatorUserTransactionEditor.php --- a/src/applications/people/editor/PhabricatorUserTransactionEditor.php +++ b/src/applications/people/editor/PhabricatorUserTransactionEditor.php @@ -11,4 +11,18 @@ return pht('Users'); } + protected function shouldPublishFeedStory( + PhabricatorLiskDAO $object, + array $xactions) { + return true; + } + + protected function getMailTo(PhabricatorLiskDAO $object) { + return array(); + } + + protected function getMailCC(PhabricatorLiskDAO $object) { + return array(); + } + } diff --git a/src/applications/people/xaction/PhabricatorUserDisableTransaction.php b/src/applications/people/xaction/PhabricatorUserDisableTransaction.php --- a/src/applications/people/xaction/PhabricatorUserDisableTransaction.php +++ b/src/applications/people/xaction/PhabricatorUserDisableTransaction.php @@ -35,19 +35,10 @@ } } - public function getTitleForFeed() { - $new = $this->getNewValue(); - if ($new) { - return pht( - '%s disabled %s.', - $this->renderAuthor(), - $this->renderObject()); - } else { - return pht( - '%s enabled %s.', - $this->renderAuthor(), - $this->renderObject()); - } + public function shouldHideForFeed() { + // Don't publish feed stories about disabling users, since this can be + // a sensitive action. + return true; } public function validateTransactions($object, array $xactions) { diff --git a/src/applications/people/xaction/PhabricatorUserNotifyTransaction.php b/src/applications/people/xaction/PhabricatorUserNotifyTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/people/xaction/PhabricatorUserNotifyTransaction.php @@ -0,0 +1,34 @@ +renderAuthor()); + } + + public function getTitleForFeed() { + return $this->getNewValue(); + } + + public function shouldHideForFeed() { + return false; + } + + public function shouldHideForMail() { + return true; + } + +} diff --git a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php --- a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php +++ b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php @@ -3378,9 +3378,28 @@ PhabricatorLiskDAO $object, array $xactions) { - return array_unique(array_merge( - $this->getMailTo($object), - $this->getMailCC($object))); + // If some transactions are forcing notification delivery, add the forced + // recipients to the notify list. + $force_list = array(); + foreach ($xactions as $xaction) { + $force_phids = $xaction->getForceNotifyPHIDs(); + + if (!$force_phids) { + continue; + } + + foreach ($force_phids as $force_phid) { + $force_list[] = $force_phid; + } + } + + $to_list = $this->getMailTo($object); + $cc_list = $this->getMailCC($object); + + $full_list = array_merge($force_list, $to_list, $cc_list); + $full_list = array_fuse($full_list); + + return array_keys($full_list); } diff --git a/src/applications/transactions/storage/PhabricatorApplicationTransaction.php b/src/applications/transactions/storage/PhabricatorApplicationTransaction.php --- a/src/applications/transactions/storage/PhabricatorApplicationTransaction.php +++ b/src/applications/transactions/storage/PhabricatorApplicationTransaction.php @@ -1662,6 +1662,15 @@ return null; } + public function setForceNotifyPHIDs(array $phids) { + $this->setMetadataValue('notify.force', $phids); + return $this; + } + + public function getForceNotifyPHIDs() { + return $this->getMetadataValue('notify.force', array()); + } + /* -( PhabricatorDestructibleInterface )----------------------------------- */