1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-30 10:42:41 +01:00
phorge-phorge/src/applications/differential/herald/DifferentialReviewersHeraldAction.php

241 lines
6.2 KiB
PHP
Raw Normal View History

<?php
abstract class DifferentialReviewersHeraldAction
extends HeraldAction {
const DO_NO_TARGETS = 'do.no-targets';
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_BLOCKING_REVIEWERS = 'do.add-blocking-reviewers';
public function getActionGroupKey() {
return HeraldApplicationActionGroup::ACTIONGROUPKEY;
}
public function supportsObject($object) {
return ($object instanceof DifferentialRevision);
}
protected function applyReviewers(array $phids, $is_blocking) {
$adapter = $this->getAdapter();
$object = $adapter->getObject();
$phids = array_fuse($phids);
if (!$phids) {
$this->logEffect(self::DO_NO_TARGETS);
return;
}
// Don't try to add revision authors as reviewers.
$authors = array();
foreach ($phids as $phid) {
if ($phid == $object->getAuthorPHID()) {
$authors[] = $phid;
unset($phids[$phid]);
}
}
if ($authors) {
$this->logEffect(self::DO_AUTHORS, $authors);
}
if (!$phids) {
return;
}
$reviewers = $object->getReviewerStatus();
$reviewers = mpull($reviewers, null, 'getReviewerPHID');
if ($is_blocking) {
$new_status = DifferentialReviewerStatus::STATUS_BLOCKING;
} else {
$new_status = DifferentialReviewerStatus::STATUS_ADDED;
}
$new_strength = DifferentialReviewerStatus::getStatusStrength(
$new_status);
$already = array();
foreach ($phids as $phid) {
if (!isset($reviewers[$phid])) {
continue;
}
// If we're applying a stronger status (usually, upgrading a reviewer
// into a blocking reviewer), skip this check so we apply the change.
$old_strength = DifferentialReviewerStatus::getStatusStrength(
$reviewers[$phid]->getStatus());
if ($old_strength <= $new_strength) {
continue;
}
$already[] = $phid;
unset($phids[$phid]);
}
if ($already) {
$this->logEffect(self::DO_ALREADY_REVIEWERS, $already);
}
if (!$phids) {
return;
}
$targets = id(new PhabricatorObjectQuery())
->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();
foreach ($phids as $phid) {
$value[$phid] = array(
'data' => array(
'status' => $new_status,
),
);
}
$edgetype_reviewer = DifferentialRevisionHasReviewerEdgeType::EDGECONST;
$xaction = $adapter->newTransaction()
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
->setMetadataValue('edge:type', $edgetype_reviewer)
->setNewValue(
array(
'+' => $value,
));
$adapter->queueTransaction($xaction);
if ($is_blocking) {
$this->logEffect(self::DO_ADD_BLOCKING_REVIEWERS, $phids);
} else {
$this->logEffect(self::DO_ADD_REVIEWERS, $phids);
}
}
protected function getActionEffectMap() {
return array(
self::DO_NO_TARGETS => array(
'icon' => 'fa-ban',
'color' => 'grey',
'name' => pht('No Targets'),
),
self::DO_AUTHORS => array(
'icon' => 'fa-user',
'color' => 'grey',
'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(
'icon' => 'fa-user',
'color' => 'green',
'name' => pht('Added Reviewers'),
),
self::DO_ADD_BLOCKING_REVIEWERS => array(
'icon' => 'fa-user',
'color' => 'green',
'name' => pht('Added Blocking Reviewers'),
),
);
}
public function renderActionEffectDescription($type, $data) {
switch ($type) {
case self::DO_NO_TARGETS:
return pht('Rule lists no targets.');
case self::DO_AUTHORS:
return pht(
'Declined to add revision author as reviewer: %s.',
$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:
return pht(
'Added %s reviewer(s): %s.',
new PhutilNumber(count($data)),
$this->renderHandleList($data));
case self::DO_ADD_BLOCKING_REVIEWERS:
return pht(
'Added %s blocking reviewer(s): %s.',
new PhutilNumber(count($data)),
$this->renderHandleList($data));
}
}
}