Index: src/__phutil_library_map__.php =================================================================== --- src/__phutil_library_map__.php +++ src/__phutil_library_map__.php @@ -197,6 +197,8 @@ 'ConduitAPI_maniphest_info_Method' => 'applications/maniphest/conduit/ConduitAPI_maniphest_info_Method.php', 'ConduitAPI_maniphest_query_Method' => 'applications/maniphest/conduit/ConduitAPI_maniphest_query_Method.php', 'ConduitAPI_maniphest_update_Method' => 'applications/maniphest/conduit/ConduitAPI_maniphest_update_Method.php', + 'ConduitAPI_nuance_Method' => 'applications/nuance/conduit/ConduitAPI_nuance_Method.php', + 'ConduitAPI_nuance_createitem_Method' => 'applications/nuance/conduit/ConduitAPI_nuance_createitem_Method.php', 'ConduitAPI_owners_Method' => 'applications/owners/conduit/ConduitAPI_owners_Method.php', 'ConduitAPI_owners_query_Method' => 'applications/owners/conduit/ConduitAPI_owners_query_Method.php', 'ConduitAPI_paste_Method' => 'applications/paste/conduit/ConduitAPI_paste_Method.php', @@ -2612,6 +2614,8 @@ 'ConduitAPI_maniphest_info_Method' => 'ConduitAPI_maniphest_Method', 'ConduitAPI_maniphest_query_Method' => 'ConduitAPI_maniphest_Method', 'ConduitAPI_maniphest_update_Method' => 'ConduitAPI_maniphest_Method', + 'ConduitAPI_nuance_Method' => 'ConduitAPIMethod', + 'ConduitAPI_nuance_createitem_Method' => 'ConduitAPI_nuance_Method', 'ConduitAPI_owners_Method' => 'ConduitAPIMethod', 'ConduitAPI_owners_query_Method' => 'ConduitAPI_owners_Method', 'ConduitAPI_paste_Method' => 'ConduitAPIMethod', Index: src/applications/nuance/conduit/ConduitAPI_nuance_Method.php =================================================================== --- /dev/null +++ src/applications/nuance/conduit/ConduitAPI_nuance_Method.php @@ -0,0 +1,17 @@ + 'required string', + 'sourcePHID' => 'required string', + 'ownerPHID' => 'optional string', + ); + } + + public function defineReturnType() { + return 'nonempty dict'; + } + + public function defineErrorTypes() { + return array( + 'ERR-NO-REQUESTOR-PHID' => pht('Items must have a requestor.'), + 'ERR-NO-SOURCE-PHID' => pht('Items must have a source.'), + ); + } + + protected function execute(ConduitAPIRequest $request) { + $source_phid = $request->getValue('sourcePHID'); + $owner_phid = $request->getValue('ownerPHID'); + $requestor_phid = $request->getValue('requestorPHID'); + + $user = $request->getUser(); + + $item = NuanceItem::initializeNewItem($user); + $xactions = array(); + + if ($source_phid) { + $xactions[] = id(new NuanceItemTransaction()) + ->setTransactionType(NuanceItemTransaction::TYPE_SOURCE) + ->setNewValue($source_phid); + } else { + throw new ConduitException('ERR-NO-SOURCE-PHID'); + } + + if ($owner_phid) { + $xactions[] = id(new NuanceItemTransaction()) + ->setTransactionType(NuanceItemTransaction::TYPE_OWNER) + ->setNewValue($owner_phid); + } + + if ($requestor_phid) { + $xactions[] = id(new NuanceItemTransaction()) + ->setTransactionType(NuanceItemTransaction::TYPE_REQUESTOR) + ->setNewValue($requestor_phid); + } else { + throw new ConduitException('ERR-NO-REQUESTOR-PHID'); + } + + $source = PhabricatorContentSource::newFromConduitRequest($request); + $editor = id(new NuanceItemEditor()) + ->setActor($user) + ->setContentSource($source) + ->applyTransactions($item, $xactions); + + return $item->toDictionary(); + } + +} Index: src/applications/nuance/editor/NuanceItemEditor.php =================================================================== --- src/applications/nuance/editor/NuanceItemEditor.php +++ src/applications/nuance/editor/NuanceItemEditor.php @@ -6,6 +6,10 @@ public function getTransactionTypes() { $types = parent::getTransactionTypes(); + $types[] = NuanceItemTransaction::TYPE_OWNER; + $types[] = NuanceItemTransaction::TYPE_SOURCE; + $types[] = NuanceItemTransaction::TYPE_REQUESTOR; + $types[] = PhabricatorTransactions::TYPE_EDGE; $types[] = PhabricatorTransactions::TYPE_COMMENT; $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; @@ -14,4 +18,65 @@ return $types; } + protected function getCustomTransactionOldValue( + PhabricatorLiskDAO $object, + PhabricatorApplicationTransaction $xaction) { + + switch ($xaction->getTransactionType()) { + case NuanceItemTransaction::TYPE_REQUESTOR: + return $object->getRequestorPHID(); + case NuanceItemTransaction::TYPE_SOURCE: + return $object->getSourcePHID(); + case NuanceItemTransaction::TYPE_OWNER: + return $object->getOwnerPHID(); + } + + return parent::getCustomTransactionOldValue($object, $xaction); + } + + protected function getCustomTransactionNewValue( + PhabricatorLiskDAO $object, + PhabricatorApplicationTransaction $xaction) { + + switch ($xaction->getTransactionType()) { + case NuanceItemTransaction::TYPE_REQUESTOR: + case NuanceItemTransaction::TYPE_SOURCE: + case NuanceItemTransaction::TYPE_OWNER: + return $xaction->getNewValue(); + } + + return parent::getCustomTransactionNewValue($object, $xaction); + } + + protected function applyCustomInternalTransaction( + PhabricatorLiskDAO $object, + PhabricatorApplicationTransaction $xaction) { + + switch ($xaction->getTransactionType()) { + case NuanceItemTransaction::TYPE_REQUESTOR: + $object->setRequestorPHID($xaction->getNewValue()); + break; + case NuanceItemTransaction::TYPE_SOURCE: + $object->setSourcePHID($xaction->getNewValue()); + break; + case NuanceItemTransaction::TYPE_OWNER: + $object->setOwnerPHID($xaction->getNewValue()); + break; + } + } + + protected function applyCustomExternalTransaction( + PhabricatorLiskDAO $object, + PhabricatorApplicationTransaction $xaction) { + + switch ($xaction->getTransactionType()) { + case NuanceItemTransaction::TYPE_REQUESTOR: + case NuanceItemTransaction::TYPE_SOURCE: + case NuanceItemTransaction::TYPE_OWNER: + return; + } + + return parent::applyCustomExternalTransaction($object, $xaction); + } + } Index: src/applications/nuance/storage/NuanceItem.php =================================================================== --- src/applications/nuance/storage/NuanceItem.php +++ src/applications/nuance/storage/NuanceItem.php @@ -4,6 +4,11 @@ extends NuanceDAO implements PhabricatorPolicyInterface { + const STATUS_OPEN = 0; + const STATUS_ASSIGNED = 10; + const STATUS_CLOSED = 20; + + protected $status; protected $ownerPHID; protected $requestorPHID; protected $sourcePHID; @@ -12,6 +17,11 @@ protected $mailKey; protected $dateNuanced; + public static function initializeNewItem(PhabricatorUser $user) { + return id(new NuanceItem()) + ->setDateNuanced(time()) + ->setStatus(NuanceItem::STATUS_OPEN); + } public function getConfiguration() { return array( self::CONFIG_AUX_PHID => true, @@ -74,7 +84,7 @@ public function getPolicy($capability) { // TODO - this should be based on the queues the item currently resides in - return PhabricatorPolicies::POLICY_NOONE; + return PhabricatorPolicies::POLICY_USER; } public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { @@ -92,4 +102,17 @@ return null; } + public function toDictionary() { + return array( + 'id' => $this->getID(), + 'phid' => $this->getPHID(), + 'ownerPHID' => $this->getOwnerPHID(), + 'requestorPHID' => $this->getRequestorPHID(), + 'sourcePHID' => $this->getSourcePHID(), + 'sourceLabel' => $this->getSourceLabel(), + 'dateCreated' => $this->getDateCreated(), + 'dateModified' => $this->getDateModified(), + 'dateNuanced' => $this->getDateNuanced(), + ); + } } Index: src/applications/nuance/storage/NuanceItemTransaction.php =================================================================== --- src/applications/nuance/storage/NuanceItemTransaction.php +++ src/applications/nuance/storage/NuanceItemTransaction.php @@ -3,6 +3,10 @@ final class NuanceItemTransaction extends NuanceTransaction { + const TYPE_OWNER = 'item-owner'; + const TYPE_REQUESTOR = 'item-requestor'; + const TYPE_SOURCE = 'item-source'; + public function getApplicationTransactionType() { return NuancePHIDTypeItem::TYPECONST; }