mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-10 14:51:06 +01:00
(stable) Promote 2018 Week 36
This commit is contained in:
commit
37a40d8272
25 changed files with 426 additions and 204 deletions
|
@ -1,53 +0,0 @@
|
||||||
#!/usr/bin/env php
|
|
||||||
<?php
|
|
||||||
|
|
||||||
$root = dirname(dirname(dirname(__FILE__)));
|
|
||||||
require_once $root.'/scripts/__init_script__.php';
|
|
||||||
|
|
||||||
$commit = new PhabricatorRepositoryCommit();
|
|
||||||
|
|
||||||
$conn_w = id(new PhabricatorRepository())->establishConnection('w');
|
|
||||||
$sizes = queryfx_all(
|
|
||||||
$conn_w,
|
|
||||||
'SELECT repositoryID, count(*) N FROM %T GROUP BY repositoryID',
|
|
||||||
$commit->getTableName());
|
|
||||||
$sizes = ipull($sizes, 'N', 'repositoryID');
|
|
||||||
|
|
||||||
$maxes = queryfx_all(
|
|
||||||
$conn_w,
|
|
||||||
'SELECT repositoryID, max(epoch) maxEpoch FROM %T GROUP BY repositoryID',
|
|
||||||
$commit->getTableName());
|
|
||||||
$maxes = ipull($maxes, 'maxEpoch', 'repositoryID');
|
|
||||||
|
|
||||||
|
|
||||||
$repository_ids = array_keys($sizes + $maxes);
|
|
||||||
|
|
||||||
echo pht('Updating %d repositories', count($repository_ids));
|
|
||||||
|
|
||||||
foreach ($repository_ids as $repository_id) {
|
|
||||||
$last_commit = queryfx_one(
|
|
||||||
$conn_w,
|
|
||||||
'SELECT id FROM %T WHERE repositoryID = %d AND epoch = %d LIMIT 1',
|
|
||||||
$commit->getTableName(),
|
|
||||||
$repository_id,
|
|
||||||
idx($maxes, $repository_id, 0));
|
|
||||||
if ($last_commit) {
|
|
||||||
$last_commit = $last_commit['id'];
|
|
||||||
} else {
|
|
||||||
$last_commit = 0;
|
|
||||||
}
|
|
||||||
queryfx(
|
|
||||||
$conn_w,
|
|
||||||
'INSERT INTO %T (repositoryID, lastCommitID, size, epoch)
|
|
||||||
VALUES (%d, %d, %d, %d) ON DUPLICATE KEY UPDATE
|
|
||||||
lastCommitID = VALUES(lastCommitID),
|
|
||||||
size = VALUES(size),
|
|
||||||
epoch = VALUES(epoch)',
|
|
||||||
PhabricatorRepository::TABLE_SUMMARY,
|
|
||||||
$repository_id,
|
|
||||||
$last_commit,
|
|
||||||
idx($sizes, $repository_id, 0),
|
|
||||||
idx($maxes, $repository_id, 0));
|
|
||||||
echo '.';
|
|
||||||
}
|
|
||||||
echo "\n".pht('Done.')."\n";
|
|
|
@ -313,6 +313,7 @@ phutil_register_library_map(array(
|
||||||
'ConduitCallTestCase' => 'applications/conduit/call/__tests__/ConduitCallTestCase.php',
|
'ConduitCallTestCase' => 'applications/conduit/call/__tests__/ConduitCallTestCase.php',
|
||||||
'ConduitColumnsParameterType' => 'applications/conduit/parametertype/ConduitColumnsParameterType.php',
|
'ConduitColumnsParameterType' => 'applications/conduit/parametertype/ConduitColumnsParameterType.php',
|
||||||
'ConduitConnectConduitAPIMethod' => 'applications/conduit/method/ConduitConnectConduitAPIMethod.php',
|
'ConduitConnectConduitAPIMethod' => 'applications/conduit/method/ConduitConnectConduitAPIMethod.php',
|
||||||
|
'ConduitConstantDescription' => 'applications/conduit/data/ConduitConstantDescription.php',
|
||||||
'ConduitEpochParameterType' => 'applications/conduit/parametertype/ConduitEpochParameterType.php',
|
'ConduitEpochParameterType' => 'applications/conduit/parametertype/ConduitEpochParameterType.php',
|
||||||
'ConduitException' => 'applications/conduit/protocol/exception/ConduitException.php',
|
'ConduitException' => 'applications/conduit/protocol/exception/ConduitException.php',
|
||||||
'ConduitGetCapabilitiesConduitAPIMethod' => 'applications/conduit/method/ConduitGetCapabilitiesConduitAPIMethod.php',
|
'ConduitGetCapabilitiesConduitAPIMethod' => 'applications/conduit/method/ConduitGetCapabilitiesConduitAPIMethod.php',
|
||||||
|
@ -5628,6 +5629,7 @@ phutil_register_library_map(array(
|
||||||
'ConduitCallTestCase' => 'PhabricatorTestCase',
|
'ConduitCallTestCase' => 'PhabricatorTestCase',
|
||||||
'ConduitColumnsParameterType' => 'ConduitParameterType',
|
'ConduitColumnsParameterType' => 'ConduitParameterType',
|
||||||
'ConduitConnectConduitAPIMethod' => 'ConduitAPIMethod',
|
'ConduitConnectConduitAPIMethod' => 'ConduitAPIMethod',
|
||||||
|
'ConduitConstantDescription' => 'Phobject',
|
||||||
'ConduitEpochParameterType' => 'ConduitParameterType',
|
'ConduitEpochParameterType' => 'ConduitParameterType',
|
||||||
'ConduitException' => 'Exception',
|
'ConduitException' => 'Exception',
|
||||||
'ConduitGetCapabilitiesConduitAPIMethod' => 'ConduitAPIMethod',
|
'ConduitGetCapabilitiesConduitAPIMethod' => 'ConduitAPIMethod',
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
final class PhabricatorAuditCommitStatusConstants extends Phobject {
|
final class PhabricatorAuditCommitStatusConstants extends Phobject {
|
||||||
|
|
||||||
|
private $key;
|
||||||
|
private $spec = array();
|
||||||
|
|
||||||
const NONE = 0;
|
const NONE = 0;
|
||||||
const NEEDS_AUDIT = 1;
|
const NEEDS_AUDIT = 1;
|
||||||
const CONCERN_RAISED = 2;
|
const CONCERN_RAISED = 2;
|
||||||
|
@ -9,17 +12,57 @@ final class PhabricatorAuditCommitStatusConstants extends Phobject {
|
||||||
const FULLY_AUDITED = 4;
|
const FULLY_AUDITED = 4;
|
||||||
const NEEDS_VERIFICATION = 5;
|
const NEEDS_VERIFICATION = 5;
|
||||||
|
|
||||||
public static function getStatusNameMap() {
|
const MODERN_NONE = 'none';
|
||||||
$map = array(
|
const MODERN_NEEDS_AUDIT = 'needs-audit';
|
||||||
self::NONE => pht('No Audits'),
|
const MODERN_CONCERN_RAISED = 'concern-raised';
|
||||||
self::NEEDS_AUDIT => pht('Audit Required'),
|
const MODERN_PARTIALLY_AUDITED = 'partially-audited';
|
||||||
self::CONCERN_RAISED => pht('Concern Raised'),
|
const MODERN_AUDITED = 'audited';
|
||||||
self::NEEDS_VERIFICATION => pht('Needs Verification'),
|
const MODERN_NEEDS_VERIFICATION = 'needs-verification';
|
||||||
self::PARTIALLY_AUDITED => pht('Partially Audited'),
|
|
||||||
self::FULLY_AUDITED => pht('Audited'),
|
|
||||||
);
|
|
||||||
|
|
||||||
return $map;
|
public static function newForLegacyStatus($status) {
|
||||||
|
$map = self::getMap();
|
||||||
|
|
||||||
|
foreach ($map as $key => $spec) {
|
||||||
|
if (idx($spec, 'legacy') == $status) {
|
||||||
|
return self::newForStatus($key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::newForStatus($status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function newForStatus($status) {
|
||||||
|
$result = new self();
|
||||||
|
|
||||||
|
$result->key = $status;
|
||||||
|
|
||||||
|
$map = self::getMap();
|
||||||
|
if (isset($map[$status])) {
|
||||||
|
$result->spec = $map[$status];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getKey() {
|
||||||
|
return $this->key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIcon() {
|
||||||
|
return idx($this->spec, 'icon');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getColor() {
|
||||||
|
return idx($this->spec, 'color');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName() {
|
||||||
|
return idx($this->spec, 'name', pht('Unknown ("%s")', $this->key));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getStatusNameMap() {
|
||||||
|
$map = self::getMap();
|
||||||
|
return ipull($map, 'name', 'legacy');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getStatusName($code) {
|
public static function getStatusName($code) {
|
||||||
|
@ -27,66 +70,71 @@ final class PhabricatorAuditCommitStatusConstants extends Phobject {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getOpenStatusConstants() {
|
public static function getOpenStatusConstants() {
|
||||||
return array(
|
$constants = array();
|
||||||
self::CONCERN_RAISED,
|
foreach (self::getMap() as $map) {
|
||||||
self::NEEDS_AUDIT,
|
if (!$map['closed']) {
|
||||||
self::NEEDS_VERIFICATION,
|
$constants[] = $map['legacy'];
|
||||||
self::PARTIALLY_AUDITED,
|
}
|
||||||
);
|
}
|
||||||
|
return $constants;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getStatusColor($code) {
|
public static function getStatusColor($code) {
|
||||||
switch ($code) {
|
$map = self::getMap();
|
||||||
case self::CONCERN_RAISED:
|
$map = ipull($map, 'color', 'legacy');
|
||||||
$color = 'red';
|
return idx($map, $code);
|
||||||
break;
|
|
||||||
case self::NEEDS_AUDIT:
|
|
||||||
$color = 'orange';
|
|
||||||
break;
|
|
||||||
case self::PARTIALLY_AUDITED:
|
|
||||||
$color = 'yellow';
|
|
||||||
break;
|
|
||||||
case self::FULLY_AUDITED:
|
|
||||||
$color = 'green';
|
|
||||||
break;
|
|
||||||
case self::NONE:
|
|
||||||
$color = 'bluegrey';
|
|
||||||
break;
|
|
||||||
case self::NEEDS_VERIFICATION:
|
|
||||||
$color = 'indigo';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$color = null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return $color;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getStatusIcon($code) {
|
public static function getStatusIcon($code) {
|
||||||
switch ($code) {
|
$map = self::getMap();
|
||||||
case self::CONCERN_RAISED:
|
$map = ipull($map, 'icon', 'legacy');
|
||||||
$icon = 'fa-times-circle';
|
return idx($map, $code);
|
||||||
break;
|
|
||||||
case self::NEEDS_AUDIT:
|
|
||||||
$icon = 'fa-exclamation-circle';
|
|
||||||
break;
|
|
||||||
case self::PARTIALLY_AUDITED:
|
|
||||||
$icon = 'fa-check-circle-o';
|
|
||||||
break;
|
|
||||||
case self::FULLY_AUDITED:
|
|
||||||
$icon = 'fa-check-circle';
|
|
||||||
break;
|
|
||||||
case self::NONE:
|
|
||||||
$icon = 'fa-check';
|
|
||||||
break;
|
|
||||||
case self::NEEDS_VERIFICATION:
|
|
||||||
$icon = 'fa-refresh';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$icon = null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return $icon;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static function getMap() {
|
||||||
|
return array(
|
||||||
|
self::MODERN_NONE => array(
|
||||||
|
'name' => pht('No Audits'),
|
||||||
|
'legacy' => self::NONE,
|
||||||
|
'icon' => 'fa-check',
|
||||||
|
'color' => 'bluegrey',
|
||||||
|
'closed' => true,
|
||||||
|
),
|
||||||
|
self::MODERN_NEEDS_AUDIT => array(
|
||||||
|
'name' => pht('Audit Required'),
|
||||||
|
'legacy' => self::NEEDS_AUDIT,
|
||||||
|
'icon' => 'fa-exclamation-circle',
|
||||||
|
'color' => 'orange',
|
||||||
|
'closed' => false,
|
||||||
|
),
|
||||||
|
self::MODERN_CONCERN_RAISED => array(
|
||||||
|
'name' => pht('Concern Raised'),
|
||||||
|
'legacy' => self::CONCERN_RAISED,
|
||||||
|
'icon' => 'fa-times-circle',
|
||||||
|
'color' => 'red',
|
||||||
|
'closed' => false,
|
||||||
|
),
|
||||||
|
self::MODERN_PARTIALLY_AUDITED => array(
|
||||||
|
'name' => pht('Partially Audited'),
|
||||||
|
'legacy' => self::PARTIALLY_AUDITED,
|
||||||
|
'icon' => 'fa-check-circle-o',
|
||||||
|
'color' => 'yellow',
|
||||||
|
'closed' => false,
|
||||||
|
),
|
||||||
|
self::MODERN_AUDITED => array(
|
||||||
|
'name' => pht('Audited'),
|
||||||
|
'legacy' => self::FULLY_AUDITED,
|
||||||
|
'icon' => 'fa-check-circle',
|
||||||
|
'color' => 'green',
|
||||||
|
'closed' => true,
|
||||||
|
),
|
||||||
|
self::MODERN_NEEDS_VERIFICATION => array(
|
||||||
|
'name' => pht('Needs Verification'),
|
||||||
|
'legacy' => self::NEEDS_VERIFICATION,
|
||||||
|
'icon' => 'fa-refresh',
|
||||||
|
'color' => 'indigo',
|
||||||
|
'closed' => false,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -258,19 +258,31 @@ final class PhabricatorAuditEditor
|
||||||
$this->didExpandInlineState = true;
|
$this->didExpandInlineState = true;
|
||||||
|
|
||||||
$actor_phid = $this->getActingAsPHID();
|
$actor_phid = $this->getActingAsPHID();
|
||||||
$actor_is_author = ($object->getAuthorPHID() == $actor_phid);
|
$author_phid = $object->getAuthorPHID();
|
||||||
if (!$actor_is_author) {
|
$actor_is_author = ($actor_phid == $author_phid);
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$state_map = PhabricatorTransactions::getInlineStateMap();
|
$state_map = PhabricatorTransactions::getInlineStateMap();
|
||||||
|
|
||||||
$inlines = id(new DiffusionDiffInlineCommentQuery())
|
$query = id(new DiffusionDiffInlineCommentQuery())
|
||||||
->setViewer($this->getActor())
|
->setViewer($this->getActor())
|
||||||
->withCommitPHIDs(array($object->getPHID()))
|
->withCommitPHIDs(array($object->getPHID()))
|
||||||
->withFixedStates(array_keys($state_map))
|
->withFixedStates(array_keys($state_map));
|
||||||
|
|
||||||
|
$inlines = array();
|
||||||
|
|
||||||
|
$inlines[] = id(clone $query)
|
||||||
|
->withAuthorPHIDs(array($actor_phid))
|
||||||
|
->withHasTransaction(false)
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
|
if ($actor_is_author) {
|
||||||
|
$inlines[] = id(clone $query)
|
||||||
|
->withHasTransaciton(true)
|
||||||
|
->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
$inlines = array_mergev($inlines);
|
||||||
|
|
||||||
if (!$inlines) {
|
if (!$inlines) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,11 +30,11 @@ final class PhabricatorAuditSynchronizeManagementWorkflow
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$old_status = $commit->getAuditStatus();
|
$old_status = $commit->getAuditStatusObject();
|
||||||
$commit->updateAuditStatus($commit->getAudits());
|
$commit->updateAuditStatus($commit->getAudits());
|
||||||
$new_status = $commit->getAuditStatus();
|
$new_status = $commit->getAuditStatusObject();
|
||||||
|
|
||||||
if ($old_status == $new_status) {
|
if ($old_status->getKey() == $new_status->getKey()) {
|
||||||
echo tsprintf(
|
echo tsprintf(
|
||||||
"%s\n",
|
"%s\n",
|
||||||
pht(
|
pht(
|
||||||
|
@ -46,10 +46,8 @@ final class PhabricatorAuditSynchronizeManagementWorkflow
|
||||||
pht(
|
pht(
|
||||||
'Updating "%s": "%s" -> "%s".',
|
'Updating "%s": "%s" -> "%s".',
|
||||||
$commit->getDisplayName(),
|
$commit->getDisplayName(),
|
||||||
PhabricatorAuditCommitStatusConstants::getStatusName(
|
$old_status->getName(),
|
||||||
$old_status),
|
$new_status->getName()));
|
||||||
PhabricatorAuditCommitStatusConstants::getStatusName(
|
|
||||||
$new_status)));
|
|
||||||
|
|
||||||
$commit->save();
|
$commit->save();
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,35 +67,48 @@ final class PhabricatorCommitSearchEngine
|
||||||
->setKey('responsiblePHIDs')
|
->setKey('responsiblePHIDs')
|
||||||
->setConduitKey('responsible')
|
->setConduitKey('responsible')
|
||||||
->setAliases(array('responsible', 'responsibles', 'responsiblePHID'))
|
->setAliases(array('responsible', 'responsibles', 'responsiblePHID'))
|
||||||
->setDatasource(new DifferentialResponsibleDatasource()),
|
->setDatasource(new DifferentialResponsibleDatasource())
|
||||||
|
->setDescription(
|
||||||
|
pht(
|
||||||
|
'Find commits where given users, projects, or packages are '.
|
||||||
|
'responsible for the next steps in the audit workflow.')),
|
||||||
id(new PhabricatorUsersSearchField())
|
id(new PhabricatorUsersSearchField())
|
||||||
->setLabel(pht('Authors'))
|
->setLabel(pht('Authors'))
|
||||||
->setKey('authorPHIDs')
|
->setKey('authorPHIDs')
|
||||||
->setConduitKey('authors')
|
->setConduitKey('authors')
|
||||||
->setAliases(array('author', 'authors', 'authorPHID')),
|
->setAliases(array('author', 'authors', 'authorPHID'))
|
||||||
|
->setDescription(pht('Find commits authored by particular users.')),
|
||||||
id(new PhabricatorSearchDatasourceField())
|
id(new PhabricatorSearchDatasourceField())
|
||||||
->setLabel(pht('Auditors'))
|
->setLabel(pht('Auditors'))
|
||||||
->setKey('auditorPHIDs')
|
->setKey('auditorPHIDs')
|
||||||
->setConduitKey('auditors')
|
->setConduitKey('auditors')
|
||||||
->setAliases(array('auditor', 'auditors', 'auditorPHID'))
|
->setAliases(array('auditor', 'auditors', 'auditorPHID'))
|
||||||
->setDatasource(new DiffusionAuditorFunctionDatasource()),
|
->setDatasource(new DiffusionAuditorFunctionDatasource())
|
||||||
|
->setDescription(
|
||||||
|
pht(
|
||||||
|
'Find commits where given users, projects, or packages are '.
|
||||||
|
'auditors.')),
|
||||||
id(new PhabricatorSearchCheckboxesField())
|
id(new PhabricatorSearchCheckboxesField())
|
||||||
->setLabel(pht('Audit Status'))
|
->setLabel(pht('Audit Status'))
|
||||||
->setKey('statuses')
|
->setKey('statuses')
|
||||||
->setAliases(array('status'))
|
->setAliases(array('status'))
|
||||||
->setOptions(PhabricatorAuditCommitStatusConstants::getStatusNameMap()),
|
->setOptions(PhabricatorAuditCommitStatusConstants::getStatusNameMap())
|
||||||
|
->setDescription(pht('Find commits with given audit statuses.')),
|
||||||
id(new PhabricatorSearchDatasourceField())
|
id(new PhabricatorSearchDatasourceField())
|
||||||
->setLabel(pht('Repositories'))
|
->setLabel(pht('Repositories'))
|
||||||
->setKey('repositoryPHIDs')
|
->setKey('repositoryPHIDs')
|
||||||
->setConduitKey('repositories')
|
->setConduitKey('repositories')
|
||||||
->setAliases(array('repository', 'repositories', 'repositoryPHID'))
|
->setAliases(array('repository', 'repositories', 'repositoryPHID'))
|
||||||
->setDatasource(new DiffusionRepositoryFunctionDatasource()),
|
->setDatasource(new DiffusionRepositoryFunctionDatasource())
|
||||||
|
->setDescription(pht('Find commits in particular repositories.')),
|
||||||
id(new PhabricatorSearchDatasourceField())
|
id(new PhabricatorSearchDatasourceField())
|
||||||
->setLabel(pht('Packages'))
|
->setLabel(pht('Packages'))
|
||||||
->setKey('packagePHIDs')
|
->setKey('packagePHIDs')
|
||||||
->setConduitKey('packages')
|
->setConduitKey('packages')
|
||||||
->setAliases(array('package', 'packages', 'packagePHID'))
|
->setAliases(array('package', 'packages', 'packagePHID'))
|
||||||
->setDatasource(new PhabricatorOwnersPackageDatasource()),
|
->setDatasource(new PhabricatorOwnersPackageDatasource())
|
||||||
|
->setDescription(
|
||||||
|
pht('Find commits which affect given packages.')),
|
||||||
id(new PhabricatorSearchThreeStateField())
|
id(new PhabricatorSearchThreeStateField())
|
||||||
->setLabel(pht('Unreachable'))
|
->setLabel(pht('Unreachable'))
|
||||||
->setKey('unreachable')
|
->setKey('unreachable')
|
||||||
|
|
|
@ -120,14 +120,11 @@ final class PhabricatorAuditListView extends AphrontView {
|
||||||
$commit_desc = $this->getCommitDescription($commit_phid);
|
$commit_desc = $this->getCommitDescription($commit_phid);
|
||||||
$committed = phabricator_datetime($commit->getEpoch(), $viewer);
|
$committed = phabricator_datetime($commit->getEpoch(), $viewer);
|
||||||
|
|
||||||
$status = $commit->getAuditStatus();
|
$status = $commit->getAuditStatusObject();
|
||||||
|
|
||||||
$status_text =
|
$status_text = $status->getName();
|
||||||
PhabricatorAuditCommitStatusConstants::getStatusName($status);
|
$status_color = $status->getColor();
|
||||||
$status_color =
|
$status_icon = $status->getIcon();
|
||||||
PhabricatorAuditCommitStatusConstants::getStatusColor($status);
|
|
||||||
$status_icon =
|
|
||||||
PhabricatorAuditCommitStatusConstants::getStatusIcon($status);
|
|
||||||
|
|
||||||
$author_phid = $commit->getAuthorPHID();
|
$author_phid = $commit->getAuthorPHID();
|
||||||
if ($author_phid) {
|
if ($author_phid) {
|
||||||
|
|
26
src/applications/conduit/data/ConduitConstantDescription.php
Normal file
26
src/applications/conduit/data/ConduitConstantDescription.php
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class ConduitConstantDescription extends Phobject {
|
||||||
|
|
||||||
|
private $key;
|
||||||
|
private $value;
|
||||||
|
|
||||||
|
public function setKey($key) {
|
||||||
|
$this->key = $key;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getKey() {
|
||||||
|
return $this->key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setValue($value) {
|
||||||
|
$this->value = $value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValue() {
|
||||||
|
return $this->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -77,19 +77,17 @@ final class DifferentialInlineCommentEditController
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function loadCommentForEdit($id) {
|
protected function loadCommentForEdit($id) {
|
||||||
$request = $this->getRequest();
|
$viewer = $this->getViewer();
|
||||||
$user = $request->getUser();
|
|
||||||
|
|
||||||
$inline = $this->loadComment($id);
|
$inline = $this->loadComment($id);
|
||||||
if (!$this->canEditInlineComment($user, $inline)) {
|
if (!$this->canEditInlineComment($viewer, $inline)) {
|
||||||
throw new Exception(pht('That comment is not editable!'));
|
throw new Exception(pht('That comment is not editable!'));
|
||||||
}
|
}
|
||||||
return $inline;
|
return $inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function loadCommentForDone($id) {
|
protected function loadCommentForDone($id) {
|
||||||
$request = $this->getRequest();
|
$viewer = $this->getViewer();
|
||||||
$viewer = $request->getUser();
|
|
||||||
|
|
||||||
$inline = $this->loadComment($id);
|
$inline = $this->loadComment($id);
|
||||||
if (!$inline) {
|
if (!$inline) {
|
||||||
|
@ -120,19 +118,32 @@ final class DifferentialInlineCommentEditController
|
||||||
throw new Exception(pht('Unable to load revision.'));
|
throw new Exception(pht('Unable to load revision.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($revision->getAuthorPHID() !== $viewer->getPHID()) {
|
$viewer_phid = $viewer->getPHID();
|
||||||
throw new Exception(pht('You are not the revision owner.'));
|
$is_owner = ($viewer_phid == $revision->getAuthorPHID());
|
||||||
|
$is_author = ($viewer_phid == $inline->getAuthorPHID());
|
||||||
|
$is_draft = ($inline->isDraft());
|
||||||
|
|
||||||
|
if ($is_owner) {
|
||||||
|
// You own the revision, so you can mark the comment as "Done".
|
||||||
|
} else if ($is_author && $is_draft) {
|
||||||
|
// You made this comment and it's still a draft, so you can mark
|
||||||
|
// it as "Done".
|
||||||
|
} else {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'You are not the revision owner, and this is not a draft comment '.
|
||||||
|
'you authored.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $inline;
|
return $inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function canEditInlineComment(
|
private function canEditInlineComment(
|
||||||
PhabricatorUser $user,
|
PhabricatorUser $viewer,
|
||||||
DifferentialInlineComment $inline) {
|
DifferentialInlineComment $inline) {
|
||||||
|
|
||||||
// Only the author may edit a comment.
|
// Only the author may edit a comment.
|
||||||
if ($inline->getAuthorPHID() != $user->getPHID()) {
|
if ($inline->getAuthorPHID() != $viewer->getPHID()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -248,19 +248,34 @@ final class DifferentialTransactionEditor
|
||||||
$this->didExpandInlineState = true;
|
$this->didExpandInlineState = true;
|
||||||
|
|
||||||
$actor_phid = $this->getActingAsPHID();
|
$actor_phid = $this->getActingAsPHID();
|
||||||
$actor_is_author = ($object->getAuthorPHID() == $actor_phid);
|
$author_phid = $object->getAuthorPHID();
|
||||||
if (!$actor_is_author) {
|
$actor_is_author = ($actor_phid == $author_phid);
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$state_map = PhabricatorTransactions::getInlineStateMap();
|
$state_map = PhabricatorTransactions::getInlineStateMap();
|
||||||
|
|
||||||
$inlines = id(new DifferentialDiffInlineCommentQuery())
|
$query = id(new DifferentialDiffInlineCommentQuery())
|
||||||
->setViewer($this->getActor())
|
->setViewer($this->getActor())
|
||||||
->withRevisionPHIDs(array($object->getPHID()))
|
->withRevisionPHIDs(array($object->getPHID()))
|
||||||
->withFixedStates(array_keys($state_map))
|
->withFixedStates(array_keys($state_map));
|
||||||
|
|
||||||
|
$inlines = array();
|
||||||
|
|
||||||
|
// We're going to undraft any "done" marks on your own inlines.
|
||||||
|
$inlines[] = id(clone $query)
|
||||||
|
->withAuthorPHIDs(array($actor_phid))
|
||||||
|
->withHasTransaction(false)
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
|
// If you're the author, we also undraft any "done" marks on other
|
||||||
|
// inlines.
|
||||||
|
if ($actor_is_author) {
|
||||||
|
$inlines[] = id(clone $query)
|
||||||
|
->withHasTransaction(true)
|
||||||
|
->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
$inlines = array_mergev($inlines);
|
||||||
|
|
||||||
if (!$inlines) {
|
if (!$inlines) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -892,6 +907,17 @@ final class DifferentialTransactionEditor
|
||||||
array $inlines,
|
array $inlines,
|
||||||
PhabricatorMetaMTAMailBody $body) {
|
PhabricatorMetaMTAMailBody $body) {
|
||||||
|
|
||||||
|
$limit = 100;
|
||||||
|
$limit_note = null;
|
||||||
|
if (count($inlines) > $limit) {
|
||||||
|
$limit_note = pht(
|
||||||
|
'(Showing first %s of %s inline comments.)',
|
||||||
|
new PhutilNumber($limit),
|
||||||
|
phutil_count($inlines));
|
||||||
|
|
||||||
|
$inlines = array_slice($inlines, 0, $limit, true);
|
||||||
|
}
|
||||||
|
|
||||||
$section = id(new DifferentialInlineCommentMailView())
|
$section = id(new DifferentialInlineCommentMailView())
|
||||||
->setViewer($this->getActor())
|
->setViewer($this->getActor())
|
||||||
->setInlines($inlines)
|
->setInlines($inlines)
|
||||||
|
@ -900,6 +926,9 @@ final class DifferentialTransactionEditor
|
||||||
$header = pht('INLINE COMMENTS');
|
$header = pht('INLINE COMMENTS');
|
||||||
|
|
||||||
$section_text = "\n".$section->getPlaintext();
|
$section_text = "\n".$section->getPlaintext();
|
||||||
|
if ($limit_note) {
|
||||||
|
$section_text = $limit_note."\n".$section_text;
|
||||||
|
}
|
||||||
|
|
||||||
$style = array(
|
$style = array(
|
||||||
'margin: 6px 0 12px 0;',
|
'margin: 6px 0 12px 0;',
|
||||||
|
@ -912,6 +941,16 @@ final class DifferentialTransactionEditor
|
||||||
),
|
),
|
||||||
$section->getHTML());
|
$section->getHTML());
|
||||||
|
|
||||||
|
if ($limit_note) {
|
||||||
|
$section_html = array(
|
||||||
|
phutil_tag(
|
||||||
|
'em',
|
||||||
|
array(),
|
||||||
|
$limit_note),
|
||||||
|
$section_html,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
$body->addPlaintextSection($header, $section_text, false);
|
$body->addPlaintextSection($header, $section_text, false);
|
||||||
$body->addHTMLSection($header, $section_html);
|
$body->addHTMLSection($header, $section_html);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1152,6 +1152,20 @@ final class DifferentialRevision extends DifferentialDAO
|
||||||
->setKey('testPlan')
|
->setKey('testPlan')
|
||||||
->setType('string')
|
->setType('string')
|
||||||
->setDescription(pht('Revision test plan.')),
|
->setDescription(pht('Revision test plan.')),
|
||||||
|
id(new PhabricatorConduitSearchFieldSpecification())
|
||||||
|
->setKey('isDraft')
|
||||||
|
->setType('bool')
|
||||||
|
->setDescription(
|
||||||
|
pht(
|
||||||
|
'True if this revision is in any draft state, and thus not '.
|
||||||
|
'notifying reviewers and subscribers about changes.')),
|
||||||
|
id(new PhabricatorConduitSearchFieldSpecification())
|
||||||
|
->setKey('holdAsDraft')
|
||||||
|
->setType('bool')
|
||||||
|
->setDescription(
|
||||||
|
pht(
|
||||||
|
'True if this revision is being held as a draft. It will not be '.
|
||||||
|
'automatically submitted for review even if tests pass.')),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1172,6 +1186,8 @@ final class DifferentialRevision extends DifferentialDAO
|
||||||
'diffPHID' => $this->getActiveDiffPHID(),
|
'diffPHID' => $this->getActiveDiffPHID(),
|
||||||
'summary' => $this->getSummary(),
|
'summary' => $this->getSummary(),
|
||||||
'testPlan' => $this->getTestPlan(),
|
'testPlan' => $this->getTestPlan(),
|
||||||
|
'isDraft' => !$this->getShouldBroadcast(),
|
||||||
|
'holdAsDraft' => (bool)$this->getHoldAsDraft(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,19 +50,17 @@ final class DiffusionInlineCommentController
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function loadCommentForEdit($id) {
|
protected function loadCommentForEdit($id) {
|
||||||
$request = $this->getRequest();
|
$viewer = $this->getViewer();
|
||||||
$user = $request->getUser();
|
|
||||||
|
|
||||||
$inline = $this->loadComment($id);
|
$inline = $this->loadComment($id);
|
||||||
if (!$this->canEditInlineComment($user, $inline)) {
|
if (!$this->canEditInlineComment($viewer, $inline)) {
|
||||||
throw new Exception(pht('That comment is not editable!'));
|
throw new Exception(pht('That comment is not editable!'));
|
||||||
}
|
}
|
||||||
return $inline;
|
return $inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function loadCommentForDone($id) {
|
protected function loadCommentForDone($id) {
|
||||||
$request = $this->getRequest();
|
$viewer = $this->getViewer();
|
||||||
$viewer = $request->getUser();
|
|
||||||
|
|
||||||
$inline = $this->loadComment($id);
|
$inline = $this->loadComment($id);
|
||||||
if (!$inline) {
|
if (!$inline) {
|
||||||
|
@ -77,20 +75,32 @@ final class DiffusionInlineCommentController
|
||||||
throw new Exception(pht('Failed to load commit.'));
|
throw new Exception(pht('Failed to load commit.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!$commit->getAuthorPHID()) ||
|
$owner_phid = $commit->getAuthorPHID();
|
||||||
($commit->getAuthorPHID() != $viewer->getPHID())) {
|
$viewer_phid = $viewer->getPHID();
|
||||||
throw new Exception(pht('You can not mark this comment as complete.'));
|
$viewer_is_owner = ($owner_phid && ($owner_phid == $viewer_phid));
|
||||||
|
$viewer_is_author = ($viewer_phid == $inline->getAuthorPHID());
|
||||||
|
$is_draft = $inline->isDraft();
|
||||||
|
|
||||||
|
if ($viewer_is_owner) {
|
||||||
|
// You can mark inlines on your own commits as "Done".
|
||||||
|
} else if ($viewer_is_author && $is_draft) {
|
||||||
|
// You can mark your own unsubmitted inlines as "Done".
|
||||||
|
} else {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'You can not mark this comment as complete: you did not author '.
|
||||||
|
'the commit and the comment is not a draft you wrote.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $inline;
|
return $inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function canEditInlineComment(
|
private function canEditInlineComment(
|
||||||
PhabricatorUser $user,
|
PhabricatorUser $viewer,
|
||||||
PhabricatorAuditInlineComment $inline) {
|
PhabricatorAuditInlineComment $inline) {
|
||||||
|
|
||||||
// Only the author may edit a comment.
|
// Only the author may edit a comment.
|
||||||
if ($inline->getAuthorPHID() != $user->getPHID()) {
|
if ($inline->getAuthorPHID() != $viewer->getPHID()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -114,10 +114,10 @@ final class DiffusionHistoryTableView extends DiffusionHistoryView {
|
||||||
'type' => $history->getFileType(),
|
'type' => $history->getFileType(),
|
||||||
));
|
));
|
||||||
|
|
||||||
$status = $commit->getAuditStatus();
|
$status = $commit->getAuditStatusObject();
|
||||||
$icon = PhabricatorAuditCommitStatusConstants::getStatusIcon($status);
|
$icon = $status->getIcon();
|
||||||
$color = PhabricatorAuditCommitStatusConstants::getStatusColor($status);
|
$color = $status->getColor();
|
||||||
$name = PhabricatorAuditCommitStatusConstants::getStatusName($status);
|
$name = $status->getName();
|
||||||
|
|
||||||
$audit_view = id(new PHUIIconView())
|
$audit_view = id(new PHUIIconView())
|
||||||
->setIcon($icon, $color)
|
->setIcon($icon, $color)
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
abstract class DrydockRepositoryOperationType extends Phobject {
|
abstract class DrydockRepositoryOperationType extends Phobject {
|
||||||
|
|
||||||
private $viewer;
|
private $viewer;
|
||||||
|
private $operation;
|
||||||
|
private $interface;
|
||||||
|
|
||||||
abstract public function applyOperation(
|
abstract public function applyOperation(
|
||||||
DrydockRepositoryOperation $operation,
|
DrydockRepositoryOperation $operation,
|
||||||
|
@ -29,6 +31,27 @@ abstract class DrydockRepositoryOperationType extends Phobject {
|
||||||
return $this->viewer;
|
return $this->viewer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final public function setOperation(DrydockRepositoryOperation $operation) {
|
||||||
|
$this->operation = $operation;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function getOperation() {
|
||||||
|
return $this->operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function setInterface(DrydockInterface $interface) {
|
||||||
|
$this->interface = $interface;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function getInterface() {
|
||||||
|
if (!$this->interface) {
|
||||||
|
throw new PhutilInvalidStateException('setInterface');
|
||||||
|
}
|
||||||
|
return $this->interface;
|
||||||
|
}
|
||||||
|
|
||||||
final public function getOperationConstant() {
|
final public function getOperationConstant() {
|
||||||
return $this->getPhobjectClassConstant('OPCONST', 32);
|
return $this->getPhobjectClassConstant('OPCONST', 32);
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,8 @@ final class DrydockRepositoryOperationQuery extends DrydockQuery {
|
||||||
protected function willFilterPage(array $operations) {
|
protected function willFilterPage(array $operations) {
|
||||||
$implementations = DrydockRepositoryOperationType::getAllOperationTypes();
|
$implementations = DrydockRepositoryOperationType::getAllOperationTypes();
|
||||||
|
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
foreach ($operations as $key => $operation) {
|
foreach ($operations as $key => $operation) {
|
||||||
$impl = idx($implementations, $operation->getOperationType());
|
$impl = idx($implementations, $operation->getOperationType());
|
||||||
if (!$impl) {
|
if (!$impl) {
|
||||||
|
@ -69,7 +71,10 @@ final class DrydockRepositoryOperationQuery extends DrydockQuery {
|
||||||
unset($operations[$key]);
|
unset($operations[$key]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$impl = clone $impl;
|
$impl = id(clone $impl)
|
||||||
|
->setViewer($viewer)
|
||||||
|
->setOperation($operation);
|
||||||
|
|
||||||
$operation->attachImplementation($impl);
|
$operation->attachImplementation($impl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,9 +137,9 @@ final class DrydockRepositoryOperation extends DrydockDAO
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOperation(DrydockInterface $interface) {
|
public function applyOperation(DrydockInterface $interface) {
|
||||||
return $this->getImplementation()->applyOperation(
|
$impl = $this->getImplementation();
|
||||||
$this,
|
$impl->setInterface($interface);
|
||||||
$interface);
|
return $impl->applyOperation($this, $interface);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getOperationDescription(PhabricatorUser $viewer) {
|
public function getOperationDescription(PhabricatorUser $viewer) {
|
||||||
|
|
|
@ -25,8 +25,6 @@ final class DrydockRepositoryOperationUpdateWorker
|
||||||
|
|
||||||
|
|
||||||
private function handleUpdate(DrydockRepositoryOperation $operation) {
|
private function handleUpdate(DrydockRepositoryOperation $operation) {
|
||||||
$viewer = $this->getViewer();
|
|
||||||
|
|
||||||
$operation_state = $operation->getOperationState();
|
$operation_state = $operation->getOperationState();
|
||||||
|
|
||||||
switch ($operation_state) {
|
switch ($operation_state) {
|
||||||
|
@ -53,9 +51,6 @@ final class DrydockRepositoryOperationUpdateWorker
|
||||||
// waiting for a lease we're holding.
|
// waiting for a lease we're holding.
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$operation->getImplementation()
|
|
||||||
->setViewer($viewer);
|
|
||||||
|
|
||||||
$lease = $this->loadWorkingCopyLease($operation);
|
$lease = $this->loadWorkingCopyLease($operation);
|
||||||
|
|
||||||
$interface = $lease->getInterface(
|
$interface = $lease->getInterface(
|
||||||
|
|
|
@ -193,7 +193,7 @@ abstract class HarbormasterBuildStepImplementation extends Phobject {
|
||||||
* @return string String with variables replaced safely into it.
|
* @return string String with variables replaced safely into it.
|
||||||
*/
|
*/
|
||||||
protected function mergeVariables($function, $pattern, array $variables) {
|
protected function mergeVariables($function, $pattern, array $variables) {
|
||||||
$regexp = '@\\$\\{(?P<name>[a-z\\./-]+)\\}@';
|
$regexp = '@\\$\\{(?P<name>[a-z\\./_-]+)\\}@';
|
||||||
|
|
||||||
$matches = null;
|
$matches = null;
|
||||||
preg_match_all($regexp, $pattern, $matches);
|
preg_match_all($regexp, $pattern, $matches);
|
||||||
|
|
|
@ -82,10 +82,10 @@ final class PhabricatorRepositoryCommitPHIDType extends PhabricatorPHIDType {
|
||||||
$handle->setURI($commit->getURI());
|
$handle->setURI($commit->getURI());
|
||||||
$handle->setTimestamp($commit->getEpoch());
|
$handle->setTimestamp($commit->getEpoch());
|
||||||
|
|
||||||
$status = $commit->getAuditStatus();
|
$status = $commit->getAuditStatusObject();
|
||||||
$icon = PhabricatorAuditCommitStatusConstants::getStatusIcon($status);
|
$icon = $status->getIcon();
|
||||||
$color = PhabricatorAuditCommitStatusConstants::getStatusColor($status);
|
$color = $status->getColor();
|
||||||
$name = PhabricatorAuditCommitStatusConstants::getStatusName($status);
|
$name = $status->getName();
|
||||||
|
|
||||||
$handle
|
$handle
|
||||||
->setStateIcon($icon)
|
->setStateIcon($icon)
|
||||||
|
|
|
@ -530,6 +530,11 @@ final class PhabricatorRepositoryCommit
|
||||||
return $data->getCommitDetail('authorPHID');
|
return $data->getCommitDetail('authorPHID');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getAuditStatusObject() {
|
||||||
|
$status = $this->getAuditStatus();
|
||||||
|
return PhabricatorAuditCommitStatusConstants::newForLegacyStatus($status);
|
||||||
|
}
|
||||||
|
|
||||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||||
|
|
||||||
public function getCapabilities() {
|
public function getCapabilities() {
|
||||||
|
|
|
@ -161,7 +161,9 @@ If you specify both a `queryKey` and `constraints`, the builtin or saved query
|
||||||
will be applied first as a starting point, then any additional values in
|
will be applied first as a starting point, then any additional values in
|
||||||
`constraints` will be applied, overwriting the defaults from the original query.
|
`constraints` will be applied, overwriting the defaults from the original query.
|
||||||
|
|
||||||
Specify constraints like this:
|
Different endpoints support different constraints. The constraints this method
|
||||||
|
supports are detailed below. As an example, you might specify constraints like
|
||||||
|
this:
|
||||||
|
|
||||||
```lang=json, name="Example Custom Constraints"
|
```lang=json, name="Example Custom Constraints"
|
||||||
{
|
{
|
||||||
|
@ -188,15 +190,26 @@ EOTEXT
|
||||||
$fields,
|
$fields,
|
||||||
array('ids', 'phids')) + $fields;
|
array('ids', 'phids')) + $fields;
|
||||||
|
|
||||||
|
$constant_lists = array();
|
||||||
|
|
||||||
$rows = array();
|
$rows = array();
|
||||||
foreach ($fields as $field) {
|
foreach ($fields as $field) {
|
||||||
$key = $field->getConduitKey();
|
$key = $field->getConduitKey();
|
||||||
$label = $field->getLabel();
|
$label = $field->getLabel();
|
||||||
|
|
||||||
|
$constants = $field->newConduitConstants();
|
||||||
|
|
||||||
$type_object = $field->getConduitParameterType();
|
$type_object = $field->getConduitParameterType();
|
||||||
if ($type_object) {
|
if ($type_object) {
|
||||||
$type = $type_object->getTypeName();
|
$type = $type_object->getTypeName();
|
||||||
$description = $field->getDescription();
|
$description = $field->getDescription();
|
||||||
|
if ($constants) {
|
||||||
|
$description = array(
|
||||||
|
$description,
|
||||||
|
' ',
|
||||||
|
phutil_tag('em', array(), pht('(See table below.)')),
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$type = null;
|
$type = null;
|
||||||
$description = phutil_tag('em', array(), pht('Not supported.'));
|
$description = phutil_tag('em', array(), pht('Not supported.'));
|
||||||
|
@ -208,6 +221,35 @@ EOTEXT
|
||||||
$type,
|
$type,
|
||||||
$description,
|
$description,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if ($constants) {
|
||||||
|
$constant_lists[] = $this->buildRemarkup(
|
||||||
|
pht(
|
||||||
|
'Constants supported by the `%s` constraint:',
|
||||||
|
'statuses'));
|
||||||
|
|
||||||
|
$constants_rows = array();
|
||||||
|
foreach ($constants as $constant) {
|
||||||
|
$constants_rows[] = array(
|
||||||
|
$constant->getKey(),
|
||||||
|
$constant->getValue(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$constants_table = id(new AphrontTableView($constants_rows))
|
||||||
|
->setHeaders(
|
||||||
|
array(
|
||||||
|
pht('Key'),
|
||||||
|
pht('Value'),
|
||||||
|
))
|
||||||
|
->setColumnClasses(
|
||||||
|
array(
|
||||||
|
'pre',
|
||||||
|
'wide',
|
||||||
|
));
|
||||||
|
|
||||||
|
$constant_lists[] = $constants_table;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$table = id(new AphrontTableView($rows))
|
$table = id(new AphrontTableView($rows))
|
||||||
|
@ -231,7 +273,8 @@ EOTEXT
|
||||||
->setCollapsed(true)
|
->setCollapsed(true)
|
||||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->appendChild($this->buildRemarkup($info))
|
->appendChild($this->buildRemarkup($info))
|
||||||
->appendChild($table);
|
->appendChild($table)
|
||||||
|
->appendChild($constant_lists);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildOrderBox(
|
private function buildOrderBox(
|
||||||
|
|
|
@ -49,4 +49,16 @@ final class PhabricatorSearchCheckboxesField
|
||||||
return new ConduitStringListParameterType();
|
return new ConduitStringListParameterType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function newConduitConstants() {
|
||||||
|
$list = array();
|
||||||
|
|
||||||
|
foreach ($this->getOptions() as $key => $option) {
|
||||||
|
$list[] = id(new ConduitConstantDescription())
|
||||||
|
->setKey($key)
|
||||||
|
->setValue($option);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -382,6 +382,10 @@ abstract class PhabricatorSearchField extends Phobject {
|
||||||
return $this->enableForConduit;
|
return $this->enableForConduit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function newConduitConstants() {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -( Utility Methods )----------------------------------------------------- */
|
/* -( Utility Methods )----------------------------------------------------- */
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ abstract class PhabricatorInlineCommentController
|
||||||
|
|
||||||
public function processRequest() {
|
public function processRequest() {
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
$user = $request->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$this->readRequestParameters();
|
$this->readRequestParameters();
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@ abstract class PhabricatorInlineCommentController
|
||||||
|
|
||||||
$inline = $this->createComment()
|
$inline = $this->createComment()
|
||||||
->setChangesetID($this->getChangesetID())
|
->setChangesetID($this->getChangesetID())
|
||||||
->setAuthorPHID($user->getPHID())
|
->setAuthorPHID($viewer->getPHID())
|
||||||
->setLineNumber($this->getLineNumber())
|
->setLineNumber($this->getLineNumber())
|
||||||
->setLineLength($this->getLineLength())
|
->setLineLength($this->getLineLength())
|
||||||
->setIsNewFile($this->getIsNewFile())
|
->setIsNewFile($this->getIsNewFile())
|
||||||
|
@ -231,6 +231,15 @@ abstract class PhabricatorInlineCommentController
|
||||||
$inline->setReplyToCommentPHID($this->getReplyToCommentPHID());
|
$inline->setReplyToCommentPHID($this->getReplyToCommentPHID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If you own this object, mark your own inlines as "Done" by default.
|
||||||
|
$owner_phid = $this->loadObjectOwnerPHID($inline);
|
||||||
|
if ($owner_phid) {
|
||||||
|
if ($viewer->getPHID() == $owner_phid) {
|
||||||
|
$fixed_state = PhabricatorInlineCommentInterface::STATE_DRAFT;
|
||||||
|
$inline->setFixedState($fixed_state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$this->saveComment($inline);
|
$this->saveComment($inline);
|
||||||
|
|
||||||
return $this->buildRenderedCommentResponse(
|
return $this->buildRenderedCommentResponse(
|
||||||
|
@ -313,10 +322,10 @@ abstract class PhabricatorInlineCommentController
|
||||||
|
|
||||||
private function buildEditDialog() {
|
private function buildEditDialog() {
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
$user = $request->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$edit_dialog = id(new PHUIDiffInlineCommentEditView())
|
$edit_dialog = id(new PHUIDiffInlineCommentEditView())
|
||||||
->setUser($user)
|
->setUser($viewer)
|
||||||
->setSubmitURI($request->getRequestURI())
|
->setSubmitURI($request->getRequestURI())
|
||||||
->setIsOnRight($this->getIsOnRight())
|
->setIsOnRight($this->getIsOnRight())
|
||||||
->setIsNewFile($this->getIsNewFile())
|
->setIsNewFile($this->getIsNewFile())
|
||||||
|
@ -342,22 +351,22 @@ abstract class PhabricatorInlineCommentController
|
||||||
$on_right) {
|
$on_right) {
|
||||||
|
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
$user = $request->getUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$engine = new PhabricatorMarkupEngine();
|
$engine = new PhabricatorMarkupEngine();
|
||||||
$engine->setViewer($user);
|
$engine->setViewer($viewer);
|
||||||
$engine->addObject(
|
$engine->addObject(
|
||||||
$inline,
|
$inline,
|
||||||
PhabricatorInlineCommentInterface::MARKUP_FIELD_BODY);
|
PhabricatorInlineCommentInterface::MARKUP_FIELD_BODY);
|
||||||
$engine->process();
|
$engine->process();
|
||||||
|
|
||||||
$phids = array($user->getPHID());
|
$phids = array($viewer->getPHID());
|
||||||
|
|
||||||
$handles = $this->loadViewerHandles($phids);
|
$handles = $this->loadViewerHandles($phids);
|
||||||
$object_owner_phid = $this->loadObjectOwnerPHID($inline);
|
$object_owner_phid = $this->loadObjectOwnerPHID($inline);
|
||||||
|
|
||||||
$view = id(new PHUIDiffInlineCommentDetailView())
|
$view = id(new PHUIDiffInlineCommentDetailView())
|
||||||
->setUser($user)
|
->setUser($viewer)
|
||||||
->setInlineComment($inline)
|
->setInlineComment($inline)
|
||||||
->setIsOnRight($on_right)
|
->setIsOnRight($on_right)
|
||||||
->setMarkupEngine($engine)
|
->setMarkupEngine($engine)
|
||||||
|
@ -378,7 +387,7 @@ abstract class PhabricatorInlineCommentController
|
||||||
|
|
||||||
private function renderTextArea($text) {
|
private function renderTextArea($text) {
|
||||||
return id(new PhabricatorRemarkupControl())
|
return id(new PhabricatorRemarkupControl())
|
||||||
->setUser($this->getRequest()->getUser())
|
->setViewer($this->getViewer())
|
||||||
->setSigil('differential-inline-comment-edit-textarea')
|
->setSigil('differential-inline-comment-edit-textarea')
|
||||||
->setName('text')
|
->setName('text')
|
||||||
->setValue($text)
|
->setValue($text)
|
||||||
|
|
|
@ -287,15 +287,24 @@ final class PHUIDiffInlineCommentDetailView
|
||||||
|
|
||||||
$done_button = null;
|
$done_button = null;
|
||||||
|
|
||||||
|
$mark_done = $this->getCanMarkDone();
|
||||||
|
|
||||||
|
// Allow users to mark their own draft inlines as "Done".
|
||||||
|
if ($viewer_phid == $inline->getAuthorPHID()) {
|
||||||
|
if ($inline->isDraft()) {
|
||||||
|
$mark_done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!$is_synthetic) {
|
if (!$is_synthetic) {
|
||||||
$draft_state = false;
|
$draft_state = false;
|
||||||
switch ($inline->getFixedState()) {
|
switch ($inline->getFixedState()) {
|
||||||
case PhabricatorInlineCommentInterface::STATE_DRAFT:
|
case PhabricatorInlineCommentInterface::STATE_DRAFT:
|
||||||
$is_done = ($this->getCanMarkDone());
|
$is_done = $mark_done;
|
||||||
$draft_state = true;
|
$draft_state = true;
|
||||||
break;
|
break;
|
||||||
case PhabricatorInlineCommentInterface::STATE_UNDRAFT:
|
case PhabricatorInlineCommentInterface::STATE_UNDRAFT:
|
||||||
$is_done = !($this->getCanMarkDone());
|
$is_done = !$mark_done;
|
||||||
$draft_state = true;
|
$draft_state = true;
|
||||||
break;
|
break;
|
||||||
case PhabricatorInlineCommentInterface::STATE_DONE:
|
case PhabricatorInlineCommentInterface::STATE_DONE:
|
||||||
|
@ -309,7 +318,7 @@ final class PHUIDiffInlineCommentDetailView
|
||||||
|
|
||||||
// If you don't have permission to mark the comment as "Done", you also
|
// If you don't have permission to mark the comment as "Done", you also
|
||||||
// can not see the draft state.
|
// can not see the draft state.
|
||||||
if (!$this->getCanMarkDone()) {
|
if (!$mark_done) {
|
||||||
$draft_state = false;
|
$draft_state = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,21 +330,19 @@ final class PHUIDiffInlineCommentDetailView
|
||||||
$classes[] = 'inline-state-is-draft';
|
$classes[] = 'inline-state-is-draft';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->getCanMarkDone()) {
|
if ($mark_done && !$this->preview) {
|
||||||
$done_input = javelin_tag(
|
$done_input = javelin_tag(
|
||||||
'input',
|
'input',
|
||||||
array(
|
array(
|
||||||
'type' => 'checkbox',
|
'type' => 'checkbox',
|
||||||
'checked' => ($is_done ? 'checked' : null),
|
'checked' => ($is_done ? 'checked' : null),
|
||||||
'disabled' => ($this->getCanMarkDone() ? null : 'disabled'),
|
|
||||||
'class' => 'differential-inline-done',
|
'class' => 'differential-inline-done',
|
||||||
'sigil' => 'differential-inline-done',
|
'sigil' => 'differential-inline-done',
|
||||||
));
|
));
|
||||||
$done_button = phutil_tag(
|
$done_button = phutil_tag(
|
||||||
'label',
|
'label',
|
||||||
array(
|
array(
|
||||||
'class' => 'differential-inline-done-label '.
|
'class' => 'differential-inline-done-label ',
|
||||||
($this->getCanMarkDone() ? null : 'done-is-disabled'),
|
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
$done_input,
|
$done_input,
|
||||||
|
|
Loading…
Reference in a new issue