我尝试调整Phabricator的Herald规则,因此视图和编辑策略是根据项目成员资格设置的。目前,无法以自动方式调整基于项目的任务视图和编辑策略。
我在Haskell项目中找到了this modification,但这似乎不再起作用了。
有人可以告诉我如何修理它们吗?
<?php
/**
* Extends Herald with a custom 'Set "Visible To" policy' action for Maniphest
* tasks.
*/
final class SetTaskViewPolicyHeraldAction extends HeraldAction {
public function appliesToAdapter(HeraldAdapter $adapter) {
return $adapter instanceof HeraldManiphestTaskAdapter;
}
public function appliesToRuleType($type) {
return $type == HeraldRuleTypeConfig::RULE_TYPE_GLOBAL;
}
public function getActionKey() {
return 'custom:view-policy';
}
public function getActionName() {
return 'Set view policy to project';
}
public function getActionType() {
return HeraldAdapter::VALUE_PROJECT;
}
public function applyEffect(
HeraldAdapter $adapter,
$object,
HeraldEffect $effect) {
// First off, ensure there's only one set project
if (count($effect->getTarget()) != 1) {
throw new HeraldInvalidConditionException(
'Expected only one project to be set for visibility policy');
}
$project = $effect->getTarget();
$project_phid = $project[0];
// Set new value by queueing a transaction, and returning the transcript.
$adapter->queueTransaction(
id(new ManiphestTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
->setNewValue($project_phid));
return new HeraldApplyTranscript(
$effect,
true,
pht('Set view policy of task'));
}
}
我只添加旧版SetTaskViewPolicyHeraldAction.php
的源代码,this link还有文件SetTaskEditPolicyHeraldAction.php
,这也与我的问题有关。
答案 0 :(得分:1)
最终找到解决方案,或者更精确地编写扩展名。
<?php
final class HeraldManiphestMoveSpaceAction extends HeraldAction {
// ACTIONCONST: internal ID, unique (assumably for mapping objects)
const ACTIONCONST = 'space.move';
// supposably key for mapping history entries
const DO_MOVE_SPACE = 'do.move.space';
// entry in Herald action selection drop down menu when configuring a rule
public function getHeraldActionName() {
return pht('Move to space');
}
// section in Herald action selection drop down menu
public function getActionGroupKey() {
return HeraldSupportActionGroup::ACTIONGROUPKEY;
}
// source for input field
protected function getDatasource() {
return new PhabricatorSpacesNamespaceDatasource();
}
// which UI element to show when configuring the action
public function getHeraldActionStandardType() {
return self::STANDARD_PHID_LIST;
}
// allowed applicable objects
public function supportsObject($object) {
return ($object instanceof PhabricatorProjectInterface);
}
// permitted user roles (globally or locally)
public function supportsRuleType($rule_type) {
return ($rule_type == HeraldRuleTypeConfig::RULE_TYPE_GLOBAL);
}
// appearance in transcript
protected function getActionEffectMap() {
return array(
self::DO_MOVE_SPACE => array(
'icon' => 'fa-diamond',
'color' => 'green',
'name' => pht('Moved to space'),
),
);
}
// description of action that will be taken (present tense)
public function renderActionDescription($value) {
return pht('Move to space: %s.', $this->renderHandleList($value));
}
// description of action that has been taken (past tense, for history view etc.)
protected function renderActionEffectDescription($type, $data) {
switch ($type) {
case self::DO_MOVE_SPACE:
return pht(
'Moved to %s space: %s.',
phutil_count($data),
$this->renderHandleList($data));
}
}
// executed by Herald rules on objects that match condition (calls function applySpace)
public function applyEffect($object, HeraldEffect $effect) {
$current_space = array($object->getSpacePHID());
// allowed objects for transaction
$allowed_types = array(
PhabricatorSpacesNamespacePHIDType::TYPECONST,
);
// loadStandardTargets() figures out the to-set spaces from the Phabricator IDs ($phids)
// and excludes $current_space from this list, potentially resulting in an empty list (NULL).
// Misconfigured Herald action may result in an empty $phids.
$new_phids = $effect->getTarget();
$new_spaces = $this->loadStandardTargets($new_phids, $allowed_types, $current_space);
// if no spaces need to be set (either because of bad rule (see above comment), or space already manually set), avoid doing work
if(!$new_spaces) {
return;
} else {
// One object can only be at one space at a time. This silently fixes if one misconfigured Herald rule tries to move one object into different spaces.
$phid = head_key($new_spaces);
$adapter = $this->getAdapter();
$xaction = $adapter->newTransaction()
->setTransactionType(PhabricatorTransactions::TYPE_SPACE)
->setNewValue($phid);
$adapter->queueTransaction($xaction);
$this->logEffect(self::DO_MOVE_SPACE, array($phid));
}
}
}
这里应该注意一些事项(也在此扩展的Github repo中记录)。我使用这个扩展主要是为了在相应的空间中自动转移任务(基于项目管理),但它也应该适用于其他对象(所有可以有空间) - 但我还没有测试过它。
一个问题是,Herald不理解(还)对象只能有一个空间 - 如果适用多个Herald规则,它们都将被执行,而最后创建的那个将决定对象的空间。作为一种解决方法,Github仓库中还有一个补丁,它创建了一个“正是”的Herald规则。
diff --git a/src/applications/herald/adapter/HeraldAdapter.php b/src/applications/herald/adapter/HeraldAdapter.php
index 78ce86294..600033247 100644
--- a/src/applications/herald/adapter/HeraldAdapter.php
+++ b/src/applications/herald/adapter/HeraldAdapter.php
@@ -10,6 +10,7 @@ abstract class HeraldAdapter extends Phobject {
const CONDITION_IS_NOT_ANY = '!isany';
const CONDITION_INCLUDE_ALL = 'all';
const CONDITION_INCLUDE_ANY = 'any';
+ const CONDITION_INCLUDE_EXACTLY = 'exactly';
const CONDITION_INCLUDE_NONE = 'none';
const CONDITION_IS_ME = 'me';
const CONDITION_IS_NOT_ME = '!me';
@@ -335,6 +336,7 @@ abstract class HeraldAdapter extends Phobject {
self::CONDITION_IS_NOT_ANY => pht('is not any of'),
self::CONDITION_INCLUDE_ALL => pht('include all of'),
self::CONDITION_INCLUDE_ANY => pht('include any of'),
+ self::CONDITION_INCLUDE_EXACTLY => pht('is exactly'), // custom adaptation for projects
self::CONDITION_INCLUDE_NONE => pht('do not include'),
self::CONDITION_IS_ME => pht('is myself'),
self::CONDITION_IS_NOT_ME => pht('is not myself'),
@@ -432,6 +434,19 @@ abstract class HeraldAdapter extends Phobject {
return (bool)array_select_keys(
array_fuse($field_value),
$condition_value);
+ case self::CONDITION_INCLUDE_EXACTLY:
+ if (!is_array($field_value)) {
+ throw new HeraldInvalidConditionException(
+ pht('Object produced non-array value!'));
+ }
+ if (!is_array($condition_value)) {
+ throw new HeraldInvalidConditionException(
+ pht('Expected condition value to be an array.'));
+ }
+
+ $have = array_select_keys(array_fuse($field_value), $condition_value);
+ return (count($have) == count($condition_value) &&
+ count($have) == count(array_fuse($field_value)));
case self::CONDITION_INCLUDE_NONE:
return !array_select_keys(
array_fuse($field_value),
@@ -592,6 +607,7 @@ abstract class HeraldAdapter extends Phobject {
case self::CONDITION_IS_NOT_ANY:
case self::CONDITION_INCLUDE_ALL:
case self::CONDITION_INCLUDE_ANY:
+ case self::CONDITION_INCLUDE_EXACTLY:
case self::CONDITION_INCLUDE_NONE:
case self::CONDITION_IS_ME:
case self::CONDITION_IS_NOT_ME:
diff --git a/src/applications/herald/field/HeraldField.php b/src/applications/herald/field/HeraldField.php
index 2abed0ff1..8bbcfa3dd 100644
--- a/src/applications/herald/field/HeraldField.php
+++ b/src/applications/herald/field/HeraldField.php
@@ -58,6 +58,7 @@ abstract class HeraldField extends Phobject {
return array(
HeraldAdapter::CONDITION_INCLUDE_ALL,
HeraldAdapter::CONDITION_INCLUDE_ANY,
+ HeraldAdapter::CONDITION_INCLUDE_EXACTLY,
HeraldAdapter::CONDITION_INCLUDE_NONE,
HeraldAdapter::CONDITION_EXISTS,
HeraldAdapter::CONDITION_NOT_EXISTS,
diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldPHIDs.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldPHIDs.php
index 78c8caa5a..be267d2e4 100644
--- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldPHIDs.php
+++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldPHIDs.php
@@ -235,6 +235,7 @@ abstract class PhabricatorStandardCustomFieldPHIDs
return array(
HeraldAdapter::CONDITION_INCLUDE_ALL,
HeraldAdapter::CONDITION_INCLUDE_ANY,
+ HeraldAdapter::CONDITION_INCLUDE_EXACTLY,
HeraldAdapter::CONDITION_INCLUDE_NONE,
HeraldAdapter::CONDITION_EXISTS,
HeraldAdapter::CONDITION_NOT_EXISTS,
请查看Github repo中的README.md以获取更多详细信息。