Merge branch 'master' into blender-tweaks-mrg

# Conflicts:
#	resources/celerity/map.php
This commit is contained in:
Nathan Letwory
2020-02-03 22:03:37 +02:00
31 changed files with 533 additions and 197 deletions

View File

@@ -9,7 +9,7 @@ return array(
'names' => array(
'conpherence.pkg.css' => '3c8a0668',
'conpherence.pkg.js' => '020aebcf',
'core.pkg.css' => '63317ed6',
'core.pkg.css' => 'cd9f882c',
'core.pkg.js' => '705aec2c',
'differential.pkg.css' => '607c84be',
'differential.pkg.js' => '1b97518d',
@@ -112,7 +112,7 @@ return array(
'rsrc/css/application/tokens/tokens.css' => 'ce5a50bd',
'rsrc/css/application/uiexample/example.css' => 'b4795059',
'rsrc/css/core/core.css' => '1b29ed61',
'rsrc/css/core/remarkup.css' => 'f06cc20e',
'rsrc/css/core/remarkup.css' => 'c286eaef',
'rsrc/css/core/syntax.css' => '220b85f9',
'rsrc/css/core/z-index.css' => '99c0f5eb',
'rsrc/css/diviner/diviner-shared.css' => '4bd263b0',
@@ -796,7 +796,7 @@ return array(
'phabricator-object-selector-css' => 'ee77366f',
'phabricator-phtize' => '2f1db1ed',
'phabricator-prefab' => '5793d835',
'phabricator-remarkup-css' => 'f06cc20e',
'phabricator-remarkup-css' => 'c286eaef',
'phabricator-search-results-css' => '9ea70ace',
'phabricator-shaped-request' => 'abf88db8',
'phabricator-slowvote-css' => '1694baed',

View File

@@ -737,12 +737,14 @@ phutil_register_library_map(array(
'DiffusionCommitAuditorsHeraldField' => 'applications/diffusion/herald/DiffusionCommitAuditorsHeraldField.php',
'DiffusionCommitAuditorsTransaction' => 'applications/diffusion/xaction/DiffusionCommitAuditorsTransaction.php',
'DiffusionCommitAuthorHeraldField' => 'applications/diffusion/herald/DiffusionCommitAuthorHeraldField.php',
'DiffusionCommitAuthorPackagesHeraldField' => 'applications/diffusion/herald/DiffusionCommitAuthorPackagesHeraldField.php',
'DiffusionCommitAuthorProjectsHeraldField' => 'applications/diffusion/herald/DiffusionCommitAuthorProjectsHeraldField.php',
'DiffusionCommitAutocloseHeraldField' => 'applications/diffusion/herald/DiffusionCommitAutocloseHeraldField.php',
'DiffusionCommitBranchesController' => 'applications/diffusion/controller/DiffusionCommitBranchesController.php',
'DiffusionCommitBranchesHeraldField' => 'applications/diffusion/herald/DiffusionCommitBranchesHeraldField.php',
'DiffusionCommitBuildableTransaction' => 'applications/diffusion/xaction/DiffusionCommitBuildableTransaction.php',
'DiffusionCommitCommitterHeraldField' => 'applications/diffusion/herald/DiffusionCommitCommitterHeraldField.php',
'DiffusionCommitCommitterPackagesHeraldField' => 'applications/diffusion/herald/DiffusionCommitCommitterPackagesHeraldField.php',
'DiffusionCommitCommitterProjectsHeraldField' => 'applications/diffusion/herald/DiffusionCommitCommitterProjectsHeraldField.php',
'DiffusionCommitConcernTransaction' => 'applications/diffusion/xaction/DiffusionCommitConcernTransaction.php',
'DiffusionCommitController' => 'applications/diffusion/controller/DiffusionCommitController.php',
@@ -908,10 +910,12 @@ phutil_register_library_map(array(
'DiffusionPhpExternalSymbolsSource' => 'applications/diffusion/symbol/DiffusionPhpExternalSymbolsSource.php',
'DiffusionPreCommitContentAffectedFilesHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentAffectedFilesHeraldField.php',
'DiffusionPreCommitContentAuthorHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentAuthorHeraldField.php',
'DiffusionPreCommitContentAuthorPackagesHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentAuthorPackagesHeraldField.php',
'DiffusionPreCommitContentAuthorProjectsHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentAuthorProjectsHeraldField.php',
'DiffusionPreCommitContentAuthorRawHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentAuthorRawHeraldField.php',
'DiffusionPreCommitContentBranchesHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentBranchesHeraldField.php',
'DiffusionPreCommitContentCommitterHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentCommitterHeraldField.php',
'DiffusionPreCommitContentCommitterPackagesHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentCommitterPackagesHeraldField.php',
'DiffusionPreCommitContentCommitterProjectsHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentCommitterProjectsHeraldField.php',
'DiffusionPreCommitContentCommitterRawHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentCommitterRawHeraldField.php',
'DiffusionPreCommitContentDiffContentAddedHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentDiffContentAddedHeraldField.php',
@@ -1528,6 +1532,7 @@ phutil_register_library_map(array(
'HeraldApplicationActionGroup' => 'applications/herald/action/HeraldApplicationActionGroup.php',
'HeraldApplyTranscript' => 'applications/herald/storage/transcript/HeraldApplyTranscript.php',
'HeraldBasicFieldGroup' => 'applications/herald/field/HeraldBasicFieldGroup.php',
'HeraldBoolFieldValue' => 'applications/herald/value/HeraldBoolFieldValue.php',
'HeraldBuildableState' => 'applications/herald/state/HeraldBuildableState.php',
'HeraldCallWebhookAction' => 'applications/herald/action/HeraldCallWebhookAction.php',
'HeraldCommentAction' => 'applications/herald/action/HeraldCommentAction.php',
@@ -6732,12 +6737,14 @@ phutil_register_library_map(array(
'DiffusionCommitAuditorsHeraldField' => 'DiffusionCommitHeraldField',
'DiffusionCommitAuditorsTransaction' => 'DiffusionCommitTransactionType',
'DiffusionCommitAuthorHeraldField' => 'DiffusionCommitHeraldField',
'DiffusionCommitAuthorPackagesHeraldField' => 'DiffusionCommitHeraldField',
'DiffusionCommitAuthorProjectsHeraldField' => 'DiffusionCommitHeraldField',
'DiffusionCommitAutocloseHeraldField' => 'DiffusionCommitHeraldField',
'DiffusionCommitBranchesController' => 'DiffusionController',
'DiffusionCommitBranchesHeraldField' => 'DiffusionCommitHeraldField',
'DiffusionCommitBuildableTransaction' => 'DiffusionCommitTransactionType',
'DiffusionCommitCommitterHeraldField' => 'DiffusionCommitHeraldField',
'DiffusionCommitCommitterPackagesHeraldField' => 'DiffusionCommitHeraldField',
'DiffusionCommitCommitterProjectsHeraldField' => 'DiffusionCommitHeraldField',
'DiffusionCommitConcernTransaction' => 'DiffusionCommitAuditTransaction',
'DiffusionCommitController' => 'DiffusionController',
@@ -6906,10 +6913,12 @@ phutil_register_library_map(array(
'DiffusionPhpExternalSymbolsSource' => 'DiffusionExternalSymbolsSource',
'DiffusionPreCommitContentAffectedFilesHeraldField' => 'DiffusionPreCommitContentHeraldField',
'DiffusionPreCommitContentAuthorHeraldField' => 'DiffusionPreCommitContentHeraldField',
'DiffusionPreCommitContentAuthorPackagesHeraldField' => 'DiffusionPreCommitContentHeraldField',
'DiffusionPreCommitContentAuthorProjectsHeraldField' => 'DiffusionPreCommitContentHeraldField',
'DiffusionPreCommitContentAuthorRawHeraldField' => 'DiffusionPreCommitContentHeraldField',
'DiffusionPreCommitContentBranchesHeraldField' => 'DiffusionPreCommitContentHeraldField',
'DiffusionPreCommitContentCommitterHeraldField' => 'DiffusionPreCommitContentHeraldField',
'DiffusionPreCommitContentCommitterPackagesHeraldField' => 'DiffusionPreCommitContentHeraldField',
'DiffusionPreCommitContentCommitterProjectsHeraldField' => 'DiffusionPreCommitContentHeraldField',
'DiffusionPreCommitContentCommitterRawHeraldField' => 'DiffusionPreCommitContentHeraldField',
'DiffusionPreCommitContentDiffContentAddedHeraldField' => 'DiffusionPreCommitContentHeraldField',
@@ -7635,6 +7644,7 @@ phutil_register_library_map(array(
'HeraldApplicationActionGroup' => 'HeraldActionGroup',
'HeraldApplyTranscript' => 'Phobject',
'HeraldBasicFieldGroup' => 'HeraldFieldGroup',
'HeraldBoolFieldValue' => 'HeraldFieldValue',
'HeraldBuildableState' => 'HeraldState',
'HeraldCallWebhookAction' => 'HeraldAction',
'HeraldCommentAction' => 'HeraldAction',

View File

@@ -1,3 +1,17 @@
<?php
final class PhabricatorAuthHighSecurityToken extends Phobject {}
final class PhabricatorAuthHighSecurityToken
extends Phobject {
private $isUnchallengedToken = false;
public function setIsUnchallengedToken($is_unchallenged_token) {
$this->isUnchallengedToken = $is_unchallenged_token;
return $this;
}
public function getIsUnchallengedToken() {
return $this->isUnchallengedToken;
}
}

View File

@@ -493,7 +493,8 @@ final class PhabricatorAuthSessionEngine extends Phobject {
// adds an auth factor, existing sessions won't get a free pass into hisec,
// since they never actually got marked as hisec.
if (!$factors) {
return $this->issueHighSecurityToken($session, true);
return $this->issueHighSecurityToken($session, true)
->setIsUnchallengedToken(true);
}
$this->request = $request;

View File

@@ -354,6 +354,69 @@ final class DifferentialHunkParser extends Phobject {
return $this;
}
public function generateVisibleBlocksMask($lines_context) {
// See T13468. This is similar to "generateVisibleLinesMask()", but
// attempts to work around a series of bugs which cancel each other
// out but make a mess of the intermediate steps.
$old = $this->getOldLines();
$new = $this->getNewLines();
$length = max(count($old), count($new));
$visible_lines = array();
for ($ii = 0; $ii < $length; $ii++) {
$old_visible = (isset($old[$ii]) && $old[$ii]['type']);
$new_visible = (isset($new[$ii]) && $new[$ii]['type']);
$visible_lines[$ii] = ($old_visible || $new_visible);
}
$mask = array();
$reveal_cursor = -1;
for ($ii = 0; $ii < $length; $ii++) {
// If this line isn't visible, it isn't going to reveal anything.
if (!$visible_lines[$ii]) {
// If it hasn't been revealed by a nearby line, mark it as masked.
if (empty($mask[$ii])) {
$mask[$ii] = false;
}
continue;
}
// If this line is visible, reveal all the lines nearby.
// First, compute the minimum and maximum offsets we want to reveal.
$min_reveal = max($ii - $lines_context, 0);
$max_reveal = min($ii + $lines_context, $length - 1);
// Naively, we'd do more work than necessary when revealing context for
// several adjacent visible lines: we would mark all the overlapping
// lines as revealed several times.
// To avoid duplicating work, keep track of the largest line we've
// revealed to. Since we reveal context by marking every consecutive
// line, we don't need to touch any line above it.
$min_reveal = max($min_reveal, $reveal_cursor);
// Reveal the remaining unrevealed lines.
for ($jj = $min_reveal; $jj <= $max_reveal; $jj++) {
$mask[$jj] = true;
}
// Move the cursor to the next line which may still need to be revealed.
$reveal_cursor = $max_reveal + 1;
}
$this->setVisibleLinesMask($mask);
return $mask;
}
public function generateVisibleLinesMask($lines_context) {
$old = $this->getOldLines();
$new = $this->getNewLines();
@@ -361,6 +424,7 @@ final class DifferentialHunkParser extends Phobject {
$visible = false;
$last = 0;
$mask = array();
for ($cursor = -$lines_context; $cursor < $max_length; $cursor++) {
$offset = $cursor + $lines_context;
if ((isset($old[$offset]) && $old[$offset]['type']) ||

View File

@@ -10,7 +10,7 @@ final class DiffusionCommitAuthorHeraldField
}
public function getHeraldFieldValue($object) {
return $object->getCommitData()->getCommitDetail('authorPHID');
return $this->getAdapter()->getAuthorPHID();
}
protected function getHeraldFieldStandardType() {

View File

@@ -0,0 +1,37 @@
<?php
final class DiffusionCommitAuthorPackagesHeraldField
extends DiffusionCommitHeraldField {
const FIELDCONST = 'diffusion.commit.author.packages';
public function getHeraldFieldName() {
return pht("Author's packages");
}
public function getHeraldFieldValue($object) {
$adapter = $this->getAdapter();
$viewer = $adapter->getViewer();
$author_phid = $adapter->getAuthorPHID();
if (!$author_phid) {
return array();
}
$packages = id(new PhabricatorOwnersPackageQuery())
->setViewer($viewer)
->withAuthorityPHIDs(array($author_phid))
->execute();
return mpull($packages, 'getPHID');
}
protected function getHeraldFieldStandardType() {
return self::STANDARD_PHID_LIST;
}
protected function getDatasource() {
return new PhabricatorOwnersPackageDatasource();
}
}

View File

@@ -11,17 +11,16 @@ final class DiffusionCommitAuthorProjectsHeraldField
public function getHeraldFieldValue($object) {
$adapter = $this->getAdapter();
$viewer = $adapter->getViewer();
$phid = $object->getCommitData()->getCommitDetail('authorPHID');
if (!$phid) {
$author_phid = $adapter->getAuthorPHID();
if (!$author_phid) {
return array();
}
$viewer = $adapter->getViewer();
$projects = id(new PhabricatorProjectQuery())
->setViewer($viewer)
->withMemberPHIDs(array($phid))
->withMemberPHIDs(array($author_phid))
->execute();
return mpull($projects, 'getPHID');

View File

@@ -10,7 +10,7 @@ final class DiffusionCommitCommitterHeraldField
}
public function getHeraldFieldValue($object) {
return $object->getCommitData()->getCommitDetail('committerPHID');
return $this->getAdapter()->getCommitterPHID();
}
protected function getHeraldFieldStandardType() {

View File

@@ -0,0 +1,37 @@
<?php
final class DiffusionCommitCommitterPackagesHeraldField
extends DiffusionCommitHeraldField {
const FIELDCONST = 'diffusion.commit.committer.packages';
public function getHeraldFieldName() {
return pht("Committer's packages");
}
public function getHeraldFieldValue($object) {
$adapter = $this->getAdapter();
$viewer = $adapter->getViewer();
$committer_phid = $adapter->getAuthorPHID();
if (!$committer_phid) {
return array();
}
$packages = id(new PhabricatorOwnersPackageQuery())
->setViewer($viewer)
->withAuthorityPHIDs(array($committer_phid))
->execute();
return mpull($packages, 'getPHID');
}
protected function getHeraldFieldStandardType() {
return self::STANDARD_PHID_LIST;
}
protected function getDatasource() {
return new PhabricatorOwnersPackageDatasource();
}
}

View File

@@ -11,17 +11,16 @@ final class DiffusionCommitCommitterProjectsHeraldField
public function getHeraldFieldValue($object) {
$adapter = $this->getAdapter();
$viewer = $adapter->getViewer();
$phid = $object->getCommitData()->getCommitDetail('committerPHID');
if (!$phid) {
$committer_phid = $adapter->getCommitterPHID();
if (!$committer_phid) {
return array();
}
$viewer = $adapter->getViewer();
$projects = id(new PhabricatorProjectQuery())
->setViewer($viewer)
->withMemberPHIDs(array($phid))
->withMemberPHIDs(array($committer_phid))
->execute();
return mpull($projects, 'getPHID');

View File

@@ -0,0 +1,37 @@
<?php
final class DiffusionPreCommitContentAuthorPackagesHeraldField
extends DiffusionPreCommitContentHeraldField {
const FIELDCONST = 'diffusion.pre.commit.author.packages';
public function getHeraldFieldName() {
return pht("Author's packages");
}
public function getHeraldFieldValue($object) {
$adapter = $this->getAdapter();
$viewer = $adapter->getViewer();
$author_phid = $adapter->getAuthorPHID();
if (!$author_phid) {
return array();
}
$packages = id(new PhabricatorOwnersPackageQuery())
->setViewer($viewer)
->withAuthorityPHIDs(array($author_phid))
->execute();
return mpull($packages, 'getPHID');
}
protected function getHeraldFieldStandardType() {
return self::STANDARD_PHID_LIST;
}
protected function getDatasource() {
return new PhabricatorOwnersPackageDatasource();
}
}

View File

@@ -11,17 +11,16 @@ final class DiffusionPreCommitContentAuthorProjectsHeraldField
public function getHeraldFieldValue($object) {
$adapter = $this->getAdapter();
$viewer = $adapter->getViewer();
$phid = $adapter->getAuthorPHID();
if (!$phid) {
$author_phid = $adapter->getAuthorPHID();
if (!$author_phid) {
return array();
}
$viewer = $adapter->getViewer();
$projects = id(new PhabricatorProjectQuery())
->setViewer($viewer)
->withMemberPHIDs(array($phid))
->withMemberPHIDs(array($author_phid))
->execute();
return mpull($projects, 'getPHID');

View File

@@ -0,0 +1,37 @@
<?php
final class DiffusionPreCommitContentCommitterPackagesHeraldField
extends DiffusionPreCommitContentHeraldField {
const FIELDCONST = 'diffusion.pre.commit.committer.packages';
public function getHeraldFieldName() {
return pht("Committer's packages");
}
public function getHeraldFieldValue($object) {
$adapter = $this->getAdapter();
$viewer = $adapter->getViewer();
$committer_phid = $adapter->getCommitterPHID();
if (!$committer_phid) {
return array();
}
$packages = id(new PhabricatorOwnersPackageQuery())
->setViewer($viewer)
->withAuthorityPHIDs(array($committer_phid))
->execute();
return mpull($packages, 'getPHID');
}
protected function getHeraldFieldStandardType() {
return self::STANDARD_PHID_LIST;
}
protected function getDatasource() {
return new PhabricatorOwnersPackageDatasource();
}
}

View File

@@ -11,17 +11,16 @@ final class DiffusionPreCommitContentCommitterProjectsHeraldField
public function getHeraldFieldValue($object) {
$adapter = $this->getAdapter();
$viewer = $adapter->getViewer();
$phid = $adapter->getCommitterPHID();
if (!$phid) {
$committer_phid = $adapter->getCommitterPHID();
if (!$committer_phid) {
return array();
}
$viewer = $adapter->getViewer();
$projects = id(new PhabricatorProjectQuery())
->setViewer($viewer)
->withMemberPHIDs(array($phid))
->withMemberPHIDs(array($committer_phid))
->execute();
return mpull($projects, 'getPHID');

View File

@@ -35,18 +35,6 @@ final class HeraldCommitAdapter
}
public function newTestAdapter(PhabricatorUser $viewer, $object) {
$object = id(new DiffusionCommitQuery())
->setViewer($viewer)
->withPHIDs(array($object->getPHID()))
->needCommitData(true)
->executeOne();
if (!$object) {
throw new Exception(
pht(
'Failed to reload commit ("%s") to fetch commit data.',
$object->getPHID()));
}
return id(clone $this)
->setObject($object);
}
@@ -56,7 +44,24 @@ final class HeraldCommitAdapter
}
public function setObject($object) {
$this->commit = $object;
$viewer = $this->getViewer();
$commit_phid = $object->getPHID();
$commit = id(new DiffusionCommitQuery())
->setViewer($viewer)
->withPHIDs(array($commit_phid))
->needCommitData(true)
->needIdentities(true)
->needAuditRequests(true)
->executeOne();
if (!$commit) {
throw new Exception(
pht(
'Failed to reload commit ("%s") to fetch commit data.',
$commit_phid));
}
$this->commit = $commit;
return $this;
}
@@ -352,6 +357,22 @@ final class HeraldCommitAdapter
return $this->getObject()->getRepository();
}
public function getAuthorPHID() {
return $this->getObject()->getEffectiveAuthorPHID();
}
public function getCommitterPHID() {
$commit = $this->getObject();
if ($commit->hasCommitterIdentity()) {
$identity = $commit->getCommitterIdentity();
return $identity->getCurrentEffectiveUserPHID();
}
return null;
}
/* -( HarbormasterBuildableAdapterInterface )------------------------------ */

View File

@@ -8,6 +8,7 @@ final class HeraldPreCommitContentAdapter extends HeraldPreCommitAdapter {
private $revision = false;
private $affectedPackages;
private $identityCache = array();
public function getAdapterContentName() {
return pht('Commit Hook: Commit Content');
@@ -166,10 +167,39 @@ final class HeraldPreCommitContentAdapter extends HeraldPreCommitAdapter {
}
}
private function lookupUser($author) {
return id(new DiffusionResolveUserQuery())
->withName($author)
->execute();
private function lookupUser($raw_identity) {
// See T13480. After the move to repository identities, we want to look
// users up in the identity table. If you push a commit which is authored
// by "A Duck <duck@example.org>" and that identity is bound to user
// "@mallard" in the identity table, Herald should see the author of the
// commit as "@mallard" when evaluating pre-commit content rules.
if (!array_key_exists($raw_identity, $this->identityCache)) {
$repository = $this->getHookEngine()->getRepository();
$viewer = $this->getHookEngine()->getViewer();
$identity_engine = id(new DiffusionRepositoryIdentityEngine())
->setViewer($viewer);
// We must provide a "sourcePHID" when resolving identities, but don't
// have a legitimate one yet. Just use the repository PHID as a
// reasonable value. This won't actually be written to storage.
$source_phid = $repository->getPHID();
$identity_engine->setSourcePHID($source_phid);
// If the identity doesn't exist yet, we don't want to create it if
// we haven't seen it before. It will be created later when we actually
// import the commit.
$identity_engine->setDryRun(true);
$author_identity = $identity_engine->newResolvedIdentity($raw_identity);
$effective_phid = $author_identity->getCurrentEffectiveUserPHID();
$this->identityCache[$raw_identity] = $effective_phid;
}
return $this->identityCache[$raw_identity];
}
private function getCommitFields() {

View File

@@ -59,7 +59,7 @@ final class PhabricatorDocumentEngineBlocks
->parseHunksForLineData($changeset->getHunks())
->reparseHunksForSpecialAttributes();
$hunk_parser->generateVisibleLinesMask(2);
$hunk_parser->generateVisibleBlocksMask(2);
$mask = $hunk_parser->getVisibleLinesMask();
$old_lines = $hunk_parser->getOldLines();
@@ -72,14 +72,7 @@ final class PhabricatorDocumentEngineBlocks
$old_line = idx($old_lines, $ii);
$new_line = idx($new_lines, $ii);
$is_visible = !empty($mask[$ii + 1]);
// TODO: There's currently a bug where one-line files get incorrectly
// masked. This causes images to completely fail to render. Just ignore
// the mask if it came back empty.
if (!$mask) {
$is_visible = true;
}
$is_visible = !empty($mask[$ii]);
if ($old_line) {
$old_hash = rtrim($old_line['text'], "\n");

View File

@@ -942,7 +942,6 @@ abstract class HeraldAdapter extends Phobject {
public function renderRuleAsText(
HeraldRule $rule,
PhabricatorHandleList $handles,
PhabricatorUser $viewer) {
require_celerity_resource('herald-css');
@@ -973,7 +972,7 @@ abstract class HeraldAdapter extends Phobject {
),
array(
$icon,
$this->renderConditionAsText($condition, $handles, $viewer),
$this->renderConditionAsText($condition, $viewer),
));
}
@@ -1004,7 +1003,7 @@ abstract class HeraldAdapter extends Phobject {
),
array(
$icon,
$this->renderActionAsText($viewer, $action, $handles),
$this->renderActionAsText($viewer, $action),
));
}
@@ -1018,7 +1017,6 @@ abstract class HeraldAdapter extends Phobject {
private function renderConditionAsText(
HeraldCondition $condition,
PhabricatorHandleList $handles,
PhabricatorUser $viewer) {
$field_type = $condition->getFieldName();
@@ -1033,7 +1031,7 @@ abstract class HeraldAdapter extends Phobject {
$condition_type = $condition->getFieldCondition();
$condition_name = idx($this->getConditionNameMap(), $condition_type);
$value = $this->renderConditionValueAsText($condition, $handles, $viewer);
$value = $this->renderConditionValueAsText($condition, $viewer);
return array(
$field_name,
@@ -1046,36 +1044,23 @@ abstract class HeraldAdapter extends Phobject {
private function renderActionAsText(
PhabricatorUser $viewer,
HeraldActionRecord $action,
PhabricatorHandleList $handles) {
HeraldActionRecord $action_record) {
$impl = $this->getActionImplementation($action->getAction());
if ($impl) {
$impl->setViewer($viewer);
$action_type = $action_record->getAction();
$action_value = $action_record->getTarget();
$value = $action->getTarget();
return $impl->renderActionDescription($value);
$action = $this->getActionImplementation($action_type);
if (!$action) {
return pht('Unknown Action ("%s")', $action_type);
}
$rule_global = HeraldRuleTypeConfig::RULE_TYPE_GLOBAL;
$action->setViewer($viewer);
$action_type = $action->getAction();
$default = pht('(Unknown Action "%s") equals', $action_type);
$action_name = idx(
$this->getActionNameMap($rule_global),
$action_type,
$default);
$target = $this->renderActionTargetAsText($action, $handles);
return hsprintf(' %s %s', $action_name, $target);
return $action->renderActionDescription($action_value);
}
private function renderConditionValueAsText(
HeraldCondition $condition,
PhabricatorHandleList $handles,
PhabricatorUser $viewer) {
$field = $this->requireFieldImplementation($condition->getFieldName());
@@ -1086,76 +1071,26 @@ abstract class HeraldAdapter extends Phobject {
$condition->getValue());
}
private function renderActionTargetAsText(
HeraldActionRecord $action,
PhabricatorHandleList $handles) {
public function renderFieldTranscriptValue(
PhabricatorUser $viewer,
$field_type,
$field_value) {
// TODO: This should be driven through HeraldAction.
$field = $this->getFieldImplementation($field_type);
if ($field) {
return $field->renderTranscriptValue(
$viewer,
$field_value);
}
$target = $action->getTarget();
if (!is_array($target)) {
$target = array($target);
}
foreach ($target as $index => $val) {
switch ($action->getAction()) {
default:
$handle = $handles->getHandleIfExists($val);
if ($handle) {
$target[$index] = $handle->renderLink();
}
break;
}
}
$target = phutil_implode_html(', ', $target);
return $target;
return phutil_tag(
'em',
array(),
pht(
'Unable to render value for unknown field type ("%s").',
$field_type));
}
/**
* Given a @{class:HeraldRule}, this function extracts all the phids that
* we'll want to load as handles later.
*
* This function performs a somewhat hacky approach to figuring out what
* is and is not a phid - try to get the phid type and if the type is
* *not* unknown assume its a valid phid.
*
* Don't try this at home. Use more strongly typed data at home.
*
* Think of the children.
*/
public static function getHandlePHIDs(HeraldRule $rule) {
$phids = array($rule->getAuthorPHID());
foreach ($rule->getConditions() as $condition) {
$value = $condition->getValue();
if (!is_array($value)) {
$value = array($value);
}
foreach ($value as $val) {
if (phid_get_type($val) !=
PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN) {
$phids[] = $val;
}
}
}
foreach ($rule->getActions() as $action) {
$target = $action->getTarget();
if (!is_array($target)) {
$target = array($target);
}
foreach ($target as $val) {
if (phid_get_type($val) !=
PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN) {
$phids[] = $val;
}
}
}
if ($rule->isObjectRule()) {
$phids[] = $rule->getTriggerObjectPHID();
}
return $phids;
}
/* -( Applying Effects )--------------------------------------------------- */

View File

@@ -143,12 +143,11 @@ final class HeraldRuleViewController extends HeraldController {
private function buildDescriptionView(HeraldRule $rule) {
$viewer = $this->getRequest()->getUser();
$view = id(new PHUIPropertyListView())
->setUser($viewer);
->setViewer($viewer);
$adapter = HeraldAdapter::getAdapterForContentType($rule->getContentType());
if ($adapter) {
$handles = $viewer->loadHandles(HeraldAdapter::getHandlePHIDs($rule));
$rule_text = $adapter->renderRuleAsText($rule, $handles, $viewer);
$rule_text = $adapter->renderRuleAsText($rule, $viewer);
$view->addTextContent($rule_text);
return $view;
}

View File

@@ -447,52 +447,64 @@ final class HeraldTranscriptController extends HeraldController {
}
private function buildObjectTranscriptPanel(HeraldTranscript $xscript) {
$viewer = $this->getViewer();
$adapter = $this->getAdapter();
$field_names = $adapter->getFieldNameMap();
$object_xscript = $xscript->getObjectTranscript();
$data = array();
$rows = array();
if ($object_xscript) {
$phid = $object_xscript->getPHID();
$handles = $this->handles;
$data += array(
pht('Object Name') => $object_xscript->getName(),
pht('Object Type') => $object_xscript->getType(),
pht('Object PHID') => $phid,
pht('Object Link') => $handles[$phid]->renderLink(),
$rows[] = array(
pht('Object Name'),
$object_xscript->getName(),
);
$rows[] = array(
pht('Object Type'),
$object_xscript->getType(),
);
$rows[] = array(
pht('Object PHID'),
$phid,
);
$rows[] = array(
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;
}
foreach ($xscript->getMetadataMap() as $key => $value) {
$rows[] = array(
$key,
$value,
);
}
$rows = array();
foreach ($data as $name => $value) {
if (!($value instanceof PhutilSafeHTML)) {
if (!is_scalar($value) && !is_null($value)) {
$value = implode("\n", $value);
if ($object_xscript) {
foreach ($object_xscript->getFields() as $field_type => $value) {
if (isset($field_names[$field_type])) {
$field_name = pht('Field: %s', $field_names[$field_type]);
} else {
$field_name = pht('Unknown Field ("%s")', $field_type);
}
if (strlen($value) > 256) {
$value = phutil_tag(
'textarea',
array(
'class' => 'herald-field-value-transcript',
),
$value);
}
$field_value = $adapter->renderFieldTranscriptValue(
$viewer,
$field_type,
$value);
$rows[] = array(
$field_name,
$field_value,
);
}
$rows[] = array($name, $value);
}
$property_list = new PHUIPropertyListView();

View File

@@ -23,7 +23,7 @@ final class HeraldAlwaysField extends HeraldField {
}
public function getHeraldFieldValueType($condition) {
return new HeraldEmptyFieldValue();
return new HeraldBoolFieldValue();
}
public function supportsObject($object) {

View File

@@ -105,11 +105,16 @@ abstract class HeraldField extends Phobject {
}
public function getHeraldFieldValueType($condition) {
// NOTE: The condition type may be "null" to indicate that the caller
// wants a generic field value type. This is used when rendering field
// values in the object transcript.
$standard_type = $this->getHeraldFieldStandardType();
switch ($standard_type) {
case self::STANDARD_BOOL:
case self::STANDARD_PHID_BOOL:
return new HeraldEmptyFieldValue();
return new HeraldBoolFieldValue();
case self::STANDARD_TEXT:
case self::STANDARD_TEXT_LIST:
case self::STANDARD_TEXT_MAP:
@@ -176,6 +181,14 @@ abstract class HeraldField extends Phobject {
return $value_type->renderEditorValue($value);
}
public function renderTranscriptValue(
PhabricatorUser $viewer,
$field_value) {
$value_type = $this->getHeraldFieldValueType($condition_type = null);
$value_type->setViewer($viewer);
return $value_type->renderTranscriptValue($field_value);
}
public function getPHIDsAffectedByCondition(HeraldCondition $condition) {
try {
$standard_type = $this->getHeraldFieldStandardType();

View File

@@ -0,0 +1,30 @@
<?php
final class HeraldBoolFieldValue
extends HeraldFieldValue {
public function getFieldValueKey() {
return 'bool';
}
public function getControlType() {
return self::CONTROL_NONE;
}
public function renderFieldValue($value) {
return null;
}
public function renderEditorValue($value) {
return null;
}
public function renderTranscriptValue($value) {
if ($value) {
return pht('true');
} else {
return pht('false');
}
}
}

View File

@@ -36,4 +36,8 @@ abstract class HeraldFieldValue extends Phobject {
return array();
}
public function renderTranscriptValue($value) {
return $this->renderFieldValue($value);
}
}

View File

@@ -19,4 +19,25 @@ final class HeraldTextFieldValue
return $value;
}
public function renderTranscriptValue($value) {
if (is_array($value)) {
$value = implode('', $value);
}
if (!strlen($value)) {
return phutil_tag('em', array(), pht('None'));
}
if (strlen($value) > 256) {
$value = phutil_tag(
'textarea',
array(
'class' => 'herald-field-value-transcript',
),
$value);
}
return $value;
}
}

View File

@@ -64,17 +64,7 @@ final class HeraldTokenizerFieldValue
}
public function renderFieldValue($value) {
$viewer = $this->getViewer();
$value = (array)$value;
if ($this->valueMap !== null) {
foreach ($value as $k => $v) {
$value[$k] = idx($this->valueMap, $v, $v);
}
return implode(', ', $value);
}
return $viewer->renderHandleList((array)$value)->setAsInline(true);
return $this->renderValueAsList($value, $for_transcript = false);
}
public function renderEditorValue($value) {
@@ -87,4 +77,33 @@ final class HeraldTokenizerFieldValue
return $datasource->getWireTokens($value);
}
public function renderTranscriptValue($value) {
return $this->renderValueAsList($value, $for_transcript = true);
}
private function renderValueAsList($value, $for_transcript) {
$viewer = $this->getViewer();
$value = (array)$value;
if (!$value) {
return phutil_tag('em', array(), pht('None'));
}
if ($this->valueMap !== null) {
foreach ($value as $k => $v) {
$value[$k] = idx($this->valueMap, $v, $v);
}
return implode(', ', $value);
}
$list = $viewer->renderHandleList($value);
if (!$for_transcript) {
$list->setAsInline(true);
}
return $list;
}
}

View File

@@ -271,6 +271,25 @@ final class PhabricatorProjectQuery
$all_graph = $this->getAllReachableAncestors($projects);
// See T13484. If the graph is damaged (and contains a cycle or an edge
// pointing at a project which has been destroyed), some of the nodes we
// started with may be filtered out by reachability tests. If any of the
// projects we are linking up don't have available ancestors, filter them
// out.
foreach ($projects as $key => $project) {
$project_phid = $project->getPHID();
if (!isset($all_graph[$project_phid])) {
$this->didRejectResult($project);
unset($projects[$key]);
continue;
}
}
if (!$projects) {
return array();
}
// NOTE: Although we may not need much information about ancestors, we
// always need to test if the viewer is a member, because we will return
// ancestor projects to the policy filter via ExtendedPolicy calls. If

View File

@@ -5155,12 +5155,14 @@ abstract class PhabricatorApplicationTransactionEditor
'an MFA check.'));
}
id(new PhabricatorAuthSessionEngine())
$token = id(new PhabricatorAuthSessionEngine())
->setWorkflowKey($workflow_key)
->requireHighSecurityToken($actor, $request, $cancel_uri);
foreach ($xactions as $xaction) {
$xaction->setIsMFATransaction(true);
if (!$token->getIsUnchallengedToken()) {
foreach ($xactions as $xaction) {
$xaction->setIsMFATransaction(true);
}
}
}

View File

@@ -46,6 +46,13 @@ final class PhabricatorEdgeQuery extends PhabricatorQuery {
* @task config
*/
public function withSourcePHIDs(array $source_phids) {
if (!$source_phids) {
throw new Exception(
pht(
'Edge list passed to "withSourcePHIDs(...)" is empty, but it must '.
'be nonempty.'));
}
$this->sourcePHIDs = $source_phids;
return $this;
}
@@ -158,11 +165,10 @@ final class PhabricatorEdgeQuery extends PhabricatorQuery {
* @task exec
*/
public function execute() {
if (!$this->sourcePHIDs) {
if ($this->sourcePHIDs === null) {
throw new Exception(
pht(
'You must use %s to query edges.',
'withSourcePHIDs()'));
'You must use "withSourcePHIDs()" to query edges.'));
}
$sources = phid_group_by_type($this->sourcePHIDs);

View File

@@ -155,7 +155,6 @@
.phabricator-remarkup .remarkup-list-with-checkmarks .remarkup-checked-item {
color: {$lightgreytext};
text-decoration: line-through;
}
.phabricator-remarkup ul.remarkup-list ol.remarkup-list,