protected final function updateCommitData($author, $message)
 {
     $commit = $this->commit;
     $data = id(new PhabricatorRepositoryCommitData())->loadOneWhere('commitID = %d', $commit->getID());
     if (!$data) {
         $data = new PhabricatorRepositoryCommitData();
     }
     $data->setCommitID($commit->getID());
     $data->setAuthorName($author);
     $data->setCommitMessage($message);
     $repository = $this->repository;
     $detail_parser = $repository->getDetail('detail-parser', 'PhabricatorRepositoryDefaultCommitMessageDetailParser');
     if ($detail_parser) {
         PhutilSymbolLoader::loadClass($detail_parser);
         $parser_obj = newv($detail_parser, array($commit, $data));
         $parser_obj->parseCommitDetails();
     }
     $data->save();
     $revision_id = $data->getCommitDetail('differential.revisionID');
     if ($revision_id) {
         $revision = id(new DifferentialRevision())->load($revision_id);
         if ($revision) {
             queryfx($revision->establishConnection('w'), 'INSERT IGNORE INTO %T (revisionID, commitPHID) VALUES (%d, %s)', DifferentialRevision::TABLE_COMMIT, $revision->getID(), $commit->getPHID());
             if ($revision->getStatus() != DifferentialRevisionStatus::COMMITTED) {
                 $editor = new DifferentialCommentEditor($revision, $revision->getAuthorPHID(), DifferentialAction::ACTION_COMMIT);
                 $editor->save();
             }
         }
     }
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $revision = id(new DifferentialRevision())->load($request->getValue('revision_id'));
     if (!$revision) {
         throw new ConduitException('ERR_BAD_REVISION');
     }
     $content_source = PhabricatorContentSource::newForSource(PhabricatorContentSource::SOURCE_CONDUIT, array());
     $editor = new DifferentialCommentEditor($revision, $request->getUser()->getPHID(), DifferentialAction::ACTION_COMMENT);
     $editor->setContentSource($content_source);
     $editor->setMessage($request->getValue('message'));
     $editor->save();
     return array('revisionid' => $revision->getID(), 'uri' => PhabricatorEnv::getURI('/D' . $revision->getID()));
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $id = $request->getValue('revision_id');
     $revision = id(new DifferentialRevision())->load($id);
     if (!$revision) {
         throw new ConduitException('ERR_NOT_FOUND');
     }
     if ($revision->getStatus() == ArcanistDifferentialRevisionStatus::CLOSED) {
         return;
     }
     $revision->loadRelationships();
     $editor = new DifferentialCommentEditor($revision, $request->getUser()->getPHID(), DifferentialAction::ACTION_CLOSE);
     $editor->save();
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $id = $request->getValue('revisionID');
     $revision = id(new DifferentialRevision())->load($id);
     if (!$revision) {
         throw new ConduitException('ERR_NOT_FOUND');
     }
     if ($revision->getStatus() == ArcanistDifferentialRevisionStatus::CLOSED) {
         // This can occur if someone runs 'close-revision' and hits a race, or
         // they have a remote hook installed but don't have the
         // 'remote_hook_installed' flag set, or similar. In any case, just treat
         // it as a no-op rather than adding another "X closed this revision"
         // message to the revision comments.
         return;
     }
     $revision->loadRelationships();
     $editor = new DifferentialCommentEditor($revision, $request->getUser()->getPHID(), DifferentialAction::ACTION_CLOSE);
     $editor->save();
     $revision->setStatus(ArcanistDifferentialRevisionStatus::CLOSED);
     $revision->setDateCommitted(time());
     $revision->save();
     return;
 }
 public function handleAction($body)
 {
     // all commands start with a bang and separated from the body by a newline
     // to make sure that actual feedback text couldn't trigger an action.
     // unrecognized commands will be parsed as part of the comment.
     $command = DifferentialAction::ACTION_COMMENT;
     $supported_commands = $this->getSupportedCommands();
     $regex = "/\\A\n*!(" . implode('|', $supported_commands) . ")\n*/";
     $matches = array();
     if (preg_match($regex, $body, $matches)) {
         $command = $matches[1];
         $body = trim(str_replace('!' . $command, '', $body));
     }
     $actor = $this->getActor();
     if (!$actor) {
         throw new Exception('No actor is set for the reply action.');
     }
     switch ($command) {
         case 'unsubscribe':
             $this->unsubscribeUser($this->getMailReceiver(), $actor);
             // TODO: Send the user a confirmation email?
             return null;
     }
     try {
         $editor = new DifferentialCommentEditor($this->getMailReceiver(), $actor->getPHID(), $command);
         // NOTE: We have to be careful about this because Facebook's
         // implementation jumps straight into handleAction() and will not have
         // a PhabricatorMetaMTAReceivedMail object.
         if ($this->receivedMail) {
             $editor->setParentMessageID($this->receivedMail->getMessageID());
         }
         $editor->setMessage($body);
         $editor->setAddCC($command != DifferentialAction::ACTION_RESIGN);
         $comment = $editor->save();
         return $comment->getID();
     } catch (Exception $ex) {
         $exception_mail = new DifferentialExceptionMail($this->getMailReceiver(), $ex, $body);
         $exception_mail->setToPHIDs(array($this->getActor()->getPHID()));
         $exception_mail->send();
         throw $ex;
     }
 }