Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/differential/view/revisioncomment/DifferentialRevisionCommentView.php b/src/applications/differential/view/revisioncomment/DifferentialRevisionCommentView.php
index 559d7b1bfa..1a32f2585d 100644
--- a/src/applications/differential/view/revisioncomment/DifferentialRevisionCommentView.php
+++ b/src/applications/differential/view/revisioncomment/DifferentialRevisionCommentView.php
@@ -1,353 +1,352 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class DifferentialRevisionCommentView extends AphrontView {
private $comment;
private $handles;
private $markupEngine;
private $preview;
private $inlines;
private $changesets;
private $target;
- private $commentNumber;
+ private $anchorName;
private $user;
private $versusDiffID;
public function setComment($comment) {
$this->comment = $comment;
return $this;
}
public function setHandles(array $handles) {
$this->handles = $handles;
return $this;
}
public function setMarkupEngine($markup_engine) {
$this->markupEngine = $markup_engine;
return $this;
}
public function setPreview($preview) {
$this->preview = $preview;
return $this;
}
public function setInlineComments(array $inline_comments) {
$this->inlines = $inline_comments;
return $this;
}
public function setChangesets(array $changesets) {
// Ship these in sorted by getSortKey() and keyed by ID... or else!
$this->changesets = $changesets;
return $this;
}
public function setTargetDiff($target) {
$this->target = $target;
return $this;
}
public function setVersusDiffID($diff_vs) {
$this->versusDiffID = $diff_vs;
return $this;
}
- public function setCommentNumber($comment_number) {
- $this->commentNumber = $comment_number;
+ public function setAnchorName($anchor_name) {
+ $this->anchorName = $anchor_name;
return $this;
}
public function setUser(PhabricatorUser $user) {
$this->user = $user;
return $this;
}
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) {
+ $anchor_name = $this->anchorName;
+ if ($anchor_name != '' && !$this->preview) {
Javelin::initBehavior('phabricator-watch-anchor');
- $anchor_name = 'comment-'.$num;
$info[] = phutil_render_tag(
'a',
array(
'name' => $anchor_name,
'id' => $anchor_name,
'href' => '#'.$anchor_name,
),
- 'Comment D'.$comment->getRevisionID().'#'.$num);
+ 'D'.$comment->getRevisionID().'#'.$anchor_name);
$comment_anchor = 'anchor-'.$anchor_name;
}
$info = implode(' &middot; ', 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))) {
$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>';
}
$title = "{$author_link} {$verb} this revision.";
if (strlen(rtrim($content)) || $this->inlines) {
$hide_comments_class = null;
} else {
$hide_comments_class = 'hide';
}
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()."\xE2\x80\x93".
($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." \xE2\x86\x97");
$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",
'id' => $comment_anchor,
'style' => $background,
),
'<div class="differential-comment-detail '.$action_class.'">'.
'<div class="differential-comment-header">'.
'<span class="differential-comment-info">'.$info.'</span>'.
'<span class="differential-comment-title">'.$title.'</span>'.
'</div>'.
'<div class="differential-comment-content '.$hide_comments_class.'">'.
$head_content.
$metadata_blocks.
'<div class="differential-comment-core">'.
$content.
'</div>'.
$inline_render.
'</div>'.
'</div>');
}
private function renderHandleList(array $phids) {
$result = array();
foreach ($phids as $phid) {
$result[] = $this->handles[$phid]->renderLink();
}
return implode(', ', $result);
}
}
diff --git a/src/applications/differential/view/revisioncommentlist/DifferentialRevisionCommentListView.php b/src/applications/differential/view/revisioncommentlist/DifferentialRevisionCommentListView.php
index 7cd331ce06..ece96a750d 100644
--- a/src/applications/differential/view/revisioncommentlist/DifferentialRevisionCommentListView.php
+++ b/src/applications/differential/view/revisioncommentlist/DifferentialRevisionCommentListView.php
@@ -1,178 +1,185 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class DifferentialRevisionCommentListView extends AphrontView {
private $comments;
private $handles;
private $inlines;
private $changesets;
private $user;
private $target;
private $versusDiffID;
public function setComments(array $comments) {
$this->comments = $comments;
return $this;
}
public function setInlineComments(array $inline_comments) {
$this->inlines = $inline_comments;
return $this;
}
public function setHandles(array $handles) {
$this->handles = $handles;
return $this;
}
public function setChangesets(array $changesets) {
$this->changesets = $changesets;
return $this;
}
public function setUser(PhabricatorUser $user) {
$this->user = $user;
return $this;
}
public function setTargetDiff(DifferentialDiff $target) {
$this->target = $target;
return $this;
}
public function setVersusDiffID($diff_vs) {
$this->versusDiffID = $diff_vs;
return $this;
}
public function render() {
require_celerity_resource('differential-revision-comment-list-css');
$engine = PhabricatorMarkupEngine::newDifferentialMarkupEngine(array(
'differential.diff' => $this->target
));
$inlines = mgroup($this->inlines, 'getCommentID');
$num = 1;
$html = array();
foreach ($this->comments as $comment) {
$view = new DifferentialRevisionCommentView();
$view->setComment($comment);
$view->setUser($this->user);
$view->setHandles($this->handles);
$view->setMarkupEngine($engine);
$view->setInlineComments(idx($inlines, $comment->getID(), array()));
$view->setChangesets($this->changesets);
$view->setTargetDiff($this->target);
$view->setVersusDiffID($this->versusDiffID);
- $view->setCommentNumber($num++);
+ if ($comment->getAction() == DifferentialAction::ACTION_SUMMARIZE) {
+ $view->setAnchorName('summary');
+ } elseif ($comment->getAction() == DifferentialAction::ACTION_TESTPLAN) {
+ $view->setAnchorName('test-plan');
+ } else {
+ $view->setAnchorName('comment-'.$num);
+ $num++;
+ }
$html[] = $view->render();
}
$objs = array_reverse(array_values($this->comments));
$html = array_reverse(array_values($html));
$user = $this->user;
$last_comment = null;
// Find the most recent comment by the viewer.
foreach ($objs as $position => $comment) {
if ($user && ($comment->getAuthorPHID() == $user->getPHID())) {
if ($last_comment === null) {
$last_comment = $position;
} else if ($last_comment == $position - 1) {
// If the viewer made several comments in a row, show them all. This
// is a spaz rule for epriestley.
$last_comment = $position;
}
}
}
$header = array();
$hidden = array();
if ($last_comment !== null) {
foreach ($objs as $position => $comment) {
if (!$comment->getID()) {
// These are synthetic comments with summary/test plan information.
$header[] = $html[$position];
unset($html[$position]);
continue;
}
if ($position <= $last_comment) {
// Always show comments after the viewer's last comment.
continue;
}
if ($position < 3) {
// Always show the 3 most recent comments.
continue;
}
$hidden[] = $position;
}
}
if (count($hidden) <= 3) {
// Don't hide if there's not much to hide.
$hidden = array();
}
$header = array_reverse($header);
$hidden = array_select_keys($html, $hidden);
$visible = array_diff_key($html, $hidden);
$hidden = array_reverse($hidden);
$visible = array_reverse($visible);
if ($hidden) {
Javelin::initBehavior(
'differential-show-all-comments',
array(
'markup' => implode("\n", $hidden),
));
$hidden = javelin_render_tag(
'div',
array(
'sigil' => "differential-all-comments-container",
),
'<div class="differential-older-comments-are-hidden">'.
number_format(count($hidden)).' older comments are hidden. '.
javelin_render_tag(
'a',
array(
'href' => '#',
'mustcapture' => true,
'sigil' => 'differential-show-all-comments',
),
'Show all comments.').
'</div>');
} else {
$hidden = null;
}
return
'<div class="differential-comment-list">'.
implode("\n", $header).
$hidden.
implode("\n", $visible).
'</div>';
}
}
diff --git a/src/applications/differential/view/revisioncommentlist/__init__.php b/src/applications/differential/view/revisioncommentlist/__init__.php
index c92b2aa36f..e8f99eaf92 100644
--- a/src/applications/differential/view/revisioncommentlist/__init__.php
+++ b/src/applications/differential/view/revisioncommentlist/__init__.php
@@ -1,19 +1,20 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
+phutil_require_module('phabricator', 'applications/differential/constants/action');
phutil_require_module('phabricator', 'applications/differential/view/revisioncomment');
phutil_require_module('phabricator', 'applications/markup/engine');
phutil_require_module('phabricator', 'infrastructure/celerity/api');
phutil_require_module('phabricator', 'infrastructure/javelin/api');
phutil_require_module('phabricator', 'infrastructure/javelin/markup');
phutil_require_module('phabricator', 'view/base');
phutil_require_module('phutil', 'utils');
phutil_require_source('DifferentialRevisionCommentListView.php');
diff --git a/src/applications/maniphest/view/transactiondetail/ManiphestTransactionDetailView.php b/src/applications/maniphest/view/transactiondetail/ManiphestTransactionDetailView.php
index 195b9baaaa..37c8a66b5b 100644
--- a/src/applications/maniphest/view/transactiondetail/ManiphestTransactionDetailView.php
+++ b/src/applications/maniphest/view/transactiondetail/ManiphestTransactionDetailView.php
@@ -1,627 +1,627 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @group maniphest
*/
class ManiphestTransactionDetailView extends ManiphestView {
private $transactions;
private $handles;
private $markupEngine;
private $forEmail;
private $preview;
private $commentNumber;
private $rangeSpecification;
private $renderSummaryOnly;
private $renderFullSummary;
private $user;
public function setTransactionGroup(array $transactions) {
$this->transactions = $transactions;
return $this;
}
public function setHandles(array $handles) {
$this->handles = $handles;
return $this;
}
public function setMarkupEngine(PhutilMarkupEngine $engine) {
$this->markupEngine = $engine;
return $this;
}
public function setPreview($preview) {
$this->preview = $preview;
return $this;
}
public function setRenderSummaryOnly($render_summary_only) {
$this->renderSummaryOnly = $render_summary_only;
return $this;
}
public function getRenderSummaryOnly() {
return $this->renderSummaryOnly;
}
public function setRenderFullSummary($render_full_summary) {
$this->renderFullSummary = $render_full_summary;
return $this;
}
public function getRenderFullSummary() {
return $this->renderFullSummary;
}
public function setCommentNumber($comment_number) {
$this->commentNumber = $comment_number;
return $this;
}
public function setUser(PhabricatorUser $user) {
$this->user = $user;
return $this;
}
public function setRangeSpecification($range) {
$this->rangeSpecification = $range;
return $this;
}
public function getRangeSpecification() {
return $this->rangeSpecification;
}
public function renderForEmail($with_date) {
$this->forEmail = true;
$transaction = reset($this->transactions);
$author = $this->renderHandles(array($transaction->getAuthorPHID()));
$action = null;
$descs = array();
$comments = null;
foreach ($this->transactions as $transaction) {
list($verb, $desc, $classes) = $this->describeAction($transaction);
if ($action === null) {
$action = $verb;
}
$desc = $author.' '.$desc.'.';
if ($with_date) {
// NOTE: This is going into a (potentially multi-recipient) email so
// we can't use a single user's timezone preferences. Use the server's
// instead, but make the timezone explicit.
$datetime = date('M jS \a\t g:i A T', $transaction->getDateCreated());
$desc = "On {$datetime}, {$desc}";
}
$descs[] = $desc;
if ($transaction->hasComments()) {
$comments = $transaction->getComments();
}
}
$descs = implode("\n", $descs);
if ($comments) {
$descs .= "\n".$comments;
}
foreach ($this->transactions as $transaction) {
$supplemental = $this->renderSupplementalInfoForEmail($transaction);
if ($supplemental) {
$descs .= "\n\n".$supplemental;
}
}
$this->forEmail = false;
return array($action, $descs);
}
public function render() {
if (!$this->user) {
throw new Exception("Call setUser() before render()!");
}
$handles = $this->handles;
$transactions = $this->transactions;
require_celerity_resource('maniphest-transaction-detail-css');
$comment_transaction = null;
foreach ($this->transactions as $transaction) {
if ($transaction->hasComments()) {
$comment_transaction = $transaction;
break;
}
}
$any_transaction = reset($transactions);
$author = $this->handles[$any_transaction->getAuthorPHID()];
$more_classes = array();
$descs = array();
foreach ($transactions as $transaction) {
list($verb, $desc, $classes) = $this->describeAction($transaction);
$more_classes = array_merge($more_classes, $classes);
$full_summary = null;
if ($this->getRenderFullSummary()) {
$full_summary = $this->renderFullSummary($transaction);
}
$descs[] = javelin_render_tag(
'div',
array(
'sigil' => 'maniphest-transaction-description',
),
$author->renderLink().' '.$desc.'.'.$full_summary);
}
$descs = implode("\n", $descs);
if ($this->getRenderSummaryOnly()) {
return $descs;
}
$more_classes = implode(' ', $more_classes);
if ($comment_transaction && $comment_transaction->hasComments()) {
$comments = $comment_transaction->getCache();
if (!strlen($comments)) {
$comments = $comment_transaction->getComments();
if (strlen($comments)) {
$comments = $this->markupEngine->markupText($comments);
$comment_transaction->setCache($comments);
if ($comment_transaction->getID() && !$this->preview) {
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
$comment_transaction->save();
unset($unguarded);
}
}
}
$comment_block =
'<div class="maniphest-transaction-comments phabricator-remarkup">'.
$comments.
'</div>';
} else {
$comment_block = null;
}
if ($this->preview) {
$timestamp = 'COMMENT PREVIEW';
} else {
$timestamp = phabricator_datetime(
$transaction->getDateCreated(),
$this->user);
}
$info = array();
$source_transaction = nonempty($comment_transaction, $any_transaction);
$content_source = new PhabricatorContentSourceView();
$content_source->setContentSource($source_transaction->getContentSource());
$content_source->setUser($this->user);
$info[] = $content_source->render();
$info[] = $timestamp;
$comment_anchor = null;
$num = $this->commentNumber;
if ($num && !$this->preview) {
Javelin::initBehavior('phabricator-watch-anchor');
$anchor_name = 'comment-'.$num;
$info[] = javelin_render_tag(
'a',
array(
'name' => $anchor_name,
'id' => $anchor_name,
'href' => '#'.$anchor_name,
),
- 'Comment T'.$any_transaction->getTaskID().'#'.$num);
+ 'T'.$any_transaction->getTaskID().'#'.$anchor_name);
$comment_anchor = 'anchor-'.$anchor_name;
}
$info = implode(' &middot; ', array_filter($info));
return phutil_render_tag(
'div',
array(
'class' => "maniphest-transaction-detail-container",
'style' => "background-image: url('".$author->getImageURI()."')",
'id' => $comment_anchor,
),
'<div class="maniphest-transaction-detail-view '.$more_classes.'">'.
'<div class="maniphest-transaction-header">'.
'<div class="maniphest-transaction-timestamp">'.
$info.
'</div>'.
$descs.
'</div>'.
$comment_block.
'</div>');
}
private function renderSupplementalInfoForEmail($transaction) {
$handles = $this->handles;
$type = $transaction->getTransactionType();
$new = $transaction->getNewValue();
$old = $transaction->getOldValue();
switch ($type) {
case ManiphestTransactionType::TYPE_DESCRIPTION:
return "NEW DESCRIPTION\n ".trim($new)."\n\n".
"PREVIOUS DESCRIPTION\n ".trim($old);
case ManiphestTransactionType::TYPE_ATTACH:
$old_raw = nonempty($old, array());
$new_raw = nonempty($new, array());
$attach_types = array(
PhabricatorPHIDConstants::PHID_TYPE_DREV,
PhabricatorPHIDConstants::PHID_TYPE_FILE,
);
foreach ($attach_types as $type) {
$old = array_keys(idx($old_raw, $type, array()));
$new = array_keys(idx($new_raw, $type, array()));
if ($old != $new) {
break;
}
}
$added = array_diff($new, $old);
if (!$added) {
break;
}
$links = array();
foreach (array_select_keys($handles, $added) as $handle) {
$links[] = ' '.PhabricatorEnv::getProductionURI($handle->getURI());
}
$links = implode("\n", $links);
switch ($type) {
case PhabricatorPHIDConstants::PHID_TYPE_DREV:
$title = 'ATTACHED REVISIONS';
break;
case PhabricatorPHIDConstants::PHID_TYPE_FILE:
$title = 'ATTACHED FILES';
break;
}
return $title."\n".$links;
default:
break;
}
return null;
}
private function describeAction($transaction) {
$verb = null;
$desc = null;
$classes = array();
$handles = $this->handles;
$type = $transaction->getTransactionType();
$author_phid = $transaction->getAuthorPHID();
$new = $transaction->getNewValue();
$old = $transaction->getOldValue();
switch ($type) {
case ManiphestTransactionType::TYPE_TITLE:
$verb = 'Retitled';
$desc = 'changed the title from '.$this->renderString($old).
' to '.$this->renderString($new);
break;
case ManiphestTransactionType::TYPE_DESCRIPTION:
$verb = 'Edited';
if ($this->forEmail || $this->getRenderFullSummary()) {
$desc = 'updated the task description';
} else {
$desc = 'updated the task description; '.
$this->renderExpandLink($transaction);
}
break;
case ManiphestTransactionType::TYPE_NONE:
$verb = 'Commented On';
$desc = 'added a comment';
break;
case ManiphestTransactionType::TYPE_OWNER:
if ($transaction->getAuthorPHID() == $new) {
$verb = 'Claimed';
$desc = 'claimed this task';
$classes[] = 'claimed';
} else if (!$new) {
$verb = 'Up For Grabs';
$desc = 'placed this task up for grabs';
$classes[] = 'upforgrab';
} else if (!$old) {
$verb = 'Assigned';
$desc = 'assigned this task to '.$this->renderHandles(array($new));
$classes[] = 'assigned';
} else {
$verb = 'Reassigned';
$desc = 'reassigned this task from '.
$this->renderHandles(array($old)).
' to '.
$this->renderHandles(array($new));
$classes[] = 'reassigned';
}
break;
case ManiphestTransactionType::TYPE_CCS:
if ($this->preview) {
$verb = 'Changed CC';
$desc = 'changed CCs..';
break;
}
$added = array_diff($new, $old);
$removed = array_diff($old, $new);
if ($added && !$removed) {
$verb = 'Added CC';
if (count($added) == 1) {
$desc = 'added '.$this->renderHandles($added).' to CC';
} else {
$desc = 'added CCs: '.$this->renderHandles($added);
}
} else if ($removed && !$added) {
$verb = 'Removed CC';
if (count($removed) == 1) {
$desc = 'removed '.$this->renderHandles($removed).' from CC';
} else {
$desc = 'removed CCs: '.$this->renderHandles($removed);
}
} else {
$verb = 'Changed CC';
$desc = 'changed CCs, added: '.$this->renderHandles($added).'; '.
'removed: '.$this->renderHandles($removed);
}
break;
case ManiphestTransactionType::TYPE_PROJECTS:
if ($this->preview) {
$verb = 'Changed Projects';
$desc = 'changed projects..';
break;
}
$added = array_diff($new, $old);
$removed = array_diff($old, $new);
if ($added && !$removed) {
$verb = 'Added Project';
if (count($added) == 1) {
$desc = 'added project '.$this->renderHandles($added);
} else {
$desc = 'added projects: '.$this->renderHandles($added);
}
} else if ($removed && !$added) {
$verb = 'Removed Project';
if (count($removed) == 1) {
$desc = 'removed project '.$this->renderHandles($removed);
} else {
$desc = 'removed projectss: '.$this->renderHandles($removed);
}
} else {
$verb = 'Changed Projects';
$desc = 'changed projects, added: '.$this->renderHandles($added).'; '.
'removed: '.$this->renderHandles($removed);
}
break;
case ManiphestTransactionType::TYPE_STATUS:
if ($new == ManiphestTaskStatus::STATUS_OPEN) {
if ($old) {
$verb = 'Reopened';
$desc = 'reopened this task';
$classes[] = 'reopened';
} else {
$verb = 'Created';
$desc = 'created this task';
$classes[] = 'created';
}
} else if ($new == ManiphestTaskStatus::STATUS_CLOSED_SPITE) {
$verb = 'Spited';
$desc = 'closed this task out of spite';
$classes[] = 'spited';
} else if ($new == ManiphestTaskStatus::STATUS_CLOSED_DUPLICATE) {
$verb = 'Merged';
$desc = 'closed this task as a duplicate';
$classes[] = 'duplicate';
} else {
$verb = 'Closed';
$full = idx(ManiphestTaskStatus::getTaskStatusMap(), $new, '???');
$desc = 'closed this task as "'.$full.'"';
$classes[] = 'closed';
}
break;
case ManiphestTransactionType::TYPE_PRIORITY:
$old_name = ManiphestTaskPriority::getTaskPriorityName($old);
$new_name = ManiphestTaskPriority::getTaskPriorityName($new);
if ($old == ManiphestTaskPriority::PRIORITY_TRIAGE) {
$verb = 'Triaged';
$desc = 'triaged this task as "'.$new_name.'" priority';
} else if ($old > $new) {
$verb = 'Lowered Priority';
$desc = 'lowered the priority of this task from "'.$old_name.'" to '.
'"'.$new_name.'"';
} else {
$verb = 'Raised Priority';
$desc = 'raised the priority of this task from "'.$old_name.'" to '.
'"'.$new_name.'"';
}
if ($new == ManiphestTaskPriority::PRIORITY_UNBREAK_NOW) {
$classes[] = 'unbreaknow';
}
break;
case ManiphestTransactionType::TYPE_ATTACH:
if ($this->preview) {
$verb = 'Changed Attached';
$desc = 'changed attachments..';
break;
}
$old_raw = nonempty($old, array());
$new_raw = nonempty($new, array());
foreach (array(
PhabricatorPHIDConstants::PHID_TYPE_DREV,
PhabricatorPHIDConstants::PHID_TYPE_TASK,
PhabricatorPHIDConstants::PHID_TYPE_FILE) as $type) {
$old = array_keys(idx($old_raw, $type, array()));
$new = array_keys(idx($new_raw, $type, array()));
if ($old != $new) {
break;
}
}
$added = array_diff($new, $old);
$removed = array_diff($old, $new);
$add_desc = $this->renderHandles($added);
$rem_desc = $this->renderHandles($removed);
switch ($type) {
case PhabricatorPHIDConstants::PHID_TYPE_DREV:
$singular = 'Differential Revision';
$plural = 'Differential Revisions';
break;
case PhabricatorPHIDConstants::PHID_TYPE_FILE:
$singular = 'file';
$plural = 'files';
break;
case PhabricatorPHIDConstants::PHID_TYPE_TASK:
$singular = 'Maniphest Task';
$plural = 'Maniphest Tasks';
$dependency = true;
break;
}
if ($added && !$removed) {
$verb = 'Attached';
if (count($added) == 1) {
$desc = 'attached '.$singular.': '.$add_desc;
} else {
$desc = 'attached '.$plural.': '.$add_desc;
}
} else if ($removed && !$added) {
$verb = 'Detached';
if (count($removed) == 1) {
$desc = 'detached '.$singular.': '.$rem_desc;
} else {
$desc = 'detached '.$plural.': '.$rem_desc;
}
} else {
$verb = 'Changed Attached';
$desc = 'changed attached '.$plural.', added: '.$add_desc.'; '.
'removed: '.$rem_desc;
}
break;
case ManiphestTransactionType::TYPE_AUXILIARY:
// TODO: This is temporary and hacky! Allow auxiliary fields to
// customize this.
$old_esc = phutil_escape_html($old);
$new_esc = phutil_escape_html($new);
$aux_key = $transaction->getMetadataValue('aux:key');
if ($old === null) {
$verb = "Set Field";
$desc = "set field '{$aux_key}' to '{$new_esc}'";
} else if ($new === null) {
$verb = "Removed Field";
$desc = "removed field '{$aux_key}'";
} else {
$verb = "Updated Field";
$desc = "updated field '{$aux_key}' ".
"from '{$old_esc}' to '{$new_esc}'";
}
break;
default:
return array($type, ' brazenly '.$type."'d", $classes);
}
return array($verb, $desc, $classes);
}
private function renderFullSummary($transaction) {
switch ($transaction->getTransactionType()) {
case ManiphestTransactionType::TYPE_DESCRIPTION:
$id = $transaction->getID();
$old_text = wordwrap($transaction->getOldValue(), 80);
$new_text = wordwrap($transaction->getNewValue(), 80);
$engine = new PhabricatorDifferenceEngine();
$changeset = $engine->generateChangesetFromFileContent($old_text,
$new_text);
$whitespace_mode = DifferentialChangesetParser::WHITESPACE_SHOW_ALL;
$parser = new DifferentialChangesetParser();
$parser->setChangeset($changeset);
$parser->setRenderingReference($id);
$parser->setWhitespaceMode($whitespace_mode);
$spec = $this->getRangeSpecification();
list($range_s, $range_e, $mask) =
DifferentialChangesetParser::parseRangeSpecification($spec);
$output = $parser->render($range_s, $range_e, $mask);
return $output;
}
return null;
}
private function renderExpandLink($transaction) {
$id = $transaction->getID();
Javelin::initBehavior('maniphest-transaction-expand');
return javelin_render_tag(
'a',
array(
'href' => '/maniphest/task/descriptionchange/'.$id.'/',
'sigil' => 'maniphest-expand-transaction',
'mustcapture' => true,
),
'show details');
}
private function renderHandles($phids) {
$links = array();
foreach ($phids as $phid) {
if ($this->forEmail) {
$links[] = $this->handles[$phid]->getName();
} else {
$links[] = $this->handles[$phid]->renderLink();
}
}
return implode(', ', $links);
}
private function renderString($string) {
if ($this->forEmail) {
return '"'.$string.'"';
} else {
return '"'.phutil_escape_html($string).'"';
}
}
}

File Metadata

Mime Type
text/x-diff
Expires
Wed, Jul 2, 6:44 AM (1 d, 5 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
164739
Default Alt Text
(38 KB)

Event Timeline