Page MenuHomePhabricator

D13166.diff
No OneTemporary

D13166.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
@@ -1140,6 +1140,7 @@
'NuanceRequestorViewController' => 'applications/nuance/controller/NuanceRequestorViewController.php',
'NuanceSchemaSpec' => 'applications/nuance/storage/NuanceSchemaSpec.php',
'NuanceSource' => 'applications/nuance/storage/NuanceSource.php',
+ 'NuanceSourceActionController' => 'applications/nuance/controller/NuanceSourceActionController.php',
'NuanceSourceCreateController' => 'applications/nuance/controller/NuanceSourceCreateController.php',
'NuanceSourceDefaultEditCapability' => 'applications/nuance/capability/NuanceSourceDefaultEditCapability.php',
'NuanceSourceDefaultViewCapability' => 'applications/nuance/capability/NuanceSourceDefaultViewCapability.php',
@@ -4473,7 +4474,11 @@
'NuanceQueueTransactionComment' => 'PhabricatorApplicationTransactionComment',
'NuanceQueueTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'NuanceQueueViewController' => 'NuanceController',
- 'NuanceRequestor' => 'NuanceDAO',
+ 'NuanceRequestor' => array(
+ 'NuanceDAO',
+ 'PhabricatorPolicyInterface',
+ 'PhabricatorApplicationTransactionInterface',
+ ),
'NuanceRequestorEditController' => 'NuanceController',
'NuanceRequestorEditor' => 'PhabricatorApplicationTransactionEditor',
'NuanceRequestorPHIDType' => 'PhabricatorPHIDType',
@@ -4489,6 +4494,7 @@
'PhabricatorApplicationTransactionInterface',
'PhabricatorPolicyInterface',
),
+ 'NuanceSourceActionController' => 'NuanceController',
'NuanceSourceCreateController' => 'NuanceController',
'NuanceSourceDefaultEditCapability' => 'PhabricatorPolicyCapability',
'NuanceSourceDefaultViewCapability' => 'PhabricatorPolicyCapability',
diff --git a/src/applications/nuance/application/PhabricatorNuanceApplication.php b/src/applications/nuance/application/PhabricatorNuanceApplication.php
--- a/src/applications/nuance/application/PhabricatorNuanceApplication.php
+++ b/src/applications/nuance/application/PhabricatorNuanceApplication.php
@@ -62,6 +62,9 @@
'new/' => 'NuanceRequestorEditController',
),
),
+ '/action/' => array(
+ '(?P<id>[1-9]\d*)/(?P<path>.*)' => 'NuanceSourceActionController',
+ ),
);
}
diff --git a/src/applications/nuance/conduit/NuanceCreateItemConduitAPIMethod.php b/src/applications/nuance/conduit/NuanceCreateItemConduitAPIMethod.php
--- a/src/applications/nuance/conduit/NuanceCreateItemConduitAPIMethod.php
+++ b/src/applications/nuance/conduit/NuanceCreateItemConduitAPIMethod.php
@@ -36,7 +36,7 @@
$user = $request->getUser();
- $item = NuanceItem::initializeNewItem($user);
+ $item = NuanceItem::initializeNewItem();
$xactions = array();
if ($source_phid) {
diff --git a/src/applications/nuance/controller/NuanceSourceActionController.php b/src/applications/nuance/controller/NuanceSourceActionController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/nuance/controller/NuanceSourceActionController.php
@@ -0,0 +1,38 @@
+<?php
+
+final class NuanceSourceActionController extends NuanceController {
+
+ public function handleRequest(AphrontRequest $request) {
+ $viewer = $this->getViewer();
+
+ $source = id(new NuanceSourceQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($request->getURIData('id')))
+ ->executeOne();
+ if (!$source) {
+ return new Aphront404Response();
+ }
+
+ $def = NuanceSourceDefinition::getDefinitionForSource($source);
+ $def->setActor($viewer);
+
+ $response = $def->handleActionRequest($request);
+ if ($response instanceof AphrontResponse) {
+ return $response;
+ }
+
+ $title = $source->getName();
+ $crumbs = $this->buildApplicationCrumbs();
+ $crumbs->addTextCrumb($title);
+
+ return $this->buildApplicationPage(
+ array(
+ $crumbs,
+ $response,
+ ),
+ array(
+ 'title' => $title,
+ ));
+ }
+
+}
diff --git a/src/applications/nuance/editor/NuanceItemEditor.php b/src/applications/nuance/editor/NuanceItemEditor.php
--- a/src/applications/nuance/editor/NuanceItemEditor.php
+++ b/src/applications/nuance/editor/NuanceItemEditor.php
@@ -17,6 +17,7 @@
$types[] = NuanceItemTransaction::TYPE_OWNER;
$types[] = NuanceItemTransaction::TYPE_SOURCE;
$types[] = NuanceItemTransaction::TYPE_REQUESTOR;
+ $types[] = NuanceItemTransaction::TYPE_PROPERTY;
$types[] = PhabricatorTransactions::TYPE_EDGE;
$types[] = PhabricatorTransactions::TYPE_COMMENT;
@@ -37,6 +38,10 @@
return $object->getSourcePHID();
case NuanceItemTransaction::TYPE_OWNER:
return $object->getOwnerPHID();
+ case NuanceItemTransaction::TYPE_PROPERTY:
+ $key = $xaction->getMetadataValue(
+ NuanceItemTransaction::PROPERTY_KEY);
+ return $object->getNuanceProperty($key);
}
return parent::getCustomTransactionOldValue($object, $xaction);
@@ -50,6 +55,7 @@
case NuanceItemTransaction::TYPE_REQUESTOR:
case NuanceItemTransaction::TYPE_SOURCE:
case NuanceItemTransaction::TYPE_OWNER:
+ case NuanceItemTransaction::TYPE_PROPERTY:
return $xaction->getNewValue();
}
@@ -70,6 +76,11 @@
case NuanceItemTransaction::TYPE_OWNER:
$object->setOwnerPHID($xaction->getNewValue());
break;
+ case NuanceItemTransaction::TYPE_PROPERTY:
+ $key = $xaction->getMetadataValue(
+ NuanceItemTransaction::PROPERTY_KEY);
+ $object->setNuanceProperty($key, $xaction->getNewValue());
+ break;
}
}
@@ -81,6 +92,7 @@
case NuanceItemTransaction::TYPE_REQUESTOR:
case NuanceItemTransaction::TYPE_SOURCE:
case NuanceItemTransaction::TYPE_OWNER:
+ case NuanceItemTransaction::TYPE_PROPERTY:
return;
}
diff --git a/src/applications/nuance/editor/NuanceRequestorEditor.php b/src/applications/nuance/editor/NuanceRequestorEditor.php
--- a/src/applications/nuance/editor/NuanceRequestorEditor.php
+++ b/src/applications/nuance/editor/NuanceRequestorEditor.php
@@ -14,12 +14,62 @@
public function getTransactionTypes() {
$types = parent::getTransactionTypes();
- $types[] = PhabricatorTransactions::TYPE_EDGE;
- $types[] = PhabricatorTransactions::TYPE_COMMENT;
+ $types[] = NuanceRequestorTransaction::TYPE_PROPERTY;
+
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
return $types;
}
+ protected function getCustomTransactionOldValue(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ switch ($xaction->getTransactionType()) {
+ case NuanceRequestorTransaction::TYPE_PROPERTY:
+ $key = $xaction->getMetadataValue(
+ NuanceRequestorTransaction::PROPERTY_KEY);
+ return $object->getNuanceProperty($key);
+ }
+
+ return parent::getCustomTransactionOldValue($object, $xaction);
+ }
+
+ protected function getCustomTransactionNewValue(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ switch ($xaction->getTransactionType()) {
+ case NuanceRequestorTransaction::TYPE_PROPERTY:
+ return $xaction->getNewValue();
+ }
+
+ return parent::getCustomTransactionNewValue($object, $xaction);
+ }
+
+ protected function applyCustomInternalTransaction(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ switch ($xaction->getTransactionType()) {
+ case NuanceRequestorTransaction::TYPE_PROPERTY:
+ $key = $xaction->getMetadataValue(
+ NuanceRequestorTransaction::PROPERTY_KEY);
+ $object->setNuanceProperty($key, $xaction->getNewValue());
+ break;
+ }
+ }
+
+ protected function applyCustomExternalTransaction(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ switch ($xaction->getTransactionType()) {
+ case NuanceRequestorTransaction::TYPE_PROPERTY:
+ return;
+ }
+
+ return parent::applyCustomExternalTransaction($object, $xaction);
+ }
}
diff --git a/src/applications/nuance/query/NuanceItemQuery.php b/src/applications/nuance/query/NuanceItemQuery.php
--- a/src/applications/nuance/query/NuanceItemQuery.php
+++ b/src/applications/nuance/query/NuanceItemQuery.php
@@ -5,7 +5,7 @@
private $ids;
private $phids;
- private $sourceIDs;
+ private $sourcePHIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
@@ -17,54 +17,52 @@
return $this;
}
- public function withSourceIDs($source_ids) {
- $this->sourceIDs = $source_ids;
+ public function withSourcePHIDs($source_phids) {
+ $this->sourcePHIDs = $source_phids;
return $this;
}
-
protected function loadPage() {
$table = new NuanceItem();
- $conn_r = $table->establishConnection('r');
+ $conn = $table->establishConnection('r');
$data = queryfx_all(
- $conn_r,
- 'SELECT FROM %T %Q %Q %Q',
+ $conn,
+ '%Q FROM %T %Q %Q %Q',
+ $this->buildSelectClause($conn),
$table->getTableName(),
- $this->buildWhereClause($conn_r),
- $this->buildOrderClause($conn_r),
- $this->buildLimitClause($conn_r));
+ $this->buildWhereClause($conn),
+ $this->buildOrderClause($conn),
+ $this->buildLimitClause($conn));
return $table->loadAllFromArray($data);
}
- protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
- $where = array();
-
- $where[] = $this->buildPagingClause($conn_r);
+ protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
+ $where = parent::buildWhereClauseParts($conn);
- if ($this->sourceID) {
+ if ($this->sourcePHIDs !== null) {
$where[] = qsprintf(
- $conn_r,
- 'sourceID IN (%Ld)',
- $this->sourceIDs);
+ $conn,
+ 'sourcePHID IN (%Ls)',
+ $this->sourcePHIDs);
}
- if ($this->ids) {
+ if ($this->ids !== null) {
$where[] = qsprintf(
- $conn_r,
+ $conn,
'id IN (%Ld)',
$this->ids);
}
- if ($this->phids) {
+ if ($this->phids !== null) {
$where[] = qsprintf(
- $conn_r,
+ $conn,
'phid IN (%Ls)',
$this->phids);
}
- return $this->formatWhereClause($where);
+ return $where;
}
}
diff --git a/src/applications/nuance/source/NuancePhabricatorFormSourceDefinition.php b/src/applications/nuance/source/NuancePhabricatorFormSourceDefinition.php
--- a/src/applications/nuance/source/NuancePhabricatorFormSourceDefinition.php
+++ b/src/applications/nuance/source/NuancePhabricatorFormSourceDefinition.php
@@ -42,4 +42,51 @@
public function renderListView() {}
+
+ public function handleActionRequest(AphrontRequest $request) {
+ $viewer = $request->getViewer();
+
+ // TODO: As above, this would eventually be driven by custom logic.
+
+ if ($request->isFormPost()) {
+ $properties = array(
+ 'complaint' => (string)$request->getStr('text'),
+ );
+
+ $content_source = PhabricatorContentSource::newFromRequest($request);
+
+ $requestor = NuanceRequestor::newFromPhabricatorUser(
+ $viewer,
+ $content_source);
+
+ $item = $this->newItemFromProperties(
+ $requestor,
+ $properties,
+ $content_source);
+
+ $uri = $item->getURI();
+ return id(new AphrontRedirectResponse())->setURI($uri);
+ }
+
+ $form = id(new AphrontFormView())
+ ->setUser($viewer)
+ ->appendRemarkupInstructions(
+ pht('IMPORTANT: This is a very rough prototype.'))
+ ->appendRemarkupInstructions(
+ pht('Got a complaint? Complain here! We love complaints.'))
+ ->appendChild(
+ id(new AphrontFormTextAreaControl())
+ ->setName('complaint')
+ ->setLabel(pht('Complaint')))
+ ->appendChild(
+ id(new AphrontFormSubmitControl())
+ ->setValue(pht('Submit Complaint')));
+
+ $box = id(new PHUIObjectBoxView())
+ ->setHeaderText(pht('Complaint Form'))
+ ->appendChild($form);
+
+ return $box;
+ }
+
}
diff --git a/src/applications/nuance/source/NuanceSourceDefinition.php b/src/applications/nuance/source/NuanceSourceDefinition.php
--- a/src/applications/nuance/source/NuanceSourceDefinition.php
+++ b/src/applications/nuance/source/NuanceSourceDefinition.php
@@ -1,5 +1,8 @@
<?php
+/**
+ * @task action Handling Action Requests
+ */
abstract class NuanceSourceDefinition extends Phobject {
private $actor;
@@ -254,4 +257,54 @@
abstract public function renderView();
abstract public function renderListView();
+
+
+ protected function newItemFromProperties(
+ NuanceRequestor $requestor,
+ array $properties,
+ PhabricatorContentSource $content_source) {
+
+ // TODO: Should we have a tighter actor/viewer model? Requestors will
+ // often have no real user associated with them...
+ $actor = PhabricatorUser::getOmnipotentUser();
+
+ $source = $this->requireSourceObject();
+
+ $item = NuanceItem::initializeNewItem();
+
+ $xactions = array();
+
+ $xactions[] = id(new NuanceItemTransaction())
+ ->setTransactionType(NuanceItemTransaction::TYPE_SOURCE)
+ ->setNewValue($source->getPHID());
+
+ $xactions[] = id(new NuanceItemTransaction())
+ ->setTransactionType(NuanceItemTransaction::TYPE_REQUESTOR)
+ ->setNewValue($requestor->getPHID());
+
+ foreach ($properties as $key => $property) {
+ $xactions[] = id(new NuanceItemTransaction())
+ ->setTransactionType(NuanceItemTransaction::TYPE_PROPERTY)
+ ->setMetadataValue(NuanceItemTransaction::PROPERTY_KEY, $key)
+ ->setNewValue($property);
+ }
+
+ $editor = id(new NuanceItemEditor())
+ ->setActor($actor)
+ ->setActingAsPHID($requestor->getActingAsPHID())
+ ->setContentSource($content_source);
+
+ $editor->applyTransactions($item, $xactions);
+
+ return $item;
+ }
+
+
+/* -( Handling Action Requests )------------------------------------------- */
+
+
+ public function handleActionRequest(AphrontRequest $request) {
+ return new Aphront404Response();
+ }
+
}
diff --git a/src/applications/nuance/storage/NuanceItem.php b/src/applications/nuance/storage/NuanceItem.php
--- a/src/applications/nuance/storage/NuanceItem.php
+++ b/src/applications/nuance/storage/NuanceItem.php
@@ -13,11 +13,11 @@
protected $requestorPHID;
protected $sourcePHID;
protected $sourceLabel;
- protected $data;
+ protected $data = array();
protected $mailKey;
protected $dateNuanced;
- public static function initializeNewItem(PhabricatorUser $user) {
+ public static function initializeNewItem() {
return id(new NuanceItem())
->setDateNuanced(time())
->setStatus(self::STATUS_OPEN);
@@ -94,6 +94,15 @@
$this->source = $source;
}
+ public function getNuanceProperty($key, $default = null) {
+ return idx($this->data, $key, $default);
+ }
+
+ public function setNuanceProperty($key, $value) {
+ $this->data[$key] = $value;
+ return $this;
+ }
+
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
diff --git a/src/applications/nuance/storage/NuanceItemTransaction.php b/src/applications/nuance/storage/NuanceItemTransaction.php
--- a/src/applications/nuance/storage/NuanceItemTransaction.php
+++ b/src/applications/nuance/storage/NuanceItemTransaction.php
@@ -3,9 +3,12 @@
final class NuanceItemTransaction
extends NuanceTransaction {
- const TYPE_OWNER = 'item-owner';
- const TYPE_REQUESTOR = 'item-requestor';
- const TYPE_SOURCE = 'item-source';
+ const PROPERTY_KEY = 'property.key';
+
+ const TYPE_OWNER = 'nuance.item.owner';
+ const TYPE_REQUESTOR = 'nuance.item.requestor';
+ const TYPE_SOURCE = 'nuance.item.source';
+ const TYPE_PROPERTY = 'nuance.item.property';
public function getApplicationTransactionType() {
return NuanceItemPHIDType::TYPECONST;
diff --git a/src/applications/nuance/storage/NuanceRequestor.php b/src/applications/nuance/storage/NuanceRequestor.php
--- a/src/applications/nuance/storage/NuanceRequestor.php
+++ b/src/applications/nuance/storage/NuanceRequestor.php
@@ -1,9 +1,12 @@
<?php
final class NuanceRequestor
- extends NuanceDAO {
+ extends NuanceDAO
+ implements
+ PhabricatorPolicyInterface,
+ PhabricatorApplicationTransactionInterface {
- protected $data;
+ protected $data = array();
protected function getConfiguration() {
return array(
@@ -19,11 +22,8 @@
NuanceRequestorPHIDType::TYPECONST);
}
- public function save() {
- if (!$this->getMailKey()) {
- $this->setMailKey(Filesystem::readRandomCharacters(20));
- }
- return parent::save();
+ public static function initializeNewRequestor() {
+ return new NuanceRequestor();
}
public function getURI() {
@@ -34,4 +34,104 @@
return idx($this->getData(), 'phabricatorUserPHID');
}
+ public function getActingAsPHID() {
+ $user_phid = $this->getPhabricatorUserPHID();
+ if ($user_phid) {
+ return $user_phid;
+ }
+
+ return id(new PhabricatorNuanceApplication())->getPHID();
+ }
+
+ public static function newFromPhabricatorUser(
+ PhabricatorUser $viewer,
+ PhabricatorContentSource $content_source) {
+
+ // TODO: This is real sketchy and creates a new requestor every time. It
+ // shouldn't do that.
+
+ $requestor = self::initializeNewRequestor();
+
+ $xactions = array();
+
+ $properties = array(
+ 'phabricatorUserPHID' => $viewer->getPHID(),
+ );
+
+ foreach ($properties as $key => $value) {
+ $xactions[] = id(new NuanceRequestorTransaction())
+ ->setTransactionType(NuanceRequestorTransaction::TYPE_PROPERTY)
+ ->setMetadataValue(NuanceRequestorTransaction::PROPERTY_KEY, $key)
+ ->setNewValue($value);
+ }
+
+ $editor = id(new NuanceRequestorEditor())
+ ->setActor($viewer)
+ ->setContentSource($content_source);
+
+ $editor->applyTransactions($requestor, $xactions);
+
+ return $requestor;
+ }
+
+ public function getNuanceProperty($key, $default = null) {
+ return idx($this->data, $key, $default);
+ }
+
+ public function setNuanceProperty($key, $value) {
+ $this->data[$key] = $value;
+ return $this;
+ }
+
+
+/* -( PhabricatorPolicyInterface )----------------------------------------- */
+
+
+ public function getCapabilities() {
+ return array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
+ );
+ }
+
+ public function getPolicy($capability) {
+ switch ($capability) {
+ case PhabricatorPolicyCapability::CAN_VIEW:
+ return PhabricatorPolicies::POLICY_USER;
+ case PhabricatorPolicyCapability::CAN_EDIT:
+ return PhabricatorPolicies::POLICY_USER;
+ }
+ }
+
+ public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
+ return false;
+ }
+
+ public function describeAutomaticCapability($capability) {
+ return null;
+ }
+
+
+/* -( PhabricatorApplicationTransactionInterface )------------------------- */
+
+
+ public function getApplicationTransactionEditor() {
+ return new NuanceRequestorEditor();
+ }
+
+ public function getApplicationTransactionObject() {
+ return $this;
+ }
+
+ public function getApplicationTransactionTemplate() {
+ return new NuanceRequestorTransaction();
+ }
+
+ public function willRenderTimeline(
+ PhabricatorApplicationTransactionView $timeline,
+ AphrontRequest $request) {
+
+ return $timeline;
+ }
+
}
diff --git a/src/applications/nuance/storage/NuanceRequestorTransaction.php b/src/applications/nuance/storage/NuanceRequestorTransaction.php
--- a/src/applications/nuance/storage/NuanceRequestorTransaction.php
+++ b/src/applications/nuance/storage/NuanceRequestorTransaction.php
@@ -3,6 +3,10 @@
final class NuanceRequestorTransaction
extends NuanceTransaction {
+ const PROPERTY_KEY = 'property.key';
+
+ const TYPE_PROPERTY = 'nuance.requestor.property';
+
public function getApplicationTransactionType() {
return NuanceRequestorPHIDType::TYPECONST;
}

File Metadata

Mime Type
text/plain
Expires
Fri, Dec 20, 10:00 AM (21 h, 3 s)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6910124
Default Alt Text
D13166.diff (19 KB)

Event Timeline