Page MenuHomePhabricator

D13488.id32631.diff
No OneTemporary

D13488.id32631.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -930,6 +930,7 @@
'HeraldCommitAdapter' => 'applications/herald/adapter/HeraldCommitAdapter.php',
'HeraldCondition' => 'applications/herald/storage/HeraldCondition.php',
'HeraldConditionTranscript' => 'applications/herald/storage/transcript/HeraldConditionTranscript.php',
+ 'HeraldContentSourceField' => 'applications/herald/field/HeraldContentSourceField.php',
'HeraldController' => 'applications/herald/controller/HeraldController.php',
'HeraldCustomAction' => 'applications/herald/extension/HeraldCustomAction.php',
'HeraldDAO' => 'applications/herald/storage/HeraldDAO.php',
@@ -939,6 +940,7 @@
'HeraldDisableController' => 'applications/herald/controller/HeraldDisableController.php',
'HeraldEffect' => 'applications/herald/engine/HeraldEffect.php',
'HeraldEngine' => 'applications/herald/engine/HeraldEngine.php',
+ 'HeraldField' => 'applications/herald/field/HeraldField.php',
'HeraldInvalidActionException' => 'applications/herald/engine/exception/HeraldInvalidActionException.php',
'HeraldInvalidConditionException' => 'applications/herald/engine/exception/HeraldInvalidConditionException.php',
'HeraldManageGlobalRulesCapability' => 'applications/herald/capability/HeraldManageGlobalRulesCapability.php',
@@ -4422,6 +4424,7 @@
'HeraldCommitAdapter' => 'HeraldAdapter',
'HeraldCondition' => 'HeraldDAO',
'HeraldConditionTranscript' => 'Phobject',
+ 'HeraldContentSourceField' => 'HeraldField',
'HeraldController' => 'PhabricatorController',
'HeraldCustomAction' => 'Phobject',
'HeraldDAO' => 'PhabricatorLiskDAO',
@@ -4431,6 +4434,7 @@
'HeraldDisableController' => 'HeraldController',
'HeraldEffect' => 'Phobject',
'HeraldEngine' => 'Phobject',
+ 'HeraldField' => 'Phobject',
'HeraldInvalidActionException' => 'Exception',
'HeraldInvalidConditionException' => 'Exception',
'HeraldManageGlobalRulesCapability' => 'PhabricatorPolicyCapability',
diff --git a/src/applications/herald/adapter/HeraldAdapter.php b/src/applications/herald/adapter/HeraldAdapter.php
--- a/src/applications/herald/adapter/HeraldAdapter.php
+++ b/src/applications/herald/adapter/HeraldAdapter.php
@@ -24,7 +24,6 @@
const FIELD_RULE = 'rule';
const FIELD_AFFECTED_PACKAGE = 'affected-package';
const FIELD_AFFECTED_PACKAGE_OWNER = 'affected-package-owner';
- const FIELD_CONTENT_SOURCE = 'contentsource';
const FIELD_ALWAYS = 'always';
const FIELD_AUTHOR_PROJECTS = 'authorprojects';
const FIELD_PROJECTS = 'projects';
@@ -113,6 +112,7 @@
private $emailPHIDs = array();
private $forcedEmailPHIDs = array();
private $unsubscribedPHIDs;
+ private $fieldMap;
public function getEmailPHIDs() {
return array_values($this->emailPHIDs);
@@ -190,11 +190,14 @@
abstract public function getHeraldName();
public function getHeraldField($field_name) {
+ $impl = $this->getFieldImplementation($field_name);
+ if ($impl) {
+ return $impl->getHeraldFieldValue($this->getObject());
+ }
+
switch ($field_name) {
case self::FIELD_RULE:
return null;
- case self::FIELD_CONTENT_SOURCE:
- return $this->getContentSource()->getSource();
case self::FIELD_ALWAYS:
return true;
case self::FIELD_IS_NEW_OBJECT:
@@ -354,9 +357,52 @@
/* -( 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() {
- $fields = array();
+ $fields = array_keys($this->getFieldImplementationMap());
$fields[] = self::FIELD_ALWAYS;
$fields[] = self::FIELD_RULE;
@@ -373,7 +419,9 @@
}
public function getFieldNameMap() {
- return array(
+ $map = mpull($this->getFieldImplementationMap(), 'getHeraldFieldName');
+
+ return $map + array(
self::FIELD_TITLE => pht('Title'),
self::FIELD_BODY => pht('Body'),
self::FIELD_AUTHOR => pht('Author'),
@@ -394,7 +442,6 @@
self::FIELD_AFFECTED_PACKAGE => pht('Any affected package'),
self::FIELD_AFFECTED_PACKAGE_OWNER =>
pht("Any affected package's owner"),
- self::FIELD_CONTENT_SOURCE => pht('Content Source'),
self::FIELD_ALWAYS => pht('Always'),
self::FIELD_AUTHOR_PROJECTS => pht("Author's projects"),
self::FIELD_PROJECTS => pht('Projects'),
@@ -452,6 +499,11 @@
}
public function getConditionsForField($field) {
+ $impl = $this->getFieldImplementation($field);
+ if ($impl) {
+ return $impl->getHeraldFieldConditions();
+ }
+
switch ($field) {
case self::FIELD_TITLE:
case self::FIELD_BODY:
@@ -526,11 +578,6 @@
self::CONDITION_RULE,
self::CONDITION_NOT_RULE,
);
- case self::FIELD_CONTENT_SOURCE:
- return array(
- self::CONDITION_IS,
- self::CONDITION_IS_NOT,
- );
case self::FIELD_ALWAYS:
return array(
self::CONDITION_UNCONDITIONALLY,
@@ -940,6 +987,10 @@
public function getValueTypeForFieldAndCondition($field, $condition) {
+ $impl = $this->getFieldImplementation($field);
+ if ($impl) {
+ return $impl->getHeraldFieldValueType($condition);
+ }
if ($this->isHeraldCustomKey($field)) {
$value_type = $this->getCustomFieldValueTypeForFieldAndCondition(
@@ -958,13 +1009,7 @@
return self::VALUE_TEXT;
case self::CONDITION_IS:
case self::CONDITION_IS_NOT:
- switch ($field) {
- case self::FIELD_CONTENT_SOURCE:
- return self::VALUE_CONTENT_SOURCE;
- default:
- return self::VALUE_TEXT;
- }
- break;
+ return self::VALUE_TEXT;
case self::CONDITION_IS_ANY:
case self::CONDITION_IS_NOT_ANY:
switch ($field) {
diff --git a/src/applications/herald/adapter/HeraldManiphestTaskAdapter.php b/src/applications/herald/adapter/HeraldManiphestTaskAdapter.php
--- a/src/applications/herald/adapter/HeraldManiphestTaskAdapter.php
+++ b/src/applications/herald/adapter/HeraldManiphestTaskAdapter.php
@@ -67,7 +67,6 @@
self::FIELD_AUTHOR,
self::FIELD_ASSIGNEE,
self::FIELD_CC,
- self::FIELD_CONTENT_SOURCE,
self::FIELD_PROJECTS,
self::FIELD_TASK_PRIORITY,
self::FIELD_TASK_STATUS,
diff --git a/src/applications/herald/field/HeraldContentSourceField.php b/src/applications/herald/field/HeraldContentSourceField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/herald/field/HeraldContentSourceField.php
@@ -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;
+ }
+
+}
diff --git a/src/applications/herald/field/HeraldField.php b/src/applications/herald/field/HeraldField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/herald/field/HeraldField.php
@@ -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();
+ }
+
+}

File Metadata

Mime Type
text/plain
Expires
Sat, Dec 21, 12:09 PM (16 h, 26 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6913926
Default Alt Text
D13488.id32631.diff (10 KB)

Event Timeline