From 701bf8317f8f154ec74ac765232bf1bcd0927c9d Mon Sep 17 00:00:00 2001 From: epriestley Date: Fri, 26 Aug 2011 12:50:28 -0700 Subject: [PATCH] Provide access to Phriction via Conduit Summary: Provide three Phriction methods for programmatic access to Phriction: - phriction.info: get information about a document - phriction.history: get change history for a document - phriction.edit: create or update a document I moved all the editing/creation logic into a new PhrictionDocumentEditor to share code between the Conduit and Web edit pathways. Test Plan: Got info and history via conduit. Edited and created new pages via conduit and web. Reviewers: hsb, jungejason, tuomaspelkonen, aran, hunterbridges Reviewed By: hunterbridges CC: skrul, aran, hunterbridges Differential Revision: 866 --- src/__phutil_library_map__.php | 9 + .../base/ConduitAPI_phriction_Method.php | 49 ++++++ .../method/phriction/base/__init__.php | 14 ++ .../edit/ConduitAPI_phriction_edit_Method.php | 60 +++++++ .../method/phriction/edit/__init__.php | 15 ++ .../ConduitAPI_phriction_history_Method.php | 68 ++++++++ .../method/phriction/history/__init__.php | 17 ++ .../info/ConduitAPI_phriction_info_Method.php | 62 +++++++ .../method/phriction/info/__init__.php | 17 ++ .../edit/PhrictionEditController.php | 51 +----- .../phriction/controller/edit/__init__.php | 5 +- .../document/PhrictionDocumentEditor.php | 155 ++++++++++++++++++ .../phriction/editor/document/__init__.php | 19 +++ 13 files changed, 493 insertions(+), 48 deletions(-) create mode 100644 src/applications/conduit/method/phriction/base/ConduitAPI_phriction_Method.php create mode 100644 src/applications/conduit/method/phriction/base/__init__.php create mode 100644 src/applications/conduit/method/phriction/edit/ConduitAPI_phriction_edit_Method.php create mode 100644 src/applications/conduit/method/phriction/edit/__init__.php create mode 100644 src/applications/conduit/method/phriction/history/ConduitAPI_phriction_history_Method.php create mode 100644 src/applications/conduit/method/phriction/history/__init__.php create mode 100644 src/applications/conduit/method/phriction/info/ConduitAPI_phriction_info_Method.php create mode 100644 src/applications/conduit/method/phriction/info/__init__.php create mode 100644 src/applications/phriction/editor/document/PhrictionDocumentEditor.php create mode 100644 src/applications/phriction/editor/document/__init__.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 4599c55c72..d851e593cc 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -124,6 +124,10 @@ phutil_register_library_map(array( 'ConduitAPI_path_getowners_Method' => 'applications/conduit/method/path/getowners', 'ConduitAPI_phid_Method' => 'applications/conduit/method/phid/base', 'ConduitAPI_phid_info_Method' => 'applications/conduit/method/phid/info', + 'ConduitAPI_phriction_Method' => 'applications/conduit/method/phriction/base', + 'ConduitAPI_phriction_edit_Method' => 'applications/conduit/method/phriction/edit', + 'ConduitAPI_phriction_history_Method' => 'applications/conduit/method/phriction/history', + 'ConduitAPI_phriction_info_Method' => 'applications/conduit/method/phriction/info', 'ConduitAPI_slowvote_info_Method' => 'applications/conduit/method/slowvote/info', 'ConduitAPI_user_Method' => 'applications/conduit/method/user/base', 'ConduitAPI_user_find_Method' => 'applications/conduit/method/user/find', @@ -673,6 +677,7 @@ phutil_register_library_map(array( 'PhrictionDiffController' => 'applications/phriction/controller/diff', 'PhrictionDocument' => 'applications/phriction/storage/document', 'PhrictionDocumentController' => 'applications/phriction/controller/document', + 'PhrictionDocumentEditor' => 'applications/phriction/editor/document', 'PhrictionDocumentPreviewController' => 'applications/phriction/controller/documentpreview', 'PhrictionDocumentTestCase' => 'applications/phriction/storage/document/__tests__', 'PhrictionEditController' => 'applications/phriction/controller/edit', @@ -805,6 +810,10 @@ phutil_register_library_map(array( 'ConduitAPI_path_getowners_Method' => 'ConduitAPIMethod', 'ConduitAPI_phid_Method' => 'ConduitAPIMethod', 'ConduitAPI_phid_info_Method' => 'ConduitAPI_phid_Method', + 'ConduitAPI_phriction_Method' => 'ConduitAPIMethod', + 'ConduitAPI_phriction_edit_Method' => 'ConduitAPI_phriction_Method', + 'ConduitAPI_phriction_history_Method' => 'ConduitAPI_phriction_Method', + 'ConduitAPI_phriction_info_Method' => 'ConduitAPI_phriction_Method', 'ConduitAPI_slowvote_info_Method' => 'ConduitAPIMethod', 'ConduitAPI_user_Method' => 'ConduitAPIMethod', 'ConduitAPI_user_find_Method' => 'ConduitAPI_user_Method', diff --git a/src/applications/conduit/method/phriction/base/ConduitAPI_phriction_Method.php b/src/applications/conduit/method/phriction/base/ConduitAPI_phriction_Method.php new file mode 100644 index 0000000000..8ed56cf690 --- /dev/null +++ b/src/applications/conduit/method/phriction/base/ConduitAPI_phriction_Method.php @@ -0,0 +1,49 @@ +getContent(); + return $this->buildDocumentContentDictionary($doc, $content); + } + + final protected function buildDocumentContentDictionary( + PhrictionDocument $doc, + PhrictionContent $content) { + + $uri = PhrictionDocument::getSlugURI($content->getSlug()); + $uri = PhabricatorEnv::getProductionURI($uri); + + return array( + 'phid' => $doc->getPHID(), + 'uri' => $uri, + 'slug' => $content->getSlug(), + 'version' => $content->getVersion(), + 'authorPHID' => $content->getAuthorPHID(), + 'title' => $content->getTitle(), + 'content' => $content->getContent(), + 'description' => $content->getDescription(), + 'dateCreated' => $content->getDateCreated(), + ); + } + +} diff --git a/src/applications/conduit/method/phriction/base/__init__.php b/src/applications/conduit/method/phriction/base/__init__.php new file mode 100644 index 0000000000..c29bfaef8f --- /dev/null +++ b/src/applications/conduit/method/phriction/base/__init__.php @@ -0,0 +1,14 @@ + 'required string', + 'title' => 'optional string', + 'content' => 'optional string', + 'description' => 'optional string', + ); + } + + public function defineReturnType() { + return 'nonempty dict'; + } + + public function defineErrorTypes() { + return array( + ); + } + + protected function execute(ConduitAPIRequest $request) { + $slug = $request->getValue('slug'); + + $editor = id(PhrictionDocumentEditor::newForSlug($slug)) + ->setUser($request->getUser()) + ->setTitle($request->getValue('title')) + ->setContent($request->getValue('content')) + ->setDescription($request->getvalue('description')) + ->save(); + + return $this->buildDocumentInfoDictionary($editor->getDocument()); + } + +} diff --git a/src/applications/conduit/method/phriction/edit/__init__.php b/src/applications/conduit/method/phriction/edit/__init__.php new file mode 100644 index 0000000000..678afe0002 --- /dev/null +++ b/src/applications/conduit/method/phriction/edit/__init__.php @@ -0,0 +1,15 @@ + 'required string', + ); + } + + public function defineReturnType() { + return 'nonempty list'; + } + + public function defineErrorTypes() { + return array( + 'ERR-BAD-DOCUMENT' => 'No such document exists.', + ); + } + + protected function execute(ConduitAPIRequest $request) { + $slug = $request->getValue('slug'); + $doc = id(new PhrictionDocument())->loadOneWhere( + 'slug = %s', + PhrictionDocument::normalizeSlug($slug)); + if (!$doc) { + throw new ConduitException('ERR-BAD-DOCUMENT'); + } + + $content = id(new PhrictionContent())->loadAllWhere( + 'documentID = %d ORDER BY version DESC', + $doc->getID()); + + $results = array(); + foreach ($content as $version) { + $results[] = $this->buildDocumentContentDictionary( + $doc, + $version); + } + + return $results; + } + +} diff --git a/src/applications/conduit/method/phriction/history/__init__.php b/src/applications/conduit/method/phriction/history/__init__.php new file mode 100644 index 0000000000..1c09d18552 --- /dev/null +++ b/src/applications/conduit/method/phriction/history/__init__.php @@ -0,0 +1,17 @@ + 'required string', + ); + } + + public function defineReturnType() { + return 'nonempty dict'; + } + + public function defineErrorTypes() { + return array( + 'ERR-BAD-DOCUMENT' => 'No such document exists.', + ); + } + + protected function execute(ConduitAPIRequest $request) { + $slug = $request->getValue('slug'); + + $doc = id(new PhrictionDocument())->loadOneWhere( + 'slug = %s', + PhrictionDocument::normalizeSlug($slug)); + + if (!$doc) { + throw new ConduitException('ERR-BAD-DOCUMENT'); + } + + $content = id(new PhrictionContent())->load($doc->getContentID()); + $doc->attachContent($content); + + return $this->buildDocumentInfoDictionary($doc); + } + +} diff --git a/src/applications/conduit/method/phriction/info/__init__.php b/src/applications/conduit/method/phriction/info/__init__.php new file mode 100644 index 0000000000..a5d500f2d9 --- /dev/null +++ b/src/applications/conduit/method/phriction/info/__init__.php @@ -0,0 +1,17 @@ +setUser($user) + ->setTitle($title) + ->setContent($request->getStr('content')) + ->setDescription($request->getStr('description')); - // TODO: This should all be transactional. + $editor->save(); - $is_new = false; - if (!$document->getID()) { - $is_new = true; - $document->save(); - } - $new_content = new PhrictionContent(); - $new_content->setSlug($document->getSlug()); - $new_content->setTitle($title); - $new_content->setDescription($request->getStr('description')); - $new_content->setContent($request->getStr('content')); - - $new_content->setDocumentID($document->getID()); - $new_content->setVersion($content->getVersion() + 1); - - $new_content->setAuthorPHID($user->getPHID()); - $new_content->save(); - - $document->setContentID($new_content->getID()); - $document->save(); - - $document->attachContent($new_content); - PhabricatorSearchPhrictionIndexer::indexDocument($document); - - id(new PhabricatorFeedStoryPublisher()) - ->setRelatedPHIDs( - array( - $document->getPHID(), - $user->getPHID(), - )) - ->setStoryAuthorPHID($user->getPHID()) - ->setStoryTime(time()) - ->setStoryType(PhabricatorFeedStoryTypeConstants::STORY_PHRICTION) - ->setStoryData( - array( - 'phid' => $document->getPHID(), - 'action' => $is_new - ? PhrictionActionConstants::ACTION_CREATE - : PhrictionActionConstants::ACTION_EDIT, - 'content' => phutil_utf8_shorten($new_content->getContent(), 140), - )) - ->publish(); - - $uri = PhrictionDocument::getSlugURI($document->getSlug()); + $uri = PhrictionDocument::getSlugURI($slug); return id(new AphrontRedirectResponse())->setURI($uri); } } diff --git a/src/applications/phriction/controller/edit/__init__.php b/src/applications/phriction/controller/edit/__init__.php index 8fcb0e1551..a29a88bcb4 100644 --- a/src/applications/phriction/controller/edit/__init__.php +++ b/src/applications/phriction/controller/edit/__init__.php @@ -8,13 +8,10 @@ phutil_require_module('phabricator', 'aphront/response/404'); phutil_require_module('phabricator', 'aphront/response/redirect'); -phutil_require_module('phabricator', 'applications/feed/constants/story'); -phutil_require_module('phabricator', 'applications/feed/publisher'); -phutil_require_module('phabricator', 'applications/phriction/constants/action'); phutil_require_module('phabricator', 'applications/phriction/controller/base'); +phutil_require_module('phabricator', 'applications/phriction/editor/document'); phutil_require_module('phabricator', 'applications/phriction/storage/content'); phutil_require_module('phabricator', 'applications/phriction/storage/document'); -phutil_require_module('phabricator', 'applications/search/index/indexer/phriction'); phutil_require_module('phabricator', 'infrastructure/celerity/api'); phutil_require_module('phabricator', 'infrastructure/env'); phutil_require_module('phabricator', 'infrastructure/javelin/api'); diff --git a/src/applications/phriction/editor/document/PhrictionDocumentEditor.php b/src/applications/phriction/editor/document/PhrictionDocumentEditor.php new file mode 100644 index 0000000000..c760d405ec --- /dev/null +++ b/src/applications/phriction/editor/document/PhrictionDocumentEditor.php @@ -0,0 +1,155 @@ + + } + + public static function newForSlug($slug) { + $slug = PhrictionDocument::normalizeSlug($slug); + $document = id(new PhrictionDocument())->loadOneWhere( + 'slug = %s', + $slug); + $content = null; + + if ($document) { + $content = id(new PhrictionContent())->load($document->getContentID()); + } else { + $document = new PhrictionDocument(); + $document->setSlug($slug); + } + + if (!$content) { + $default_title = PhrictionDocument::getDefaultSlugTitle($slug); + $content = new PhrictionContent(); + $content->setSlug($slug); + $content->setTitle($default_title); + } + + $obj = new PhrictionDocumentEditor(); + $obj->document = $document; + $obj->content = $content; + + return $obj; + } + + public function setUser(PhabricatorUser $user) { + $this->user = $user; + return $this; + } + + public function setTitle($title) { + $this->newTitle = $title; + return $this; + } + + public function setContent($content) { + $this->newContent = $content; + return $this; + } + + public function setDescription($description) { + $this->description = $description; + return $this; + } + + public function getDocument() { + return $this->document; + } + + public function save() { + if (!$this->user) { + throw new Exception("Call setUser() before save()!"); + } + + $document = $this->document; + $content = $this->content; + + $new_content = new PhrictionContent(); + $new_content->setSlug($document->getSlug()); + $new_content->setAuthorPHID($this->user->getPHID()); + + $new_content->setTitle( + coalesce( + $this->newTitle, + $content->getTitle())); + + $new_content->setContent( + coalesce( + $this->newContent, + $content->getContent())); + + if (strlen($this->description)) { + $new_content->setDescription($this->description); + } + + $new_content->setVersion($content->getVersion() + 1); + + // TODO: This should be transactional. + $is_new = false; + if (!$document->getID()) { + $is_new = true; + $document->save(); + } + + $new_content->setDocumentID($document->getID()); + $new_content->save(); + + $document->setContentID($new_content->getID()); + $document->save(); + + $document->attachContent($new_content); + PhabricatorSearchPhrictionIndexer::indexDocument($document); + + id(new PhabricatorFeedStoryPublisher()) + ->setRelatedPHIDs( + array( + $document->getPHID(), + $this->user->getPHID(), + )) + ->setStoryAuthorPHID($this->user->getPHID()) + ->setStoryTime(time()) + ->setStoryType(PhabricatorFeedStoryTypeConstants::STORY_PHRICTION) + ->setStoryData( + array( + 'phid' => $document->getPHID(), + 'action' => $is_new + ? PhrictionActionConstants::ACTION_CREATE + : PhrictionActionConstants::ACTION_EDIT, + 'content' => phutil_utf8_shorten($new_content->getContent(), 140), + )) + ->publish(); + + return $this; + } + +} diff --git a/src/applications/phriction/editor/document/__init__.php b/src/applications/phriction/editor/document/__init__.php new file mode 100644 index 0000000000..1844b3b0c8 --- /dev/null +++ b/src/applications/phriction/editor/document/__init__.php @@ -0,0 +1,19 @@ +