1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-22 05:20:56 +01:00

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
This commit is contained in:
epriestley 2011-08-26 12:50:28 -07:00
parent ee6c24b98d
commit 701bf8317f
13 changed files with 493 additions and 48 deletions

View file

@ -124,6 +124,10 @@ phutil_register_library_map(array(
'ConduitAPI_path_getowners_Method' => 'applications/conduit/method/path/getowners', 'ConduitAPI_path_getowners_Method' => 'applications/conduit/method/path/getowners',
'ConduitAPI_phid_Method' => 'applications/conduit/method/phid/base', 'ConduitAPI_phid_Method' => 'applications/conduit/method/phid/base',
'ConduitAPI_phid_info_Method' => 'applications/conduit/method/phid/info', '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_slowvote_info_Method' => 'applications/conduit/method/slowvote/info',
'ConduitAPI_user_Method' => 'applications/conduit/method/user/base', 'ConduitAPI_user_Method' => 'applications/conduit/method/user/base',
'ConduitAPI_user_find_Method' => 'applications/conduit/method/user/find', 'ConduitAPI_user_find_Method' => 'applications/conduit/method/user/find',
@ -673,6 +677,7 @@ phutil_register_library_map(array(
'PhrictionDiffController' => 'applications/phriction/controller/diff', 'PhrictionDiffController' => 'applications/phriction/controller/diff',
'PhrictionDocument' => 'applications/phriction/storage/document', 'PhrictionDocument' => 'applications/phriction/storage/document',
'PhrictionDocumentController' => 'applications/phriction/controller/document', 'PhrictionDocumentController' => 'applications/phriction/controller/document',
'PhrictionDocumentEditor' => 'applications/phriction/editor/document',
'PhrictionDocumentPreviewController' => 'applications/phriction/controller/documentpreview', 'PhrictionDocumentPreviewController' => 'applications/phriction/controller/documentpreview',
'PhrictionDocumentTestCase' => 'applications/phriction/storage/document/__tests__', 'PhrictionDocumentTestCase' => 'applications/phriction/storage/document/__tests__',
'PhrictionEditController' => 'applications/phriction/controller/edit', 'PhrictionEditController' => 'applications/phriction/controller/edit',
@ -805,6 +810,10 @@ phutil_register_library_map(array(
'ConduitAPI_path_getowners_Method' => 'ConduitAPIMethod', 'ConduitAPI_path_getowners_Method' => 'ConduitAPIMethod',
'ConduitAPI_phid_Method' => 'ConduitAPIMethod', 'ConduitAPI_phid_Method' => 'ConduitAPIMethod',
'ConduitAPI_phid_info_Method' => 'ConduitAPI_phid_Method', '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_slowvote_info_Method' => 'ConduitAPIMethod',
'ConduitAPI_user_Method' => 'ConduitAPIMethod', 'ConduitAPI_user_Method' => 'ConduitAPIMethod',
'ConduitAPI_user_find_Method' => 'ConduitAPI_user_Method', 'ConduitAPI_user_find_Method' => 'ConduitAPI_user_Method',

View file

@ -0,0 +1,49 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @group conduit
*/
abstract class ConduitAPI_phriction_Method extends ConduitAPIMethod {
final protected function buildDocumentInfoDictionary(PhrictionDocument $doc) {
$content = $doc->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(),
);
}
}

View file

@ -0,0 +1,14 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/conduit/method/base');
phutil_require_module('phabricator', 'applications/phriction/storage/document');
phutil_require_module('phabricator', 'infrastructure/env');
phutil_require_source('ConduitAPI_phriction_Method.php');

View file

@ -0,0 +1,60 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_phriction_edit_Method
extends ConduitAPI_phriction_Method {
public function getMethodDescription() {
return "Update a Phriction document.";
}
public function defineParamTypes() {
return array(
'slug' => '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());
}
}

View file

@ -0,0 +1,15 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/conduit/method/phriction/base');
phutil_require_module('phabricator', 'applications/phriction/editor/document');
phutil_require_module('phutil', 'utils');
phutil_require_source('ConduitAPI_phriction_edit_Method.php');

View file

@ -0,0 +1,68 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_phriction_history_Method
extends ConduitAPI_phriction_Method {
public function getMethodDescription() {
return "Retrieve history about a Phriction docuemnt.";
}
public function defineParamTypes() {
return array(
'slug' => '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;
}
}

View file

@ -0,0 +1,17 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/conduit/method/phriction/base');
phutil_require_module('phabricator', 'applications/conduit/protocol/exception');
phutil_require_module('phabricator', 'applications/phriction/storage/content');
phutil_require_module('phabricator', 'applications/phriction/storage/document');
phutil_require_module('phutil', 'utils');
phutil_require_source('ConduitAPI_phriction_history_Method.php');

View file

@ -0,0 +1,62 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_phriction_info_Method
extends ConduitAPI_phriction_Method {
public function getMethodDescription() {
return "Retrieve information about a Phriction document.";
}
public function defineParamTypes() {
return array(
'slug' => '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);
}
}

View file

@ -0,0 +1,17 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/conduit/method/phriction/base');
phutil_require_module('phabricator', 'applications/conduit/protocol/exception');
phutil_require_module('phabricator', 'applications/phriction/storage/content');
phutil_require_module('phabricator', 'applications/phriction/storage/document');
phutil_require_module('phutil', 'utils');
phutil_require_source('ConduitAPI_phriction_info_Method.php');

View file

@ -88,52 +88,15 @@ class PhrictionEditController
} }
if (!count($errors)) { if (!count($errors)) {
$editor = id(PhrictionDocumentEditor::newForSlug($slug))
->setUser($user)
->setTitle($title)
->setContent($request->getStr('content'))
->setDescription($request->getStr('description'));
// TODO: This should all be transactional. $editor->save();
$is_new = false; $uri = PhrictionDocument::getSlugURI($slug);
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());
return id(new AphrontRedirectResponse())->setURI($uri); return id(new AphrontRedirectResponse())->setURI($uri);
} }
} }

View file

@ -8,13 +8,10 @@
phutil_require_module('phabricator', 'aphront/response/404'); phutil_require_module('phabricator', 'aphront/response/404');
phutil_require_module('phabricator', 'aphront/response/redirect'); 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/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/content');
phutil_require_module('phabricator', 'applications/phriction/storage/document'); 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/celerity/api');
phutil_require_module('phabricator', 'infrastructure/env'); phutil_require_module('phabricator', 'infrastructure/env');
phutil_require_module('phabricator', 'infrastructure/javelin/api'); phutil_require_module('phabricator', 'infrastructure/javelin/api');

View file

@ -0,0 +1,155 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Create or update Phriction documents.
*/
final class PhrictionDocumentEditor {
private $document;
private $content;
private $user;
private $newTitle;
private $newContent;
private $description;
private function __construct() {
// <restricted>
}
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;
}
}

View file

@ -0,0 +1,19 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
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/storage/content');
phutil_require_module('phabricator', 'applications/phriction/storage/document');
phutil_require_module('phabricator', 'applications/search/index/indexer/phriction');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhrictionDocumentEditor.php');