Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/herald/adapter/HeraldAdapter.php b/src/applications/herald/adapter/HeraldAdapter.php
index cbe17d2d9d..10ffd41cf5 100644
--- a/src/applications/herald/adapter/HeraldAdapter.php
+++ b/src/applications/herald/adapter/HeraldAdapter.php
@@ -1,386 +1,387 @@
<?php
abstract class HeraldAdapter {
const FIELD_TITLE = 'title';
const FIELD_BODY = 'body';
const FIELD_AUTHOR = 'author';
const FIELD_REVIEWER = 'reviewer';
const FIELD_REVIEWERS = 'reviewers';
const FIELD_CC = 'cc';
const FIELD_TAGS = 'tags';
const FIELD_DIFF_FILE = 'diff-file';
const FIELD_DIFF_CONTENT = 'diff-content';
const FIELD_REPOSITORY = 'repository';
const FIELD_RULE = 'rule';
const FIELD_AFFECTED_PACKAGE = 'affected-package';
const FIELD_AFFECTED_PACKAGE_OWNER = 'affected-package-owner';
const CONDITION_CONTAINS = 'contains';
const CONDITION_NOT_CONTAINS = '!contains';
const CONDITION_IS = 'is';
const CONDITION_IS_NOT = '!is';
const CONDITION_IS_ANY = 'isany';
const CONDITION_IS_NOT_ANY = '!isany';
const CONDITION_INCLUDE_ALL = 'all';
const CONDITION_INCLUDE_ANY = 'any';
const CONDITION_INCLUDE_NONE = 'none';
const CONDITION_IS_ME = 'me';
const CONDITION_IS_NOT_ME = '!me';
const CONDITION_REGEXP = 'regexp';
const CONDITION_RULE = 'conditions';
const CONDITION_NOT_RULE = '!conditions';
const CONDITION_EXISTS = 'exists';
const CONDITION_NOT_EXISTS = '!exists';
const CONDITION_REGEXP_PAIR = 'regexp-pair';
const ACTION_ADD_CC = 'addcc';
const ACTION_REMOVE_CC = 'remcc';
const ACTION_EMAIL = 'email';
const ACTION_NOTHING = 'nothing';
const ACTION_AUDIT = 'audit';
const ACTION_FLAG = 'flag';
const VALUE_TEXT = 'text';
const VALUE_NONE = 'none';
const VALUE_EMAIL = 'email';
const VALUE_USER = 'user';
const VALUE_TAG = 'tag';
const VALUE_RULE = 'rule';
const VALUE_REPOSITORY = 'repository';
const VALUE_OWNERS_PACKAGE = 'package';
const VALUE_PROJECT = 'project';
const VALUE_FLAG_COLOR = 'flagcolor';
abstract public function getPHID();
abstract public function getHeraldName();
abstract public function getHeraldField($field_name);
abstract public function applyHeraldEffects(array $effects);
public function isEnabled() {
return true;
}
/**
* NOTE: You generally should not override this; it exists to support legacy
* adapters which had hard-coded content types.
*/
public function getAdapterContentType() {
return get_class($this);
}
abstract public function getAdapterContentName();
/* -( Fields )------------------------------------------------------------- */
abstract public function getFields();
public function getFieldNameMap() {
return array(
self::FIELD_TITLE => pht('Title'),
self::FIELD_BODY => pht('Body'),
self::FIELD_AUTHOR => pht('Author'),
self::FIELD_REVIEWER => pht('Reviewer'),
self::FIELD_REVIEWERS => pht('Reviewers'),
self::FIELD_CC => pht('CCs'),
self::FIELD_TAGS => pht('Tags'),
self::FIELD_DIFF_FILE => pht('Any changed filename'),
self::FIELD_DIFF_CONTENT => pht('Any changed file content'),
self::FIELD_REPOSITORY => pht('Repository'),
self::FIELD_RULE => pht('Another Herald rule'),
self::FIELD_AFFECTED_PACKAGE => pht('Any affected package'),
self::FIELD_AFFECTED_PACKAGE_OWNER =>
pht("Any affected package's owner"),
);
}
/* -( Conditions )--------------------------------------------------------- */
public function getConditionNameMap() {
return array(
self::CONDITION_CONTAINS => pht('contains'),
self::CONDITION_NOT_CONTAINS => pht('does not contain'),
self::CONDITION_IS => pht('is'),
self::CONDITION_IS_NOT => pht('is not'),
self::CONDITION_IS_ANY => pht('is any of'),
self::CONDITION_IS_NOT_ANY => pht('is not any of'),
self::CONDITION_INCLUDE_ALL => pht('include all of'),
self::CONDITION_INCLUDE_ANY => pht('include any of'),
self::CONDITION_INCLUDE_NONE => pht('include none of'),
self::CONDITION_IS_ME => pht('is myself'),
self::CONDITION_IS_NOT_ME => pht('is not myself'),
self::CONDITION_REGEXP => pht('matches regexp'),
self::CONDITION_RULE => pht('matches:'),
self::CONDITION_NOT_RULE => pht('does not match:'),
self::CONDITION_EXISTS => pht('exists'),
self::CONDITION_NOT_EXISTS => pht('does not exist'),
self::CONDITION_REGEXP_PAIR => pht('matches regexp pair'),
);
}
public function getConditionsForField($field) {
switch ($field) {
case self::FIELD_TITLE:
case self::FIELD_BODY:
return array(
self::CONDITION_CONTAINS,
self::CONDITION_NOT_CONTAINS,
self::CONDITION_IS,
self::CONDITION_IS_NOT,
self::CONDITION_REGEXP,
);
case self::FIELD_AUTHOR:
case self::FIELD_REPOSITORY:
case self::FIELD_REVIEWER:
return array(
self::CONDITION_IS_ANY,
self::CONDITION_IS_NOT_ANY,
);
case self::FIELD_TAGS:
case self::FIELD_REVIEWERS:
case self::FIELD_CC:
return array(
self::CONDITION_INCLUDE_ALL,
self::CONDITION_INCLUDE_ANY,
self::CONDITION_INCLUDE_NONE,
);
case self::FIELD_DIFF_FILE:
return array(
self::CONDITION_CONTAINS,
self::CONDITION_REGEXP,
);
case self::FIELD_DIFF_CONTENT:
return array(
self::CONDITION_CONTAINS,
self::CONDITION_REGEXP,
self::CONDITION_REGEXP_PAIR,
);
case self::FIELD_RULE:
return array(
self::CONDITION_RULE,
self::CONDITION_NOT_RULE,
);
case self::FIELD_AFFECTED_PACKAGE:
case self::FIELD_AFFECTED_PACKAGE_OWNER:
return array(
self::CONDITION_INCLUDE_ANY,
self::CONDITION_INCLUDE_NONE,
);
default:
throw new Exception(
"This adapter does not define conditions for field '{$field}'!");
}
}
/* -( Actions )------------------------------------------------------------ */
abstract public function getActions($rule_type);
public function getActionNameMap($rule_type) {
switch ($rule_type) {
case HeraldRuleTypeConfig::RULE_TYPE_GLOBAL:
return array(
self::ACTION_NOTHING => pht('Do nothing'),
self::ACTION_ADD_CC => pht('Add emails to CC'),
self::ACTION_REMOVE_CC => pht('Remove emails from CC'),
self::ACTION_EMAIL => pht('Send an email to'),
self::ACTION_AUDIT => pht('Trigger an Audit by'),
+ self::ACTION_FLAG => pht('Mark with flag'),
);
case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL:
return array(
self::ACTION_NOTHING => pht('Do nothing'),
self::ACTION_ADD_CC => pht('Add me to CC'),
self::ACTION_REMOVE_CC => pht('Remove me from CC'),
self::ACTION_EMAIL => pht('Send me an email'),
self::ACTION_AUDIT => pht('Trigger an Audit by me'),
self::ACTION_FLAG => pht('Mark with flag'),
);
default:
throw new Exception("Unknown rule type '{$rule_type}'!");
}
}
/* -( Values )------------------------------------------------------------- */
public function getValueTypeForFieldAndCondition($field, $condition) {
switch ($condition) {
case self::CONDITION_CONTAINS:
case self::CONDITION_NOT_CONTAINS:
case self::CONDITION_IS:
case self::CONDITION_IS_NOT:
case self::CONDITION_REGEXP:
case self::CONDITION_REGEXP_PAIR:
return self::VALUE_TEXT;
case self::CONDITION_IS_ANY:
case self::CONDITION_IS_NOT_ANY:
switch ($field) {
case self::FIELD_REPOSITORY:
return self::VALUE_REPOSITORY;
default:
return self::VALUE_USER;
}
break;
case self::CONDITION_INCLUDE_ALL:
case self::CONDITION_INCLUDE_ANY:
case self::CONDITION_INCLUDE_NONE:
switch ($field) {
case self::FIELD_REPOSITORY:
return self::VALUE_REPOSITORY;
case self::FIELD_CC:
return self::VALUE_EMAIL;
case self::FIELD_TAGS:
return self::VALUE_TAG;
case self::FIELD_AFFECTED_PACKAGE:
return self::VALUE_OWNERS_PACKAGE;
default:
return self::VALUE_USER;
}
break;
case self::CONDITION_IS_ME:
case self::CONDITION_IS_NOT_ME:
case self::CONDITION_EXISTS:
case self::CONDITION_NOT_EXISTS:
return self::VALUE_NONE;
case self::CONDITION_RULE:
case self::CONDITION_NOT_RULE:
return self::VALUE_RULE;
default:
throw new Exception("Unknown condition '{$condition}'.");
}
}
public static function getValueTypeForAction($action, $rule_type) {
$is_personal = ($rule_type == HeraldRuleTypeConfig::RULE_TYPE_PERSONAL);
if ($is_personal) {
switch ($action) {
case self::ACTION_ADD_CC:
case self::ACTION_REMOVE_CC:
case self::ACTION_EMAIL:
case self::ACTION_NOTHING:
case self::ACTION_AUDIT:
return self::VALUE_NONE;
case self::ACTION_FLAG:
return self::VALUE_FLAG_COLOR;
default:
throw new Exception("Unknown or invalid action '{$action}'.");
}
} else {
switch ($action) {
case self::ACTION_ADD_CC:
case self::ACTION_REMOVE_CC:
case self::ACTION_EMAIL:
return self::VALUE_EMAIL;
case self::ACTION_NOTHING:
return self::VALUE_NONE;
case self::ACTION_AUDIT:
return self::VALUE_PROJECT;
case self::ACTION_FLAG:
return self::VALUE_FLAG_COLOR;
default:
throw new Exception("Unknown or invalid action '{$action}'.");
}
}
}
public static function applyFlagEffect(HeraldEffect $effect, $phid) {
$color = $effect->getTarget();
// TODO: Silly that we need to load this again here.
$rule = id(new HeraldRule())->load($effect->getRuleID());
$user = id(new PhabricatorUser())->loadOneWhere(
'phid = %s',
$rule->getAuthorPHID());
$flag = PhabricatorFlagQuery::loadUserFlag($user, $phid);
if ($flag) {
return new HeraldApplyTranscript(
$effect,
false,
pht('Object already flagged.'));
}
$handle = PhabricatorObjectHandleData::loadOneHandle(
$phid,
$user);
$flag = new PhabricatorFlag();
$flag->setOwnerPHID($user->getPHID());
$flag->setType($handle->getType());
$flag->setObjectPHID($handle->getPHID());
// TOOD: Should really be transcript PHID, but it doesn't exist yet.
$flag->setReasonPHID($user->getPHID());
$flag->setColor($color);
$flag->setNote(
pht('Flagged by Herald Rule "%s".', $rule->getName()));
$flag->save();
return new HeraldApplyTranscript(
$effect,
true,
pht('Added flag.'));
}
public static function getAllAdapters() {
static $adapters;
if (!$adapters) {
$adapters = id(new PhutilSymbolLoader())
->setAncestorClass(__CLASS__)
->loadObjects();
}
return $adapters;
}
public static function getAllEnabledAdapters() {
$adapters = self::getAllAdapters();
foreach ($adapters as $key => $adapter) {
if (!$adapter->isEnabled()) {
unset($adapters[$key]);
}
}
return $adapters;
}
public static function getAdapterForContentType($content_type) {
$adapters = self::getAllAdapters();
foreach ($adapters as $adapter) {
if ($adapter->getAdapterContentType() == $content_type) {
return $adapter;
}
}
throw new Exception(
pht(
'No adapter exists for Herald content type "%s".',
$content_type));
}
public static function getEnabledAdapterMap() {
$map = array();
$adapters = HeraldAdapter::getAllEnabledAdapters();
foreach ($adapters as $adapter) {
$type = $adapter->getAdapterContentType();
$name = $adapter->getAdapterContentName();
$map[$type] = $name;
}
asort($map);
return $map;
}
}
diff --git a/src/applications/herald/config/HeraldActionConfig.php b/src/applications/herald/config/HeraldActionConfig.php
index feee86d955..f7bb0b0c39 100644
--- a/src/applications/herald/config/HeraldActionConfig.php
+++ b/src/applications/herald/config/HeraldActionConfig.php
@@ -1,124 +1,60 @@
<?php
final class HeraldActionConfig {
const ACTION_ADD_CC = 'addcc';
const ACTION_REMOVE_CC = 'remcc';
const ACTION_EMAIL = 'email';
const ACTION_NOTHING = 'nothing';
const ACTION_AUDIT = 'audit';
const ACTION_FLAG = 'flag';
- // TODO: Remove; still used by transcripts.
- public static function getActionMessageMapForRuleType($rule_type) {
- $generic_mappings = array(
- self::ACTION_NOTHING => pht('Do nothing'),
- self::ACTION_ADD_CC => pht('Add emails to CC'),
- self::ACTION_REMOVE_CC => pht('Remove emails from CC'),
- self::ACTION_EMAIL => pht('Send an email to'),
- self::ACTION_AUDIT => pht('Trigger an Audit'),
- self::ACTION_FLAG => pht('Mark with flag'),
- );
-
- switch ($rule_type) {
- case HeraldRuleTypeConfig::RULE_TYPE_GLOBAL:
- $specific_mappings = array(
- self::ACTION_AUDIT => pht('Trigger an Audit for project'),
- );
- break;
- case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL:
- $specific_mappings = array(
- self::ACTION_ADD_CC => pht('CC me'),
- self::ACTION_REMOVE_CC => pht('Remove me from CC'),
- self::ACTION_EMAIL => pht('Email me'),
- self::ACTION_AUDIT => pht('Trigger an Audit by me'),
- );
- break;
- case null:
- $specific_mappings = array();
- // Use generic mappings, used on transcript.
- break;
- default:
- throw new Exception("Unknown rule type '${rule_type}'");
- }
- return $specific_mappings + $generic_mappings;
- }
-
- // TODO: Remove; still used by transcripts.
- public static function getActionMessageMap($content_type,
- $rule_type) {
- $map = self::getActionMessageMapForRuleType($rule_type);
- switch ($content_type) {
- case HeraldContentTypeConfig::CONTENT_TYPE_DIFFERENTIAL:
- return array_select_keys(
- $map,
- array(
- self::ACTION_ADD_CC,
- self::ACTION_REMOVE_CC,
- self::ACTION_EMAIL,
- self::ACTION_FLAG,
- self::ACTION_NOTHING,
- ));
- case HeraldContentTypeConfig::CONTENT_TYPE_COMMIT:
- return array_select_keys(
- $map,
- array(
- self::ACTION_EMAIL,
- self::ACTION_AUDIT,
- self::ACTION_FLAG,
- self::ACTION_NOTHING,
- ));
- default:
- throw new Exception("Unknown content type '{$content_type}'.");
- }
- }
-
/**
* Create a HeraldAction to save from data.
*
* $data is of the form:
* array(
* 0 => <action type>
* 1 => array(<targets>)
* )
*/
public static function willSaveAction($rule_type,
$author_phid,
$data) {
$obj = new HeraldAction();
$obj->setAction($data[0]);
// for personal rule types, set the target to be the owner of the rule
if ($rule_type == HeraldRuleTypeConfig::RULE_TYPE_PERSONAL) {
switch ($obj->getAction()) {
case HeraldActionConfig::ACTION_EMAIL:
case HeraldActionConfig::ACTION_ADD_CC:
case HeraldActionConfig::ACTION_REMOVE_CC:
case HeraldActionConfig::ACTION_AUDIT:
$data[1] = array($author_phid => $author_phid);
break;
case HeraldActionConfig::ACTION_FLAG:
// Make sure flag color is valid; set to blue if not.
$color_map = PhabricatorFlagColor::getColorNameMap();
if (empty($color_map[$data[1]])) {
$data[1] = PhabricatorFlagColor::COLOR_BLUE;
}
break;
case HeraldActionConfig::ACTION_NOTHING:
break;
default:
throw new Exception('Unrecognized action type: ' .
$obj->getAction());
}
}
if (is_array($data[1])) {
$obj->setTarget(array_keys($data[1]));
} else {
$obj->setTarget($data[1]);
}
return $obj;
}
}
diff --git a/src/applications/herald/config/HeraldConditionConfig.php b/src/applications/herald/config/HeraldConditionConfig.php
index 4772e51f88..e5ae6e4c94 100644
--- a/src/applications/herald/config/HeraldConditionConfig.php
+++ b/src/applications/herald/config/HeraldConditionConfig.php
@@ -1,49 +1,24 @@
<?php
final class HeraldConditionConfig {
// TODO: Remove; still used by Engine/etc.
const CONDITION_CONTAINS = 'contains';
const CONDITION_NOT_CONTAINS = '!contains';
const CONDITION_IS = 'is';
const CONDITION_IS_NOT = '!is';
const CONDITION_IS_ANY = 'isany';
const CONDITION_IS_NOT_ANY = '!isany';
const CONDITION_INCLUDE_ALL = 'all';
const CONDITION_INCLUDE_ANY = 'any';
const CONDITION_INCLUDE_NONE = 'none';
const CONDITION_IS_ME = 'me';
const CONDITION_IS_NOT_ME = '!me';
const CONDITION_REGEXP = 'regexp';
const CONDITION_RULE = 'conditions';
const CONDITION_NOT_RULE = '!conditions';
const CONDITION_EXISTS = 'exists';
const CONDITION_NOT_EXISTS = '!exists';
const CONDITION_REGEXP_PAIR = 'regexp-pair';
- // TODO: Remove; still used by Transcripts.
- public static function getConditionMap() {
- $map = array(
- self::CONDITION_CONTAINS => pht('contains'),
- self::CONDITION_NOT_CONTAINS => pht('does not contain'),
- self::CONDITION_IS => pht('is'),
- self::CONDITION_IS_NOT => pht('is not'),
- self::CONDITION_IS_ANY => pht('is any of'),
- self::CONDITION_IS_NOT_ANY => pht('is not any of'),
- self::CONDITION_INCLUDE_ALL => pht('include all of'),
- self::CONDITION_INCLUDE_ANY => pht('include any of'),
- self::CONDITION_INCLUDE_NONE => pht('include none of'),
- self::CONDITION_IS_ME => pht('is myself'),
- self::CONDITION_IS_NOT_ME => pht('is not myself'),
- self::CONDITION_REGEXP => pht('matches regexp'),
- self::CONDITION_RULE => pht('matches:'),
- self::CONDITION_NOT_RULE => pht('does not match:'),
- self::CONDITION_EXISTS => pht('exists'),
- self::CONDITION_NOT_EXISTS => pht('does not exist'),
- self::CONDITION_REGEXP_PAIR => pht('matches regexp pair'),
- );
-
- return $map;
- }
-
}
diff --git a/src/applications/herald/config/HeraldFieldConfig.php b/src/applications/herald/config/HeraldFieldConfig.php
index c5fc4fb977..b4939fd762 100644
--- a/src/applications/herald/config/HeraldFieldConfig.php
+++ b/src/applications/herald/config/HeraldFieldConfig.php
@@ -1,51 +1,24 @@
<?php
final class HeraldFieldConfig {
// TODO: Remove; still required by conditions, etc.
const FIELD_TITLE = 'title';
const FIELD_BODY = 'body';
const FIELD_AUTHOR = 'author';
const FIELD_REVIEWER = 'reviewer';
const FIELD_REVIEWERS = 'reviewers';
const FIELD_CC = 'cc';
const FIELD_TAGS = 'tags';
const FIELD_DIFF_FILE = 'diff-file';
const FIELD_DIFF_CONTENT = 'diff-content';
const FIELD_REPOSITORY = 'repository';
const FIELD_RULE = 'rule';
const FIELD_AFFECTED_PACKAGE = 'affected-package';
const FIELD_AFFECTED_PACKAGE_OWNER = 'affected-package-owner';
const FIELD_NEED_AUDIT_FOR_PACKAGE = 'need-audit-for-package';
const FIELD_DIFFERENTIAL_REVISION = 'differential-revision';
const FIELD_DIFFERENTIAL_REVIEWERS = 'differential-reviewers';
const FIELD_DIFFERENTIAL_CCS = 'differential-ccs';
- // TODO: Remove; still required by transcripts.
- public static function getFieldMap() {
- $map = array(
- self::FIELD_TITLE => pht('Title'),
- self::FIELD_BODY => pht('Body'),
- self::FIELD_AUTHOR => pht('Author'),
- self::FIELD_REVIEWER => pht('Reviewer'),
- self::FIELD_REVIEWERS => pht('Reviewers'),
- self::FIELD_CC => pht('CCs'),
- self::FIELD_TAGS => pht('Tags'),
- self::FIELD_DIFF_FILE => pht('Any changed filename'),
- self::FIELD_DIFF_CONTENT => pht('Any changed file content'),
- self::FIELD_REPOSITORY => pht('Repository'),
- self::FIELD_RULE => pht('Another Herald rule'),
- self::FIELD_AFFECTED_PACKAGE => pht('Any affected package'),
- self::FIELD_AFFECTED_PACKAGE_OWNER =>
- pht("Any affected package's owner"),
- self::FIELD_NEED_AUDIT_FOR_PACKAGE =>
- pht('Affected packages that need audit'),
- self::FIELD_DIFFERENTIAL_REVISION => pht('Differential revision'),
- self::FIELD_DIFFERENTIAL_REVIEWERS => pht('Differential reviewers'),
- self::FIELD_DIFFERENTIAL_CCS => pht('Differential CCs'),
- );
-
- return $map;
- }
-
}
diff --git a/src/applications/herald/controller/HeraldTranscriptController.php b/src/applications/herald/controller/HeraldTranscriptController.php
index 2fb2f76f24..fafb404902 100644
--- a/src/applications/herald/controller/HeraldTranscriptController.php
+++ b/src/applications/herald/controller/HeraldTranscriptController.php
@@ -1,523 +1,494 @@
<?php
final class HeraldTranscriptController extends HeraldController {
const FILTER_AFFECTED = 'affected';
const FILTER_OWNED = 'owned';
const FILTER_ALL = 'all';
private $id;
private $filter;
private $handles;
+ private $adapter;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
$map = $this->getFilterMap();
$this->filter = idx($data, 'filter');
if (empty($map[$this->filter])) {
$this->filter = self::FILTER_AFFECTED;
}
}
+ private function getAdapter() {
+ return $this->adapter;
+ }
+
public function processRequest() {
$xscript = id(new HeraldTranscript())->load($this->id);
if (!$xscript) {
throw new Exception('Uknown transcript!');
}
require_celerity_resource('herald-test-css');
$nav = $this->buildSideNav();
$object_xscript = $xscript->getObjectTranscript();
if (!$object_xscript) {
$notice = id(new AphrontErrorView())
->setSeverity(AphrontErrorView::SEVERITY_NOTICE)
->setTitle(pht('Old Transcript'))
->appendChild(phutil_tag(
'p',
array(),
pht('Details of this transcript have been garbage collected.')));
$nav->appendChild($notice);
} else {
+
+ $this->adapter = HeraldAdapter::getAdapterForContentType(
+ $object_xscript->getType());
+
$filter = $this->getFilterPHIDs();
$this->filterTranscript($xscript, $filter);
$phids = array_merge($filter, $this->getTranscriptPHIDs($xscript));
$phids = array_unique($phids);
$phids = array_filter($phids);
$handles = $this->loadViewerHandles($phids);
$this->handles = $handles;
if ($xscript->getDryRun()) {
$notice = new AphrontErrorView();
$notice->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
$notice->setTitle(pht('Dry Run'));
$notice->appendChild(pht('This was a dry run to test Herald '.
'rules, no actions were executed.'));
$nav->appendChild($notice);
}
$apply_xscript_panel = $this->buildApplyTranscriptPanel(
$xscript);
$nav->appendChild($apply_xscript_panel);
$action_xscript_panel = $this->buildActionTranscriptPanel(
$xscript);
$nav->appendChild($action_xscript_panel);
$object_xscript_panel = $this->buildObjectTranscriptPanel(
$xscript);
$nav->appendChild($object_xscript_panel);
}
$crumbs = id($this->buildApplicationCrumbs())
->addCrumb(
id(new PhabricatorCrumbView())
->setName(pht('Transcripts'))
->setHref($this->getApplicationURI('/transcript/')))
->addCrumb(
id(new PhabricatorCrumbView())
->setName($xscript->getID()));
$nav->setCrumbs($crumbs);
return $this->buildApplicationPage(
$nav,
array(
'title' => pht('Transcript'),
'device' => true,
'dust' => true,
));
}
protected function renderConditionTestValue($condition, $handles) {
$value = $condition->getTestValue();
if (!is_scalar($value) && $value !== null) {
foreach ($value as $key => $phid) {
$handle = idx($handles, $phid);
if ($handle) {
$value[$key] = $handle->getName();
} else {
// This shouldn't ever really happen as we are supposed to have
// grabbed handles for everything, but be super liberal in what
// we accept here since we expect all sorts of weird issues as we
// version the system.
$value[$key] = 'Unknown Object #'.$phid;
}
}
sort($value);
$value = implode(', ', $value);
}
return hsprintf('<span class="condition-test-value">%s</span>', $value);
}
private function buildSideNav() {
$nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI('/herald/transcript/'.$this->id.'/'));
$items = array();
$filters = $this->getFilterMap();
foreach ($filters as $key => $name) {
$nav->addFilter($key, $name);
}
$nav->selectFilter($this->filter, null);
return $nav;
}
protected function getFilterMap() {
return array(
self::FILTER_AFFECTED => pht('Rules that Affected Me'),
self::FILTER_OWNED => pht('Rules I Own'),
self::FILTER_ALL => pht('All Rules'),
);
}
protected function getFilterPHIDs() {
return array($this->getRequest()->getUser()->getPHID());
-
-/* TODO
- $viewer_id = $this->getRequest()->getUser()->getPHID();
-
- $fbids = array();
- if ($this->filter == self::FILTER_AFFECTED) {
- $fbids[] = $viewer_id;
- require_module_lazy('intern/subscriptions');
- $datastore = new SubscriberDatabaseStore();
- $lists = $datastore->getUserMailmanLists($viewer_id);
- foreach ($lists as $list) {
- $fbids[] = $list;
- }
- }
- return $fbids;
-*/
}
protected function getTranscriptPHIDs($xscript) {
$phids = array();
$object_xscript = $xscript->getObjectTranscript();
if (!$object_xscript) {
return array();
}
$phids[] = $object_xscript->getPHID();
foreach ($xscript->getApplyTranscripts() as $apply_xscript) {
// TODO: This is total hacks. Add another amazing layer of abstraction.
$target = (array)$apply_xscript->getTarget();
foreach ($target as $phid) {
if ($phid) {
$phids[] = $phid;
}
}
}
foreach ($xscript->getRuleTranscripts() as $rule_xscript) {
$phids[] = $rule_xscript->getRuleOwner();
}
$condition_xscripts = $xscript->getConditionTranscripts();
if ($condition_xscripts) {
$condition_xscripts = call_user_func_array(
'array_merge',
$condition_xscripts);
}
foreach ($condition_xscripts as $condition_xscript) {
$value = $condition_xscript->getTestValue();
// TODO: Also total hacks.
if (is_array($value)) {
foreach ($value as $phid) {
if ($phid) { // TODO: Probably need to make sure this "looks like" a
// PHID or decrease the level of hacks here; this used
// to be an is_numeric() check in Facebook land.
$phids[] = $phid;
}
}
}
}
return $phids;
}
protected function filterTranscript($xscript, $filter_phids) {
$filter_owned = ($this->filter == self::FILTER_OWNED);
$filter_affected = ($this->filter == self::FILTER_AFFECTED);
if (!$filter_owned && !$filter_affected) {
// No filtering to be done.
return;
}
if (!$xscript->getObjectTranscript()) {
return;
}
$user_phid = $this->getRequest()->getUser()->getPHID();
$keep_apply_xscripts = array();
$keep_rule_xscripts = array();
$filter_phids = array_fill_keys($filter_phids, true);
$rule_xscripts = $xscript->getRuleTranscripts();
foreach ($xscript->getApplyTranscripts() as $id => $apply_xscript) {
$rule_id = $apply_xscript->getRuleID();
if ($filter_owned) {
if (empty($rule_xscripts[$rule_id])) {
// No associated rule so you can't own this effect.
continue;
}
if ($rule_xscripts[$rule_id]->getRuleOwner() != $user_phid) {
continue;
}
} else if ($filter_affected) {
$targets = (array)$apply_xscript->getTarget();
if (!array_select_keys($filter_phids, $targets)) {
continue;
}
}
$keep_apply_xscripts[$id] = true;
if ($rule_id) {
$keep_rule_xscripts[$rule_id] = true;
}
}
foreach ($rule_xscripts as $rule_id => $rule_xscript) {
if ($filter_owned && $rule_xscript->getRuleOwner() == $user_phid) {
$keep_rule_xscripts[$rule_id] = true;
}
}
$xscript->setRuleTranscripts(
array_intersect_key(
$xscript->getRuleTranscripts(),
$keep_rule_xscripts));
$xscript->setApplyTranscripts(
array_intersect_key(
$xscript->getApplyTranscripts(),
$keep_apply_xscripts));
$xscript->setConditionTranscripts(
array_intersect_key(
$xscript->getConditionTranscripts(),
$keep_rule_xscripts));
}
private function buildApplyTranscriptPanel($xscript) {
$handles = $this->handles;
+ $adapter = $this->getAdapter();
- $action_names = HeraldActionConfig::getActionMessageMapForRuleType(null);
+ $rule_type_global = HeraldRuleTypeConfig::RULE_TYPE_GLOBAL;
+ $action_names = $adapter->getActionNameMap($rule_type_global);
$rows = array();
foreach ($xscript->getApplyTranscripts() as $apply_xscript) {
$target = $apply_xscript->getTarget();
switch ($apply_xscript->getAction()) {
case HeraldActionConfig::ACTION_NOTHING:
$target = '';
break;
case HeraldActionConfig::ACTION_FLAG:
$target = PhabricatorFlagColor::getColorName($target);
break;
default:
if ($target) {
foreach ($target as $k => $phid) {
$target[$k] = $handles[$phid]->getName();
}
$target = implode("\n", $target);
} else {
$target = '<empty>';
}
break;
}
if ($apply_xscript->getApplied()) {
$success = pht('SUCCESS');
$outcome =
hsprintf('<span class="outcome-success">%s</span>', $success);
} else {
$failure = pht('FAILURE');
$outcome =
hsprintf('<span class="outcome-failure">%s</span>', $failure);
}
$rows[] = array(
- $action_names[$apply_xscript->getAction()],
+ idx($action_names, $apply_xscript->getAction(), pht('Unknown')),
$target,
hsprintf(
'<strong>Taken because:</strong> %s<br />'.
'<strong>Outcome:</strong> %s %s',
$apply_xscript->getReason(),
$outcome,
$apply_xscript->getAppliedReason()),
);
}
$table = new AphrontTableView($rows);
$table->setNoDataString(pht('No actions were taken.'));
$table->setHeaders(
array(
pht('Action'),
pht('Target'),
pht('Details'),
));
$table->setColumnClasses(
array(
'',
'',
'wide',
));
$panel = new AphrontPanelView();
$panel->setHeader(pht('Actions Taken'));
$panel->appendChild($table);
$panel->setNoBackground();
return $panel;
}
private function buildActionTranscriptPanel($xscript) {
$action_xscript = mgroup($xscript->getApplyTranscripts(), 'getRuleID');
- $field_names = HeraldFieldConfig::getFieldMap();
- $condition_names = HeraldConditionConfig::getConditionMap();
+ $adapter = $this->getAdapter();
+
+
+ $field_names = $adapter->getFieldNameMap();
+ $condition_names = $adapter->getConditionNameMap();
$handles = $this->handles;
$rule_markup = array();
foreach ($xscript->getRuleTranscripts() as $rule_id => $rule) {
$cond_markup = array();
foreach ($xscript->getConditionTranscriptsForRule($rule_id) as $cond) {
if ($cond->getNote()) {
$note = hsprintf(
'<div class="herald-condition-note">%s</div>',
$cond->getNote());
} else {
$note = null;
}
if ($cond->getResult()) {
$result = hsprintf(
'<span class="herald-outcome condition-pass">'.
"\xE2\x9C\x93".
'</span>');
} else {
$result = hsprintf(
'<span class="herald-outcome condition-fail">'.
"\xE2\x9C\x98".
'</span>');
}
$cond_markup[] = phutil_tag(
'li',
array(),
pht(
'%s Condition: %s %s %s%s',
$result,
- $field_names[$cond->getFieldName()],
- $condition_names[$cond->getCondition()],
+ idx($field_names, $cond->getFieldName(), pht('Unknown')),
+ idx($condition_names, $cond->getCondition(), pht('Unknown')),
$this->renderConditionTestValue($cond, $handles),
$note));
}
if ($rule->getResult()) {
$pass = pht('PASS');
$result = hsprintf(
'<span class="herald-outcome rule-pass">%s</span>', $pass);
$class = 'herald-rule-pass';
} else {
$fail = pht('FAIL');
$result = hsprintf(
'<span class="herald-outcome rule-fail">%s</span>', $fail);
$class = 'herald-rule-fail';
}
$cond_markup[] = hsprintf('<li>%s %s</li>', $result, $rule->getReason());
-
-/*
- if ($rule->getResult()) {
- $actions = idx($action_xscript, $rule_id, array());
- if ($actions) {
- $cond_markup[] = <li><div class="action-header">Actions</div></li>;
- foreach ($actions as $action) {
-
- $target = $action->getTarget();
- if ($target) {
- foreach ((array)$target as $k => $phid) {
- $target[$k] = $handles[$phid]->getName();
- }
- $target = <strong>: {implode(', ', $target)}</strong>;
- }
-
- $cond_markup[] =
- <li>
- {$action_names[$action->getAction()]}
- {$target}
- </li>;
- }
- }
- }
-*/
$user_phid = $this->getRequest()->getUser()->getPHID();
$name = $rule->getRuleName();
- if ($rule->getRuleOwner() == $user_phid) {
-// $name = <a href={"/herald/rule/".$rule->getRuleID()."/"}>{$name}</a>;
- }
$rule_markup[] =
phutil_tag(
'li',
array(
'class' => $class,
),
hsprintf(
'<div class="rule-name"><strong>%s</strong> %s</div>%s',
$name,
$handles[$rule->getRuleOwner()]->getName(),
phutil_tag('ul', array(), $cond_markup)));
}
$panel = '';
if ($rule_markup) {
$panel = new AphrontPanelView();
$panel->setHeader(pht('Rule Details'));
$panel->setNoBackground();
$panel->appendChild(phutil_tag(
'ul',
array('class' => 'herald-explain-list'),
$rule_markup));
}
return $panel;
}
private function buildObjectTranscriptPanel($xscript) {
- $field_names = HeraldFieldConfig::getFieldMap();
+ $adapter = $this->getAdapter();
+ $field_names = $adapter->getFieldNameMap();
$object_xscript = $xscript->getObjectTranscript();
$data = array();
if ($object_xscript) {
$phid = $object_xscript->getPHID();
$handles = $this->loadViewerHandles(array($phid));
$data += array(
pht('Object Name') => $object_xscript->getName(),
pht('Object Type') => $object_xscript->getType(),
pht('Object PHID') => $phid,
pht('Object Link') => $handles[$phid]->renderLink(),
);
}
$data += $xscript->getMetadataMap();
if ($object_xscript) {
foreach ($object_xscript->getFields() as $field => $value) {
$field = idx($field_names, $field, '['.$field.'?]');
$data['Field: '.$field] = $value;
}
}
$rows = array();
foreach ($data as $name => $value) {
if (!($value instanceof PhutilSafeHTML)) {
if (!is_scalar($value) && !is_null($value)) {
$value = implode("\n", $value);
}
if (strlen($value) > 256) {
$value = phutil_tag(
'textarea',
array(
'class' => 'herald-field-value-transcript',
),
$value);
}
}
$rows[] = array($name, $value);
}
$table = new AphrontTableView($rows);
$table->setColumnClasses(
array(
'header',
'wide',
));
$panel = new AphrontPanelView();
$panel->setHeader(pht('Object Transcript'));
$panel->setNoBackground();
$panel->appendChild($table);
return $panel;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Mon, Mar 16, 11:37 PM (1 d, 15 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
963626
Default Alt Text
(38 KB)

Event Timeline