Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14361911
D13488.id32631.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
10 KB
Referenced Files
None
Subscribers
None
D13488.id32631.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D13488: Begin modularizing Herald fields
Attached
Detach File
Event Timeline
Log In to Comment