From 50f257adee182df5f3e0c3dbae2d044a1e0122cc Mon Sep 17 00:00:00 2001 From: epriestley Date: Sun, 29 Nov 2015 11:28:27 -0800 Subject: [PATCH] Allow EditEngine Conduit endpoints to accept object IDs and monograms Summary: Ref T9132. This is a quality-of-life improvement for new `application.edit` endpoints. Instead of strictly requiring PHIDs, allow IDs or monograms. This primarily makes these endpoints easier to test and use. Test Plan: Edited objects via API by passing IDs, PHIDs and monograms. Reviewers: chad Reviewed By: chad Maniphest Tasks: T9132 Differential Revision: https://secure.phabricator.com/D14600 --- .../editengine/PhabricatorEditEngine.php | 86 +++++++++++++++++-- .../PhabricatorEditEngineAPIMethod.php | 10 ++- 2 files changed, 87 insertions(+), 9 deletions(-) diff --git a/src/applications/transactions/editengine/PhabricatorEditEngine.php b/src/applications/transactions/editengine/PhabricatorEditEngine.php index 59ca02f313..1445ea59b2 100644 --- a/src/applications/transactions/editengine/PhabricatorEditEngine.php +++ b/src/applications/transactions/editengine/PhabricatorEditEngine.php @@ -378,6 +378,83 @@ abstract class PhabricatorEditEngine } + /** + * Try to load an object by ID, PHID, or monogram. This is done primarily + * to make Conduit a little easier to use. + * + * @param wild ID, PHID, or monogram. + * @return object Corresponding editable object. + * @task load + */ + private function newObjectFromIdentifier($identifier) { + if (is_int($identifier) || ctype_digit($identifier)) { + $object = $this->newObjectFromID($identifier); + + if (!$object) { + throw new Exception( + pht( + 'No object exists with ID "%s".', + $identifier)); + } + + return $object; + } + + $type_unknown = PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN; + if (phid_get_type($identifier) != $type_unknown) { + $object = $this->newObjectFromPHID($identifier); + + if (!$object) { + throw new Exception( + pht( + 'No object exists with PHID "%s".', + $identifier)); + } + + return $object; + } + + $target = id(new PhabricatorObjectQuery()) + ->setViewer($this->getViewer()) + ->withNames(array($identifier)) + ->executeOne(); + if (!$target) { + throw new Exception( + pht( + 'Monogram "%s" does not identify a valid object.', + $identifier)); + } + + $expect = $this->newEditableObject(); + $expect_class = get_class($expect); + $target_class = get_class($target); + if ($expect_class !== $target_class) { + throw new Exception( + pht( + 'Monogram "%s" identifies an object of the wrong type. Loaded '. + 'object has class "%s", but this editor operates on objects of '. + 'type "%s".', + $identifier, + $target_class, + $expect_class)); + } + + // Load the object by PHID using this engine's standard query. This makes + // sure it's really valid, goes through standard policy check logic, and + // picks up any `need...()` clauses we want it to load with. + + $object = $this->newObjectFromPHID($target->getPHID()); + if (!$object) { + throw new Exception( + pht( + 'Failed to reload object identified by monogram "%s" when '. + 'querying by PHID.', + $identifier)); + } + + return $object; + } + /** * Load an object by ID. * @@ -851,13 +928,10 @@ abstract class PhabricatorEditEngine get_class($this))); } - $phid = $request->getValue('objectPHID'); - if ($phid) { + $identifier = $request->getValue('objectIdentifier'); + if ($identifier) { $this->setIsCreate(false); - $object = $this->newObjectFromPHID($phid); - if (!$object) { - throw new Exception(pht('No such object with PHID "%s".', $phid)); - } + $object = $this->newObjectFromIdentifier($identifier); } else { $this->setIsCreate(true); $object = $this->newEditableObject(); diff --git a/src/applications/transactions/editengine/PhabricatorEditEngineAPIMethod.php b/src/applications/transactions/editengine/PhabricatorEditEngineAPIMethod.php index ca6b9fe370..8358352675 100644 --- a/src/applications/transactions/editengine/PhabricatorEditEngineAPIMethod.php +++ b/src/applications/transactions/editengine/PhabricatorEditEngineAPIMethod.php @@ -22,7 +22,7 @@ abstract class PhabricatorEditEngineAPIMethod final protected function defineParamTypes() { return array( 'transactions' => 'list>', - 'objectPHID' => 'optional phid', + 'objectIdentifier' => 'optional id|phid|string', ); } @@ -90,7 +90,7 @@ Exactly which types of edits are available depends on the object you're editing. Creating Objects ---------------- -To create an object, pass a list of `transactions` but leave `objectPHID` +To create an object, pass a list of `transactions` but leave `objectIdentifier` empty. This will create a new object with the initial field values you specify. @@ -99,7 +99,11 @@ Editing Objects --------------- To edit an object, pass a list of `transactions` and specify an object to -apply them to with `objectPHID`. This will apply the changes to the object. +apply them to with `objectIdentifier`. This will apply the changes to the +object. + +You may pass an ID (like `123`), PHID (like `PHID-WXYZ-abcdef...`), or +monogram (like `T123`, for objects which have monograms). Return Type