mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-25 15:00:58 +01:00
Share target filtering code in HeraldAction
Ref T8726. This shares some target filtering code with the base class.
This commit is contained in:
parent
a3e2f655eb
commit
5f76c71d78
13 changed files with 118 additions and 451 deletions
|
@ -30,4 +30,3 @@ final class DifferentialReviewersAddBlockingReviewersHeraldAction
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,4 +27,3 @@ final class DifferentialReviewersAddBlockingSelfHeraldAction
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,4 +30,3 @@ final class DifferentialReviewersAddReviewersHeraldAction
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,4 +27,3 @@ final class DifferentialReviewersAddSelfHeraldAction
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,7 @@
|
||||||
abstract class DifferentialReviewersHeraldAction
|
abstract class DifferentialReviewersHeraldAction
|
||||||
extends HeraldAction {
|
extends HeraldAction {
|
||||||
|
|
||||||
const DO_NO_TARGETS = 'do.no-targets';
|
|
||||||
const DO_AUTHORS = 'do.authors';
|
const DO_AUTHORS = 'do.authors';
|
||||||
const DO_INVALID = 'do.invalid';
|
|
||||||
const DO_ALREADY_REVIEWERS = 'do.already-reviewers';
|
|
||||||
const DO_PERMISSION = 'do.permission';
|
|
||||||
const DO_ADD_REVIEWERS = 'do.add-reviewers';
|
const DO_ADD_REVIEWERS = 'do.add-reviewers';
|
||||||
const DO_ADD_BLOCKING_REVIEWERS = 'do.add-blocking-reviewers';
|
const DO_ADD_BLOCKING_REVIEWERS = 'do.add-blocking-reviewers';
|
||||||
|
|
||||||
|
@ -24,10 +20,6 @@ abstract class DifferentialReviewersHeraldAction
|
||||||
$object = $adapter->getObject();
|
$object = $adapter->getObject();
|
||||||
|
|
||||||
$phids = array_fuse($phids);
|
$phids = array_fuse($phids);
|
||||||
if (!$phids) {
|
|
||||||
$this->logEffect(self::DO_NO_TARGETS);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't try to add revision authors as reviewers.
|
// Don't try to add revision authors as reviewers.
|
||||||
$authors = array();
|
$authors = array();
|
||||||
|
@ -40,10 +32,9 @@ abstract class DifferentialReviewersHeraldAction
|
||||||
|
|
||||||
if ($authors) {
|
if ($authors) {
|
||||||
$this->logEffect(self::DO_AUTHORS, $authors);
|
$this->logEffect(self::DO_AUTHORS, $authors);
|
||||||
}
|
if (!$phids) {
|
||||||
|
return;
|
||||||
if (!$phids) {
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$reviewers = $object->getReviewerStatus();
|
$reviewers = $object->getReviewerStatus();
|
||||||
|
@ -58,7 +49,7 @@ abstract class DifferentialReviewersHeraldAction
|
||||||
$new_strength = DifferentialReviewerStatus::getStatusStrength(
|
$new_strength = DifferentialReviewerStatus::getStatusStrength(
|
||||||
$new_status);
|
$new_status);
|
||||||
|
|
||||||
$already = array();
|
$current = array();
|
||||||
foreach ($phids as $phid) {
|
foreach ($phids as $phid) {
|
||||||
if (!isset($reviewers[$phid])) {
|
if (!isset($reviewers[$phid])) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -72,65 +63,20 @@ abstract class DifferentialReviewersHeraldAction
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$already[] = $phid;
|
$current[] = $phid;
|
||||||
unset($phids[$phid]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($already) {
|
$allowed_types = array(
|
||||||
$this->logEffect(self::DO_ALREADY_REVIEWERS, $already);
|
PhabricatorPeopleUserPHIDType::TYPECONST,
|
||||||
}
|
PhabricatorProjectProjectPHIDType::TYPECONST,
|
||||||
|
);
|
||||||
|
|
||||||
if (!$phids) {
|
$targets = $this->loadStandardTargets($phids, $allowed_types, $current);
|
||||||
|
if (!$targets) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$targets = id(new PhabricatorObjectQuery())
|
$phids = array_fuse(array_keys($targets));
|
||||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
|
||||||
->withPHIDs($phids)
|
|
||||||
->execute();
|
|
||||||
$targets = mpull($targets, null, 'getPHID');
|
|
||||||
|
|
||||||
$invalid = array();
|
|
||||||
foreach ($phids as $phid) {
|
|
||||||
if (empty($targets[$phid])) {
|
|
||||||
$invalid[] = $phid;
|
|
||||||
unset($phids[$phid]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($invalid) {
|
|
||||||
$this->logEffect(self::DO_INVALID, $invalid);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$phids) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$no_access = array();
|
|
||||||
foreach ($targets as $phid => $target) {
|
|
||||||
if (!($target instanceof PhabricatorUser)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$can_view = PhabricatorPolicyFilter::hasCapability(
|
|
||||||
$target,
|
|
||||||
$object,
|
|
||||||
PhabricatorPolicyCapability::CAN_VIEW);
|
|
||||||
if ($can_view) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$no_access[] = $phid;
|
|
||||||
unset($phids[$phid]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($no_access) {
|
|
||||||
$this->logEffect(self::DO_PERMISSION, $no_access);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$phids) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$value = array();
|
$value = array();
|
||||||
foreach ($phids as $phid) {
|
foreach ($phids as $phid) {
|
||||||
|
@ -162,31 +108,11 @@ abstract class DifferentialReviewersHeraldAction
|
||||||
|
|
||||||
protected function getActionEffectMap() {
|
protected function getActionEffectMap() {
|
||||||
return array(
|
return array(
|
||||||
self::DO_NO_TARGETS => array(
|
|
||||||
'icon' => 'fa-ban',
|
|
||||||
'color' => 'grey',
|
|
||||||
'name' => pht('No Targets'),
|
|
||||||
),
|
|
||||||
self::DO_AUTHORS => array(
|
self::DO_AUTHORS => array(
|
||||||
'icon' => 'fa-user',
|
'icon' => 'fa-user',
|
||||||
'color' => 'grey',
|
'color' => 'grey',
|
||||||
'name' => pht('Revision Author'),
|
'name' => pht('Revision Author'),
|
||||||
),
|
),
|
||||||
self::DO_INVALID => array(
|
|
||||||
'icon' => 'fa-ban',
|
|
||||||
'color' => 'red',
|
|
||||||
'name' => pht('Invalid Targets'),
|
|
||||||
),
|
|
||||||
self::DO_ALREADY_REVIEWERS => array(
|
|
||||||
'icon' => 'fa-user',
|
|
||||||
'color' => 'grey',
|
|
||||||
'name' => pht('Already Reviewers'),
|
|
||||||
),
|
|
||||||
self::DO_PERMISSION => array(
|
|
||||||
'icon' => 'fa-ban',
|
|
||||||
'color' => 'red',
|
|
||||||
'name' => pht('No Permission'),
|
|
||||||
),
|
|
||||||
self::DO_ADD_REVIEWERS => array(
|
self::DO_ADD_REVIEWERS => array(
|
||||||
'icon' => 'fa-user',
|
'icon' => 'fa-user',
|
||||||
'color' => 'green',
|
'color' => 'green',
|
||||||
|
@ -202,27 +128,10 @@ abstract class DifferentialReviewersHeraldAction
|
||||||
|
|
||||||
protected function renderActionEffectDescription($type, $data) {
|
protected function renderActionEffectDescription($type, $data) {
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case self::DO_NO_TARGETS:
|
|
||||||
return pht('Rule lists no targets.');
|
|
||||||
case self::DO_AUTHORS:
|
case self::DO_AUTHORS:
|
||||||
return pht(
|
return pht(
|
||||||
'Declined to add revision author as reviewer: %s.',
|
'Declined to add revision author as reviewer: %s.',
|
||||||
$this->renderHandleList($data));
|
$this->renderHandleList($data));
|
||||||
case self::DO_INVALID:
|
|
||||||
return pht(
|
|
||||||
'Declined to act on %s invalid target(s): %s.',
|
|
||||||
new PhutilNumber(count($data)),
|
|
||||||
$this->renderHandleList($data));
|
|
||||||
case self::DO_ALREADY_REVIEWERS:
|
|
||||||
return pht(
|
|
||||||
'%s target(s) were already reviewers: %s.',
|
|
||||||
new PhutilNumber(count($data)),
|
|
||||||
$this->renderHandleList($data));
|
|
||||||
case self::DO_PERMISSION:
|
|
||||||
return pht(
|
|
||||||
'%s target(s) do not have permission to see the revision: %s.',
|
|
||||||
new PhutilNumber(count($data)),
|
|
||||||
$this->renderHandleList($data));
|
|
||||||
case self::DO_ADD_REVIEWERS:
|
case self::DO_ADD_REVIEWERS:
|
||||||
return pht(
|
return pht(
|
||||||
'Added %s reviewer(s): %s.',
|
'Added %s reviewer(s): %s.',
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
final class HarbormasterRunBuildPlansHeraldAction
|
final class HarbormasterRunBuildPlansHeraldAction
|
||||||
extends HeraldAction {
|
extends HeraldAction {
|
||||||
|
|
||||||
const DO_NO_TARGETS = 'do.no-targets';
|
|
||||||
const DO_INVALID = 'do.invalid';
|
|
||||||
const DO_BUILD = 'do.build';
|
const DO_BUILD = 'do.build';
|
||||||
|
|
||||||
const ACTIONCONST = 'harbormaster.build';
|
const ACTIONCONST = 'harbormaster.build';
|
||||||
|
@ -21,33 +19,16 @@ final class HarbormasterRunBuildPlansHeraldAction
|
||||||
protected function applyBuilds(array $phids) {
|
protected function applyBuilds(array $phids) {
|
||||||
$adapter = $this->getAdapter();
|
$adapter = $this->getAdapter();
|
||||||
|
|
||||||
$phids = array_fuse($phids);
|
$allowed_types = array(
|
||||||
if (!$phids) {
|
HarbormasterBuildPlanPHIDType::TYPECONST,
|
||||||
$this->logEffect(self::DO_NO_TARGETS);
|
);
|
||||||
|
|
||||||
|
$targets = $this->loadStandardTargets($phids, $allowed_types, array());
|
||||||
|
if (!$targets) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$plans = id(new HarbormasterBuildPlanQuery())
|
$phids = array_fuse(array_keys($targets));
|
||||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
|
||||||
->withPHIDs($phids)
|
|
||||||
->execute();
|
|
||||||
$plans = mpull($plans, null, 'getPHID');
|
|
||||||
|
|
||||||
$invalid = array();
|
|
||||||
foreach ($phids as $phid) {
|
|
||||||
if (empty($plans[$phid])) {
|
|
||||||
$invalid[] = $phid;
|
|
||||||
unset($plans[$phid]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($invalid) {
|
|
||||||
$this->logEffect(self::DO_INVALID, $phids);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$phids) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($phids as $phid) {
|
foreach ($phids as $phid) {
|
||||||
$adapter->queueHarbormasterBuildPlanPHID($phid);
|
$adapter->queueHarbormasterBuildPlanPHID($phid);
|
||||||
|
@ -58,16 +39,6 @@ final class HarbormasterRunBuildPlansHeraldAction
|
||||||
|
|
||||||
protected function getActionEffectMap() {
|
protected function getActionEffectMap() {
|
||||||
return array(
|
return array(
|
||||||
self::DO_NO_TARGETS => array(
|
|
||||||
'icon' => 'fa-ban',
|
|
||||||
'color' => 'grey',
|
|
||||||
'name' => pht('No Targets'),
|
|
||||||
),
|
|
||||||
self::DO_INVALID => array(
|
|
||||||
'icon' => 'fa-ban',
|
|
||||||
'color' => 'red',
|
|
||||||
'name' => pht('Invalid Targets'),
|
|
||||||
),
|
|
||||||
self::DO_BUILD => array(
|
self::DO_BUILD => array(
|
||||||
'icon' => 'fa-play',
|
'icon' => 'fa-play',
|
||||||
'color' => 'green',
|
'color' => 'green',
|
||||||
|
@ -78,13 +49,6 @@ final class HarbormasterRunBuildPlansHeraldAction
|
||||||
|
|
||||||
protected function renderActionEffectDescription($type, $data) {
|
protected function renderActionEffectDescription($type, $data) {
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case self::DO_NO_TARGETS:
|
|
||||||
return pht('Rule lists no targets.');
|
|
||||||
case self::DO_INVALID:
|
|
||||||
return pht(
|
|
||||||
'%s build plan(s) are not valid: %s.',
|
|
||||||
new PhutilNumber(count($data)),
|
|
||||||
$this->renderHandleList($data));
|
|
||||||
case self::DO_BUILD:
|
case self::DO_BUILD:
|
||||||
return pht(
|
return pht(
|
||||||
'Started %s build(s): %s.',
|
'Started %s build(s): %s.',
|
||||||
|
|
|
@ -3,9 +3,6 @@
|
||||||
final class LegalpadRequireSignatureHeraldAction
|
final class LegalpadRequireSignatureHeraldAction
|
||||||
extends HeraldAction {
|
extends HeraldAction {
|
||||||
|
|
||||||
const DO_NO_TARGETS = 'do.no-targets';
|
|
||||||
const DO_ALREADY_REQUIRED = 'do.already-required';
|
|
||||||
const DO_INVALID = 'do.invalid';
|
|
||||||
const DO_SIGNED = 'do.signed';
|
const DO_SIGNED = 'do.signed';
|
||||||
const DO_REQUIRED = 'do.required';
|
const DO_REQUIRED = 'do.required';
|
||||||
|
|
||||||
|
@ -24,54 +21,20 @@ final class LegalpadRequireSignatureHeraldAction
|
||||||
|
|
||||||
protected function applyRequire(array $phids) {
|
protected function applyRequire(array $phids) {
|
||||||
$adapter = $this->getAdapter();
|
$adapter = $this->getAdapter();
|
||||||
|
|
||||||
$edgetype_legal = LegalpadObjectNeedsSignatureEdgeType::EDGECONST;
|
$edgetype_legal = LegalpadObjectNeedsSignatureEdgeType::EDGECONST;
|
||||||
|
|
||||||
$phids = array_fuse($phids);
|
|
||||||
|
|
||||||
if (!$phids) {
|
|
||||||
$this->logEffect(self::DO_NO_TARGETS);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$current = $adapter->loadEdgePHIDs($edgetype_legal);
|
$current = $adapter->loadEdgePHIDs($edgetype_legal);
|
||||||
|
|
||||||
$already = array();
|
$allowed_types = array(
|
||||||
foreach ($phids as $phid) {
|
PhabricatorLegalpadDocumentPHIDType::TYPECONST,
|
||||||
if (isset($current[$phid])) {
|
);
|
||||||
$already[] = $phid;
|
|
||||||
unset($phids[$phid]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($already) {
|
$targets = $this->loadStandardTargets($phids, $allowed_types, $current);
|
||||||
$this->logEffect(self::DO_ALREADY_REQUIRED, $phids);
|
if (!$targets) {
|
||||||
}
|
|
||||||
|
|
||||||
if (!$phids) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$documents = id(new LegalpadDocumentQuery())
|
$phids = array_fuse(array_keys($targets));
|
||||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
|
||||||
->withPHIDs($phids)
|
|
||||||
->execute();
|
|
||||||
$documents = mpull($documents, null, 'getPHID');
|
|
||||||
|
|
||||||
$invalid = array();
|
|
||||||
foreach ($phids as $phid) {
|
|
||||||
if (empty($documents[$phid])) {
|
|
||||||
$invalid[] = $phid;
|
|
||||||
unset($documents[$phid]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($invalid) {
|
|
||||||
$this->logEffect(self::DO_INVALID, $phids);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$phids) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$object = $adapter->getObject();
|
$object = $adapter->getObject();
|
||||||
$author_phid = $object->getAuthorPHID();
|
$author_phid = $object->getAuthorPHID();
|
||||||
|
@ -114,21 +77,6 @@ final class LegalpadRequireSignatureHeraldAction
|
||||||
|
|
||||||
protected function getActionEffectMap() {
|
protected function getActionEffectMap() {
|
||||||
return array(
|
return array(
|
||||||
self::DO_NO_TARGETS => array(
|
|
||||||
'icon' => 'fa-ban',
|
|
||||||
'color' => 'grey',
|
|
||||||
'name' => pht('No Targets'),
|
|
||||||
),
|
|
||||||
self::DO_INVALID => array(
|
|
||||||
'icon' => 'fa-ban',
|
|
||||||
'color' => 'red',
|
|
||||||
'name' => pht('Invalid Targets'),
|
|
||||||
),
|
|
||||||
self::DO_ALREADY_REQUIRED => array(
|
|
||||||
'icon' => 'fa-terminal',
|
|
||||||
'color' => 'grey',
|
|
||||||
'name' => pht('Already Required'),
|
|
||||||
),
|
|
||||||
self::DO_SIGNED => array(
|
self::DO_SIGNED => array(
|
||||||
'icon' => 'fa-terminal',
|
'icon' => 'fa-terminal',
|
||||||
'color' => 'green',
|
'color' => 'green',
|
||||||
|
@ -144,18 +92,6 @@ final class LegalpadRequireSignatureHeraldAction
|
||||||
|
|
||||||
protected function renderActionEffectDescription($type, $data) {
|
protected function renderActionEffectDescription($type, $data) {
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case self::DO_NO_TARGETS:
|
|
||||||
return pht('Rule lists no targets.');
|
|
||||||
case self::DO_INVALID:
|
|
||||||
return pht(
|
|
||||||
'%s document(s) are not valid: %s.',
|
|
||||||
new PhutilNumber(count($data)),
|
|
||||||
$this->renderHandleList($data));
|
|
||||||
case self::DO_ALREADY_REQUIRED:
|
|
||||||
return pht(
|
|
||||||
'%s document signature(s) are already required: %s.',
|
|
||||||
new PhutilNumber(count($data)),
|
|
||||||
$this->renderHandleList($data));
|
|
||||||
case self::DO_SIGNED:
|
case self::DO_SIGNED:
|
||||||
return pht(
|
return pht(
|
||||||
'%s document(s) are already signed: %s.',
|
'%s document(s) are already signed: %s.',
|
||||||
|
|
|
@ -3,10 +3,6 @@
|
||||||
abstract class ManiphestTaskAssignHeraldAction
|
abstract class ManiphestTaskAssignHeraldAction
|
||||||
extends HeraldAction {
|
extends HeraldAction {
|
||||||
|
|
||||||
const DO_EMPTY = 'do.send';
|
|
||||||
const DO_ALREADY = 'do.already';
|
|
||||||
const DO_INVALID = 'do.invalid';
|
|
||||||
const DO_PERMISSION = 'do.permission';
|
|
||||||
const DO_ASSIGN = 'do.assign';
|
const DO_ASSIGN = 'do.assign';
|
||||||
|
|
||||||
public function supportsObject($object) {
|
public function supportsObject($object) {
|
||||||
|
@ -18,38 +14,21 @@ abstract class ManiphestTaskAssignHeraldAction
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function applyAssign(array $phids) {
|
protected function applyAssign(array $phids) {
|
||||||
$phid = head($phids);
|
|
||||||
|
|
||||||
if (!$phid) {
|
|
||||||
$this->logEffect(self::DO_EMPTY);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$adapter = $this->getAdapter();
|
$adapter = $this->getAdapter();
|
||||||
$object = $adapter->getObject();
|
$object = $adapter->getObject();
|
||||||
|
|
||||||
if ($object->getOwnerPHID() == $phid) {
|
$current = array($object->getOwnerPHID());
|
||||||
$this->logEffect(self::DO_ALREADY, array($phid));
|
|
||||||
|
$allowed_types = array(
|
||||||
|
PhabricatorPeopleUserPHIDType::TYPECONST,
|
||||||
|
);
|
||||||
|
|
||||||
|
$targets = $this->loadStandardTargets($phids, $allowed_types, $current);
|
||||||
|
if (!$targets) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = id(new PhabricatorPeopleQuery())
|
$phid = head_key($targets);
|
||||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
|
||||||
->withPHIDs(array($phid))
|
|
||||||
->executeOne();
|
|
||||||
if (!$user) {
|
|
||||||
$this->logEffect(self::DO_INVALID, array($phid));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$can_view = PhabricatorPolicyFilter::hasCapability(
|
|
||||||
$user,
|
|
||||||
$object,
|
|
||||||
PhabricatorPolicyCapability::CAN_VIEW);
|
|
||||||
if (!$can_view) {
|
|
||||||
$this->logEffect(self::DO_PERMISSION, array($phid));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$xaction = $adapter->newTransaction()
|
$xaction = $adapter->newTransaction()
|
||||||
->setTransactionType(ManiphestTransaction::TYPE_OWNER)
|
->setTransactionType(ManiphestTransaction::TYPE_OWNER)
|
||||||
|
@ -62,26 +41,6 @@ abstract class ManiphestTaskAssignHeraldAction
|
||||||
|
|
||||||
protected function getActionEffectMap() {
|
protected function getActionEffectMap() {
|
||||||
return array(
|
return array(
|
||||||
self::DO_EMPTY => array(
|
|
||||||
'icon' => 'fa-ban',
|
|
||||||
'color' => 'grey',
|
|
||||||
'name' => pht('Empty Action'),
|
|
||||||
),
|
|
||||||
self::DO_ALREADY => array(
|
|
||||||
'icon' => 'fa-user',
|
|
||||||
'color' => 'grey',
|
|
||||||
'name' => pht('Already Assigned'),
|
|
||||||
),
|
|
||||||
self::DO_INVALID => array(
|
|
||||||
'icon' => 'fa-ban',
|
|
||||||
'color' => 'red',
|
|
||||||
'name' => pht('Invalid Owner'),
|
|
||||||
),
|
|
||||||
self::DO_PERMISSION => array(
|
|
||||||
'icon' => 'fa-ban',
|
|
||||||
'color' => 'red',
|
|
||||||
'name' => pht('No Permission'),
|
|
||||||
),
|
|
||||||
self::DO_ASSIGN => array(
|
self::DO_ASSIGN => array(
|
||||||
'icon' => 'fa-user',
|
'icon' => 'fa-user',
|
||||||
'color' => 'green',
|
'color' => 'green',
|
||||||
|
@ -92,20 +51,6 @@ abstract class ManiphestTaskAssignHeraldAction
|
||||||
|
|
||||||
protected function renderActionEffectDescription($type, $data) {
|
protected function renderActionEffectDescription($type, $data) {
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case self::DO_EMPTY:
|
|
||||||
return pht('Action lists no user to assign.');
|
|
||||||
case self::DO_ALREADY:
|
|
||||||
return pht(
|
|
||||||
'User is already task owner: %s.',
|
|
||||||
$this->renderHandleList($data));
|
|
||||||
case self::DO_INVALID:
|
|
||||||
return pht(
|
|
||||||
'User is invalid: %s.',
|
|
||||||
$this->renderHandleList($data));
|
|
||||||
case self::DO_PERMISSION:
|
|
||||||
return pht(
|
|
||||||
'User does not have permission to see task: %s.',
|
|
||||||
$this->renderHandleList($data));
|
|
||||||
case self::DO_ASSIGN:
|
case self::DO_ASSIGN:
|
||||||
return pht(
|
return pht(
|
||||||
'Assigned task to: %s.',
|
'Assigned task to: %s.',
|
||||||
|
|
|
@ -24,6 +24,22 @@ abstract class PhabricatorMetaMTAEmailHeraldAction
|
||||||
protected function applyEmail(array $phids, $force) {
|
protected function applyEmail(array $phids, $force) {
|
||||||
$adapter = $this->getAdapter();
|
$adapter = $this->getAdapter();
|
||||||
|
|
||||||
|
$allowed_types = array(
|
||||||
|
PhabricatorPeopleUserPHIDType::TYPECONST,
|
||||||
|
PhabricatorProjectProjectPHIDType::TYPECONST,
|
||||||
|
);
|
||||||
|
|
||||||
|
// There's no stateful behavior for this action: we always just send an
|
||||||
|
// email.
|
||||||
|
$current = array();
|
||||||
|
|
||||||
|
$targets = $this->loadStandardTargets($phids, $allowed_types, $current);
|
||||||
|
if (!$targets) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$phids = array_fuse(array_keys($targets));
|
||||||
|
|
||||||
foreach ($phids as $phid) {
|
foreach ($phids as $phid) {
|
||||||
$adapter->addEmailPHID($phid, $force);
|
$adapter->addEmailPHID($phid, $force);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,6 @@
|
||||||
abstract class PhabricatorProjectHeraldAction
|
abstract class PhabricatorProjectHeraldAction
|
||||||
extends HeraldAction {
|
extends HeraldAction {
|
||||||
|
|
||||||
const DO_NO_TARGETS = 'do.no-targets';
|
|
||||||
const DO_INVALID = 'do.invalid';
|
|
||||||
const DO_ALREADY_ASSOCIATED = 'do.already-associated';
|
|
||||||
const DO_ALREADY_UNASSOCIATED = 'do.already-unassociated';
|
|
||||||
const DO_ADD_PROJECTS = 'do.add-projects';
|
const DO_ADD_PROJECTS = 'do.add-projects';
|
||||||
const DO_REMOVE_PROJECTS = 'do.remove-projects';
|
const DO_REMOVE_PROJECTS = 'do.remove-projects';
|
||||||
|
|
||||||
|
@ -23,38 +19,24 @@ abstract class PhabricatorProjectHeraldAction
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function applyProjects(array $phids, $is_add) {
|
protected function applyProjects(array $phids, $is_add) {
|
||||||
$phids = array_fuse($phids);
|
|
||||||
$adapter = $this->getAdapter();
|
$adapter = $this->getAdapter();
|
||||||
|
|
||||||
if (!$phids) {
|
$allowed_types = array(
|
||||||
$this->logEffect(self::DO_NO_TARGETS);
|
PhabricatorProjectProjectPHIDType::TYPECONST,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Detection of "No Effect" is a bit tricky for this action, so just do it
|
||||||
|
// manually a little later on.
|
||||||
|
$current = array();
|
||||||
|
|
||||||
|
$targets = $this->loadStandardTargets($phids, $allowed_types, $current);
|
||||||
|
if (!$targets) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$projects = id(new PhabricatorProjectQuery())
|
$phids = array_fuse(array_keys($targets));
|
||||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
|
||||||
->withPHIDs($phids)
|
|
||||||
->execute();
|
|
||||||
$projects = mpull($projects, null, 'getPHID');
|
|
||||||
|
|
||||||
$invalid = array();
|
|
||||||
foreach ($phids as $phid) {
|
|
||||||
if (empty($projects[$phid])) {
|
|
||||||
$invalid[] = $phid;
|
|
||||||
unset($phids[$phid]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($invalid) {
|
|
||||||
$this->logEffect(self::DO_INVALID, $invalid);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$phids) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$project_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
|
$project_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
|
||||||
|
|
||||||
$current = $adapter->loadEdgePHIDs($project_type);
|
$current = $adapter->loadEdgePHIDs($project_type);
|
||||||
|
|
||||||
if ($is_add) {
|
if ($is_add) {
|
||||||
|
@ -67,7 +49,7 @@ abstract class PhabricatorProjectHeraldAction
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($already) {
|
if ($already) {
|
||||||
$this->logEffect(self::DO_ALREADY_ASSOCIATED, $already);
|
$this->logEffect(self::DO_STANDARD_NO_EFFECT, $already);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$already = array();
|
$already = array();
|
||||||
|
@ -79,7 +61,7 @@ abstract class PhabricatorProjectHeraldAction
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($already) {
|
if ($already) {
|
||||||
$this->logEffect(self::DO_ALREADY_UNASSOCIATED, $already);
|
$this->logEffect(self::DO_STANDARD_NO_EFFECT, $already);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,26 +94,6 @@ abstract class PhabricatorProjectHeraldAction
|
||||||
|
|
||||||
protected function getActionEffectMap() {
|
protected function getActionEffectMap() {
|
||||||
return array(
|
return array(
|
||||||
self::DO_NO_TARGETS => array(
|
|
||||||
'icon' => 'fa-ban',
|
|
||||||
'color' => 'grey',
|
|
||||||
'name' => pht('No Targets'),
|
|
||||||
),
|
|
||||||
self::DO_INVALID => array(
|
|
||||||
'icon' => 'fa-ban',
|
|
||||||
'color' => 'red',
|
|
||||||
'name' => pht('Invalid Targets'),
|
|
||||||
),
|
|
||||||
self::DO_ALREADY_ASSOCIATED => array(
|
|
||||||
'icon' => 'fa-chevron-right',
|
|
||||||
'color' => 'grey',
|
|
||||||
'name' => pht('Already Associated'),
|
|
||||||
),
|
|
||||||
self::DO_ALREADY_UNASSOCIATED => array(
|
|
||||||
'icon' => 'fa-chevron-right',
|
|
||||||
'color' => 'grey',
|
|
||||||
'name' => pht('Already Unassociated'),
|
|
||||||
),
|
|
||||||
self::DO_ADD_PROJECTS => array(
|
self::DO_ADD_PROJECTS => array(
|
||||||
'icon' => 'fa-briefcase',
|
'icon' => 'fa-briefcase',
|
||||||
'color' => 'green',
|
'color' => 'green',
|
||||||
|
@ -147,23 +109,6 @@ abstract class PhabricatorProjectHeraldAction
|
||||||
|
|
||||||
protected function renderActionEffectDescription($type, $data) {
|
protected function renderActionEffectDescription($type, $data) {
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case self::DO_NO_TARGETS:
|
|
||||||
return pht('Rule lists no projects.');
|
|
||||||
case self::DO_INVALID:
|
|
||||||
return pht(
|
|
||||||
'Declined to act on %s invalid project(s): %s.',
|
|
||||||
new PhutilNumber(count($data)),
|
|
||||||
$this->renderHandleList($data));
|
|
||||||
case self::DO_ALREADY_ASSOCIATED:
|
|
||||||
return pht(
|
|
||||||
'%s project(s) are already associated: %s.',
|
|
||||||
new PhutilNumber(count($data)),
|
|
||||||
$this->renderHandleList($data));
|
|
||||||
case self::DO_ALREADY_UNASSOCIATED:
|
|
||||||
return pht(
|
|
||||||
'%s project(s) are not associated: %s.',
|
|
||||||
new PhutilNumber(count($data)),
|
|
||||||
$this->renderHandleList($data));
|
|
||||||
case self::DO_ADD_PROJECTS:
|
case self::DO_ADD_PROJECTS:
|
||||||
return pht(
|
return pht(
|
||||||
'Added %s project(s): %s.',
|
'Added %s project(s): %s.',
|
||||||
|
|
|
@ -3,12 +3,8 @@
|
||||||
abstract class PhabricatorSubscriptionsHeraldAction
|
abstract class PhabricatorSubscriptionsHeraldAction
|
||||||
extends HeraldAction {
|
extends HeraldAction {
|
||||||
|
|
||||||
const DO_NO_TARGETS = 'do.no-targets';
|
|
||||||
const DO_PREVIOUSLY_UNSUBSCRIBED = 'do.previously-unsubscribed';
|
const DO_PREVIOUSLY_UNSUBSCRIBED = 'do.previously-unsubscribed';
|
||||||
const DO_INVALID = 'do.invalid';
|
|
||||||
const DO_AUTOSUBSCRIBED = 'do.autosubscribed';
|
const DO_AUTOSUBSCRIBED = 'do.autosubscribed';
|
||||||
const DO_ALREADY_SUBSCRIBED = 'do.already-subscribed';
|
|
||||||
const DO_ALREADY_UNSUBSCRIBED = 'do.already-unsubscribed';
|
|
||||||
const DO_SUBSCRIBED = 'do.subscribed';
|
const DO_SUBSCRIBED = 'do.subscribed';
|
||||||
const DO_UNSUBSCRIBED = 'do.unsubscribed';
|
const DO_UNSUBSCRIBED = 'do.unsubscribed';
|
||||||
|
|
||||||
|
@ -23,18 +19,22 @@ abstract class PhabricatorSubscriptionsHeraldAction
|
||||||
protected function applySubscribe(array $phids, $is_add) {
|
protected function applySubscribe(array $phids, $is_add) {
|
||||||
$adapter = $this->getAdapter();
|
$adapter = $this->getAdapter();
|
||||||
|
|
||||||
if ($is_add) {
|
$allowed_types = array(
|
||||||
$kind = '+';
|
PhabricatorPeopleUserPHIDType::TYPECONST,
|
||||||
} else {
|
PhabricatorProjectProjectPHIDType::TYPECONST,
|
||||||
$kind = '-';
|
);
|
||||||
}
|
|
||||||
|
|
||||||
$subscriber_phids = array_fuse($phids);
|
// Evaluating "No Effect" is a bit tricky for this rule type, so just
|
||||||
if (!$subscriber_phids) {
|
// do it manually below.
|
||||||
$this->logEffect(self::DO_NO_TARGETS);
|
$current = array();
|
||||||
|
|
||||||
|
$targets = $this->loadStandardTargets($phids, $allowed_types, $current);
|
||||||
|
if (!$targets) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$phids = array_fuse(array_keys($targets));
|
||||||
|
|
||||||
// The "Add Subscribers" rule only adds subscribers who haven't previously
|
// The "Add Subscribers" rule only adds subscribers who haven't previously
|
||||||
// unsubscribed from the object explicitly. Filter these subscribers out
|
// unsubscribed from the object explicitly. Filter these subscribers out
|
||||||
// before continuing.
|
// before continuing.
|
||||||
|
@ -43,9 +43,9 @@ abstract class PhabricatorSubscriptionsHeraldAction
|
||||||
PhabricatorObjectHasUnsubscriberEdgeType::EDGECONST);
|
PhabricatorObjectHasUnsubscriberEdgeType::EDGECONST);
|
||||||
|
|
||||||
foreach ($unsubscribed as $phid) {
|
foreach ($unsubscribed as $phid) {
|
||||||
if (isset($subscriber_phids[$phid])) {
|
if (isset($phids[$phid])) {
|
||||||
$unsubscribed[$phid] = $phid;
|
$unsubscribed[$phid] = $phid;
|
||||||
unset($subscriber_phids[$phid]);
|
unset($phids[$phid]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,41 +56,16 @@ abstract class PhabricatorSubscriptionsHeraldAction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$subscriber_phids) {
|
if (!$phids) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filter out PHIDs which aren't valid subscribers. Lower levels of the
|
|
||||||
// stack will fail loudly if we try to add subscribers with invalid PHIDs
|
|
||||||
// or unknown PHID types, so drop them here.
|
|
||||||
$invalid = array();
|
|
||||||
foreach ($subscriber_phids as $phid) {
|
|
||||||
$type = phid_get_type($phid);
|
|
||||||
switch ($type) {
|
|
||||||
case PhabricatorPeopleUserPHIDType::TYPECONST:
|
|
||||||
case PhabricatorProjectProjectPHIDType::TYPECONST:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$invalid[$phid] = $phid;
|
|
||||||
unset($subscriber_phids[$phid]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($invalid) {
|
|
||||||
$this->logEffect(self::DO_INVALID, array_values($invalid));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$subscriber_phids) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$auto = array();
|
$auto = array();
|
||||||
$object = $adapter->getObject();
|
$object = $adapter->getObject();
|
||||||
foreach ($subscriber_phids as $phid) {
|
foreach ($phids as $phid) {
|
||||||
if ($object->isAutomaticallySubscribed($phid)) {
|
if ($object->isAutomaticallySubscribed($phid)) {
|
||||||
$auto[$phid] = $phid;
|
$auto[$phid] = $phid;
|
||||||
unset($subscriber_phids[$phid]);
|
unset($phids[$phid]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +73,7 @@ abstract class PhabricatorSubscriptionsHeraldAction
|
||||||
$this->logEffect(self::DO_AUTOSUBSCRIBED, array_values($auto));
|
$this->logEffect(self::DO_AUTOSUBSCRIBED, array_values($auto));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$subscriber_phids) {
|
if (!$phids) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,57 +82,58 @@ abstract class PhabricatorSubscriptionsHeraldAction
|
||||||
|
|
||||||
if ($is_add) {
|
if ($is_add) {
|
||||||
$already = array();
|
$already = array();
|
||||||
foreach ($subscriber_phids as $phid) {
|
foreach ($phids as $phid) {
|
||||||
if (isset($current[$phid])) {
|
if (isset($current[$phid])) {
|
||||||
$already[$phid] = $phid;
|
$already[$phid] = $phid;
|
||||||
unset($subscriber_phids[$phid]);
|
unset($phids[$phid]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($already) {
|
if ($already) {
|
||||||
$this->logEffect(self::DO_ALREADY_SUBSCRIBED, $already);
|
$this->logEffect(self::DO_STANDARD_NO_EFFECT, $already);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$already = array();
|
$already = array();
|
||||||
foreach ($subscriber_phids as $phid) {
|
foreach ($phids as $phid) {
|
||||||
if (empty($current[$phid])) {
|
if (empty($current[$phid])) {
|
||||||
$already[$phid] = $phid;
|
$already[$phid] = $phid;
|
||||||
unset($subscriber_phids[$phid]);
|
unset($phids[$phid]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($already) {
|
if ($already) {
|
||||||
$this->logEffect(self::DO_ALREADY_UNSUBSCRIBED, $already);
|
$this->logEffect(self::DO_STANDARD_NO_EFFECT, $already);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$subscriber_phids) {
|
if (!$phids) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($is_add) {
|
||||||
|
$kind = '+';
|
||||||
|
} else {
|
||||||
|
$kind = '-';
|
||||||
|
}
|
||||||
|
|
||||||
$xaction = $adapter->newTransaction()
|
$xaction = $adapter->newTransaction()
|
||||||
->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS)
|
->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS)
|
||||||
->setNewValue(
|
->setNewValue(
|
||||||
array(
|
array(
|
||||||
$kind => $subscriber_phids,
|
$kind => $phids,
|
||||||
));
|
));
|
||||||
|
|
||||||
$adapter->queueTransaction($xaction);
|
$adapter->queueTransaction($xaction);
|
||||||
|
|
||||||
if ($is_add) {
|
if ($is_add) {
|
||||||
$this->logEffect(self::DO_SUBSCRIBED, $subscriber_phids);
|
$this->logEffect(self::DO_SUBSCRIBED, $phids);
|
||||||
} else {
|
} else {
|
||||||
$this->logEffect(self::DO_UNSUBSCRIBED, $subscriber_phids);
|
$this->logEffect(self::DO_UNSUBSCRIBED, $phids);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getActionEffectMap() {
|
protected function getActionEffectMap() {
|
||||||
return array(
|
return array(
|
||||||
self::DO_NO_TARGETS => array(
|
|
||||||
'icon' => 'fa-ban',
|
|
||||||
'color' => 'grey',
|
|
||||||
'name' => pht('No Targets'),
|
|
||||||
),
|
|
||||||
self::DO_PREVIOUSLY_UNSUBSCRIBED => array(
|
self::DO_PREVIOUSLY_UNSUBSCRIBED => array(
|
||||||
'icon' => 'fa-minus-circle',
|
'icon' => 'fa-minus-circle',
|
||||||
'color' => 'grey',
|
'color' => 'grey',
|
||||||
|
@ -168,21 +144,6 @@ abstract class PhabricatorSubscriptionsHeraldAction
|
||||||
'color' => 'grey',
|
'color' => 'grey',
|
||||||
'name' => pht('Automatically Subscribed'),
|
'name' => pht('Automatically Subscribed'),
|
||||||
),
|
),
|
||||||
self::DO_INVALID => array(
|
|
||||||
'icon' => 'fa-ban',
|
|
||||||
'color' => 'red',
|
|
||||||
'name' => pht('Invalid Targets'),
|
|
||||||
),
|
|
||||||
self::DO_ALREADY_SUBSCRIBED => array(
|
|
||||||
'icon' => 'fa-chevron-right',
|
|
||||||
'color' => 'grey',
|
|
||||||
'name' => pht('Already Subscribed'),
|
|
||||||
),
|
|
||||||
self::DO_ALREADY_UNSUBSCRIBED => array(
|
|
||||||
'icon' => 'fa-chevron-right',
|
|
||||||
'color' => 'grey',
|
|
||||||
'name' => pht('Already Unsubscribed'),
|
|
||||||
),
|
|
||||||
self::DO_SUBSCRIBED => array(
|
self::DO_SUBSCRIBED => array(
|
||||||
'icon' => 'fa-envelope',
|
'icon' => 'fa-envelope',
|
||||||
'color' => 'green',
|
'color' => 'green',
|
||||||
|
@ -198,34 +159,17 @@ abstract class PhabricatorSubscriptionsHeraldAction
|
||||||
|
|
||||||
protected function renderActionEffectDescription($type, $data) {
|
protected function renderActionEffectDescription($type, $data) {
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case self::DO_NO_TARGETS:
|
|
||||||
return pht('Rule lists no targets.');
|
|
||||||
case self::DO_PREVIOUSLY_UNSUBSCRIBED:
|
case self::DO_PREVIOUSLY_UNSUBSCRIBED:
|
||||||
return pht(
|
return pht(
|
||||||
'Declined to resubscribe %s target(s) because they previously '.
|
'Declined to resubscribe %s target(s) because they previously '.
|
||||||
'unsubscribed: %s.',
|
'unsubscribed: %s.',
|
||||||
new PhutilNumber(count($data)),
|
new PhutilNumber(count($data)),
|
||||||
$this->renderHandleList($data));
|
$this->renderHandleList($data));
|
||||||
case self::DO_INVALID:
|
|
||||||
return pht(
|
|
||||||
'Declined to act on %s invalid target(s): %s.',
|
|
||||||
new PhutilNumber(count($data)),
|
|
||||||
$this->renderHandleList($data));
|
|
||||||
case self::DO_AUTOSUBSCRIBED:
|
case self::DO_AUTOSUBSCRIBED:
|
||||||
return pht(
|
return pht(
|
||||||
'%s automatically subscribed target(s) were not affected: %s.',
|
'%s automatically subscribed target(s) were not affected: %s.',
|
||||||
new PhutilNumber(count($data)),
|
new PhutilNumber(count($data)),
|
||||||
$this->renderHandleList($data));
|
$this->renderHandleList($data));
|
||||||
case self::DO_ALREADY_SUBSCRIBED:
|
|
||||||
return pht(
|
|
||||||
'%s target(s) are already subscribed: %s.',
|
|
||||||
new PhutilNumber(count($data)),
|
|
||||||
$this->renderHandleList($data));
|
|
||||||
case self::DO_ALREADY_UNSUBSCRIBED:
|
|
||||||
return pht(
|
|
||||||
'%s target(s) are not subscribed: %s.',
|
|
||||||
new PhutilNumber(count($data)),
|
|
||||||
$this->renderHandleList($data));
|
|
||||||
case self::DO_SUBSCRIBED:
|
case self::DO_SUBSCRIBED:
|
||||||
return pht(
|
return pht(
|
||||||
'Added %s subscriber(s): %s.',
|
'Added %s subscriber(s): %s.',
|
||||||
|
|
|
@ -1706,7 +1706,7 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
|
|
||||||
$lists = array($new_set, $new_add, $new_rem);
|
$lists = array($new_set, $new_add, $new_rem);
|
||||||
foreach ($lists as $list) {
|
foreach ($lists as $list) {
|
||||||
$this->checkEdgeList($list);
|
$this->checkEdgeList($list, $xaction->getMetadataValue('edge:type'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = array();
|
$result = array();
|
||||||
|
@ -1743,7 +1743,7 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function checkEdgeList($list) {
|
private function checkEdgeList($list, $edge_type) {
|
||||||
if (!$list) {
|
if (!$list) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1751,16 +1751,18 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
if (phid_get_type($key) === PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN) {
|
if (phid_get_type($key) === PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN) {
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
pht(
|
pht(
|
||||||
"Edge transactions must have destination PHIDs as in edge ".
|
'Edge transactions must have destination PHIDs as in edge '.
|
||||||
"lists (found key '%s').",
|
'lists (found key "%s" on transaction of type "%s").',
|
||||||
$key));
|
$key,
|
||||||
|
$edge_type));
|
||||||
}
|
}
|
||||||
if (!is_array($item) && $item !== $key) {
|
if (!is_array($item) && $item !== $key) {
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
pht(
|
pht(
|
||||||
"Edge transactions must have PHIDs or edge specs as values ".
|
'Edge transactions must have PHIDs or edge specs as values '.
|
||||||
"(found value '%s').",
|
'(found value "%s" on transaction of type "%s").',
|
||||||
$item));
|
$item,
|
||||||
|
$edge_type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1348,6 +1348,16 @@ final class PhabricatorUSEnglishTranslation
|
||||||
'Added auditors: %2$s.',
|
'Added auditors: %2$s.',
|
||||||
),
|
),
|
||||||
|
|
||||||
|
'%s target(s) do not have permission to see this object: %s.' => array(
|
||||||
|
'A target does not have permission to see this object: %2$s.',
|
||||||
|
'Targets do not have permission to see this object: %2$s.',
|
||||||
|
),
|
||||||
|
|
||||||
|
'This action has no effect on %s target(s): %s.' => array(
|
||||||
|
'This action has no effect on a target: %2$s.',
|
||||||
|
'This action has no effect on targets: %2$s.',
|
||||||
|
),
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue