protected function getVerb() { $comment = $this->getComment(); $action = $comment->getAction(); $verb = DifferentialAction::getActionPastTenseVerb($action); return $verb; }
public function runBackgroundTasks() { $iterator = new PhabricatorTimelineIterator('ircdiffx', array('difx')); if (!$this->skippedOldEvents) { // Since we only want to post notifications about new events, skip // everything that's happened in the past when we start up so we'll // only process real-time events. foreach ($iterator as $event) { // Ignore all old events. } $this->skippedOldEvents = true; return; } foreach ($iterator as $event) { $data = $event->getData(); if (!$data) { continue; } $actor_phid = $data['actor_phid']; $phids = array($actor_phid); $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles(); $verb = DifferentialAction::getActionPastTenseVerb($data['action']); $actor_name = $handles[$actor_phid]->getName(); $message = "{$actor_name} {$verb} revision D" . $data['revision_id'] . "."; foreach ($this->getConfig('notification.channels') as $channel) { $this->write('PRIVMSG', "{$channel} :{$message}"); } } }
public function render() { $viewer = $this->getViewer(); $this->requireResource('differential-revision-add-comment-css'); $revision = $this->revision; $action = null; if ($this->draft) { $action = idx($this->draft->getMetadata(), 'action'); } $enable_reviewers = DifferentialAction::allowReviewers($action); $enable_ccs = $action == DifferentialAction::ACTION_ADDCCS; $add_reviewers_labels = array('add_reviewers' => pht('Add Reviewers'), 'request_review' => pht('Add Reviewers'), 'resign' => pht('Suggest Reviewers')); $mailable_source = new PhabricatorMetaMTAMailableDatasource(); // TODO: This should be a reviewers datasource, but it's a mess. $reviewer_source = new PhabricatorMetaMTAMailableDatasource(); $form = new AphrontFormView(); $form->setWorkflow(true)->setViewer($viewer)->setAction($this->actionURI)->addHiddenInput('revision_id', $revision->getID())->appendChild(id(new AphrontFormSelectControl())->setLabel(pht('Action'))->setName('action')->setValue($action)->setID('comment-action')->setOptions($this->actions))->appendControl(id(new AphrontFormTokenizerControl())->setLabel($enable_reviewers ? $add_reviewers_labels[$action] : $add_reviewers_labels['add_reviewers'])->setName('reviewers')->setControlID('add-reviewers')->setControlStyle($enable_reviewers ? null : 'display: none')->setID('add-reviewers-tokenizer')->setDisableBehavior(true)->setDatasource($reviewer_source))->appendControl(id(new AphrontFormTokenizerControl())->setLabel(pht('Add Subscribers'))->setName('ccs')->setControlID('add-ccs')->setControlStyle($enable_ccs ? null : 'display: none')->setID('add-ccs-tokenizer')->setDisableBehavior(true)->setDatasource($mailable_source))->appendChild(id(new PhabricatorRemarkupControl())->setName('comment')->setID('comment-content')->setLabel(pht('Comment'))->setValue($this->draft ? $this->draft->getDraft() : null)->setViewer($viewer))->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Submit'))); Javelin::initBehavior('differential-add-reviewers-and-ccs', array('dynamic' => array('add-reviewers-tokenizer' => array('actions' => array('request_review' => 1, 'add_reviewers' => 1, 'resign' => 1), 'src' => $reviewer_source->getDatasourceURI(), 'value' => $this->reviewers, 'row' => 'add-reviewers', 'labels' => $add_reviewers_labels, 'placeholder' => $reviewer_source->getPlaceholderText()), 'add-ccs-tokenizer' => array('actions' => array('add_ccs' => 1), 'src' => $mailable_source->getDatasourceURI(), 'value' => $this->ccs, 'row' => 'add-ccs', 'placeholder' => $mailable_source->getPlaceholderText())), 'select' => 'comment-action')); $diff = $revision->loadActiveDiff(); $rev_id = $revision->getID(); Javelin::initBehavior('differential-feedback-preview', array('uri' => '/differential/comment/preview/' . $rev_id . '/', 'preview' => 'comment-preview', 'action' => 'comment-action', 'content' => 'comment-content', 'previewTokenizers' => array('reviewers' => 'add-reviewers-tokenizer', 'ccs' => 'add-ccs-tokenizer'), 'inlineuri' => '/differential/comment/inline/preview/' . $rev_id . '/', 'inline' => 'inline-comment-preview')); $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business'); $header_text = $is_serious ? pht('Add Comment') : pht('Leap Into Action!'); $header = id(new PHUIHeaderView())->setHeader($header_text); $anchor = id(new PhabricatorAnchorView())->setAnchorName('comment')->setNavigationMarker(true); $loading = phutil_tag('span', array('class' => 'aphront-panel-preview-loading-text'), pht('Loading comment preview...')); $preview = phutil_tag_div('aphront-panel-preview aphront-panel-flush', array(phutil_tag('div', array('id' => 'comment-preview'), $loading), phutil_tag('div', array('id' => 'inline-comment-preview')))); $comment_box = id(new PHUIObjectBoxView())->setHeader($header)->appendChild($anchor)->appendChild($form); if ($this->errorView) { $comment_box->setInfoView($this->errorView); } return array($comment_box, $preview); }
public function renderView() { $data = $this->getStoryData(); $author_phid = $data->getAuthorPHID(); $view = new PhabricatorFeedStoryView(); $revision_phid = $data->getValue('revision_phid'); $action = $data->getValue('action'); $verb = DifferentialAction::getActionPastTenseVerb($action); $view->setTitle($this->linkTo($author_phid) . " {$verb} revision " . $this->linkTo($revision_phid) . '.'); $view->setEpoch($data->getEpoch()); $action = $data->getValue('action'); switch ($action) { case DifferentialAction::ACTION_CREATE: case DifferentialAction::ACTION_COMMIT: $full_size = true; break; default: $full_size = false; break; } if ($full_size) { $view->setImage($this->getHandle($author_phid)->getImageURI()); $content = $this->renderSummary($data->getValue('feedback_content')); $view->appendChild($content); } else { $view->setOneLineStory(true); } return $view; }
private function getLineForData($data) { $actor_phid = $data->getAuthorPHID(); $owner_phid = $data->getValue('revision_author_phid'); $revision_phid = $data->getValue('revision_phid'); $action = $data->getValue('action'); $actor_link = $this->linkTo($actor_phid); $revision_link = $this->linkTo($revision_phid); $owner_link = $this->linkTo($owner_phid); $verb = DifferentialAction::getActionPastTenseVerb($action); $one_line = "{$actor_link} {$verb} revision {$revision_link}"; return $one_line; }
public function render() { require_celerity_resource('differential-revision-add-comment-css'); $revision = $this->revision; $actions = array(); foreach ($this->actions as $action) { $actions[$action] = DifferentialAction::getActionVerb($action); } $form = new AphrontFormView(); $form->setUser($this->user)->setAction($this->actionURI)->addHiddenInput('revision_id', $revision->getID())->appendChild(id(new AphrontFormSelectControl())->setLabel('Action')->setName('action')->setID('comment-action')->setOptions($actions))->appendChild(id(new AphrontFormTokenizerControl())->setLabel('Add Reviewers')->setName('reviewers')->setControlID('add-reviewers')->setControlStyle('display: none')->setID('add-reviewers-tokenizer')->setDisableBehavior(true))->appendChild(id(new AphrontFormTokenizerControl())->setLabel('Add CCs')->setName('ccs')->setControlID('add-ccs')->setControlStyle('display: none')->setID('add-ccs-tokenizer')->setDisableBehavior(true))->appendChild(id(new AphrontFormTextAreaControl())->setName('comment')->setID('comment-content')->setLabel('Comment')->setEnableDragAndDropFileUploads(true)->setValue($this->draft))->appendChild(id(new AphrontFormSubmitControl())->setValue('Clowncopterize')); Javelin::initBehavior('differential-add-reviewers-and-ccs', array('dynamic' => array('add_reviewers' => array('tokenizer' => 'add-reviewers-tokenizer', 'src' => '/typeahead/common/users/', 'row' => 'add-reviewers'), 'add_ccs' => array('tokenizer' => 'add-ccs-tokenizer', 'src' => '/typeahead/common/mailable/', 'row' => 'add-ccs')), 'select' => 'comment-action')); $diff = $revision->loadActiveDiff(); $lint_warning = null; $unit_warning = null; if ($diff->getLintStatus() >= DifferentialLintStatus::LINT_WARN) { $titles = array(DifferentialLintStatus::LINT_WARN => 'Lint Warning', DifferentialLintStatus::LINT_FAIL => 'Lint Failure', DifferentialLintStatus::LINT_SKIP => 'Lint Skipped'); $content = "<p>This diff has Lint Problems. Make sure you are OK with them " . "before you accept this diff.</p>"; $lint_warning = $this->generateWarningView($diff->getLintStatus(), $titles, 'lint-warning', $content); } if ($diff->getUnitStatus() >= DifferentialUnitStatus::UNIT_WARN) { $titles = array(DifferentialUnitStatus::UNIT_WARN => 'Unit Tests Warning', DifferentialUnitStatus::UNIT_FAIL => 'Unit Tests Failure', DifferentialUnitStatus::UNIT_SKIP => 'Unit Tests Skipped', DifferentialUnitStatus::UNIT_POSTPONED => 'Unit Tests Postponed'); $content = "<p>This diff has Unit Test Problems. Make sure you are OK with them " . "before you accept this diff.</p>"; $unit_warning = $this->generateWarningView($diff->getUnitStatus(), $titles, 'unit-warning', $content); } Javelin::initBehavior('differential-accept-with-errors', array('select' => 'comment-action', 'lint_warning' => $lint_warning ? 'lint-warning' : null, 'unit_warning' => $unit_warning ? 'unit-warning' : null)); $rev_id = $revision->getID(); Javelin::initBehavior('differential-feedback-preview', array('uri' => '/differential/comment/preview/' . $rev_id . '/', 'preview' => 'comment-preview', 'action' => 'comment-action', 'content' => 'comment-content', 'inlineuri' => '/differential/comment/inline/preview/' . $rev_id . '/', 'inline' => 'inline-comment-preview')); $panel_view = new AphrontPanelView(); $panel_view->appendChild($form); if ($lint_warning) { $panel_view->appendChild($lint_warning); } if ($unit_warning) { $panel_view->appendChild($unit_warning); } $panel_view->setHeader('Leap Into Action'); $panel_view->addClass('aphront-panel-accent'); $panel_view->addClass('aphront-panel-flush'); return '<div class="differential-add-comment-panel">' . $panel_view->render() . '<div class="aphront-panel-preview aphront-panel-flush">' . '<div id="comment-preview">' . '<span class="aphront-panel-preview-loading-text">' . 'Loading comment preview...' . '</span>' . '</div>' . '<div id="inline-comment-preview">' . '</div>' . '</div>' . '</div>'; }
public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); if ($request->isFormPost()) { $phid_arr = $request->getArr('view_user'); $view_target = head($phid_arr); return id(new AphrontRedirectResponse())->setURI($request->getRequestURI()->alter('phid', $view_target)); } $params = array_filter(array('phid' => $request->getStr('phid'))); // Fill in the defaults we'll actually use for calculations if any // parameters are missing. $params += array('phid' => $user->getPHID()); $side_nav = new AphrontSideNavFilterView(); $side_nav->setBaseURI(id(new PhutilURI('/differential/stats/'))->alter('phid', $params['phid'])); foreach (array(DifferentialAction::ACTION_CLOSE, DifferentialAction::ACTION_ACCEPT, DifferentialAction::ACTION_REJECT, DifferentialAction::ACTION_UPDATE, DifferentialAction::ACTION_COMMENT) as $action) { $verb = ucfirst(DifferentialAction::getActionPastTenseVerb($action)); $side_nav->addFilter($action, $verb); } $this->filter = $side_nav->selectFilter($this->filter, DifferentialAction::ACTION_CLOSE); $panels = array(); $handles = $this->loadViewerHandles(array($params['phid'])); $filter_form = id(new AphrontFormView())->setAction('/differential/stats/' . $this->filter . '/')->setUser($user); $filter_form->appendChild($this->renderControl($params['phid'], $handles)); $filter_form->appendChild(id(new AphrontFormSubmitControl())->setValue('Filter Revisions')); $side_nav->appendChild($filter_form); $comments = $this->loadComments($params['phid']); $revisions = $this->loadRevisions($params['phid']); $diffs = $this->loadDiffs($revisions); $panel = new AphrontPanelView(); $panel->setHeader('Differential rate analysis'); $panel->appendChild(id(new DifferentialRevisionStatsView())->setComments($comments)->setFilter($this->filter)->setRevisions($revisions)->setDiffs($diffs)->setUser($user)); $panels[] = $panel; foreach ($panels as $panel) { $side_nav->appendChild($panel); } return $this->buildStandardPageResponse($side_nav, array('title' => 'Differential statistics')); }
public function renderView() { $data = $this->getStoryData(); $handles = $this->getHandles(); $author_phid = $data->getAuthorPHID(); $objects = $this->getObjects(); $view = new PhabricatorFeedStoryView(); $revision_phid = $data->getValue('revision_phid'); $action = $data->getValue('action'); $verb = DifferentialAction::getActionPastTenseVerb($action); $view->setTitle('<strong>' . $handles[$author_phid]->renderLink() . '</strong>' . ' ' . $verb . ' revision ' . '<strong>' . $handles[$revision_phid]->renderLink() . '</strong>.'); $view->setEpoch($data->getEpoch()); $action = $data->getValue('action'); switch ($action) { case DifferentialAction::ACTION_CREATE: case DifferentialAction::ACTION_COMMIT: $full_size = true; break; default: $full_size = false; break; } if ($full_size) { if (!empty($objects[$author_phid])) { $image_phid = $objects[$author_phid]->getProfileImagePHID(); $image_uri = PhabricatorFileURI::getViewURIForPHID($image_phid); $view->setImage($image_uri); } $content = phutil_escape_html($data->getValue('feedback_content')); $content = str_replace("\n", '<br />', $content); $view->appendChild($content); } else { $view->setOneLineStory(true); } return $view; }
public function processRequest() { $request = $this->getRequest(); $author_phid = $request->getUser()->getPHID(); $action = $request->getStr('action'); $engine = PhabricatorMarkupEngine::newDifferentialMarkupEngine(); $comment = new DifferentialComment(); $comment->setContent($request->getStr('content')); $comment->setAction($action); $comment->setAuthorPHID($author_phid); $handles = array($author_phid); $reviewers = $request->getStrList('reviewers'); if (DifferentialAction::allowReviewers($action) && $reviewers) { $comment->setMetadata(array(DifferentialComment::METADATA_ADDED_REVIEWERS => $reviewers)); $handles = array_merge($handles, $reviewers); } $ccs = $request->getStrList('ccs'); if ($action == DifferentialAction::ACTION_ADDCCS && $ccs) { $comment->setMetadata(array(DifferentialComment::METADATA_ADDED_CCS => $ccs)); $handles = array_merge($handles, $ccs); } $handles = $this->loadViewerHandles($handles); $view = new DifferentialRevisionCommentView(); $view->setUser($request->getUser()); $view->setComment($comment); $view->setHandles($handles); $view->setMarkupEngine($engine); $view->setPreview(true); $view->setTargetDiff(null); $metadata = array('reviewers' => $reviewers, 'ccs' => $ccs); if ($action != DifferentialAction::ACTION_COMMENT) { $metadata['action'] = $action; } id(new PhabricatorDraft())->setAuthorPHID($author_phid)->setDraftKey('differential-comment-' . $this->id)->setDraft($comment->getContent())->setMetadata($metadata)->replaceOrDelete(); return id(new AphrontAjaxResponse())->setContent($view->render()); }
public function getTitle() { $author_phid = $this->getAuthorPHID(); $author_handle = $this->renderHandleLink($author_phid); $old = $this->getOldValue(); $new = $this->getNewValue(); switch ($this->getTransactionType()) { case self::TYPE_INLINE: return pht('%s added inline comments.', $author_handle); case self::TYPE_UPDATE: if ($this->getMetadataValue('isCommitUpdate')) { return pht('This revision was automatically updated to reflect the ' . 'committed changes.'); } else { if ($new) { // TODO: Migrate to PHIDs and use handles here? if (phid_get_type($new) == DifferentialDiffPHIDType::TYPECONST) { return pht('%s updated this revision to %s.', $author_handle, $this->renderHandleLink($new)); } else { return pht('%s updated this revision.', $author_handle); } } else { return pht('%s updated this revision.', $author_handle); } } case self::TYPE_ACTION: switch ($new) { case DifferentialAction::ACTION_CLOSE: if (!$this->getMetadataValue('isCommitClose')) { return DifferentialAction::getBasicStoryText($new, $author_handle); } $commit_name = $this->renderHandleLink($this->getMetadataValue('commitPHID')); $committer_phid = $this->getMetadataValue('committerPHID'); $author_phid = $this->getMetadataValue('authorPHID'); if ($this->getHandleIfExists($committer_phid)) { $committer_name = $this->renderHandleLink($committer_phid); } else { $committer_name = $this->getMetadataValue('committerName'); } if ($this->getHandleIfExists($author_phid)) { $author_name = $this->renderHandleLink($author_phid); } else { $author_name = $this->getMetadataValue('authorName'); } if ($committer_name && $committer_name != $author_name) { return pht('Closed by commit %s (authored by %s, committed by %s).', $commit_name, $author_name, $committer_name); } else { return pht('Closed by commit %s (authored by %s).', $commit_name, $author_name); } break; default: return DifferentialAction::getBasicStoryText($new, $author_handle); } break; case self::TYPE_STATUS: switch ($this->getNewValue()) { case ArcanistDifferentialRevisionStatus::ACCEPTED: return pht('This revision is now accepted and ready to land.'); case ArcanistDifferentialRevisionStatus::NEEDS_REVISION: return pht('This revision now requires changes to proceed.'); case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW: return pht('This revision now requires review to proceed.'); } } return parent::getTitle(); }
public function render() { if (!$this->user) { throw new Exception("Call setUser() before rendering!"); } require_celerity_resource('phabricator-remarkup-css'); require_celerity_resource('differential-revision-comment-css'); $comment = $this->comment; $action = $comment->getAction(); $action_class = 'differential-comment-action-' . phutil_escape_html($action); if ($this->preview) { $date = 'COMMENT PREVIEW'; } else { $date = phabricator_datetime($comment->getDateCreated(), $this->user); } $info = array($date); $comment_anchor = null; $num = $this->commentNumber; if ($num && !$this->preview) { Javelin::initBehavior('phabricator-watch-anchor'); $info[] = phutil_render_tag('a', array('name' => 'comment-' . $num, 'href' => '#comment-' . $num), 'Comment D' . $comment->getRevisionID() . '#' . $num); $comment_anchor = 'anchor-comment-' . $num; } $info = implode(' · ', $info); $author = $this->handles[$comment->getAuthorPHID()]; $author_link = $author->renderLink(); $verb = DifferentialAction::getActionPastTenseVerb($comment->getAction()); $verb = phutil_escape_html($verb); $content = $comment->getContent(); $head_content = null; if (strlen(rtrim($content))) { $title = "{$author_link} {$verb} this revision:"; $cache = $comment->getCache(); if (strlen($cache)) { $content = $cache; } else { $content = $this->markupEngine->markupText($content); if ($comment->getID()) { $comment->setCache($content); $comment->save(); } } $content = '<div class="phabricator-remarkup">' . $content . '</div>'; } else { $title = null; $head_content = '<div class="differential-comment-nocontent">' . "<p>{$author_link} {$verb} this revision.</p>" . '</div>'; $content = null; } if ($this->inlines) { $inline_render = array(); $inlines = $this->inlines; $changesets = $this->changesets; $inlines_by_changeset = mgroup($inlines, 'getChangesetID'); $inlines_by_changeset = array_select_keys($inlines_by_changeset, array_keys($this->changesets)); $inline_render[] = '<table class="differential-inline-summary">'; foreach ($inlines_by_changeset as $changeset_id => $inlines) { $changeset = $changesets[$changeset_id]; $inlines = msort($inlines, 'getLineNumber'); $inline_render[] = '<tr>' . '<th colspan="2">' . phutil_escape_html($changeset->getFileName()) . '</th>' . '</tr>'; foreach ($inlines as $inline) { if (!$inline->getLineLength()) { $lines = $inline->getLineNumber(); } else { $lines = $inline->getLineNumber() . "–" . ($inline->getLineNumber() + $inline->getLineLength()); } if (!$this->target || $changeset->getDiffID() === $this->target->getID()) { $lines = phutil_render_tag('a', array('href' => '#inline-' . $inline->getID(), 'class' => 'num'), $lines); } $inline_content = $inline->getContent(); if (strlen($inline_content)) { $inline_cache = $inline->getCache(); if ($inline_cache) { $inline_content = $inline_cache; } else { $inline_content = $this->markupEngine->markupText($inline_content); if ($inline->getID()) { $inline->setCache($inline_content); $inline->save(); } } } $inline_render[] = '<tr>' . '<td class="inline-line-number">' . $lines . '</td>' . '<td>' . '<div class="phabricator-remarkup">' . $inline_content . '</div>' . '</td>' . '</tr>'; } } $inline_render[] = '</table>'; $inline_render = implode("\n", $inline_render); $inline_render = '<div class="differential-inline-summary-section">' . 'Inline Comments' . '</div>' . $inline_render; } else { $inline_render = null; } $background = null; $uri = $author->getImageURI(); if ($uri) { $background = "background-image: url('{$uri}');"; } $metadata_blocks = array(); $metadata = $comment->getMetadata(); $added_reviewers = idx($metadata, DifferentialComment::METADATA_ADDED_REVIEWERS); if ($added_reviewers) { $reviewers = 'Added reviewers: ' . $this->renderHandleList($added_reviewers); $metadata_blocks[] = $reviewers; } $added_ccs = idx($metadata, DifferentialComment::METADATA_ADDED_CCS); if ($added_ccs) { $ccs = 'Added CCs: ' . $this->renderHandleList($added_ccs); $metadata_blocks[] = $ccs; } if ($metadata_blocks) { $metadata_blocks = '<div class="differential-comment-metadata">' . implode("\n", $metadata_blocks) . '</div>'; } else { $metadata_blocks = null; } return phutil_render_tag('div', array('class' => "differential-comment {$action_class}", 'id' => $comment_anchor), '<div class="differential-comment-head">' . '<span class="differential-comment-info">' . $info . '</span>' . '<span class="differential-comment-title">' . $title . '</span>' . '<div style="clear: both;"></div>' . '</div>' . '<div class="differential-comment-body" style="' . $background . '">' . '<div class="differential-comment-content">' . $head_content . $metadata_blocks . '<div class="differential-comment-core">' . $content . '</div>' . $inline_render . '</div>' . '</div>'); }
public function renderForAsanaBridge($implied_context = false) { $data = $this->getStoryData(); $comment = $data->getValue('feedback_content'); $author_name = $this->getHandle($this->getAuthorPHID())->getName(); $action = $this->getValue('action'); $engine = PhabricatorMarkupEngine::newMarkupEngine(array())->setConfig('viewer', new PhabricatorUser())->setMode(PhutilRemarkupEngine::MODE_TEXT); $revision_phid = $this->getPrimaryObjectPHID(); $revision_name = $this->getHandle($revision_phid)->getFullName(); if ($implied_context) { $title = DifferentialAction::getBasicStoryText($action, $author_name); } else { switch ($action) { case DifferentialAction::ACTION_COMMENT: $title = pht('%s commented on revision %s', $author_name, $revision_name); break; case DifferentialAction::ACTION_ACCEPT: $title = pht('%s accepted revision %s', $author_name, $revision_name); break; case DifferentialAction::ACTION_REJECT: $title = pht('%s requested changes to revision %s', $author_name, $revision_name); break; case DifferentialAction::ACTION_RETHINK: $title = pht('%s planned changes to revision %s', $author_name, $revision_name); break; case DifferentialAction::ACTION_ABANDON: $title = pht('%s abandoned revision %s', $author_name, $revision_name); break; case DifferentialAction::ACTION_CLOSE: $title = pht('%s closed revision %s', $author_name, $revision_name); break; case DifferentialAction::ACTION_REQUEST: $title = pht('%s requested a review of revision %s', $author_name, $revision_name); break; case DifferentialAction::ACTION_RECLAIM: $title = pht('%s reclaimed revision %s', $author_name, $revision_name); break; case DifferentialAction::ACTION_UPDATE: $title = pht('%s updated revision %s', $author_name, $revision_name); break; case DifferentialAction::ACTION_RESIGN: $title = pht('%s resigned from revision %s', $author_name, $revision_name); break; case DifferentialAction::ACTION_SUMMARIZE: $title = pht('%s summarized revision %s', $author_name, $revision_name); break; case DifferentialAction::ACTION_TESTPLAN: $title = pht('%s explained the test plan for revision %s', $author_name, $revision_name); break; case DifferentialAction::ACTION_CREATE: $title = pht('%s created revision %s', $author_name, $revision_name); break; case DifferentialAction::ACTION_ADDREVIEWERS: $title = pht('%s added reviewers to revision %s', $author_name, $revision_name); break; case DifferentialAction::ACTION_ADDCCS: $title = pht('%s added CCs to revision %s', $author_name, $revision_name); break; case DifferentialAction::ACTION_CLAIM: $title = pht('%s commandeered revision %s', $author_name, $revision_name); break; case DifferentialAction::ACTION_REOPEN: $title = pht('%s reopened revision %s', $author_name, $revision_name); break; case DifferentialTransaction::TYPE_INLINE: $title = pht('%s added inline comments to %s', $author_name, $revision_name); break; default: $title = pht('%s edited revision %s', $author_name, $revision_name); break; } } if (strlen($comment)) { $comment = $engine->markupText($comment); $title .= "\n\n"; $title .= $comment; } // Roughly render inlines into the comment. $xaction_phids = $data->getValue('temporaryTransactionPHIDs'); if ($xaction_phids) { $inlines = id(new DifferentialTransactionQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withPHIDs($xaction_phids)->needComments(true)->withTransactionTypes(array(DifferentialTransaction::TYPE_INLINE))->execute(); if ($inlines) { $title .= "\n\n"; $title .= pht('Inline Comments'); $title .= "\n"; $changeset_ids = array(); foreach ($inlines as $inline) { $changeset_ids[] = $inline->getComment()->getChangesetID(); } $changesets = id(new DifferentialChangeset())->loadAllWhere('id IN (%Ld)', $changeset_ids); foreach ($inlines as $inline) { $comment = $inline->getComment(); $changeset = idx($changesets, $comment->getChangesetID()); if (!$changeset) { continue; } $filename = $changeset->getDisplayFilename(); $linenumber = $comment->getLineNumber(); $inline_text = $engine->markupText($comment->getContent()); $inline_text = rtrim($inline_text); $title .= "{$filename}:{$linenumber} {$inline_text}\n"; } } } return $title; }
public function render() { if (!$this->user) { throw new Exception("Call setUser() before rendering!"); } require_celerity_resource('phabricator-remarkup-css'); require_celerity_resource('differential-revision-comment-css'); $comment = $this->comment; $action = $comment->getAction(); $action_class = 'differential-comment-action-' . $action; if ($this->preview) { $date = 'COMMENT PREVIEW'; } else { $date = phabricator_datetime($comment->getDateCreated(), $this->user); } $info = array(); $content_source = new PhabricatorContentSourceView(); $content_source->setContentSource($comment->getContentSource()); $content_source->setUser($this->user); $info[] = $content_source->render(); $info[] = $date; $comment_anchor = null; $num = $this->commentNumber; if ($num && !$this->preview) { Javelin::initBehavior('phabricator-watch-anchor'); $info[] = phutil_render_tag('a', array('name' => 'comment-' . $num, 'href' => '#comment-' . $num), 'Comment D' . $comment->getRevisionID() . '#' . $num); $comment_anchor = 'anchor-comment-' . $num; } $info = implode(' · ', array_filter($info)); $author = $this->handles[$comment->getAuthorPHID()]; $author_link = $author->renderLink(); $verb = DifferentialAction::getActionPastTenseVerb($comment->getAction()); $verb = phutil_escape_html($verb); $content = $comment->getContent(); $head_content = null; if (strlen(rtrim($content))) { $title = "{$author_link} {$verb} this revision:"; $cache = $comment->getCache(); if (strlen($cache)) { $content = $cache; } else { $content = $this->markupEngine->markupText($content); if ($comment->getID()) { $comment->setCache($content); $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $comment->save(); unset($unguarded); } } $content = '<div class="phabricator-remarkup">' . $content . '</div>'; } else { $title = null; $head_content = '<div class="differential-comment-nocontent">' . "<p>{$author_link} {$verb} this revision.</p>" . '</div>'; $content = null; } if ($this->inlines) { $inline_render = array(); $inlines = $this->inlines; $changesets = $this->changesets; $inlines_by_changeset = mgroup($inlines, 'getChangesetID'); $inlines_by_changeset = array_select_keys($inlines_by_changeset, array_keys($this->changesets)); $inline_render[] = '<table class="differential-inline-summary">'; foreach ($inlines_by_changeset as $changeset_id => $inlines) { $changeset = $changesets[$changeset_id]; $inlines = msort($inlines, 'getLineNumber'); $inline_render[] = '<tr>' . '<th colspan="3">' . phutil_escape_html($changeset->getFileName()) . '</th>' . '</tr>'; foreach ($inlines as $inline) { if (!$inline->getLineLength()) { $lines = $inline->getLineNumber(); } else { $lines = $inline->getLineNumber() . "–" . ($inline->getLineNumber() + $inline->getLineLength()); } $on_target = $this->target && $this->target->getID() == $changeset->getDiffID(); $is_visible = false; if ($inline->getIsNewFile()) { // This comment is on the right side of the versus diff, and visible // on the left side of the page. if ($this->versusDiffID) { if ($changeset->getDiffID() == $this->versusDiffID) { $is_visible = true; } } // This comment is on the right side of the target diff, and visible // on the right side of the page. if ($on_target) { $is_visible = true; } } else { // Ths comment is on the left side of the target diff, and visible // on the left side of the page. if (!$this->versusDiffID) { if ($on_target) { $is_visible = true; } } // TODO: We still get one edge case wrong here, when we have a // versus diff and the file didn't exist in the old version. The // comment is visible because we show the left side of the target // diff when there's no corresponding file in the versus diff, but // we incorrectly link it off-page. } $where = null; if ($is_visible) { $lines = phutil_render_tag('a', array('href' => '#inline-' . $inline->getID(), 'class' => 'num'), $lines); } else { $diff_id = $changeset->getDiffID(); $lines = phutil_render_tag('a', array('href' => '?id=' . $diff_id . '#inline-' . $inline->getID(), 'class' => 'num', 'target' => '_blank'), $lines . " ↗"); $where = '(On Diff #' . $diff_id . ')'; } $inline_content = $inline->getContent(); if (strlen($inline_content)) { $inline_cache = $inline->getCache(); if ($inline_cache) { $inline_content = $inline_cache; } else { $inline_content = $this->markupEngine->markupText($inline_content); if ($inline->getID()) { $inline->setCache($inline_content); $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $inline->save(); unset($unguarded); } } } $inline_render[] = '<tr>' . '<td class="inline-line-number">' . $lines . '</td>' . '<td class="inline-which-diff">' . $where . '</td>' . '<td>' . '<div class="phabricator-remarkup">' . $inline_content . '</div>' . '</td>' . '</tr>'; } } $inline_render[] = '</table>'; $inline_render = implode("\n", $inline_render); $inline_render = '<div class="differential-inline-summary-section">' . 'Inline Comments' . '</div>' . $inline_render; } else { $inline_render = null; } $background = null; $uri = $author->getImageURI(); if ($uri) { $background = "background-image: url('{$uri}');"; } $metadata_blocks = array(); $metadata = $comment->getMetadata(); $added_reviewers = idx($metadata, DifferentialComment::METADATA_ADDED_REVIEWERS); if ($added_reviewers) { $reviewers = 'Added reviewers: ' . $this->renderHandleList($added_reviewers); $metadata_blocks[] = $reviewers; } $added_ccs = idx($metadata, DifferentialComment::METADATA_ADDED_CCS); if ($added_ccs) { $ccs = 'Added CCs: ' . $this->renderHandleList($added_ccs); $metadata_blocks[] = $ccs; } if ($metadata_blocks) { $metadata_blocks = '<div class="differential-comment-metadata">' . implode("\n", $metadata_blocks) . '</div>'; } else { $metadata_blocks = null; } return phutil_render_tag('div', array('class' => "differential-comment {$action_class}", 'id' => $comment_anchor), '<div class="differential-comment-head">' . '<span class="differential-comment-info">' . $info . '</span>' . '<span class="differential-comment-title">' . $title . '</span>' . '<div style="clear: both;"></div>' . '</div>' . '<div class="differential-comment-body" style="' . $background . '">' . '<div class="differential-comment-content">' . $head_content . $metadata_blocks . '<div class="differential-comment-core">' . $content . '</div>' . $inline_render . '</div>' . '</div>'); }
public function getTitle() { $author_phid = $this->getAuthorPHID(); $author_handle = $this->renderHandleLink($author_phid); $old = $this->getOldValue(); $new = $this->getNewValue(); switch ($this->getTransactionType()) { case self::TYPE_INLINE: return pht('%s added inline comments.', $author_handle); case self::TYPE_UPDATE: if ($new) { // TODO: Migrate to PHIDs and use handles here? if (phid_get_type($new) == DifferentialDiffPHIDType::TYPECONST) { return pht('%s updated this revision to %s.', $author_handle, $this->renderHandleLink($new)); } else { return pht('%s updated this revision.', $author_handle); } } else { return pht('%s updated this revision.', $author_handle); } case self::TYPE_ACTION: return DifferentialAction::getBasicStoryText($new, $author_handle); case self::TYPE_STATUS: switch ($this->getNewValue()) { case ArcanistDifferentialRevisionStatus::ACCEPTED: return pht('This revision is now accepted and ready to land.'); case ArcanistDifferentialRevisionStatus::NEEDS_REVISION: return pht('This revision now requires changes to proceed.'); case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW: return pht('This revision now requires review to proceed.'); } } return parent::getTitle(); }
private function getRevisionCommentActions(DifferentialRevision $revision) { $actions = array(DifferentialAction::ACTION_COMMENT => true); $admin_actions = array(); $viewer = $this->getRequest()->getUser(); $viewer_phid = $viewer->getPHID(); $viewer_is_admin = $viewer->getIsAdmin(); $viewer_is_owner = $viewer_phid == $revision->getAuthorPHID(); $viewer_is_reviewer = in_array($viewer_phid, $revision->getReviewers()); $viewer_did_accept = $viewer_phid === $revision->loadReviewedBy(); if ($viewer_is_owner) { switch ($revision->getStatus()) { case DifferentialRevisionStatus::NEEDS_REVIEW: $actions[DifferentialAction::ACTION_ABANDON] = true; $actions[DifferentialAction::ACTION_RETHINK] = true; break; case DifferentialRevisionStatus::NEEDS_REVISION: $actions[DifferentialAction::ACTION_ABANDON] = true; $actions[DifferentialAction::ACTION_REQUEST] = true; break; case DifferentialRevisionStatus::ACCEPTED: $actions[DifferentialAction::ACTION_ABANDON] = true; $actions[DifferentialAction::ACTION_REQUEST] = true; $actions[DifferentialAction::ACTION_RETHINK] = true; break; case DifferentialRevisionStatus::COMMITTED: break; case DifferentialRevisionStatus::ABANDONED: $actions[DifferentialAction::ACTION_RECLAIM] = true; break; } } else { switch ($revision->getStatus()) { case DifferentialRevisionStatus::NEEDS_REVIEW: $admin_actions[DifferentialAction::ACTION_ABANDON] = $viewer_is_admin; $actions[DifferentialAction::ACTION_ACCEPT] = true; $actions[DifferentialAction::ACTION_REJECT] = true; $actions[DifferentialAction::ACTION_RESIGN] = $viewer_is_reviewer; break; case DifferentialRevisionStatus::NEEDS_REVISION: $admin_actions[DifferentialAction::ACTION_ABANDON] = $viewer_is_admin; $actions[DifferentialAction::ACTION_ACCEPT] = true; $actions[DifferentialAction::ACTION_RESIGN] = $viewer_is_reviewer; break; case DifferentialRevisionStatus::ACCEPTED: $admin_actions[DifferentialAction::ACTION_ABANDON] = $viewer_is_admin; $actions[DifferentialAction::ACTION_REJECT] = true; $actions[DifferentialAction::ACTION_RESIGN] = $viewer_is_reviewer && !$viewer_did_accept; break; case DifferentialRevisionStatus::COMMITTED: case DifferentialRevisionStatus::ABANDONED: break; } } $actions[DifferentialAction::ACTION_ADDREVIEWERS] = true; $actions[DifferentialAction::ACTION_ADDCCS] = true; $actions = array_keys(array_filter($actions)); $admin_actions = array_keys(array_filter($admin_actions)); $actions_dict = array(); foreach ($actions as $action) { $actions_dict[$action] = DifferentialAction::getActionVerb($action); } foreach ($admin_actions as $action) { $actions_dict[$action] = '(Admin) ' . DifferentialAction::getActionVerb($action); } return $actions_dict; }
private function getRevisionCommentActions(DifferentialRevision $revision) { $actions = array(DifferentialAction::ACTION_COMMENT => true); $viewer = $this->getRequest()->getUser(); $viewer_phid = $viewer->getPHID(); $viewer_is_owner = $viewer_phid == $revision->getAuthorPHID(); $viewer_is_reviewer = in_array($viewer_phid, $revision->getReviewers()); $viewer_did_accept = $viewer_phid === $revision->loadReviewedBy(); $status = $revision->getStatus(); $allow_self_accept = PhabricatorEnv::getEnvConfig('differential.allow-self-accept', false); if ($viewer_is_owner) { switch ($status) { case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW: $actions[DifferentialAction::ACTION_ACCEPT] = $allow_self_accept; $actions[DifferentialAction::ACTION_ABANDON] = true; $actions[DifferentialAction::ACTION_RETHINK] = true; break; case ArcanistDifferentialRevisionStatus::NEEDS_REVISION: $actions[DifferentialAction::ACTION_ACCEPT] = $allow_self_accept; $actions[DifferentialAction::ACTION_ABANDON] = true; $actions[DifferentialAction::ACTION_REQUEST] = true; break; case ArcanistDifferentialRevisionStatus::ACCEPTED: $actions[DifferentialAction::ACTION_ABANDON] = true; $actions[DifferentialAction::ACTION_REQUEST] = true; $actions[DifferentialAction::ACTION_RETHINK] = true; $actions[DifferentialAction::ACTION_CLOSE] = true; break; case ArcanistDifferentialRevisionStatus::CLOSED: break; case ArcanistDifferentialRevisionStatus::ABANDONED: $actions[DifferentialAction::ACTION_RECLAIM] = true; break; } } else { switch ($status) { case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW: $actions[DifferentialAction::ACTION_ACCEPT] = true; $actions[DifferentialAction::ACTION_REJECT] = true; $actions[DifferentialAction::ACTION_RESIGN] = $viewer_is_reviewer; break; case ArcanistDifferentialRevisionStatus::NEEDS_REVISION: $actions[DifferentialAction::ACTION_ACCEPT] = true; $actions[DifferentialAction::ACTION_RESIGN] = $viewer_is_reviewer; break; case ArcanistDifferentialRevisionStatus::ACCEPTED: $actions[DifferentialAction::ACTION_REJECT] = true; $actions[DifferentialAction::ACTION_RESIGN] = $viewer_is_reviewer && !$viewer_did_accept; break; case ArcanistDifferentialRevisionStatus::CLOSED: case ArcanistDifferentialRevisionStatus::ABANDONED: break; } if ($status != ArcanistDifferentialRevisionStatus::CLOSED) { $actions[DifferentialAction::ACTION_CLAIM] = true; } } $actions[DifferentialAction::ACTION_ADDREVIEWERS] = true; $actions[DifferentialAction::ACTION_ADDCCS] = true; $actions = array_keys(array_filter($actions)); $actions_dict = array(); foreach ($actions as $action) { $actions_dict[$action] = DifferentialAction::getActionVerb($action); } return $actions_dict; }
public function handleRequest(AphrontRequest $request) { $viewer = $this->getViewer(); $id = $request->getURIData('id'); $revision = id(new DifferentialRevisionQuery())->setViewer($viewer)->withIDs(array($id))->executeOne(); if (!$revision) { return new Aphront404Response(); } $type_comment = PhabricatorTransactions::TYPE_COMMENT; $type_action = DifferentialTransaction::TYPE_ACTION; $type_edge = PhabricatorTransactions::TYPE_EDGE; $type_subscribers = PhabricatorTransactions::TYPE_SUBSCRIBERS; $xactions = array(); $action = $request->getStr('action'); switch ($action) { case DifferentialAction::ACTION_COMMENT: case DifferentialAction::ACTION_ADDREVIEWERS: case DifferentialAction::ACTION_ADDCCS: break; default: $xactions[] = id(new DifferentialTransaction())->setTransactionType($type_action)->setNewValue($action); break; } $edge_reviewer = DifferentialRevisionHasReviewerEdgeType::EDGECONST; $reviewers = $request->getStrList('reviewers'); if (DifferentialAction::allowReviewers($action) && $reviewers) { $faux_edges = array(); foreach ($reviewers as $phid) { $faux_edges[$phid] = array('src' => $revision->getPHID(), 'type' => $edge_reviewer, 'dst' => $phid); } $xactions[] = id(new DifferentialTransaction())->setTransactionType($type_edge)->setMetadataValue('edge:type', $edge_reviewer)->setOldValue(array())->setNewValue($faux_edges); } $ccs = $request->getStrList('ccs'); if ($ccs) { $xactions[] = id(new DifferentialTransaction())->setTransactionType($type_subscribers)->setOldValue(array())->setNewValue(array_fuse($ccs)); } // Add a comment transaction if there's nothing, so we'll generate a // nonempty result. if (strlen($request->getStr('content')) || !$xactions) { $xactions[] = id(new DifferentialTransaction())->setTransactionType($type_comment)->attachComment(id(new ManiphestTransactionComment())->setContent($request->getStr('content'))); } foreach ($xactions as $xaction) { $xaction->setAuthorPHID($viewer->getPHID()); } $engine = new PhabricatorMarkupEngine(); $engine->setViewer($request->getUser()); foreach ($xactions as $xaction) { if ($xaction->hasComment()) { $engine->addObject($xaction->getComment(), PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT); } } $engine->process(); $phids = mpull($xactions, 'getRequiredHandlePHIDs'); $phids = array_mergev($phids); $handles = id(new PhabricatorHandleQuery())->setViewer($viewer)->withPHIDs($phids)->execute(); foreach ($xactions as $xaction) { $xaction->setHandles($handles); } $view = id(new DifferentialTransactionView())->setUser($viewer)->setTransactions($xactions)->setIsPreview(true); $metadata = array('reviewers' => $reviewers, 'ccs' => $ccs); if ($action != DifferentialAction::ACTION_COMMENT) { $metadata['action'] = $action; } $draft_key = 'differential-comment-' . $id; $draft = id(new PhabricatorDraft())->setAuthorPHID($viewer->getPHID())->setDraftKey($draft_key)->setDraft($request->getStr('content'))->setMetadata($metadata)->replaceOrDelete(); if ($draft->isDeleted()) { DifferentialDraft::deleteHasDraft($viewer->getPHID(), $revision->getPHID(), $draft_key); } else { DifferentialDraft::markHasDraft($viewer->getPHID(), $revision->getPHID(), $draft_key); } return id(new AphrontAjaxResponse())->setContent((string) phutil_implode_html('', $view->buildEvents())); }
public function render() { if (!$this->user) { throw new Exception("Call setUser() before rendering!"); } require_celerity_resource('phabricator-remarkup-css'); require_celerity_resource('differential-revision-comment-css'); $comment = $this->comment; $action = $comment->getAction(); $action_class = 'differential-comment-action-' . $action; $info = array(); $content = $comment->getContent(); $hide_comments = true; if (strlen(rtrim($content))) { $hide_comments = false; $cache = $comment->getCache(); if (strlen($cache)) { $content = $cache; } else { $content = $this->markupEngine->markupText($content); if ($comment->getID()) { $comment->setCache($content); $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $comment->save(); unset($unguarded); } } $content = '<div class="phabricator-remarkup">' . $content . '</div>'; } $inline_render = $this->renderInlineComments(); if ($inline_render) { $hide_comments = false; } $author = $this->handles[$comment->getAuthorPHID()]; $author_link = $author->renderLink(); $metadata = $comment->getMetadata(); $added_reviewers = idx($metadata, DifferentialComment::METADATA_ADDED_REVIEWERS, array()); $added_ccs = idx($metadata, DifferentialComment::METADATA_ADDED_CCS, array()); $verb = DifferentialAction::getActionPastTenseVerb($comment->getAction()); $verb = phutil_escape_html($verb); $actions = array(); switch ($comment->getAction()) { case DifferentialAction::ACTION_ADDCCS: $actions[] = "{$author_link} added CCs: " . $this->renderHandleList($added_ccs) . "."; $added_ccs = null; break; case DifferentialAction::ACTION_ADDREVIEWERS: $actions[] = "{$author_link} added reviewers: " . $this->renderHandleList($added_reviewers) . "."; $added_reviewers = null; break; case DifferentialAction::ACTION_UPDATE: $diff_id = idx($metadata, DifferentialComment::METADATA_DIFF_ID); if ($diff_id) { $diff_link = phutil_render_tag('a', array('href' => '/D' . $comment->getRevisionID() . '?id=' . $diff_id), 'Diff #' . phutil_escape_html($diff_id)); $actions[] = "{$author_link} updated this revision to {$diff_link}."; } else { $actions[] = "{$author_link} {$verb} this revision."; } break; default: $actions[] = "{$author_link} {$verb} this revision."; break; } if ($added_reviewers) { $actions[] = "{$author_link} added reviewers: " . $this->renderHandleList($added_reviewers) . "."; } if ($added_ccs) { $actions[] = "{$author_link} added CCs: " . $this->renderHandleList($added_ccs) . "."; } foreach ($actions as $key => $action) { $actions[$key] = '<div>' . $action . '</div>'; } $xaction_view = id(new PhabricatorTransactionView())->setUser($this->user)->setImageURI($author->getImageURI())->setContentSource($comment->getContentSource())->addClass($action_class)->setActions($actions); if ($this->preview) { $xaction_view->setIsPreview($this->preview); } else { $xaction_view->setEpoch($comment->getDateCreated()); if ($this->anchorName) { $anchor_name = $this->anchorName; $anchor_text = 'D' . $comment->getRevisionID() . '#' . $anchor_name; $xaction_view->setAnchor($anchor_name, $anchor_text); } } if (!$hide_comments) { $xaction_view->appendChild('<div class="differential-comment-core">' . $content . '</div>' . $this->renderSingleView($inline_render)); } return $xaction_view->render(); }
private function getRevisionCommentActions(DifferentialRevision $revision) { $actions = array(DifferentialAction::ACTION_COMMENT => true); $viewer = $this->getRequest()->getUser(); $viewer_phid = $viewer->getPHID(); $viewer_is_owner = $viewer_phid == $revision->getAuthorPHID(); $viewer_is_reviewer = in_array($viewer_phid, $revision->getReviewers()); $status = $revision->getStatus(); $viewer_has_accepted = false; $viewer_has_rejected = false; $status_accepted = DifferentialReviewerStatus::STATUS_ACCEPTED; $status_rejected = DifferentialReviewerStatus::STATUS_REJECTED; foreach ($revision->getReviewerStatus() as $reviewer) { if ($reviewer->getReviewerPHID() == $viewer_phid) { if ($reviewer->getStatus() == $status_accepted) { $viewer_has_accepted = true; } if ($reviewer->getStatus() == $status_rejected) { $viewer_has_rejected = true; } break; } } $allow_self_accept = PhabricatorEnv::getEnvConfig('differential.allow-self-accept'); $always_allow_abandon = PhabricatorEnv::getEnvConfig('differential.always-allow-abandon'); $always_allow_close = PhabricatorEnv::getEnvConfig('differential.always-allow-close'); $allow_reopen = PhabricatorEnv::getEnvConfig('differential.allow-reopen'); if ($viewer_is_owner) { switch ($status) { case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW: $actions[DifferentialAction::ACTION_ACCEPT] = $allow_self_accept; $actions[DifferentialAction::ACTION_ABANDON] = true; $actions[DifferentialAction::ACTION_RETHINK] = true; break; case ArcanistDifferentialRevisionStatus::NEEDS_REVISION: case ArcanistDifferentialRevisionStatus::CHANGES_PLANNED: $actions[DifferentialAction::ACTION_ACCEPT] = $allow_self_accept; $actions[DifferentialAction::ACTION_ABANDON] = true; $actions[DifferentialAction::ACTION_REQUEST] = true; break; case ArcanistDifferentialRevisionStatus::ACCEPTED: $actions[DifferentialAction::ACTION_ABANDON] = true; $actions[DifferentialAction::ACTION_REQUEST] = true; $actions[DifferentialAction::ACTION_RETHINK] = true; $actions[DifferentialAction::ACTION_CLOSE] = true; break; case ArcanistDifferentialRevisionStatus::CLOSED: break; case ArcanistDifferentialRevisionStatus::ABANDONED: $actions[DifferentialAction::ACTION_RECLAIM] = true; break; } } else { switch ($status) { case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW: $actions[DifferentialAction::ACTION_ABANDON] = $always_allow_abandon; $actions[DifferentialAction::ACTION_ACCEPT] = true; $actions[DifferentialAction::ACTION_REJECT] = true; $actions[DifferentialAction::ACTION_RESIGN] = $viewer_is_reviewer; break; case ArcanistDifferentialRevisionStatus::NEEDS_REVISION: case ArcanistDifferentialRevisionStatus::CHANGES_PLANNED: $actions[DifferentialAction::ACTION_ABANDON] = $always_allow_abandon; $actions[DifferentialAction::ACTION_ACCEPT] = true; $actions[DifferentialAction::ACTION_REJECT] = !$viewer_has_rejected; $actions[DifferentialAction::ACTION_RESIGN] = $viewer_is_reviewer; break; case ArcanistDifferentialRevisionStatus::ACCEPTED: $actions[DifferentialAction::ACTION_ABANDON] = $always_allow_abandon; $actions[DifferentialAction::ACTION_ACCEPT] = !$viewer_has_accepted; $actions[DifferentialAction::ACTION_REJECT] = true; $actions[DifferentialAction::ACTION_RESIGN] = $viewer_is_reviewer; break; case ArcanistDifferentialRevisionStatus::CLOSED: case ArcanistDifferentialRevisionStatus::ABANDONED: break; } if ($status != ArcanistDifferentialRevisionStatus::CLOSED) { $actions[DifferentialAction::ACTION_CLAIM] = true; $actions[DifferentialAction::ACTION_CLOSE] = $always_allow_close; } } $actions[DifferentialAction::ACTION_ADDREVIEWERS] = true; $actions[DifferentialAction::ACTION_ADDCCS] = true; $actions[DifferentialAction::ACTION_REOPEN] = $allow_reopen && $status == ArcanistDifferentialRevisionStatus::CLOSED; $actions = array_keys(array_filter($actions)); $actions_dict = array(); foreach ($actions as $action) { $actions_dict[$action] = DifferentialAction::getActionVerb($action); } return $actions_dict; }
public function render() { require_celerity_resource('differential-revision-add-comment-css'); $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business'); $revision = $this->revision; $action = null; if ($this->draft) { $action = idx($this->draft->getMetadata(), 'action'); } $enable_reviewers = DifferentialAction::allowReviewers($action); $enable_ccs = $action == DifferentialAction::ACTION_ADDCCS; $form = new AphrontFormView(); $form->setWorkflow(true)->setUser($this->user)->setAction($this->actionURI)->addHiddenInput('revision_id', $revision->getID())->appendChild(id(new AphrontFormSelectControl())->setLabel('Action')->setName('action')->setValue($action)->setID('comment-action')->setOptions($this->actions))->appendChild(id(new AphrontFormTokenizerControl())->setLabel('Add Reviewers')->setName('reviewers')->setControlID('add-reviewers')->setControlStyle($enable_reviewers ? null : 'display: none')->setID('add-reviewers-tokenizer')->setDisableBehavior(true))->appendChild(id(new AphrontFormTokenizerControl())->setLabel('Add CCs')->setName('ccs')->setControlID('add-ccs')->setControlStyle($enable_ccs ? null : 'display: none')->setID('add-ccs-tokenizer')->setDisableBehavior(true))->appendChild(id(new PhabricatorRemarkupControl())->setName('comment')->setID('comment-content')->setLabel('Comment')->setValue($this->draft ? $this->draft->getDraft() : null))->appendChild(id(new AphrontFormSubmitControl())->setValue($is_serious ? 'Submit' : 'Clowncopterize')); Javelin::initBehavior('differential-add-reviewers-and-ccs', array('dynamic' => array('add-reviewers-tokenizer' => array('actions' => array('request_review' => 1, 'add_reviewers' => 1), 'src' => '/typeahead/common/users/', 'value' => $this->reviewers, 'row' => 'add-reviewers', 'ondemand' => PhabricatorEnv::getEnvConfig('tokenizer.ondemand'), 'placeholder' => 'Type a user name...'), 'add-ccs-tokenizer' => array('actions' => array('add_ccs' => 1), 'src' => '/typeahead/common/mailable/', 'value' => $this->ccs, 'row' => 'add-ccs', 'ondemand' => PhabricatorEnv::getEnvConfig('tokenizer.ondemand'), 'placeholder' => 'Type a user or mailing list...')), 'select' => 'comment-action')); $diff = $revision->loadActiveDiff(); $warnings = mpull($this->auxFields, 'renderWarningBoxForRevisionAccept'); $lint_warning = null; $unit_warning = null; Javelin::initBehavior('differential-accept-with-errors', array('select' => 'comment-action', 'warnings' => 'warnings')); $rev_id = $revision->getID(); Javelin::initBehavior('differential-feedback-preview', array('uri' => '/differential/comment/preview/' . $rev_id . '/', 'preview' => 'comment-preview', 'action' => 'comment-action', 'content' => 'comment-content', 'previewTokenizers' => array('reviewers' => 'add-reviewers-tokenizer', 'ccs' => 'add-ccs-tokenizer'), 'inlineuri' => '/differential/comment/inline/preview/' . $rev_id . '/', 'inline' => 'inline-comment-preview')); $panel_view = new AphrontPanelView(); $panel_view->appendChild($form); $warning_container = '<div id="warnings">'; foreach ($warnings as $warning) { if ($warning) { $warning_container .= $warning->render(); } } $warning_container .= '</div>'; $panel_view->appendChild($warning_container); if ($lint_warning) { $panel_view->appendChild($lint_warning); } if ($unit_warning) { $panel_view->appendChild($unit_warning); } $panel_view->setHeader($is_serious ? 'Add Comment' : 'Leap Into Action'); $panel_view->addClass('aphront-panel-accent'); $panel_view->addClass('aphront-panel-flush'); return id(new PhabricatorAnchorView())->setAnchorName('comment')->setNavigationMarker(true)->render() . '<div class="differential-add-comment-panel">' . $panel_view->render() . '<div class="aphront-panel-preview aphront-panel-flush">' . '<div id="comment-preview">' . '<span class="aphront-panel-preview-loading-text">' . 'Loading comment preview...' . '</span>' . '</div>' . '<div id="inline-comment-preview">' . '</div>' . '</div>' . '</div>'; }