1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-02-03 02:18:24 +01:00
phorge-phorge/src/applications/transactions/view/PhabricatorApplicationTransactionView.php

300 lines
7.3 KiB
PHP
Raw Normal View History

<?php
/**
* @concrete-extensible
*/
class PhabricatorApplicationTransactionView extends AphrontView {
private $transactions;
private $engine;
private $anchorOffset = 1;
private $showEditActions = true;
private $isPreview;
private $objectPHID;
private $isDetailView;
public function setIsDetailView($is_detail_view) {
$this->isDetailView = $is_detail_view;
return $this;
}
public function setObjectPHID($object_phid) {
$this->objectPHID = $object_phid;
return $this;
}
public function getObjectPHID() {
return $this->objectPHID;
}
public function setIsPreview($is_preview) {
$this->isPreview = $is_preview;
return $this;
}
public function setShowEditActions($show_edit_actions) {
$this->showEditActions = $show_edit_actions;
return $this;
}
public function getShowEditActions() {
return $this->showEditActions;
}
public function setAnchorOffset($anchor_offset) {
$this->anchorOffset = $anchor_offset;
return $this;
}
public function setMarkupEngine(PhabricatorMarkupEngine $engine) {
$this->engine = $engine;
return $this;
}
public function setTransactions(array $transactions) {
assert_instances_of($transactions, 'PhabricatorApplicationTransaction');
$this->transactions = $transactions;
return $this;
}
public function buildEvents() {
$user = $this->getUser();
$anchor = $this->anchorOffset;
$events = array();
$xactions = $this->transactions;
foreach ($xactions as $key => $xaction) {
if ($xaction->shouldHide()) {
unset($xactions[$key]);
}
}
$last = null;
$last_key = null;
$groups = array();
foreach ($xactions as $key => $xaction) {
if ($last && $this->shouldGroupTransactions($last, $xaction)) {
$groups[$last_key][] = $xaction;
unset($xactions[$key]);
} else {
$last = $xaction;
$last_key = $key;
}
}
foreach ($xactions as $key => $xaction) {
$xaction->attachTransactionGroup(idx($groups, $key, array()));
$event = id(new PhabricatorTimelineEventView())
->setUser($user)
->setTransactionPHID($xaction->getPHID())
->setUserHandle($xaction->getHandle($xaction->getAuthorPHID()))
->setIcon($xaction->getIcon())
->setColor($xaction->getColor());
$title = $xaction->getTitle();
if ($xaction->hasChangeDetails()) {
if ($this->isPreview || $this->isDetailView) {
$details = $this->buildChangeDetails($xaction);
} else {
$details = $this->buildChangeDetailsLink($xaction);
}
$title = array(
$title,
' ',
$details,
);
}
$event->setTitle($title);
if ($this->isPreview) {
$event->setIsPreview(true);
} else {
$event
->setDateCreated($xaction->getDateCreated())
->setContentSource($xaction->getContentSource())
->setAnchor($anchor);
$anchor++;
}
$has_deleted_comment = $xaction->getComment() &&
$xaction->getComment()->getIsDeleted();
if ($this->getShowEditActions() && !$this->isPreview) {
if ($xaction->getCommentVersion() > 1) {
$event->setIsEdited(true);
}
$can_edit = PhabricatorPolicyCapability::CAN_EDIT;
if ($xaction->hasComment() || $has_deleted_comment) {
$has_edit_capability = PhabricatorPolicyFilter::hasCapability(
$user,
$xaction,
$can_edit);
if ($has_edit_capability) {
$event->setIsEditable(true);
}
}
}
$content = $this->renderTransactionContent($xaction);
if ($content) {
$event->appendChild($content);
}
$events[] = $event;
}
return $events;
}
public function render() {
if (!$this->getObjectPHID()) {
throw new Exception("Call setObjectPHID() before render()!");
}
$view = new PhabricatorTimelineView();
$events = $this->buildEvents();
foreach ($events as $event) {
$view->addEvent($event);
}
if ($this->getShowEditActions()) {
$list_id = celerity_generate_unique_node_id();
$view->setID($list_id);
Javelin::initBehavior(
'phabricator-transaction-list',
array(
'listID' => $list_id,
'objectPHID' => $this->getObjectPHID(),
'nextAnchor' => $this->anchorOffset + count($events),
));
}
return $view->render();
}
protected function getOrBuildEngine() {
if ($this->engine) {
return $this->engine;
}
$field = PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT;
$engine = id(new PhabricatorMarkupEngine())
->setViewer($this->getUser());
foreach ($this->transactions as $xaction) {
if (!$xaction->hasComment()) {
continue;
}
$engine->addObject($xaction->getComment(), $field);
}
$engine->process();
return $engine;
}
private function buildChangeDetails(
PhabricatorApplicationTransaction $xaction) {
Javelin::initBehavior('phabricator-reveal-content');
$show_id = celerity_generate_unique_node_id();
$hide_id = celerity_generate_unique_node_id();
$content_id = celerity_generate_unique_node_id();
$show_more = javelin_tag(
'a',
array(
'href' => '#',
'sigil' => 'reveal-content',
'mustcapture' => true,
'id' => $show_id,
'style' => 'display: none',
'meta' => array(
'hideIDs' => array($show_id),
'showIDs' => array($hide_id, $content_id),
),
),
pht('(Show Details)'));
$hide_more = javelin_tag(
'a',
array(
'href' => '#',
'sigil' => 'reveal-content',
'mustcapture' => true,
'id' => $hide_id,
'meta' => array(
'hideIDs' => array($hide_id, $content_id),
'showIDs' => array($show_id),
),
),
pht('(Hide Details)'));
$content = phutil_tag(
'div',
array(
'id' => $content_id,
'class' => 'phabricator-timeline-change-details',
),
$xaction->renderChangeDetails($this->getUser()));
return array(
$show_more,
$hide_more,
$content,
);
}
private function buildChangeDetailsLink(
PhabricatorApplicationTransaction $xaction) {
return javelin_tag(
'a',
array(
'href' => '/transactions/detail/'.$xaction->getPHID().'/',
'sigil' => 'transaction-detail',
'mustcapture' => true,
'meta' => array(
'anchor' => $this->anchorOffset,
),
),
pht('(Show Details)'));
}
protected function shouldGroupTransactions(
PhabricatorApplicationTransaction $u,
PhabricatorApplicationTransaction $v) {
return false;
}
protected function renderTransactionContent(
PhabricatorApplicationTransaction $xaction) {
$field = PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT;
$engine = $this->getOrBuildEngine();
$comment = $xaction->getComment();
if ($xaction->hasComment()) {
if ($comment->getIsDeleted()) {
return phutil_tag(
'em',
array(),
pht('This comment has been deleted.'));
} else {
return $engine->getOutput($comment, $field);
}
}
return null;
}
}