Page MenuHomePhabricator

D14599.diff
No OneTemporary

D14599.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
@@ -1844,6 +1844,7 @@
'PhabricatorChatLogQuery' => 'applications/chatlog/query/PhabricatorChatLogQuery.php',
'PhabricatorChunkedFileStorageEngine' => 'applications/files/engine/PhabricatorChunkedFileStorageEngine.php',
'PhabricatorClusterConfigOptions' => 'applications/config/option/PhabricatorClusterConfigOptions.php',
+ 'PhabricatorCommentEditEngineExtension' => 'applications/transactions/editengineextension/PhabricatorCommentEditEngineExtension.php',
'PhabricatorCommentEditField' => 'applications/transactions/editfield/PhabricatorCommentEditField.php',
'PhabricatorCommentEditType' => 'applications/transactions/edittype/PhabricatorCommentEditType.php',
'PhabricatorCommitBranchesField' => 'applications/repository/customfield/PhabricatorCommitBranchesField.php',
@@ -2132,6 +2133,8 @@
'PhabricatorEditEngineConfigurationTransactionQuery' => 'applications/transactions/query/PhabricatorEditEngineConfigurationTransactionQuery.php',
'PhabricatorEditEngineConfigurationViewController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationViewController.php',
'PhabricatorEditEngineController' => 'applications/transactions/controller/PhabricatorEditEngineController.php',
+ 'PhabricatorEditEngineExtension' => 'applications/transactions/editengineextension/PhabricatorEditEngineExtension.php',
+ 'PhabricatorEditEngineExtensionModule' => 'applications/transactions/editengineextension/PhabricatorEditEngineExtensionModule.php',
'PhabricatorEditEngineListController' => 'applications/transactions/controller/PhabricatorEditEngineListController.php',
'PhabricatorEditEngineQuery' => 'applications/transactions/query/PhabricatorEditEngineQuery.php',
'PhabricatorEditEngineSearchEngine' => 'applications/transactions/query/PhabricatorEditEngineSearchEngine.php',
@@ -2706,6 +2709,7 @@
'PhabricatorPolicyDAO' => 'applications/policy/storage/PhabricatorPolicyDAO.php',
'PhabricatorPolicyDataTestCase' => 'applications/policy/__tests__/PhabricatorPolicyDataTestCase.php',
'PhabricatorPolicyEditController' => 'applications/policy/controller/PhabricatorPolicyEditController.php',
+ 'PhabricatorPolicyEditEngineExtension' => 'applications/policy/editor/PhabricatorPolicyEditEngineExtension.php',
'PhabricatorPolicyEditField' => 'applications/transactions/editfield/PhabricatorPolicyEditField.php',
'PhabricatorPolicyException' => 'applications/policy/exception/PhabricatorPolicyException.php',
'PhabricatorPolicyExplainController' => 'applications/policy/controller/PhabricatorPolicyExplainController.php',
@@ -2797,6 +2801,7 @@
'PhabricatorProjectUserFunctionDatasource' => 'applications/project/typeahead/PhabricatorProjectUserFunctionDatasource.php',
'PhabricatorProjectViewController' => 'applications/project/controller/PhabricatorProjectViewController.php',
'PhabricatorProjectWatchController' => 'applications/project/controller/PhabricatorProjectWatchController.php',
+ 'PhabricatorProjectsEditEngineExtension' => 'applications/project/editor/PhabricatorProjectsEditEngineExtension.php',
'PhabricatorProjectsEditField' => 'applications/transactions/editfield/PhabricatorProjectsEditField.php',
'PhabricatorProjectsPolicyRule' => 'applications/project/policyrule/PhabricatorProjectsPolicyRule.php',
'PhabricatorProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorProtocolAdapter.php',
@@ -3087,6 +3092,7 @@
'PhabricatorSubscriptionsAddSubscribersHeraldAction' => 'applications/subscriptions/herald/PhabricatorSubscriptionsAddSubscribersHeraldAction.php',
'PhabricatorSubscriptionsApplication' => 'applications/subscriptions/application/PhabricatorSubscriptionsApplication.php',
'PhabricatorSubscriptionsEditController' => 'applications/subscriptions/controller/PhabricatorSubscriptionsEditController.php',
+ 'PhabricatorSubscriptionsEditEngineExtension' => 'applications/subscriptions/editor/PhabricatorSubscriptionsEditEngineExtension.php',
'PhabricatorSubscriptionsEditor' => 'applications/subscriptions/editor/PhabricatorSubscriptionsEditor.php',
'PhabricatorSubscriptionsHeraldAction' => 'applications/subscriptions/herald/PhabricatorSubscriptionsHeraldAction.php',
'PhabricatorSubscriptionsListController' => 'applications/subscriptions/controller/PhabricatorSubscriptionsListController.php',
@@ -5896,6 +5902,7 @@
'PhabricatorChatLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorChunkedFileStorageEngine' => 'PhabricatorFileStorageEngine',
'PhabricatorClusterConfigOptions' => 'PhabricatorApplicationConfigOptions',
+ 'PhabricatorCommentEditEngineExtension' => 'PhabricatorEditEngineExtension',
'PhabricatorCommentEditField' => 'PhabricatorEditField',
'PhabricatorCommentEditType' => 'PhabricatorEditType',
'PhabricatorCommitBranchesField' => 'PhabricatorCommitCustomField',
@@ -6232,6 +6239,8 @@
'PhabricatorEditEngineConfigurationTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorEditEngineConfigurationViewController' => 'PhabricatorEditEngineController',
'PhabricatorEditEngineController' => 'PhabricatorApplicationTransactionController',
+ 'PhabricatorEditEngineExtension' => 'Phobject',
+ 'PhabricatorEditEngineExtensionModule' => 'PhabricatorConfigModule',
'PhabricatorEditEngineListController' => 'PhabricatorEditEngineController',
'PhabricatorEditEngineQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorEditEngineSearchEngine' => 'PhabricatorApplicationSearchEngine',
@@ -6898,6 +6907,7 @@
'PhabricatorPolicyDAO' => 'PhabricatorLiskDAO',
'PhabricatorPolicyDataTestCase' => 'PhabricatorTestCase',
'PhabricatorPolicyEditController' => 'PhabricatorPolicyController',
+ 'PhabricatorPolicyEditEngineExtension' => 'PhabricatorEditEngineExtension',
'PhabricatorPolicyEditField' => 'PhabricatorEditField',
'PhabricatorPolicyException' => 'Exception',
'PhabricatorPolicyExplainController' => 'PhabricatorPolicyController',
@@ -7014,6 +7024,7 @@
'PhabricatorProjectUserFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
'PhabricatorProjectViewController' => 'PhabricatorProjectController',
'PhabricatorProjectWatchController' => 'PhabricatorProjectController',
+ 'PhabricatorProjectsEditEngineExtension' => 'PhabricatorEditEngineExtension',
'PhabricatorProjectsEditField' => 'PhabricatorTokenizerEditField',
'PhabricatorProjectsPolicyRule' => 'PhabricatorPolicyRule',
'PhabricatorProtocolAdapter' => 'Phobject',
@@ -7360,6 +7371,7 @@
'PhabricatorSubscriptionsAddSubscribersHeraldAction' => 'PhabricatorSubscriptionsHeraldAction',
'PhabricatorSubscriptionsApplication' => 'PhabricatorApplication',
'PhabricatorSubscriptionsEditController' => 'PhabricatorController',
+ 'PhabricatorSubscriptionsEditEngineExtension' => 'PhabricatorEditEngineExtension',
'PhabricatorSubscriptionsEditor' => 'PhabricatorEditor',
'PhabricatorSubscriptionsHeraldAction' => 'HeraldAction',
'PhabricatorSubscriptionsListController' => 'PhabricatorController',
diff --git a/src/applications/policy/editor/PhabricatorPolicyEditEngineExtension.php b/src/applications/policy/editor/PhabricatorPolicyEditEngineExtension.php
new file mode 100644
--- /dev/null
+++ b/src/applications/policy/editor/PhabricatorPolicyEditEngineExtension.php
@@ -0,0 +1,118 @@
+<?php
+
+final class PhabricatorPolicyEditEngineExtension
+ extends PhabricatorEditEngineExtension {
+
+ const EXTENSIONKEY = 'policy.policy';
+
+ public function getExtensionPriority() {
+ return 250;
+ }
+
+ public function isExtensionEnabled() {
+ return true;
+ }
+
+ public function getExtensionName() {
+ return pht('Policies');
+ }
+
+ public function supportsObject(
+ PhabricatorEditEngine $engine,
+ PhabricatorApplicationTransactionInterface $object) {
+ return ($object instanceof PhabricatorPolicyInterface);
+ }
+
+ public function buildCustomEditFields(
+ PhabricatorEditEngine $engine,
+ PhabricatorApplicationTransactionInterface $object) {
+
+ $viewer = $engine->getViewer();
+
+ $editor = $object->getApplicationTransactionEditor();
+ $types = $editor->getTransactionTypesForObject($object);
+ $types = array_fuse($types);
+
+ $policies = id(new PhabricatorPolicyQuery())
+ ->setViewer($viewer)
+ ->setObject($object)
+ ->execute();
+
+ $map = array(
+ PhabricatorTransactions::TYPE_VIEW_POLICY => array(
+ 'key' => 'policy.view',
+ 'aliases' => array('view'),
+ 'capability' => PhabricatorPolicyCapability::CAN_VIEW,
+ 'label' => pht('View Policy'),
+ 'description' => pht('Controls who can view the object.'),
+ 'edit' => 'view',
+ ),
+ PhabricatorTransactions::TYPE_EDIT_POLICY => array(
+ 'key' => 'policy.edit',
+ 'aliases' => array('edit'),
+ 'capability' => PhabricatorPolicyCapability::CAN_EDIT,
+ 'label' => pht('Edit Policy'),
+ 'description' => pht('Controls who can edit the object.'),
+ 'edit' => 'edit',
+ ),
+ PhabricatorTransactions::TYPE_JOIN_POLICY => array(
+ 'key' => 'policy.join',
+ 'aliases' => array('join'),
+ 'capability' => PhabricatorPolicyCapability::CAN_JOIN,
+ 'label' => pht('Join Policy'),
+ 'description' => pht('Controls who can join the object.'),
+ 'edit' => 'join',
+ ),
+ );
+
+ $fields = array();
+ foreach ($map as $type => $spec) {
+ if (empty($types[$type])) {
+ continue;
+ }
+
+ $capability = $spec['capability'];
+ $key = $spec['key'];
+ $aliases = $spec['aliases'];
+ $label = $spec['label'];
+ $description = $spec['description'];
+ $edit = $spec['edit'];
+
+ $policy_field = id(new PhabricatorPolicyEditField())
+ ->setKey($key)
+ ->setLabel($label)
+ ->setDescription($description)
+ ->setAliases($aliases)
+ ->setCapability($capability)
+ ->setPolicies($policies)
+ ->setTransactionType($type)
+ ->setEditTypeKey($edit)
+ ->setValue($object->getPolicy($capability));
+ $fields[] = $policy_field;
+
+ if (!($object instanceof PhabricatorSpacesInterface)) {
+ if ($capability == PhabricatorPolicyCapability::CAN_VIEW) {
+ $type_space = PhabricatorTransactions::TYPE_SPACE;
+ if (isset($types[$type_space])) {
+ $space_field = id(new PhabricatorSpaceEditField())
+ ->setKey('spacePHID')
+ ->setLabel(pht('Space'))
+ ->setEditTypeKey('space')
+ ->setDescription(
+ pht('Shifts the object in the Spaces application.'))
+ ->setIsReorderable(false)
+ ->setAliases(array('space', 'policy.space'))
+ ->setTransactionType($type_space)
+ ->setValue($object->getSpacePHID());
+ $fields[] = $space_field;
+
+ $policy_field->setSpaceField($space_field);
+ }
+ }
+ }
+ }
+
+ return $fields;
+ }
+
+}
diff --git a/src/applications/project/editor/PhabricatorProjectsEditEngineExtension.php b/src/applications/project/editor/PhabricatorProjectsEditEngineExtension.php
new file mode 100644
--- /dev/null
+++ b/src/applications/project/editor/PhabricatorProjectsEditEngineExtension.php
@@ -0,0 +1,60 @@
+<?php
+
+final class PhabricatorProjectsEditEngineExtension
+ extends PhabricatorEditEngineExtension {
+
+ const EXTENSIONKEY = 'projects.projects';
+
+ public function getExtensionPriority() {
+ return 500;
+ }
+
+ public function isExtensionEnabled() {
+ return PhabricatorApplication::isClassInstalled(
+ 'PhabricatorProjectApplication');
+ }
+
+ public function getExtensionName() {
+ return pht('Projects');
+ }
+
+ public function supportsObject(
+ PhabricatorEditEngine $engine,
+ PhabricatorApplicationTransactionInterface $object) {
+
+ return ($object instanceof PhabricatorProjectInterface);
+ }
+
+ public function buildCustomEditFields(
+ PhabricatorEditEngine $engine,
+ PhabricatorApplicationTransactionInterface $object) {
+
+ $edge_type = PhabricatorTransactions::TYPE_EDGE;
+ $project_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
+
+ $object_phid = $object->getPHID();
+ if ($object_phid) {
+ $project_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
+ $object_phid,
+ $project_edge_type);
+ $project_phids = array_reverse($project_phids);
+ } else {
+ $project_phids = array();
+ }
+
+ $projects_field = id(new PhabricatorProjectsEditField())
+ ->setKey('projectPHIDs')
+ ->setLabel(pht('Projects'))
+ ->setEditTypeKey('projects')
+ ->setDescription(pht('Add or remove associated projects.'))
+ ->setAliases(array('project', 'projects'))
+ ->setTransactionType($edge_type)
+ ->setMetadataValue('edge:type', $project_edge_type)
+ ->setValue($project_phids);
+
+ return array(
+ $projects_field,
+ );
+ }
+
+}
diff --git a/src/applications/subscriptions/editor/PhabricatorSubscriptionsEditEngineExtension.php b/src/applications/subscriptions/editor/PhabricatorSubscriptionsEditEngineExtension.php
new file mode 100644
--- /dev/null
+++ b/src/applications/subscriptions/editor/PhabricatorSubscriptionsEditEngineExtension.php
@@ -0,0 +1,56 @@
+<?php
+
+final class PhabricatorSubscriptionsEditEngineExtension
+ extends PhabricatorEditEngineExtension {
+
+ const EXTENSIONKEY = 'subscriptions.subscribers';
+
+ public function getExtensionPriority() {
+ return 750;
+ }
+
+ public function isExtensionEnabled() {
+ return true;
+ }
+
+ public function getExtensionName() {
+ return pht('Subscriptions');
+ }
+
+ public function supportsObject(
+ PhabricatorEditEngine $engine,
+ PhabricatorApplicationTransactionInterface $object) {
+ return ($object instanceof PhabricatorSubscribableInterface);
+ }
+
+ public function buildCustomEditFields(
+ PhabricatorEditEngine $engine,
+ PhabricatorApplicationTransactionInterface $object) {
+
+ $subscribers_type = PhabricatorTransactions::TYPE_SUBSCRIBERS;
+
+ $object_phid = $object->getPHID();
+ if ($object_phid) {
+ $sub_phids = PhabricatorSubscribersQuery::loadSubscribersForPHID(
+ $object_phid);
+ } else {
+ // TODO: Allow applications to provide default subscribers? Maniphest
+ // does this at a minimum.
+ $sub_phids = array();
+ }
+
+ $subscribers_field = id(new PhabricatorSubscribersEditField())
+ ->setKey('subscriberPHIDs')
+ ->setLabel(pht('Subscribers'))
+ ->setEditTypeKey('subscribers')
+ ->setDescription(pht('Manage subscribers.'))
+ ->setAliases(array('subscriber', 'subscribers'))
+ ->setTransactionType($subscribers_type)
+ ->setValue($sub_phids);
+
+ return array(
+ $subscribers_field,
+ );
+ }
+
+}
diff --git a/src/applications/transactions/editengine/PhabricatorEditEngine.php b/src/applications/transactions/editengine/PhabricatorEditEngine.php
--- a/src/applications/transactions/editengine/PhabricatorEditEngine.php
+++ b/src/applications/transactions/editengine/PhabricatorEditEngine.php
@@ -73,163 +73,27 @@
final protected function buildEditFields($object) {
$viewer = $this->getViewer();
- $editor = $object->getApplicationTransactionEditor();
-
- $types = $editor->getTransactionTypesForObject($object);
- $types = array_fuse($types);
$fields = $this->buildCustomEditFields($object);
- if ($object instanceof PhabricatorPolicyInterface) {
- $policies = id(new PhabricatorPolicyQuery())
- ->setViewer($viewer)
- ->setObject($object)
- ->execute();
-
- $map = array(
- PhabricatorTransactions::TYPE_VIEW_POLICY => array(
- 'key' => 'policy.view',
- 'aliases' => array('view'),
- 'capability' => PhabricatorPolicyCapability::CAN_VIEW,
- 'label' => pht('View Policy'),
- 'description' => pht('Controls who can view the object.'),
- 'edit' => 'view',
- ),
- PhabricatorTransactions::TYPE_EDIT_POLICY => array(
- 'key' => 'policy.edit',
- 'aliases' => array('edit'),
- 'capability' => PhabricatorPolicyCapability::CAN_EDIT,
- 'label' => pht('Edit Policy'),
- 'description' => pht('Controls who can edit the object.'),
- 'edit' => 'edit',
- ),
- PhabricatorTransactions::TYPE_JOIN_POLICY => array(
- 'key' => 'policy.join',
- 'aliases' => array('join'),
- 'capability' => PhabricatorPolicyCapability::CAN_JOIN,
- 'label' => pht('Join Policy'),
- 'description' => pht('Controls who can join the object.'),
- 'edit' => 'join',
- ),
- );
+ $extensions = PhabricatorEditEngineExtension::getAllEnabledExtensions();
+ foreach ($extensions as $extension) {
+ $extension->setViewer($viewer);
- foreach ($map as $type => $spec) {
- if (empty($types[$type])) {
- continue;
- }
-
- $capability = $spec['capability'];
- $key = $spec['key'];
- $aliases = $spec['aliases'];
- $label = $spec['label'];
- $description = $spec['description'];
- $edit = $spec['edit'];
-
- $policy_field = id(new PhabricatorPolicyEditField())
- ->setKey($key)
- ->setLabel($label)
- ->setDescription($description)
- ->setAliases($aliases)
- ->setCapability($capability)
- ->setPolicies($policies)
- ->setTransactionType($type)
- ->setEditTypeKey($edit)
- ->setValue($object->getPolicy($capability));
- $fields[] = $policy_field;
-
- if ($object instanceof PhabricatorSpacesInterface) {
- if ($capability == PhabricatorPolicyCapability::CAN_VIEW) {
- $type_space = PhabricatorTransactions::TYPE_SPACE;
- if (isset($types[$type_space])) {
- $space_field = id(new PhabricatorSpaceEditField())
- ->setKey('spacePHID')
- ->setLabel(pht('Space'))
- ->setEditTypeKey('space')
- ->setDescription(
- pht('Shifts the object in the Spaces application.'))
- ->setIsReorderable(false)
- ->setAliases(array('space', 'policy.space'))
- ->setTransactionType($type_space)
- ->setValue($object->getSpacePHID());
- $fields[] = $space_field;
-
- $policy_field->setSpaceField($space_field);
- }
- }
- }
+ if (!$extension->supportsObject($this, $object)) {
+ continue;
}
- }
-
- $edge_type = PhabricatorTransactions::TYPE_EDGE;
- $object_phid = $object->getPHID();
-
- $project_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
- if ($object instanceof PhabricatorProjectInterface) {
- if (isset($types[$edge_type])) {
- if ($object_phid) {
- $project_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
- $object_phid,
- $project_edge_type);
- $project_phids = array_reverse($project_phids);
- } else {
- $project_phids = array();
- }
-
- $edge_field = id(new PhabricatorProjectsEditField())
- ->setKey('projectPHIDs')
- ->setLabel(pht('Projects'))
- ->setEditTypeKey('projects')
- ->setDescription(pht('Add or remove associated projects.'))
- ->setAliases(array('project', 'projects'))
- ->setTransactionType($edge_type)
- ->setMetadataValue('edge:type', $project_edge_type)
- ->setValue($project_phids);
- $fields[] = $edge_field;
- }
- }
+ $extension_fields = $extension->buildCustomEditFields($this, $object);
- $subscribers_type = PhabricatorTransactions::TYPE_SUBSCRIBERS;
-
- if ($object instanceof PhabricatorSubscribableInterface) {
- if (isset($types[$subscribers_type])) {
- if ($object_phid) {
- $sub_phids = PhabricatorSubscribersQuery::loadSubscribersForPHID(
- $object_phid);
- } else {
- // TODO: Allow applications to provide default subscribers; Maniphest
- // does this at a minimum.
- $sub_phids = array();
- }
+ // TODO: Validate this in more detail with a more tailored error.
+ assert_instances_of($extension_fields, 'PhabricatorEditField');
- $subscribers_field = id(new PhabricatorSubscribersEditField())
- ->setKey('subscriberPHIDs')
- ->setLabel(pht('Subscribers'))
- ->setEditTypeKey('subscribers')
- ->setDescription(pht('Manage subscribers.'))
- ->setAliases(array('subscriber', 'subscribers'))
- ->setTransactionType($subscribers_type)
- ->setValue($sub_phids);
- $fields[] = $subscribers_field;
+ foreach ($extension_fields as $field) {
+ $fields[] = $field;
}
}
- $xaction = $object->getApplicationTransactionTemplate();
- $comment = $xaction->getApplicationTransactionCommentObject();
- if ($comment) {
- $comment_type = PhabricatorTransactions::TYPE_COMMENT;
-
- $comment_field = id(new PhabricatorCommentEditField())
- ->setKey('comment')
- ->setLabel(pht('Comments'))
- ->setDescription(pht('Add comments.'))
- ->setAliases(array('comments'))
- ->setIsHidden(true)
- ->setTransactionType($comment_type)
- ->setValue(null);
- $fields[] = $comment_field;
- }
-
$config = $this->getEditEngineConfiguration();
$fields = $config->applyConfigurationToFields($this, $fields);
@@ -678,6 +542,8 @@
$validation_exception = null;
if ($request->isFormPost()) {
foreach ($fields as $field) {
+ $field->setIsSubmittedForm(true);
+
if ($field->getIsLocked() || $field->getIsHidden()) {
continue;
}
@@ -709,6 +575,20 @@
->setURI($this->getObjectViewURI($object));
} catch (PhabricatorApplicationTransactionValidationException $ex) {
$validation_exception = $ex;
+
+ foreach ($fields as $field) {
+ $xaction_type = $field->getTransactionType();
+ if ($xaction_type === null) {
+ continue;
+ }
+
+ $message = $ex->getShortMessage($xaction_type);
+ if ($message === null) {
+ continue;
+ }
+
+ $field->setControlError($message);
+ }
}
} else {
if ($this->getIsCreate()) {
diff --git a/src/applications/transactions/editengineextension/PhabricatorCommentEditEngineExtension.php b/src/applications/transactions/editengineextension/PhabricatorCommentEditEngineExtension.php
new file mode 100644
--- /dev/null
+++ b/src/applications/transactions/editengineextension/PhabricatorCommentEditEngineExtension.php
@@ -0,0 +1,55 @@
+<?php
+
+final class PhabricatorCommentEditEngineExtension
+ extends PhabricatorEditEngineExtension {
+
+ const EXTENSIONKEY = 'transactions.comment';
+
+ public function getExtensionPriority() {
+ return 9000;
+ }
+
+ public function isExtensionEnabled() {
+ return true;
+ }
+
+ public function getExtensionName() {
+ return pht('Comments');
+ }
+
+ public function supportsObject(
+ PhabricatorEditEngine $engine,
+ PhabricatorApplicationTransactionInterface $object) {
+
+ $xaction = $object->getApplicationTransactionTemplate();
+
+ try {
+ $comment = $xaction->getApplicationTransactionCommentObject();
+ } catch (PhutilMethodNotImplementedException $ex) {
+ $comment = null;
+ }
+
+ return (bool)$comment;
+ }
+
+ public function buildCustomEditFields(
+ PhabricatorEditEngine $engine,
+ PhabricatorApplicationTransactionInterface $object) {
+
+ $comment_type = PhabricatorTransactions::TYPE_COMMENT;
+
+ $comment_field = id(new PhabricatorCommentEditField())
+ ->setKey('comment')
+ ->setLabel(pht('Comments'))
+ ->setDescription(pht('Add comments.'))
+ ->setAliases(array('comments'))
+ ->setIsHidden(true)
+ ->setTransactionType($comment_type)
+ ->setValue(null);
+
+ return array(
+ $comment_field,
+ );
+ }
+
+}
diff --git a/src/applications/transactions/editengineextension/PhabricatorEditEngineExtension.php b/src/applications/transactions/editengineextension/PhabricatorEditEngineExtension.php
new file mode 100644
--- /dev/null
+++ b/src/applications/transactions/editengineextension/PhabricatorEditEngineExtension.php
@@ -0,0 +1,55 @@
+<?php
+
+abstract class PhabricatorEditEngineExtension 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;
+ }
+
+ public function getExtensionPriority() {
+ return 1000;
+ }
+
+ abstract public function isExtensionEnabled();
+ abstract public function getExtensionName();
+
+ abstract public function supportsObject(
+ PhabricatorEditEngine $engine,
+ PhabricatorApplicationTransactionInterface $object);
+
+ abstract public function buildCustomEditFields(
+ PhabricatorEditEngine $engine,
+ PhabricatorApplicationTransactionInterface $object);
+
+ final public static function getAllExtensions() {
+ return id(new PhutilClassMapQuery())
+ ->setAncestorClass(__CLASS__)
+ ->setUniqueMethod('getExtensionKey')
+ ->setSortMethod('getExtensionPriority')
+ ->execute();
+ }
+
+ final public static function getAllEnabledExtensions() {
+ $extensions = self::getAllExtensions();
+
+ foreach ($extensions as $key => $extension) {
+ if (!$extension->isExtensionEnabled()) {
+ unset($extensions[$key]);
+ }
+ }
+
+ return $extensions;
+ }
+
+}
diff --git a/src/applications/transactions/editengineextension/PhabricatorEditEngineExtensionModule.php b/src/applications/transactions/editengineextension/PhabricatorEditEngineExtensionModule.php
new file mode 100644
--- /dev/null
+++ b/src/applications/transactions/editengineextension/PhabricatorEditEngineExtensionModule.php
@@ -0,0 +1,52 @@
+<?php
+
+final class PhabricatorEditEngineExtensionModule
+ extends PhabricatorConfigModule {
+
+ public function getModuleKey() {
+ return 'editengine';
+ }
+
+ public function getModuleName() {
+ return pht('EditEngine Extensions');
+ }
+
+ public function renderModuleStatus(AphrontRequest $request) {
+ $viewer = $request->getViewer();
+
+ $extensions = PhabricatorEditEngineExtension::getAllExtensions();
+
+ $rows = array();
+ foreach ($extensions as $extension) {
+ $rows[] = array(
+ $extension->getExtensionPriority(),
+ get_class($extension),
+ $extension->getExtensionName(),
+ $extension->isExtensionEnabled()
+ ? pht('Yes')
+ : pht('No'),
+ );
+ }
+
+ $table = id(new AphrontTableView($rows))
+ ->setHeaders(
+ array(
+ pht('Priority'),
+ pht('Class'),
+ pht('Name'),
+ pht('Enabled'),
+ ))
+ ->setColumnClasses(
+ array(
+ null,
+ null,
+ 'wide pri',
+ null,
+ ));
+
+ return id(new PHUIObjectBoxView())
+ ->setHeaderText(pht('EditEngine Extensions'))
+ ->setTable($table);
+ }
+
+}
diff --git a/src/applications/transactions/editfield/PhabricatorDatasourceEditField.php b/src/applications/transactions/editfield/PhabricatorDatasourceEditField.php
--- a/src/applications/transactions/editfield/PhabricatorDatasourceEditField.php
+++ b/src/applications/transactions/editfield/PhabricatorDatasourceEditField.php
@@ -11,6 +11,9 @@
}
public function getDatasource() {
+ if (!$this->datasource) {
+ throw new PhutilInvalidStateException('setDatasource');
+ }
return $this->datasource;
}
diff --git a/src/applications/transactions/editfield/PhabricatorEditField.php b/src/applications/transactions/editfield/PhabricatorEditField.php
--- a/src/applications/transactions/editfield/PhabricatorEditField.php
+++ b/src/applications/transactions/editfield/PhabricatorEditField.php
@@ -13,12 +13,15 @@
private $metadata = array();
private $description;
private $editTypeKey;
+ private $isRequired;
private $isLocked;
private $isHidden;
private $isPreview;
private $isEditDefaults;
+ private $isSubmittedForm;
+ private $controlError;
private $isReorderable = true;
private $isDefaultable = true;
@@ -145,6 +148,33 @@
throw new PhutilMethodNotImplementedException();
}
+ public function setIsSubmittedForm($is_submitted) {
+ $this->isSubmittedForm = $is_submitted;
+ return $this;
+ }
+
+ public function getIsSubmittedForm() {
+ return $this->isSubmittedForm;
+ }
+
+ public function setIsRequired($is_required) {
+ $this->isRequired = $is_required;
+ return $this;
+ }
+
+ public function getIsRequired() {
+ return $this->isRequired;
+ }
+
+ public function setControlError($control_error) {
+ $this->controlError = $control_error;
+ return $this;
+ }
+
+ public function getControlError() {
+ return $this->controlError;
+ }
+
protected function renderControl() {
$control = $this->newControl();
if ($control === null) {
@@ -176,6 +206,16 @@
$control->setDisabled($disabled);
+
+ if ($this->getIsSubmittedForm()) {
+ $error = $this->getControlError();
+ if ($error !== null) {
+ $control->setError($error);
+ }
+ } else if ($this->getIsRequired()) {
+ $control->setError(true);
+ }
+
return $control;
}

File Metadata

Mime Type
text/plain
Expires
Thu, May 9, 8:13 PM (3 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6276491
Default Alt Text
D14599.diff (29 KB)

Event Timeline