Page MenuHomePhabricator

D7585.id17121.diff

D7585.id17121.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
@@ -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

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)

Event Timeline