public function publish()
 {
     if (!$this->storyType) {
         throw new Exception("Call setStoryType() before publishing!");
     }
     $chrono_key = $this->generateChronologicalKey();
     $story = new PhabricatorFeedStoryData();
     $story->setStoryType($this->storyType);
     $story->setStoryData($this->storyData);
     $story->setAuthorPHID((string) $this->storyAuthorPHID);
     $story->setChronologicalKey($chrono_key);
     $story->save();
     if ($this->relatedPHIDs) {
         $ref = new PhabricatorFeedStoryReference();
         $sql = array();
         $conn = $ref->establishConnection('w');
         foreach (array_unique($this->relatedPHIDs) as $phid) {
             $sql[] = qsprintf($conn, '(%s, %s)', $phid, $chrono_key);
         }
         queryfx($conn, 'INSERT INTO %T (objectPHID, chronologicalKey) VALUES %Q', $ref->getTableName(), implode(', ', $sql));
     }
     if (PhabricatorEnv::getEnvConfig('notification.enabled')) {
         $this->insertNotifications($chrono_key);
         $this->sendNotification($chrono_key);
     }
     return $story;
 }
 public function publish()
 {
     $class = $this->storyType;
     if (!$class) {
         throw new Exception(pht('Call %s before publishing!', 'setStoryType()'));
     }
     if (!class_exists($class)) {
         throw new Exception(pht("Story type must be a valid class name and must subclass %s. " . "'%s' is not a loadable class.", 'PhabricatorFeedStory', $class));
     }
     if (!is_subclass_of($class, 'PhabricatorFeedStory')) {
         throw new Exception(pht("Story type must be a valid class name and must subclass %s. " . "'%s' is not a subclass of %s.", 'PhabricatorFeedStory', $class, 'PhabricatorFeedStory'));
     }
     $chrono_key = $this->generateChronologicalKey();
     $story = new PhabricatorFeedStoryData();
     $story->setStoryType($this->storyType);
     $story->setStoryData($this->storyData);
     $story->setAuthorPHID((string) $this->storyAuthorPHID);
     $story->setChronologicalKey($chrono_key);
     $story->save();
     if ($this->relatedPHIDs) {
         $ref = new PhabricatorFeedStoryReference();
         $sql = array();
         $conn = $ref->establishConnection('w');
         foreach (array_unique($this->relatedPHIDs) as $phid) {
             $sql[] = qsprintf($conn, '(%s, %s)', $phid, $chrono_key);
         }
         queryfx($conn, 'INSERT INTO %T (objectPHID, chronologicalKey) VALUES %Q', $ref->getTableName(), implode(', ', $sql));
     }
     $subscribed_phids = $this->subscribedPHIDs;
     if ($subscribed_phids) {
         $subscribed_phids = $this->filterSubscribedPHIDs($subscribed_phids);
         $this->insertNotifications($chrono_key, $subscribed_phids);
         $this->sendNotification($chrono_key, $subscribed_phids);
     }
     PhabricatorWorker::scheduleTask('FeedPublisherWorker', array('key' => $chrono_key));
     return $story;
 }