Page MenuHomePhabricator

D18954.id45453.diff
No OneTemporary

D18954.id45453.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
@@ -2583,6 +2583,7 @@
'PhabricatorCustomFieldEditEngineExtension' => 'infrastructure/customfield/engineextension/PhabricatorCustomFieldEditEngineExtension.php',
'PhabricatorCustomFieldEditField' => 'infrastructure/customfield/editor/PhabricatorCustomFieldEditField.php',
'PhabricatorCustomFieldEditType' => 'infrastructure/customfield/editor/PhabricatorCustomFieldEditType.php',
+ 'PhabricatorCustomFieldExportEngineExtension' => 'infrastructure/export/PhabricatorCustomFieldExportEngineExtension.php',
'PhabricatorCustomFieldFulltextEngineExtension' => 'infrastructure/customfield/engineextension/PhabricatorCustomFieldFulltextEngineExtension.php',
'PhabricatorCustomFieldHeraldAction' => 'infrastructure/customfield/herald/PhabricatorCustomFieldHeraldAction.php',
'PhabricatorCustomFieldHeraldActionGroup' => 'infrastructure/customfield/herald/PhabricatorCustomFieldHeraldActionGroup.php',
@@ -2847,6 +2848,7 @@
'PhabricatorEventType' => 'infrastructure/events/constant/PhabricatorEventType.php',
'PhabricatorExampleEventListener' => 'infrastructure/events/PhabricatorExampleEventListener.php',
'PhabricatorExecFutureFileUploadSource' => 'applications/files/uploadsource/PhabricatorExecFutureFileUploadSource.php',
+ 'PhabricatorExportEngineExtension' => 'infrastructure/export/PhabricatorExportEngineExtension.php',
'PhabricatorExportField' => 'infrastructure/export/PhabricatorExportField.php',
'PhabricatorExportFormat' => 'infrastructure/export/PhabricatorExportFormat.php',
'PhabricatorExtendedPolicyInterface' => 'applications/policy/interface/PhabricatorExtendedPolicyInterface.php',
@@ -7991,6 +7993,7 @@
'PhabricatorCustomFieldEditEngineExtension' => 'PhabricatorEditEngineExtension',
'PhabricatorCustomFieldEditField' => 'PhabricatorEditField',
'PhabricatorCustomFieldEditType' => 'PhabricatorEditType',
+ 'PhabricatorCustomFieldExportEngineExtension' => 'PhabricatorExportEngineExtension',
'PhabricatorCustomFieldFulltextEngineExtension' => 'PhabricatorFulltextEngineExtension',
'PhabricatorCustomFieldHeraldAction' => 'HeraldAction',
'PhabricatorCustomFieldHeraldActionGroup' => 'HeraldActionGroup',
@@ -8280,6 +8283,7 @@
'PhabricatorEventType' => 'PhutilEventType',
'PhabricatorExampleEventListener' => 'PhabricatorEventListener',
'PhabricatorExecFutureFileUploadSource' => 'PhabricatorFileUploadSource',
+ 'PhabricatorExportEngineExtension' => 'Phobject',
'PhabricatorExportField' => 'Phobject',
'PhabricatorExportFormat' => 'Phobject',
'PhabricatorExtendingPhabricatorConfigOptions' => 'PhabricatorApplicationConfigOptions',
diff --git a/src/applications/search/engine/PhabricatorApplicationSearchEngine.php b/src/applications/search/engine/PhabricatorApplicationSearchEngine.php
--- a/src/applications/search/engine/PhabricatorApplicationSearchEngine.php
+++ b/src/applications/search/engine/PhabricatorApplicationSearchEngine.php
@@ -1483,6 +1483,26 @@
$fields[$key] = $export_field;
}
+ $extensions = $this->newExportExtensions();
+ foreach ($extensions as $extension) {
+ $extension_fields = $extension->newExportFields();
+ foreach ($extension_fields as $extension_field) {
+ $key = $extension_field->getKey();
+
+ if (isset($fields[$key])) {
+ throw new Exception(
+ pht(
+ 'Export engine extension ("%s") defines an export field with '.
+ 'a key ("%s") that collides with another field. Each field '.
+ 'must have a unique key.',
+ get_class($extension_field),
+ $key));
+ }
+
+ $fields[$key] = $extension_field;
+ }
+ }
+
return $fields;
}
@@ -1514,6 +1534,25 @@
$maps[$ii] += $export_data[$ii];
}
+ $extensions = $this->newExportExtensions();
+ foreach ($extensions as $extension) {
+ $extension_data = $extension->newExportData($objects);
+ $extension_data = array_values($extension_data);
+ if (count($export_data) !== count($objects)) {
+ throw new Exception(
+ pht(
+ 'Export engine extension ("%s") exported the wrong number of '.
+ 'objects, expected %s but got %s.',
+ get_class($extension),
+ phutil_count($objects),
+ phutil_count($export_data)));
+ }
+
+ for ($ii = 0; $ii < $n; $ii++) {
+ $maps[$ii] += $extension_data[$ii];
+ }
+ }
+
return $maps;
}
@@ -1525,4 +1564,23 @@
throw new PhutilMethodNotImplementedException();
}
+ private function newExportExtensions() {
+ $object = $this->newResultObject();
+ $viewer = $this->requireViewer();
+
+ $extensions = PhabricatorExportEngineExtension::getAllExtensions();
+
+ $supported = array();
+ foreach ($extensions as $extension) {
+ $extension = clone $extension;
+ $extension->setViewer($viewer);
+
+ if ($extension->supportsObject($object)) {
+ $supported[] = $extension;
+ }
+ }
+
+ return $supported;
+ }
+
}
diff --git a/src/infrastructure/customfield/field/PhabricatorCustomField.php b/src/infrastructure/customfield/field/PhabricatorCustomField.php
--- a/src/infrastructure/customfield/field/PhabricatorCustomField.php
+++ b/src/infrastructure/customfield/field/PhabricatorCustomField.php
@@ -35,6 +35,7 @@
const ROLE_HERALD = 'herald';
const ROLE_EDITENGINE = 'EditEngine';
const ROLE_HERALDACTION = 'herald.action';
+ const ROLE_EXPORT = 'export';
/* -( Building Applications with Custom Fields )--------------------------- */
@@ -299,6 +300,8 @@
case self::ROLE_EDITENGINE:
return $this->shouldAppearInEditView() ||
$this->shouldAppearInEditEngine();
+ case self::ROLE_EXPORT:
+ return $this->shouldAppearInDataExport();
case self::ROLE_DEFAULT:
return true;
default:
@@ -1362,6 +1365,46 @@
}
+/* -( Data Export )-------------------------------------------------------- */
+
+
+ public function shouldAppearInDataExport() {
+ if ($this->proxy) {
+ return $this->proxy->shouldAppearInDataExport();
+ }
+
+ try {
+ $this->newExportFieldType();
+ return true;
+ } catch (PhabricatorCustomFieldImplementationIncompleteException $ex) {
+ return false;
+ }
+ }
+
+ public function newExportField() {
+ if ($this->proxy) {
+ return $this->proxy->newExportField();
+ }
+
+ return $this->newExportFieldType()
+ ->setLabel($this->getFieldName());
+ }
+
+ public function newExportData() {
+ if ($this->proxy) {
+ return $this->proxy->newExportData();
+ }
+ throw new PhabricatorCustomFieldImplementationIncompleteException($this);
+ }
+
+ protected function newExportFieldType() {
+ if ($this->proxy) {
+ return $this->proxy->newExportFieldType();
+ }
+ throw new PhabricatorCustomFieldImplementationIncompleteException($this);
+ }
+
+
/* -( Conduit )------------------------------------------------------------ */
diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php
--- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php
+++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php
@@ -496,5 +496,8 @@
return $this->getFieldValue();
}
+ public function newExportData() {
+ return $this->getFieldValue();
+ }
}
diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldInt.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldInt.php
--- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldInt.php
+++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldInt.php
@@ -124,4 +124,8 @@
return new ConduitIntParameterType();
}
+ protected function newExportFieldType() {
+ return new PhabricatorIntExportField();
+ }
+
}
diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldText.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldText.php
--- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldText.php
+++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldText.php
@@ -76,4 +76,8 @@
return new ConduitStringParameterType();
}
+ protected function newExportFieldType() {
+ return new PhabricatorStringExportField();
+ }
+
}
diff --git a/src/infrastructure/export/PhabricatorCustomFieldExportEngineExtension.php b/src/infrastructure/export/PhabricatorCustomFieldExportEngineExtension.php
new file mode 100644
--- /dev/null
+++ b/src/infrastructure/export/PhabricatorCustomFieldExportEngineExtension.php
@@ -0,0 +1,86 @@
+<?php
+
+final class PhabricatorCustomFieldExportEngineExtension
+ extends PhabricatorExportEngineExtension {
+
+ const EXTENSIONKEY = 'custom-field';
+
+ private $object;
+
+ public function supportsObject($object) {
+ $this->object = $object;
+ return ($object instanceof PhabricatorCustomFieldInterface);
+ }
+
+ public function newExportFields() {
+ $prototype = $this->object;
+
+ $fields = $this->newCustomFields($prototype);
+
+ $results = array();
+ foreach ($fields as $field) {
+ $field_key = $field->getModernFieldKey();
+
+ $results[] = $field->newExportField()
+ ->setKey($field_key);
+ }
+
+ return $results;
+ }
+
+ public function newExportData(array $objects) {
+ $viewer = $this->getViewer();
+
+ $field_map = array();
+ foreach ($objects as $object) {
+ $object_phid = $object->getPHID();
+
+ $fields = PhabricatorCustomField::getObjectFields(
+ $object,
+ PhabricatorCustomField::ROLE_EXPORT);
+
+ $fields
+ ->setViewer($viewer)
+ ->readFieldsFromObject($object);
+
+ $field_map[$object_phid] = $fields;
+ }
+
+ $all_fields = array();
+ foreach ($field_map as $field_list) {
+ foreach ($field_list->getFields() as $field) {
+ $all_fields[] = $field;
+ }
+ }
+
+ id(new PhabricatorCustomFieldStorageQuery())
+ ->addFields($all_fields)
+ ->execute();
+
+ $results = array();
+ foreach ($objects as $object) {
+ $object_phid = $object->getPHID();
+ $object_fields = $field_map[$object_phid];
+
+ $map = array();
+ foreach ($object_fields->getFields() as $field) {
+ $key = $field->getModernFieldKey();
+ $map[$key] = $field->newExportData();
+ }
+
+ $results[] = $map;
+ }
+
+ return $results;
+ }
+
+ private function newCustomFields($object) {
+ $fields = PhabricatorCustomField::getObjectFields(
+ $object,
+ PhabricatorCustomField::ROLE_EXPORT);
+ $fields->setViewer($this->getViewer());
+
+ return $fields->getFields();
+ }
+
+}
diff --git a/src/infrastructure/export/PhabricatorExportEngineExtension.php b/src/infrastructure/export/PhabricatorExportEngineExtension.php
new file mode 100644
--- /dev/null
+++ b/src/infrastructure/export/PhabricatorExportEngineExtension.php
@@ -0,0 +1,31 @@
+<?php
+
+abstract class PhabricatorExportEngineExtension extends Phobject {
+
+ private $viewer;
+
+ final public function getExtensionKey() {
+ return $this->getPhobjectClassConstant('EXTENSIONKEY');
+ }
+
+ final public function setViewer($viewer) {
+ $this->viewer = $viewer;
+ return $this;
+ }
+
+ final public function getViewer() {
+ return $this->viewer;
+ }
+
+ abstract public function supportsObject($object);
+ abstract public function newExportFields();
+ abstract public function newExportData(array $objects);
+
+ final public static function getAllExtensions() {
+ return id(new PhutilClassMapQuery())
+ ->setAncestorClass(__CLASS__)
+ ->setUniqueMethod('getExtensionKey')
+ ->execute();
+ }
+
+}

File Metadata

Mime Type
text/plain
Expires
Fri, Oct 18, 9:41 PM (4 w, 1 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6724835
Default Alt Text
D18954.id45453.diff (11 KB)

Event Timeline