Changeset View
Changeset View
Standalone View
Standalone View
src/applications/herald/controller/HeraldTranscriptController.php
<?php | <?php | ||||
final class HeraldTranscriptController extends HeraldController { | final class HeraldTranscriptController extends HeraldController { | ||||
private $handles; | private $handles; | ||||
private $adapter; | private $adapter; | ||||
private function getAdapter() { | private function getAdapter() { | ||||
return $this->adapter; | return $this->adapter; | ||||
} | } | ||||
public function buildApplicationMenu() { | |||||
// Use the menu we build in this controller, not the default menu for | |||||
// Herald. | |||||
return null; | |||||
} | |||||
public function handleRequest(AphrontRequest $request) { | public function handleRequest(AphrontRequest $request) { | ||||
$viewer = $this->getViewer(); | $viewer = $this->getViewer(); | ||||
$xscript = id(new HeraldTranscriptQuery()) | $xscript = id(new HeraldTranscriptQuery()) | ||||
->setViewer($viewer) | ->setViewer($viewer) | ||||
->withIDs(array($request->getURIData('id'))) | ->withIDs(array($request->getURIData('id'))) | ||||
->executeOne(); | ->executeOne(); | ||||
if (!$xscript) { | if (!$xscript) { | ||||
return new Aphront404Response(); | return new Aphront404Response(); | ||||
} | } | ||||
$view_key = $this->getViewKey($request); | |||||
if (!$view_key) { | |||||
return new Aphront404Response(); | |||||
} | |||||
$navigation = $this->newSideNavView($xscript, $view_key); | |||||
$object = $xscript->getObject(); | $object = $xscript->getObject(); | ||||
require_celerity_resource('herald-test-css'); | require_celerity_resource('herald-test-css'); | ||||
$content = array(); | $content = array(); | ||||
$object_xscript = $xscript->getObjectTranscript(); | $object_xscript = $xscript->getObjectTranscript(); | ||||
if (!$object_xscript) { | if (!$object_xscript) { | ||||
$notice = id(new PHUIInfoView()) | $notice = id(new PHUIInfoView()) | ||||
Show All 21 Lines | if (!$object_xscript) { | ||||
$phids = $this->getTranscriptPHIDs($xscript); | $phids = $this->getTranscriptPHIDs($xscript); | ||||
$phids = array_unique($phids); | $phids = array_unique($phids); | ||||
$phids = array_filter($phids); | $phids = array_filter($phids); | ||||
$handles = $this->loadViewerHandles($phids); | $handles = $this->loadViewerHandles($phids); | ||||
$this->handles = $handles; | $this->handles = $handles; | ||||
if ($xscript->getDryRun()) { | |||||
$notice = new PHUIInfoView(); | |||||
$notice->setSeverity(PHUIInfoView::SEVERITY_NOTICE); | |||||
$notice->setTitle(pht('Dry Run')); | |||||
$notice->appendChild( | |||||
pht( | |||||
'This was a dry run to test Herald rules, '. | |||||
'no actions were executed.')); | |||||
$content[] = $notice; | |||||
} | |||||
$warning_panel = $this->buildWarningPanel($xscript); | $warning_panel = $this->buildWarningPanel($xscript); | ||||
$content[] = $warning_panel; | $content[] = $warning_panel; | ||||
$content[] = array( | $content[] = $this->newContentView($xscript, $view_key); | ||||
$this->buildActionTranscriptPanel($xscript), | |||||
$this->buildObjectTranscriptPanel($xscript), | |||||
$this->buildTransactionsTranscriptPanel( | |||||
$object, | |||||
$xscript), | |||||
$this->buildProfilerTranscriptPanel($xscript), | |||||
); | |||||
} | } | ||||
$crumbs = id($this->buildApplicationCrumbs()) | $crumbs = id($this->buildApplicationCrumbs()) | ||||
->addTextCrumb( | ->addTextCrumb( | ||||
pht('Transcripts'), | pht('Transcripts'), | ||||
$this->getApplicationURI('/transcript/')) | $this->getApplicationURI('/transcript/')) | ||||
->addTextCrumb($xscript->getID()) | ->addTextCrumb(pht('Transcript %d', $xscript->getID())) | ||||
->setBorder(true); | ->setBorder(true); | ||||
$title = pht('Transcript: %s', $xscript->getID()); | $title = pht('Herald Transcript %s', $xscript->getID()); | ||||
$header = $this->newHeaderView($xscript, $title); | |||||
$header = id(new PHUIHeaderView()) | |||||
->setHeader($title) | |||||
->setHeaderIcon('fa-file'); | |||||
$view = id(new PHUITwoColumnView()) | $view = id(new PHUITwoColumnView()) | ||||
->setHeader($header) | ->setHeader($header) | ||||
->setFooter($content); | ->setFooter($content); | ||||
return $this->newPage() | return $this->newPage() | ||||
->setTitle($title) | ->setTitle($title) | ||||
->setCrumbs($crumbs) | ->setCrumbs($crumbs) | ||||
->appendChild( | ->setNavigation($navigation) | ||||
array( | ->appendChild($view); | ||||
$view, | |||||
)); | |||||
} | } | ||||
protected function renderConditionTestValue($condition, $handles) { | protected function renderConditionTestValue($condition, $handles) { | ||||
// TODO: This is all a hacky mess and should be driven through FieldValue | // TODO: This is all a hacky mess and should be driven through FieldValue | ||||
// eventually. | // eventually. | ||||
switch ($condition->getFieldName()) { | switch ($condition->getFieldName()) { | ||||
case HeraldAnotherRuleField::FIELDCONST: | case HeraldAnotherRuleField::FIELDCONST: | ||||
▲ Show 20 Lines • Show All 322 Lines • ▼ Show 20 Lines | foreach ($rule_xscripts as $rule_xscript) { | ||||
} | } | ||||
} | } | ||||
} | } | ||||
$box = id(new PHUIObjectBoxView()) | $box = id(new PHUIObjectBoxView()) | ||||
->setHeaderText(pht('Rule Transcript')) | ->setHeaderText(pht('Rule Transcript')) | ||||
->appendChild($rule_list); | ->appendChild($rule_list); | ||||
return $box; | $content = array(); | ||||
if ($xscript->getDryRun()) { | |||||
$notice = new PHUIInfoView(); | |||||
$notice->setSeverity(PHUIInfoView::SEVERITY_NOTICE); | |||||
$notice->setTitle(pht('Dry Run')); | |||||
$notice->appendChild( | |||||
pht( | |||||
'This was a dry run to test Herald rules, '. | |||||
'no actions were executed.')); | |||||
$content[] = $notice; | |||||
} | |||||
$content[] = $box; | |||||
return $content; | |||||
} | } | ||||
private function buildObjectTranscriptPanel(HeraldTranscript $xscript) { | private function buildObjectTranscriptPanel(HeraldTranscript $xscript) { | ||||
$viewer = $this->getViewer(); | $viewer = $this->getViewer(); | ||||
$adapter = $this->getAdapter(); | $adapter = $this->getAdapter(); | ||||
$field_names = $adapter->getFieldNameMap(); | $field_names = $adapter->getFieldNameMap(); | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | private function buildObjectTranscriptPanel(HeraldTranscript $xscript) { | ||||
$box = new PHUIObjectBoxView(); | $box = new PHUIObjectBoxView(); | ||||
$box->setHeaderText(pht('Object Transcript')); | $box->setHeaderText(pht('Object Transcript')); | ||||
$box->appendChild($property_list); | $box->appendChild($property_list); | ||||
return $box; | return $box; | ||||
} | } | ||||
private function buildTransactionsTranscriptPanel( | private function buildTransactionsTranscriptPanel(HeraldTranscript $xscript) { | ||||
$object, | |||||
HeraldTranscript $xscript) { | |||||
$viewer = $this->getViewer(); | $viewer = $this->getViewer(); | ||||
$object_xscript = $xscript->getObjectTranscript(); | $xaction_phids = $this->getTranscriptTransactionPHIDs($xscript); | ||||
$xaction_phids = $object_xscript->getAppliedTransactionPHIDs(); | |||||
// If the value is "null", this is an older transcript or this adapter | |||||
// does not use transactions. We render nothing. | |||||
// | |||||
// If the value is "array()", this is a modern transcript which uses | |||||
// transactions, there just weren't any applied. Below, we'll render a | |||||
// "No Transactions Applied" state. | |||||
if ($xaction_phids === null) { | |||||
return null; | |||||
} | |||||
// If this object doesn't implement the right interface, we won't be | |||||
// able to load the transactions. Just bail. | |||||
if (!($object instanceof PhabricatorApplicationTransactionInterface)) { | |||||
return null; | |||||
} | |||||
if ($xaction_phids) { | |||||
$object = $xscript->getObject(); | |||||
$query = PhabricatorApplicationTransactionQuery::newQueryForObject( | $query = PhabricatorApplicationTransactionQuery::newQueryForObject( | ||||
$object); | $object); | ||||
if ($xaction_phids) { | |||||
$xactions = $query | $xactions = $query | ||||
->setViewer($viewer) | ->setViewer($viewer) | ||||
->withPHIDs($xaction_phids) | ->withPHIDs($xaction_phids) | ||||
->execute(); | ->execute(); | ||||
$xactions = mpull($xactions, null, 'getPHID'); | $xactions = mpull($xactions, null, 'getPHID'); | ||||
} else { | } else { | ||||
$xactions = array(); | $xactions = array(); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 139 Lines • ▼ Show 20 Lines | private function buildProfilerTranscriptPanel(HeraldTranscript $xscript) { | ||||
$box_view = id(new PHUIObjectBoxView()) | $box_view = id(new PHUIObjectBoxView()) | ||||
->setHeaderText(pht('Profile')) | ->setHeaderText(pht('Profile')) | ||||
->setTable($table_view); | ->setTable($table_view); | ||||
return $box_view; | return $box_view; | ||||
} | } | ||||
private function getViewKey(AphrontRequest $request) { | |||||
$view_key = $request->getURIData('view'); | |||||
if ($view_key === null) { | |||||
return 'rules'; | |||||
} | |||||
switch ($view_key) { | |||||
case 'fields': | |||||
case 'xactions': | |||||
case 'profile': | |||||
return $view_key; | |||||
default: | |||||
return null; | |||||
} | |||||
} | |||||
private function newSideNavView( | |||||
HeraldTranscript $xscript, | |||||
$view_key) { | |||||
$base_uri = urisprintf( | |||||
'transcript/%d/', | |||||
$xscript->getID()); | |||||
$base_uri = $this->getApplicationURI($base_uri); | |||||
$base_uri = new PhutilURI($base_uri); | |||||
$nav = id(new AphrontSideNavFilterView()) | |||||
->setBaseURI($base_uri); | |||||
$nav->newLink('rules') | |||||
->setHref($base_uri) | |||||
->setName(pht('Rules')) | |||||
->setIcon('fa-list-ul'); | |||||
$nav->newLink('fields') | |||||
->setName(pht('Field Values')) | |||||
->setIcon('fa-file-text-o'); | |||||
$xaction_phids = $this->getTranscriptTransactionPHIDs($xscript); | |||||
$has_xactions = (bool)$xaction_phids; | |||||
$nav->newLink('xactions') | |||||
->setName(pht('Transactions')) | |||||
->setIcon('fa-forward') | |||||
->setDisabled(!$has_xactions); | |||||
$nav->newLink('profile') | |||||
->setName(pht('Profiler')) | |||||
->setIcon('fa-tachometer'); | |||||
$nav->selectFilter($view_key); | |||||
return $nav; | |||||
} | |||||
private function newContentView( | |||||
HeraldTranscript $xscript, | |||||
$view_key) { | |||||
switch ($view_key) { | |||||
case 'rules': | |||||
$content = $this->buildActionTranscriptPanel($xscript); | |||||
break; | |||||
case 'fields': | |||||
$content = $this->buildObjectTranscriptPanel($xscript); | |||||
break; | |||||
case 'xactions': | |||||
$content = $this->buildTransactionsTranscriptPanel($xscript); | |||||
break; | |||||
case 'profile': | |||||
$content = $this->buildProfilerTranscriptPanel($xscript); | |||||
break; | |||||
default: | |||||
throw new Exception(pht('Unknown view key "%s".', $view_key)); | |||||
} | |||||
return $content; | |||||
} | |||||
private function getTranscriptTransactionPHIDs(HeraldTranscript $xscript) { | |||||
$object_xscript = $xscript->getObjectTranscript(); | |||||
$xaction_phids = $object_xscript->getAppliedTransactionPHIDs(); | |||||
// If the value is "null", this is an older transcript or this adapter | |||||
// does not use transactions. | |||||
// | |||||
// (If the value is "array()", this is a modern transcript which uses | |||||
// transactions, there just weren't any applied.) | |||||
if ($xaction_phids === null) { | |||||
return array(); | |||||
} | |||||
$object = $xscript->getObject(); | |||||
// If this object doesn't implement the right interface, we won't be | |||||
// able to load the transactions. | |||||
if (!($object instanceof PhabricatorApplicationTransactionInterface)) { | |||||
return array(); | |||||
} | |||||
return $xaction_phids; | |||||
} | |||||
private function newHeaderView(HeraldTranscript $xscript, $title) { | |||||
$header = id(new PHUIHeaderView()) | |||||
->setHeader($title) | |||||
->setHeaderIcon('fa-list-ul'); | |||||
if ($xscript->getDryRun()) { | |||||
$dry_run_tag = id(new PHUITagView()) | |||||
->setType(PHUITagView::TYPE_SHADE) | |||||
->setColor(PHUITagView::COLOR_VIOLET) | |||||
->setName(pht('Dry Run')) | |||||
->setIcon('fa-exclamation-triangle'); | |||||
$header->addTag($dry_run_tag); | |||||
} | |||||
return $header; | |||||
} | |||||
} | } |