mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-20 05:42:40 +01:00
Begin modularizing Herald fields
Summary: Ref T8726. This lays groundwork for modularizing Herald fields and modularizes the "Content source" field. This doesn't touch conditions or values yet. Test Plan: Created a rule with a "content source" field, created a new task, saw rule apply. Reviewers: btrahan Reviewed By: btrahan Subscribers: eadler, joshuaspence, epriestley Maniphest Tasks: T8726 Differential Revision: https://secure.phabricator.com/D13488
This commit is contained in:
parent
d9ab267de6
commit
b266412f3e
5 changed files with 157 additions and 19 deletions
|
@ -934,6 +934,7 @@ phutil_register_library_map(array(
|
||||||
'HeraldCommitAdapter' => 'applications/herald/adapter/HeraldCommitAdapter.php',
|
'HeraldCommitAdapter' => 'applications/herald/adapter/HeraldCommitAdapter.php',
|
||||||
'HeraldCondition' => 'applications/herald/storage/HeraldCondition.php',
|
'HeraldCondition' => 'applications/herald/storage/HeraldCondition.php',
|
||||||
'HeraldConditionTranscript' => 'applications/herald/storage/transcript/HeraldConditionTranscript.php',
|
'HeraldConditionTranscript' => 'applications/herald/storage/transcript/HeraldConditionTranscript.php',
|
||||||
|
'HeraldContentSourceField' => 'applications/herald/field/HeraldContentSourceField.php',
|
||||||
'HeraldController' => 'applications/herald/controller/HeraldController.php',
|
'HeraldController' => 'applications/herald/controller/HeraldController.php',
|
||||||
'HeraldCustomAction' => 'applications/herald/extension/HeraldCustomAction.php',
|
'HeraldCustomAction' => 'applications/herald/extension/HeraldCustomAction.php',
|
||||||
'HeraldDAO' => 'applications/herald/storage/HeraldDAO.php',
|
'HeraldDAO' => 'applications/herald/storage/HeraldDAO.php',
|
||||||
|
@ -943,6 +944,7 @@ phutil_register_library_map(array(
|
||||||
'HeraldDisableController' => 'applications/herald/controller/HeraldDisableController.php',
|
'HeraldDisableController' => 'applications/herald/controller/HeraldDisableController.php',
|
||||||
'HeraldEffect' => 'applications/herald/engine/HeraldEffect.php',
|
'HeraldEffect' => 'applications/herald/engine/HeraldEffect.php',
|
||||||
'HeraldEngine' => 'applications/herald/engine/HeraldEngine.php',
|
'HeraldEngine' => 'applications/herald/engine/HeraldEngine.php',
|
||||||
|
'HeraldField' => 'applications/herald/field/HeraldField.php',
|
||||||
'HeraldInvalidActionException' => 'applications/herald/engine/exception/HeraldInvalidActionException.php',
|
'HeraldInvalidActionException' => 'applications/herald/engine/exception/HeraldInvalidActionException.php',
|
||||||
'HeraldInvalidConditionException' => 'applications/herald/engine/exception/HeraldInvalidConditionException.php',
|
'HeraldInvalidConditionException' => 'applications/herald/engine/exception/HeraldInvalidConditionException.php',
|
||||||
'HeraldManageGlobalRulesCapability' => 'applications/herald/capability/HeraldManageGlobalRulesCapability.php',
|
'HeraldManageGlobalRulesCapability' => 'applications/herald/capability/HeraldManageGlobalRulesCapability.php',
|
||||||
|
@ -4429,6 +4431,7 @@ phutil_register_library_map(array(
|
||||||
'HeraldCommitAdapter' => 'HeraldAdapter',
|
'HeraldCommitAdapter' => 'HeraldAdapter',
|
||||||
'HeraldCondition' => 'HeraldDAO',
|
'HeraldCondition' => 'HeraldDAO',
|
||||||
'HeraldConditionTranscript' => 'Phobject',
|
'HeraldConditionTranscript' => 'Phobject',
|
||||||
|
'HeraldContentSourceField' => 'HeraldField',
|
||||||
'HeraldController' => 'PhabricatorController',
|
'HeraldController' => 'PhabricatorController',
|
||||||
'HeraldCustomAction' => 'Phobject',
|
'HeraldCustomAction' => 'Phobject',
|
||||||
'HeraldDAO' => 'PhabricatorLiskDAO',
|
'HeraldDAO' => 'PhabricatorLiskDAO',
|
||||||
|
@ -4438,6 +4441,7 @@ phutil_register_library_map(array(
|
||||||
'HeraldDisableController' => 'HeraldController',
|
'HeraldDisableController' => 'HeraldController',
|
||||||
'HeraldEffect' => 'Phobject',
|
'HeraldEffect' => 'Phobject',
|
||||||
'HeraldEngine' => 'Phobject',
|
'HeraldEngine' => 'Phobject',
|
||||||
|
'HeraldField' => 'Phobject',
|
||||||
'HeraldInvalidActionException' => 'Exception',
|
'HeraldInvalidActionException' => 'Exception',
|
||||||
'HeraldInvalidConditionException' => 'Exception',
|
'HeraldInvalidConditionException' => 'Exception',
|
||||||
'HeraldManageGlobalRulesCapability' => 'PhabricatorPolicyCapability',
|
'HeraldManageGlobalRulesCapability' => 'PhabricatorPolicyCapability',
|
||||||
|
|
|
@ -24,7 +24,6 @@ abstract class HeraldAdapter extends Phobject {
|
||||||
const FIELD_RULE = 'rule';
|
const FIELD_RULE = 'rule';
|
||||||
const FIELD_AFFECTED_PACKAGE = 'affected-package';
|
const FIELD_AFFECTED_PACKAGE = 'affected-package';
|
||||||
const FIELD_AFFECTED_PACKAGE_OWNER = 'affected-package-owner';
|
const FIELD_AFFECTED_PACKAGE_OWNER = 'affected-package-owner';
|
||||||
const FIELD_CONTENT_SOURCE = 'contentsource';
|
|
||||||
const FIELD_ALWAYS = 'always';
|
const FIELD_ALWAYS = 'always';
|
||||||
const FIELD_AUTHOR_PROJECTS = 'authorprojects';
|
const FIELD_AUTHOR_PROJECTS = 'authorprojects';
|
||||||
const FIELD_PROJECTS = 'projects';
|
const FIELD_PROJECTS = 'projects';
|
||||||
|
@ -113,6 +112,7 @@ abstract class HeraldAdapter extends Phobject {
|
||||||
private $emailPHIDs = array();
|
private $emailPHIDs = array();
|
||||||
private $forcedEmailPHIDs = array();
|
private $forcedEmailPHIDs = array();
|
||||||
private $unsubscribedPHIDs;
|
private $unsubscribedPHIDs;
|
||||||
|
private $fieldMap;
|
||||||
|
|
||||||
public function getEmailPHIDs() {
|
public function getEmailPHIDs() {
|
||||||
return array_values($this->emailPHIDs);
|
return array_values($this->emailPHIDs);
|
||||||
|
@ -190,11 +190,14 @@ abstract class HeraldAdapter extends Phobject {
|
||||||
abstract public function getHeraldName();
|
abstract public function getHeraldName();
|
||||||
|
|
||||||
public function getHeraldField($field_name) {
|
public function getHeraldField($field_name) {
|
||||||
|
$impl = $this->getFieldImplementation($field_name);
|
||||||
|
if ($impl) {
|
||||||
|
return $impl->getHeraldFieldValue($this->getObject());
|
||||||
|
}
|
||||||
|
|
||||||
switch ($field_name) {
|
switch ($field_name) {
|
||||||
case self::FIELD_RULE:
|
case self::FIELD_RULE:
|
||||||
return null;
|
return null;
|
||||||
case self::FIELD_CONTENT_SOURCE:
|
|
||||||
return $this->getContentSource()->getSource();
|
|
||||||
case self::FIELD_ALWAYS:
|
case self::FIELD_ALWAYS:
|
||||||
return true;
|
return true;
|
||||||
case self::FIELD_IS_NEW_OBJECT:
|
case self::FIELD_IS_NEW_OBJECT:
|
||||||
|
@ -354,9 +357,52 @@ abstract class HeraldAdapter extends Phobject {
|
||||||
|
|
||||||
/* -( Fields )------------------------------------------------------------- */
|
/* -( Fields )------------------------------------------------------------- */
|
||||||
|
|
||||||
|
private function getFieldImplementationMap() {
|
||||||
|
if ($this->fieldMap === null) {
|
||||||
|
// We can't use PhutilClassMapQuery here because field expansion
|
||||||
|
// depends on the adapter and object.
|
||||||
|
|
||||||
|
$object = $this->getObject();
|
||||||
|
|
||||||
|
$map = array();
|
||||||
|
$all = HeraldField::getAllFields();
|
||||||
|
foreach ($all as $key => $field) {
|
||||||
|
if (!$field->supportsObject($object)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$subfields = $field->getFieldsForObject($object);
|
||||||
|
foreach ($subfields as $subkey => $subfield) {
|
||||||
|
if (isset($map[$subkey])) {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'Two HeraldFields (of classes "%s" and "%s") have the same '.
|
||||||
|
'field key ("%s") after expansion for an object of class '.
|
||||||
|
'"%s" inside adapter "%s". Each field must have a unique '.
|
||||||
|
'field key.',
|
||||||
|
get_class($subfield),
|
||||||
|
get_class($map[$subkey]),
|
||||||
|
$subkey,
|
||||||
|
get_class($object),
|
||||||
|
get_class($this)));
|
||||||
|
}
|
||||||
|
|
||||||
|
$subfield = id(clone $subfield)->setAdapter($this);
|
||||||
|
|
||||||
|
$map[$subkey] = $subfield;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->fieldMap = $map;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->fieldMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getFieldImplementation($key) {
|
||||||
|
return idx($this->getFieldImplementationMap(), $key);
|
||||||
|
}
|
||||||
|
|
||||||
public function getFields() {
|
public function getFields() {
|
||||||
$fields = array();
|
$fields = array_keys($this->getFieldImplementationMap());
|
||||||
|
|
||||||
$fields[] = self::FIELD_ALWAYS;
|
$fields[] = self::FIELD_ALWAYS;
|
||||||
$fields[] = self::FIELD_RULE;
|
$fields[] = self::FIELD_RULE;
|
||||||
|
@ -373,7 +419,9 @@ abstract class HeraldAdapter extends Phobject {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFieldNameMap() {
|
public function getFieldNameMap() {
|
||||||
return array(
|
$map = mpull($this->getFieldImplementationMap(), 'getHeraldFieldName');
|
||||||
|
|
||||||
|
return $map + array(
|
||||||
self::FIELD_TITLE => pht('Title'),
|
self::FIELD_TITLE => pht('Title'),
|
||||||
self::FIELD_BODY => pht('Body'),
|
self::FIELD_BODY => pht('Body'),
|
||||||
self::FIELD_AUTHOR => pht('Author'),
|
self::FIELD_AUTHOR => pht('Author'),
|
||||||
|
@ -394,7 +442,6 @@ abstract class HeraldAdapter extends Phobject {
|
||||||
self::FIELD_AFFECTED_PACKAGE => pht('Any affected package'),
|
self::FIELD_AFFECTED_PACKAGE => pht('Any affected package'),
|
||||||
self::FIELD_AFFECTED_PACKAGE_OWNER =>
|
self::FIELD_AFFECTED_PACKAGE_OWNER =>
|
||||||
pht("Any affected package's owner"),
|
pht("Any affected package's owner"),
|
||||||
self::FIELD_CONTENT_SOURCE => pht('Content Source'),
|
|
||||||
self::FIELD_ALWAYS => pht('Always'),
|
self::FIELD_ALWAYS => pht('Always'),
|
||||||
self::FIELD_AUTHOR_PROJECTS => pht("Author's projects"),
|
self::FIELD_AUTHOR_PROJECTS => pht("Author's projects"),
|
||||||
self::FIELD_PROJECTS => pht('Projects'),
|
self::FIELD_PROJECTS => pht('Projects'),
|
||||||
|
@ -452,6 +499,11 @@ abstract class HeraldAdapter extends Phobject {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getConditionsForField($field) {
|
public function getConditionsForField($field) {
|
||||||
|
$impl = $this->getFieldImplementation($field);
|
||||||
|
if ($impl) {
|
||||||
|
return $impl->getHeraldFieldConditions();
|
||||||
|
}
|
||||||
|
|
||||||
switch ($field) {
|
switch ($field) {
|
||||||
case self::FIELD_TITLE:
|
case self::FIELD_TITLE:
|
||||||
case self::FIELD_BODY:
|
case self::FIELD_BODY:
|
||||||
|
@ -526,11 +578,6 @@ abstract class HeraldAdapter extends Phobject {
|
||||||
self::CONDITION_RULE,
|
self::CONDITION_RULE,
|
||||||
self::CONDITION_NOT_RULE,
|
self::CONDITION_NOT_RULE,
|
||||||
);
|
);
|
||||||
case self::FIELD_CONTENT_SOURCE:
|
|
||||||
return array(
|
|
||||||
self::CONDITION_IS,
|
|
||||||
self::CONDITION_IS_NOT,
|
|
||||||
);
|
|
||||||
case self::FIELD_ALWAYS:
|
case self::FIELD_ALWAYS:
|
||||||
return array(
|
return array(
|
||||||
self::CONDITION_UNCONDITIONALLY,
|
self::CONDITION_UNCONDITIONALLY,
|
||||||
|
@ -940,6 +987,10 @@ abstract class HeraldAdapter extends Phobject {
|
||||||
|
|
||||||
|
|
||||||
public function getValueTypeForFieldAndCondition($field, $condition) {
|
public function getValueTypeForFieldAndCondition($field, $condition) {
|
||||||
|
$impl = $this->getFieldImplementation($field);
|
||||||
|
if ($impl) {
|
||||||
|
return $impl->getHeraldFieldValueType($condition);
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->isHeraldCustomKey($field)) {
|
if ($this->isHeraldCustomKey($field)) {
|
||||||
$value_type = $this->getCustomFieldValueTypeForFieldAndCondition(
|
$value_type = $this->getCustomFieldValueTypeForFieldAndCondition(
|
||||||
|
@ -958,13 +1009,7 @@ abstract class HeraldAdapter extends Phobject {
|
||||||
return self::VALUE_TEXT;
|
return self::VALUE_TEXT;
|
||||||
case self::CONDITION_IS:
|
case self::CONDITION_IS:
|
||||||
case self::CONDITION_IS_NOT:
|
case self::CONDITION_IS_NOT:
|
||||||
switch ($field) {
|
|
||||||
case self::FIELD_CONTENT_SOURCE:
|
|
||||||
return self::VALUE_CONTENT_SOURCE;
|
|
||||||
default:
|
|
||||||
return self::VALUE_TEXT;
|
return self::VALUE_TEXT;
|
||||||
}
|
|
||||||
break;
|
|
||||||
case self::CONDITION_IS_ANY:
|
case self::CONDITION_IS_ANY:
|
||||||
case self::CONDITION_IS_NOT_ANY:
|
case self::CONDITION_IS_NOT_ANY:
|
||||||
switch ($field) {
|
switch ($field) {
|
||||||
|
|
|
@ -67,7 +67,6 @@ final class HeraldManiphestTaskAdapter extends HeraldAdapter {
|
||||||
self::FIELD_AUTHOR,
|
self::FIELD_AUTHOR,
|
||||||
self::FIELD_ASSIGNEE,
|
self::FIELD_ASSIGNEE,
|
||||||
self::FIELD_CC,
|
self::FIELD_CC,
|
||||||
self::FIELD_CONTENT_SOURCE,
|
|
||||||
self::FIELD_PROJECTS,
|
self::FIELD_PROJECTS,
|
||||||
self::FIELD_TASK_PRIORITY,
|
self::FIELD_TASK_PRIORITY,
|
||||||
self::FIELD_TASK_STATUS,
|
self::FIELD_TASK_STATUS,
|
||||||
|
|
30
src/applications/herald/field/HeraldContentSourceField.php
Normal file
30
src/applications/herald/field/HeraldContentSourceField.php
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class HeraldContentSourceField extends HeraldField {
|
||||||
|
|
||||||
|
const FIELDCONST = 'contentsource';
|
||||||
|
|
||||||
|
public function getHeraldFieldName() {
|
||||||
|
return pht('Content source');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHeraldFieldValue($object) {
|
||||||
|
return $this->getAdapter()->getContentSource()->getSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHeraldFieldConditions() {
|
||||||
|
return array(
|
||||||
|
HeraldAdapter::CONDITION_IS,
|
||||||
|
HeraldAdapter::CONDITION_IS_NOT,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHeraldFieldValueType($condition) {
|
||||||
|
return HeraldAdapter::VALUE_CONTENT_SOURCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function supportsObject($object) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
60
src/applications/herald/field/HeraldField.php
Normal file
60
src/applications/herald/field/HeraldField.php
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
abstract class HeraldField extends Phobject {
|
||||||
|
|
||||||
|
private $adapter;
|
||||||
|
|
||||||
|
abstract public function getHeraldFieldName();
|
||||||
|
abstract public function getHeraldFieldValue($object);
|
||||||
|
abstract public function getHeraldFieldConditions();
|
||||||
|
abstract public function getHeraldFieldValueType($condition);
|
||||||
|
|
||||||
|
abstract public function supportsObject($object);
|
||||||
|
|
||||||
|
public function getFieldsForObject($object) {
|
||||||
|
return array($this->getFieldConstant() => $this);
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function setAdapter(HeraldAdapter $adapter) {
|
||||||
|
$this->adapter = $adapter;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function getAdapter() {
|
||||||
|
return $this->adapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function getFieldConstant() {
|
||||||
|
$class = new ReflectionClass($this);
|
||||||
|
|
||||||
|
$const = $class->getConstant('FIELDCONST');
|
||||||
|
if ($const === false) {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'"%s" class "%s" must define a "%s" property.',
|
||||||
|
__CLASS__,
|
||||||
|
get_class($this),
|
||||||
|
'FIELDCONST'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_string($const) || (strlen($const) > 32)) {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'"%s" class "%s" has an invalid "%s" property. Field constants '.
|
||||||
|
'must be strings and no more than 32 bytes in length.',
|
||||||
|
__CLASS__,
|
||||||
|
get_class($this),
|
||||||
|
'FIELDCONST'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $const;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public static function getAllFields() {
|
||||||
|
return id(new PhutilClassMapQuery())
|
||||||
|
->setAncestorClass(__CLASS__)
|
||||||
|
->setUniqueMethod('getFieldConstant')
|
||||||
|
->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue