Index: src/__phutil_library_map__.php =================================================================== --- src/__phutil_library_map__.php +++ src/__phutil_library_map__.php @@ -1697,6 +1697,7 @@ 'PhabricatorNamedQuery' => 'applications/search/storage/PhabricatorNamedQuery.php', 'PhabricatorNamedQueryQuery' => 'applications/search/query/PhabricatorNamedQueryQuery.php', 'PhabricatorNoteExample' => 'applications/uiexample/examples/PhabricatorNoteExample.php', + 'PhabricatorNotificationAdHocFeedStory' => 'applications/notification/feed/PhabricatorNotificationAdHocFeedStory.php', 'PhabricatorNotificationBuilder' => 'applications/notification/builder/PhabricatorNotificationBuilder.php', 'PhabricatorNotificationClearController' => 'applications/notification/controller/PhabricatorNotificationClearController.php', 'PhabricatorNotificationClient' => 'applications/notification/client/PhabricatorNotificationClient.php', @@ -1707,6 +1708,7 @@ 'PhabricatorNotificationPanelController' => 'applications/notification/controller/PhabricatorNotificationPanelController.php', 'PhabricatorNotificationQuery' => 'applications/notification/PhabricatorNotificationQuery.php', 'PhabricatorNotificationStatusController' => 'applications/notification/controller/PhabricatorNotificationStatusController.php', + 'PhabricatorNotificationTestController' => 'applications/notification/controller/PhabricatorNotificationTestController.php', 'PhabricatorOAuthClientAuthorization' => 'applications/oauthserver/storage/PhabricatorOAuthClientAuthorization.php', 'PhabricatorOAuthClientAuthorizationBaseController' => 'applications/oauthserver/controller/clientauthorization/PhabricatorOAuthClientAuthorizationBaseController.php', 'PhabricatorOAuthClientAuthorizationDeleteController' => 'applications/oauthserver/controller/clientauthorization/PhabricatorOAuthClientAuthorizationDeleteController.php', @@ -4430,6 +4432,7 @@ ), 'PhabricatorNamedQueryQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorNoteExample' => 'PhabricatorUIExample', + 'PhabricatorNotificationAdHocFeedStory' => 'PhabricatorFeedStory', 'PhabricatorNotificationClearController' => 'PhabricatorNotificationController', 'PhabricatorNotificationConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorNotificationController' => 'PhabricatorController', @@ -4438,6 +4441,7 @@ 'PhabricatorNotificationPanelController' => 'PhabricatorNotificationController', 'PhabricatorNotificationQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorNotificationStatusController' => 'PhabricatorNotificationController', + 'PhabricatorNotificationTestController' => 'PhabricatorNotificationController', 'PhabricatorOAuthClientAuthorization' => 'PhabricatorOAuthServerDAO', 'PhabricatorOAuthClientAuthorizationBaseController' => 'PhabricatorOAuthServerController', 'PhabricatorOAuthClientAuthorizationDeleteController' => 'PhabricatorOAuthClientAuthorizationBaseController', Index: src/applications/feed/PhabricatorFeedStoryPublisher.php =================================================================== --- src/applications/feed/PhabricatorFeedStoryPublisher.php +++ src/applications/feed/PhabricatorFeedStoryPublisher.php @@ -10,6 +10,17 @@ private $primaryObjectPHID; private $subscribedPHIDs = array(); private $mailRecipientPHIDs = array(); + private $notifyAuthor; + + + public function setNotifyAuthor($notify_author) { + $this->notifyAuthor = $notify_author; + return $this; + } + + public function getNotifyAuthor() { + return $this->notifyAuthor; + } public function setRelatedPHIDs(array $phids) { $this->relatedPHIDs = $phids; @@ -116,9 +127,12 @@ private function insertNotifications($chrono_key) { $subscribed_phids = $this->subscribedPHIDs; - $subscribed_phids = array_diff( - $subscribed_phids, - array($this->storyAuthorPHID)); + + if (!$this->notifyAuthor) { + $subscribed_phids = array_diff( + $subscribed_phids, + array($this->storyAuthorPHID)); + } if (!$subscribed_phids) { return; Index: src/applications/notification/application/PhabricatorApplicationNotifications.php =================================================================== --- src/applications/notification/application/PhabricatorApplicationNotifications.php +++ src/applications/notification/application/PhabricatorApplicationNotifications.php @@ -19,6 +19,7 @@ 'individual/' => 'PhabricatorNotificationIndividualController', 'status/' => 'PhabricatorNotificationStatusController', 'clear/' => 'PhabricatorNotificationClearController', + 'test/' => 'PhabricatorNotificationTestController', ), ); } Index: src/applications/notification/controller/PhabricatorNotificationIndividualController.php =================================================================== --- src/applications/notification/controller/PhabricatorNotificationIndividualController.php +++ src/applications/notification/controller/PhabricatorNotificationIndividualController.php @@ -26,7 +26,7 @@ $response = array( 'pertinent' => true, 'primaryObjectPHID' => head($stories)->getPrimaryObjectPHID(), - 'content' => $content, + 'content' => hsprintf('%s', $content), ); return id(new AphrontAjaxResponse())->setContent($response); Index: src/applications/notification/controller/PhabricatorNotificationStatusController.php =================================================================== --- src/applications/notification/controller/PhabricatorNotificationStatusController.php +++ src/applications/notification/controller/PhabricatorNotificationStatusController.php @@ -59,8 +59,23 @@ 'wide', )); + $test_icon = id(new PHUIIconView()) + ->setSpriteSheet(PHUIIconView::SPRITE_ICONS) + ->setSpriteIcon('warning'); + + $test_button = id(new PHUIButtonView()) + ->setTag('a') + ->setWorkflow(true) + ->setText(pht('Send Test Notification')) + ->setHref($this->getApplicationURI("test/")) + ->setIcon($test_icon); + + $header = id(new PHUIHeaderView()) + ->setHeader(pht('Notification Server Status')) + ->addActionLink($test_button); + $box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Server Status')) + ->setHeader($header) ->appendChild($table); return $box; Index: src/applications/notification/controller/PhabricatorNotificationTestController.php =================================================================== --- /dev/null +++ src/applications/notification/controller/PhabricatorNotificationTestController.php @@ -0,0 +1,38 @@ +<?php + +final class PhabricatorNotificationTestController + extends PhabricatorNotificationController { + + public function processRequest() { + $request = $this->getRequest(); + $viewer = $request->getUser(); + + $story_type = 'PhabricatorNotificationAdHocFeedStory'; + $story_data = array( + 'title' => pht( + 'This is a test notification, sent at %s.', + phabricator_datetime(time(), $viewer)), + ); + + $viewer_phid = $viewer->getPHID(); + + // TODO: When it's easier to get these buttons to render as forms, this + // would be slightly nicer as a more standard isFormPost() check. + + if ($request->validateCSRF()) { + id(new PhabricatorFeedStoryPublisher()) + ->setStoryType($story_type) + ->setStoryData($story_data) + ->setStoryTime(time()) + ->setStoryAuthorPHID($viewer_phid) + ->setRelatedPHIDs(array($viewer_phid)) + ->setPrimaryObjectPHID($viewer_phid) + ->setSubscribedPHIDs(array($viewer_phid)) + ->setNotifyAuthor(true) + ->publish(); + } + + return id(new AphrontAjaxResponse()); + } + +} Index: src/applications/notification/feed/PhabricatorNotificationAdHocFeedStory.php =================================================================== --- /dev/null +++ src/applications/notification/feed/PhabricatorNotificationAdHocFeedStory.php @@ -0,0 +1,27 @@ +<?php + +final class PhabricatorNotificationAdHocFeedStory extends PhabricatorFeedStory { + + public function getPrimaryObjectPHID() { + return $this->getAuthorPHID(); + } + + public function renderView() { + $data = $this->getStoryData(); + + $author_phid = $data->getAuthorPHID(); + + $view = $this->newStoryView(); + + $view->setTitle($data->getValue('title')); + $view->setImage($this->getHandle($author_phid)->getImageURI()); + + return $view; + } + + public function renderText() { + $data = $this->getStoryData(); + return $data->getValue('title'); + } + +}