Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F91656
D7585.id17121.diff
All Users
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
20 KB
Referenced Files
None
Subscribers
None
D7585.id17121.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
@@ -866,6 +866,7 @@
'NuancePHIDTypeQueue' => 'applications/nuance/phid/NuancePHIDTypeQueue.php',
'NuancePHIDTypeRequestor' => 'applications/nuance/phid/NuancePHIDTypeRequestor.php',
'NuancePHIDTypeSource' => 'applications/nuance/phid/NuancePHIDTypeSource.php',
+ 'NuancePhabricatorFormSourceDefinition' => 'applications/nuance/source/NuancePhabricatorFormSourceDefinition.php',
'NuanceQuery' => 'applications/nuance/query/NuanceQuery.php',
'NuanceQueue' => 'applications/nuance/storage/NuanceQueue.php',
'NuanceQueueEditController' => 'applications/nuance/controller/NuanceQueueEditController.php',
@@ -886,13 +887,13 @@
'NuanceRequestorTransactionQuery' => 'applications/nuance/query/NuanceRequestorTransactionQuery.php',
'NuanceRequestorViewController' => 'applications/nuance/controller/NuanceRequestorViewController.php',
'NuanceSource' => 'applications/nuance/storage/NuanceSource.php',
+ 'NuanceSourceDefinition' => 'applications/nuance/source/NuanceSourceDefinition.php',
'NuanceSourceEditController' => 'applications/nuance/controller/NuanceSourceEditController.php',
'NuanceSourceEditor' => 'applications/nuance/editor/NuanceSourceEditor.php',
'NuanceSourceQuery' => 'applications/nuance/query/NuanceSourceQuery.php',
'NuanceSourceTransaction' => 'applications/nuance/storage/NuanceSourceTransaction.php',
'NuanceSourceTransactionComment' => 'applications/nuance/storage/NuanceSourceTransactionComment.php',
'NuanceSourceTransactionQuery' => 'applications/nuance/query/NuanceSourceTransactionQuery.php',
- 'NuanceSourceType' => 'applications/nuance/constants/NuanceSourceType.php',
'NuanceSourceViewController' => 'applications/nuance/controller/NuanceSourceViewController.php',
'NuanceTransaction' => 'applications/nuance/storage/NuanceTransaction.php',
'OwnersPackageReplyHandler' => 'applications/owners/mail/OwnersPackageReplyHandler.php',
@@ -3214,6 +3215,7 @@
'NuancePHIDTypeQueue' => 'PhabricatorPHIDType',
'NuancePHIDTypeRequestor' => 'PhabricatorPHIDType',
'NuancePHIDTypeSource' => 'PhabricatorPHIDType',
+ 'NuancePhabricatorFormSourceDefinition' => 'NuanceSourceDefinition',
'NuanceQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'NuanceQueue' =>
array(
@@ -3242,13 +3244,13 @@
0 => 'NuanceDAO',
1 => 'PhabricatorPolicyInterface',
),
+ 'NuanceSourceDefinition' => 'Phobject',
'NuanceSourceEditController' => 'NuanceController',
'NuanceSourceEditor' => 'PhabricatorApplicationTransactionEditor',
'NuanceSourceQuery' => 'NuanceQuery',
'NuanceSourceTransaction' => 'NuanceTransaction',
'NuanceSourceTransactionComment' => 'PhabricatorApplicationTransactionComment',
'NuanceSourceTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
- 'NuanceSourceType' => 'NuanceConstants',
'NuanceSourceViewController' => 'NuanceController',
'NuanceTransaction' => 'PhabricatorApplicationTransaction',
'OwnersPackageReplyHandler' => 'PhabricatorMailReplyHandler',
diff --git a/src/applications/nuance/constants/NuanceSourceType.php b/src/applications/nuance/constants/NuanceSourceType.php
deleted file mode 100644
--- a/src/applications/nuance/constants/NuanceSourceType.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<?php
-
-final class NuanceSourceType extends NuanceConstants {
-
- /* internal source types */
- const PHABRICATOR_FORM = 1;
-
- /* social media source types */
- const TWITTER = 101;
-
- /* engineering media source types */
- const GITHUB = 201;
-
-
- public static function getSelectOptions() {
-
- return array(
- self::PHABRICATOR_FORM => pht('Phabricator Form'),
- );
- }
-
-}
diff --git a/src/applications/nuance/controller/NuanceSourceEditController.php b/src/applications/nuance/controller/NuanceSourceEditController.php
--- a/src/applications/nuance/controller/NuanceSourceEditController.php
+++ b/src/applications/nuance/controller/NuanceSourceEditController.php
@@ -28,7 +28,6 @@
if ($is_new) {
$source = NuanceSource::initializeNewSource($user);
- $title = pht('Create Source');
} else {
$source = id(new NuanceSourceQuery())
->setViewer($user)
@@ -39,71 +38,29 @@
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
- $title = pht('Edit Source');
}
if (!$source) {
return new Aphront404Response();
}
- $error_view = null;
- $e_name = null;
- if ($request->isFormPost()) {
- $error_view = id(new AphrontErrorView())
- ->setTitle(pht('This does not work at all yet.'));
- }
+ $definition = NuanceSourceDefinition::getDefinitionForSource($source);
+ $definition->setActor($user);
- $policies = id(new PhabricatorPolicyQuery())
- ->setViewer($user)
- ->setObject($source)
- ->execute();
+ $response = $definition->buildEditLayout($request);
+ if ($response instanceof AphrontResponse) {
+ return $response;
+ }
+ $layout = $response;
$crumbs = $this->buildApplicationCrumbs();
-
- $form = id(new AphrontFormView())
- ->setUser($user)
- ->appendChild(
- id(new AphrontFormTextControl())
- ->setLabel(pht('Name'))
- ->setName('name')
- ->setError($e_name)
- ->setValue($source->getName()))
- ->appendChild(
- id(new AphrontFormSelectControl())
- ->setLabel(pht('Type'))
- ->setName('type')
- ->setOptions(NuanceSourceType::getSelectOptions())
- ->setValue($source->getType()))
- ->appendChild(
- id(new AphrontFormPolicyControl())
- ->setUser($user)
- ->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
- ->setPolicyObject($source)
- ->setPolicies($policies)
- ->setName('viewPolicy'))
- ->appendChild(
- id(new AphrontFormPolicyControl())
- ->setUser($user)
- ->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
- ->setPolicyObject($source)
- ->setPolicies($policies)
- ->setName('editPolicy'))
- ->appendChild(
- id(new AphrontFormSubmitControl())
- ->setValue(pht('Save')));
-
- $layout = id(new PHUIObjectBoxView())
- ->setHeaderText($title)
- ->setFormError($error_view)
- ->setForm($form);
-
return $this->buildApplicationPage(
array(
$crumbs,
$layout,
),
array(
- 'title' => $title,
+ 'title' => $definition->getEditTitle(),
'device' => true));
}
}
diff --git a/src/applications/nuance/editor/NuanceSourceEditor.php b/src/applications/nuance/editor/NuanceSourceEditor.php
--- a/src/applications/nuance/editor/NuanceSourceEditor.php
+++ b/src/applications/nuance/editor/NuanceSourceEditor.php
@@ -6,12 +6,59 @@
public function getTransactionTypes() {
$types = parent::getTransactionTypes();
+ $types[] = NuanceSourceTransaction::TYPE_CREATE;
+ $types[] = NuanceSourceTransaction::TYPE_NAME;
+
$types[] = PhabricatorTransactions::TYPE_EDGE;
$types[] = PhabricatorTransactions::TYPE_COMMENT;
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
return $types;
}
+ protected function getCustomTransactionOldValue(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ switch ($xaction->getTransactionType()) {
+ case NuanceSourceTransaction::TYPE_CREATE:
+ return null;
+ case NuanceSourceTransaction::TYPE_NAME:
+ return $object->getName();
+ }
+
+ return parent::getCustomTransactionOldValue($object, $xaction);
+ }
+
+ protected function getCustomTransactionNewValue(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ switch ($xaction->getTransactionType()) {
+ case NuanceSourceTransaction::TYPE_CREATE:
+ return $object->getPHID();
+ case NuanceSourceTransaction::TYPE_NAME:
+ return $xaction->getNewValue();
+ }
+
+ return parent::getCustomTransactionNewValue($object, $xaction);
+ }
+
+ protected function applyCustomInternalTransaction(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ switch ($xaction->getTransactionType()) {
+ case NuanceSourceTransaction::TYPE_NAME:
+ $object->setName($xaction->getNewValue());
+ break;
+ }
+ }
+
+ protected function applyCustomExternalTransaction(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+ }
+
}
diff --git a/src/applications/nuance/query/NuanceSourceQuery.php b/src/applications/nuance/query/NuanceSourceQuery.php
--- a/src/applications/nuance/query/NuanceSourceQuery.php
+++ b/src/applications/nuance/query/NuanceSourceQuery.php
@@ -35,7 +35,7 @@
$data = queryfx_all(
$conn_r,
- 'SELECT FROM %T %Q %Q %Q',
+ 'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
diff --git a/src/applications/nuance/source/NuancePhabricatorFormSourceDefinition.php b/src/applications/nuance/source/NuancePhabricatorFormSourceDefinition.php
new file mode 100644
--- /dev/null
+++ b/src/applications/nuance/source/NuancePhabricatorFormSourceDefinition.php
@@ -0,0 +1,72 @@
+<?php
+
+final class NuancePhabricatorFormSourceDefinition
+ extends NuanceSourceDefinition {
+
+ public function getName() {
+ return pht('Phabricator Form');
+ }
+
+ public function getSourceTypeConstant() {
+ return 0;
+ }
+
+ public function scour() {
+ return null;
+ }
+
+ public function renderEditForm(array $errors) {
+ $user = $this->requireActor();
+ $source = $this->requireSourceObject();
+ $e_name = idx($errors, 'e_name');
+
+ $form = id(new AphrontFormView())
+ ->setUser($user)
+ ->appendChild(
+ id(new AphrontFormTextControl())
+ ->setLabel(pht('Name'))
+ ->setName('name')
+ ->setError($e_name)
+ ->setValue($source->getName()))
+ ->appendChild(
+ id(new AphrontFormSelectControl())
+ ->setLabel(pht('Type'))
+ ->setName('type')
+ ->setOptions(self::getSelectOptions())
+ ->setValue($source->getType()));
+
+ /* TODO - add a box to allow for custom fields to be defined here, so that
+ * these NuanceSource objects made from this defintion can be used to
+ * capture arbitrary data */
+
+ return $form;
+ }
+
+ protected function validateEditRequest(AphrontRequest $request) {
+ list($form_errors,
+ $error_messages,
+ $transactions) = parent::validateEditRequest($request);
+
+ $name = $request->getStr('name');
+ if (!strlen($name)) {
+ $form_errors['e_name'] = true;
+ $error_messages[] = pht('You must specify a name for this source.');
+ } else {
+ $transactions[] = id(new NuanceSourceTransaction())
+ ->setTransactionType(NuanceSourceTransaction::TYPE_NAME)
+ ->setNewvalue($name);
+ }
+
+ return array(
+ $form_errors,
+ $error_messages,
+ $transactions);
+ }
+
+ public function renderView() {
+ }
+
+ public function renderListView() {
+ }
+
+}
diff --git a/src/applications/nuance/source/NuanceSourceDefinition.php b/src/applications/nuance/source/NuanceSourceDefinition.php
new file mode 100644
--- /dev/null
+++ b/src/applications/nuance/source/NuanceSourceDefinition.php
@@ -0,0 +1,256 @@
+<?php
+
+abstract class NuanceSourceDefinition extends Phobject {
+
+ private $actor;
+ private $sourceObject;
+
+ public function setActor(PhabricatorUser $actor) {
+ $this->actor = $actor;
+ return $this;
+ }
+ public function getActor() {
+ return $this->actor;
+ }
+ public function requireActor() {
+ $actor = $this->getActor();
+ if (!$actor) {
+ throw new Exception('You must "setActor()" first!');
+ }
+ return $actor;
+ }
+
+ public function setSourceObject(NuanceSource $source) {
+ $source->setType($this->getSourceTypeConstant());
+ $this->sourceObject = $source;
+ return $this;
+ }
+ public function getSourceObject() {
+ return $this->sourceObject;
+ }
+ public function requireSourceObject() {
+ $source = $this->getSourceObject();
+ if (!$source) {
+ throw new Exception('You must "setSourceObject()" first!');
+ }
+ return $source;
+ }
+
+ public static function getSelectOptions() {
+ $definitions = self::getAllDefinitions();
+
+ $options = array();
+ foreach ($definitions as $definition) {
+ $key = $definition->getSourceTypeConstant();
+ $name = $definition->getName();
+ $options[$key] = $name;
+ }
+
+ return $options;
+ }
+
+ /**
+ * Gives a @{class:NuanceSourceDefinition} object for a given
+ * @{class:NuanceSource}. Note you still need to @{method:setActor}
+ * before the @{class:NuanceSourceDefinition} object will be useful.
+ */
+ public static function getDefinitionForSource(NuanceSource $source) {
+ $definitions = self::getAllDefinitions();
+ $map = mpull($definitions, null, 'getSourceTypeConstant');
+ $definition = $map[$source->getType()];
+ $definition->setSourceObject($source);
+
+ return $definition;
+ }
+
+ public static function getAllDefinitions() {
+ static $definitions;
+
+ if ($definitions === null) {
+ $objects = id(new PhutilSymbolLoader())
+ ->setAncestorClass(__CLASS__)
+ ->loadObjects();
+ foreach ($objects as $definition) {
+ $key = $definition->getSourceTypeConstant();
+ $name = $definition->getName();
+ if (isset($definitions[$key])) {
+ $conflict = $definitions[$key];
+ throw new Exception(sprintf(
+ 'Defintion %s conflicts with definition %s. This is a programming '.
+ 'error.',
+ $conflict,
+ $name));
+ }
+ }
+ $definitions = $objects;
+ }
+ return $definitions;
+ }
+
+ /**
+ * A human readable string like "Twitter" or "Phabricator Form".
+ */
+ abstract public function getName();
+
+ /**
+ * This should be a UINT. Please pick a number higher than 1000; Phabricator
+ * may ship more native @{class:NuanceSourceDefinition}s in the future that
+ * may conflict with the 0-1000 UINT space.
+ */
+ abstract public function getSourceTypeConstant();
+
+ /**
+ * Code to create and updat @{class:NuanceItem}s and
+ * @{class:NuanceRequestor}s via daemons goes here.
+ *
+ * If that does not make sense for the @{class:NuanceSource} you are
+ * defining, simply return null. For example,
+ * @{class:NuancePhabricatorFormSourceDefinition} since these are one-way
+ * contact forms.
+ */
+ abstract public function scour();
+
+ private function getSourceObjectPolicies(
+ PhabricatorUser $user,
+ NuanceSource $source) {
+
+ $user = $this->requireActor();
+ $source = $this->requireSourceObject();
+ return id(new PhabricatorPolicyQuery())
+ ->setViewer($user)
+ ->setObject($source)
+ ->execute();
+ }
+
+ final public function getEditTitle() {
+ $source = $this->requireSourceObject();
+ if ($source->getPHID()) {
+ $title = pht('Edit "%s" source.', $source->getName());
+ } else {
+ $title = pht('Create a new "%s" source.', $this->getName());
+ }
+
+ return $title;
+ }
+
+ final public function buildEditLayout(AphrontRequest $request) {
+ $actor = $this->requireActor();
+ $source = $this->requireSourceObject();
+
+ $form_errors = array();
+ $error_messages = array();
+ $transactions = array();
+ if ($request->isFormPost()) {
+ list($form_errors,
+ $error_messages,
+ $transactions) = $this->validateEditRequest($request);
+ if (empty($error_messages)) {
+ $content_source = PhabricatorContentSource::newFromRequest($request);
+ $editor = id(new NuanceSourceEditor())
+ ->setActor($actor)
+ ->setContentSource($content_source)
+ ->setContinueOnNoEffect(true)
+ ->applyTransactions($source, $transactions);
+
+ return id(new AphrontRedirectResponse())
+ ->setURI($source->getURI());
+ }
+ }
+
+ $form = $this->renderEditForm($form_errors);
+ $this->augmentEditForm($form);
+ $layout = id(new PHUIObjectBoxView())
+ ->setHeaderText($this->getEditTitle())
+ ->setForm($form);
+ if ($error_messages) {
+ $layout->setFormError($this->renderEditErrorView($error_messages));
+ }
+
+ return $layout;
+ }
+
+ /**
+ * Code to create a form to edit the @{class:NuanceItem} you are defining.
+ *
+ * return @{class:AphrontFormView}
+ */
+ abstract protected function renderEditForm(array $errors);
+
+ /**
+ * This adds the proper policy controls and a save button.
+ */
+ private function augmentEditForm(AphrontFormView $form) {
+ $user = $this->requireActor();
+ $source = $this->requireSourceObject();
+ $policies = $this->getSourceObjectPolicies($user, $source);
+
+ $form
+ ->appendChild(
+ id(new AphrontFormPolicyControl())
+ ->setUser($user)
+ ->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
+ ->setPolicyObject($source)
+ ->setPolicies($policies)
+ ->setName('viewPolicy'))
+ ->appendChild(
+ id(new AphrontFormPolicyControl())
+ ->setUser($user)
+ ->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
+ ->setPolicyObject($source)
+ ->setPolicies($policies)
+ ->setName('editPolicy'))
+ ->appendChild(
+ id(new AphrontFormSubmitControl())
+ ->setValue(pht('Save')));
+
+ return $form;
+ }
+
+ /**
+ * return @{class:AphrontErrorView}
+ */
+ public function renderEditErrorView(array $errors) {
+ return id(new AphrontErrorView())
+ ->setTitle(pht('Error with submission.'))
+ ->setErrors($errors);
+ }
+
+ /**
+ * Validates the user submission from the @{class:AphrontFormView} defined
+ * in @{method:renderEdit}. Inheriting classes should typically call this
+ * parent method first in the class to get the TYPE_CREATE transaction
+ * and policy transactions for free.
+ *
+ * return array($form_errors, $error_messages, $transactions)
+ */
+ protected function validateEditRequest(AphrontRequest $request) {
+ $form_errors = array();
+ $error_messages = array();
+ $transactions = array();
+ $source = $this->requireSourceObject();
+ if (!$source->getPHID()) {
+ $transactions[] = id(new NuanceSourceTransaction())
+ ->setTransactionType(NuanceSourceTransaction::TYPE_CREATE);
+ }
+
+ if ($request->isFormPost()) {
+ $transactions[] = id(new NuanceSourceTransaction())
+ ->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY)
+ ->setNewValue($request->getStr('editPolicy'));
+ $transactions[] = id(new NuanceSourceTransaction())
+ ->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
+ ->setNewValue($request->getStr('viewPolicy'));
+ }
+
+ return array(
+ $form_errors,
+ $error_messages,
+ $transactions
+ );
+ }
+
+ abstract public function renderView();
+
+ abstract public function renderListView();
+}
+
diff --git a/src/applications/nuance/storage/NuanceSource.php b/src/applications/nuance/storage/NuanceSource.php
--- a/src/applications/nuance/storage/NuanceSource.php
+++ b/src/applications/nuance/storage/NuanceSource.php
@@ -47,9 +47,14 @@
$edit_policy = $app->getPolicy(
NuanceCapabilitySourceDefaultEdit::CAPABILITY);
+ $definitions = NuanceSourceDefinition::getAllDefinitions();
+ $lucky_definition = head($definitions);
+
return id(new NuanceSource())
->setViewPolicy($view_policy)
- ->setEditPolicy($edit_policy);
+ ->setEditPolicy($edit_policy)
+ ->setType($lucky_definition->getSourceTypeConstant());
+
}
public function getCapabilities() {
diff --git a/src/applications/nuance/storage/NuanceSourceTransaction.php b/src/applications/nuance/storage/NuanceSourceTransaction.php
--- a/src/applications/nuance/storage/NuanceSourceTransaction.php
+++ b/src/applications/nuance/storage/NuanceSourceTransaction.php
@@ -3,6 +3,9 @@
final class NuanceSourceTransaction
extends NuanceTransaction {
+ CONST TYPE_CREATE = 'create-source';
+ const TYPE_NAME = 'name-source';
+
public function getApplicationTransactionType() {
return NuancePHIDTypeSource::TYPECONST;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Storage Engine
amazon-s3
Storage Format
Raw Data
Storage Handle
phabricator/rb/h5/br6aeh4gfszbjxz7
Default Alt Text
D7585.id17121.diff (20 KB)
Attached To
Mode
D7585: Nuance - federate out the design of NuanceSource via NuanceSourceDefinition
Attached
Detach File
Event Timeline
Log In to Comment