1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-10 00:42:41 +01:00

Provide phame.post.edit Conduit API method

Summary:
Ref T9897. This one is a little more involved because of how getting a post on a blog works.

I also changed moving posts to be a real transaction (which shows up in history, now).

Test Plan: Created posts from web UI and conduit.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T9897

Differential Revision: https://secure.phabricator.com/D14902
This commit is contained in:
epriestley 2015-12-28 05:46:22 -08:00
parent 00f1389f72
commit e0a97c88db
10 changed files with 197 additions and 38 deletions

View file

@ -3429,6 +3429,7 @@ phutil_register_library_map(array(
'PhamePost' => 'applications/phame/storage/PhamePost.php',
'PhamePostCommentController' => 'applications/phame/controller/post/PhamePostCommentController.php',
'PhamePostController' => 'applications/phame/controller/post/PhamePostController.php',
'PhamePostEditConduitAPIMethod' => 'applications/phame/conduit/PhamePostEditConduitAPIMethod.php',
'PhamePostEditController' => 'applications/phame/controller/post/PhamePostEditController.php',
'PhamePostEditEngine' => 'applications/phame/editor/PhamePostEditEngine.php',
'PhamePostEditor' => 'applications/phame/editor/PhamePostEditor.php',
@ -4159,7 +4160,7 @@ phutil_register_library_map(array(
'ConduitMethodDoesNotExistException' => 'ConduitMethodNotFoundException',
'ConduitMethodNotFoundException' => 'ConduitException',
'ConduitPHIDListParameterType' => 'ConduitListParameterType',
'ConduitPHIDParameterType' => 'ConduitListParameterType',
'ConduitPHIDParameterType' => 'ConduitParameterType',
'ConduitParameterType' => 'Phobject',
'ConduitPingConduitAPIMethod' => 'ConduitAPIMethod',
'ConduitProjectListParameterType' => 'ConduitListParameterType',
@ -7891,6 +7892,7 @@ phutil_register_library_map(array(
),
'PhamePostCommentController' => 'PhamePostController',
'PhamePostController' => 'PhameController',
'PhamePostEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod',
'PhamePostEditController' => 'PhamePostController',
'PhamePostEditEngine' => 'PhabricatorEditEngine',
'PhamePostEditor' => 'PhabricatorApplicationTransactionEditor',

View file

@ -1,7 +1,7 @@
<?php
final class ConduitPHIDParameterType
extends ConduitListParameterType {
extends ConduitParameterType {
protected function getParameterValue(array $request, $key) {
$value = parent::getParameterValue($request, $key);

View file

@ -0,0 +1,18 @@
<?php
final class PhamePostEditConduitAPIMethod
extends PhabricatorEditEngineAPIMethod {
public function getAPIMethodName() {
return 'phame.post.edit';
}
public function newEditEngine() {
return new PhamePostEditEngine();
}
public function getMethodSummary() {
return pht('Create or edit blog posts in Phame.');
}
}

View file

@ -2,6 +2,17 @@
final class PhamePostEditController extends PhamePostController {
private $blog;
public function setBlog(PhameBlog $blog) {
$this->blog = $blog;
return $this;
}
public function getBlog() {
return $this->blog;
}
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
@ -12,6 +23,7 @@ final class PhamePostEditController extends PhamePostController {
->withIDs(array($id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
@ -32,15 +44,29 @@ final class PhamePostEditController extends PhamePostController {
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$blog) {
return new Aphront404Response();
}
$this->setBlog($blog);
return id(new PhamePostEditEngine())
->setController($this)
->setBlog($blog)
->buildResponse();
}
protected function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
$blog = $this->getBlog();
$crumbs->addTextCrumb(
$blog->getName(),
$blog->getViewURI());
return $crumbs;
}
}

View file

@ -20,59 +20,57 @@ final class PhamePostMoveController extends PhamePostController {
return new Aphront404Response();
}
$view_uri = '/post/view/'.$post->getID().'/';
$view_uri = $this->getApplicationURI($view_uri);
$view_uri = $post->getViewURI();
$v_blog = $post->getBlog()->getPHID();
if ($request->isFormPost()) {
$blog = id(new PhameBlogQuery())
->setViewer($viewer)
->withIDs(array($request->getInt('blog')))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
$v_blog = $request->getStr('blogPHID');
if ($blog) {
$post->setBlogPHID($blog->getPHID());
$post->save();
$xactions = array();
$xactions[] = id(new PhamePostTransaction())
->setTransactionType(PhamePostTransaction::TYPE_BLOG)
->setNewValue($v_blog);
return id(new AphrontRedirectResponse())
->setURI($view_uri.'?moved=1');
}
$editor = id(new PhamePostEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnMissingFields(true)
->setContinueOnNoEffect(true);
$editor->applyTransactions($post, $xactions);
$view_uri = $post->getViewURI();
return id(new AphrontRedirectResponse())
->setURI($view_uri.'?moved=1');
}
$blogs = id(new PhameBlogQuery())
->setViewer($viewer)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->execute();
$options = mpull($blogs, 'getName', 'getID');
$options = mpull($blogs, 'getName', 'getPHID');
asort($options);
$selected_value = null;
if ($post && $post->getBlog()) {
$selected_value = $post->getBlog()->getID();
}
$form = id(new PHUIFormLayoutView())
->setUser($viewer)
->appendChild(
id(new AphrontFormSelectControl())
->setLabel(pht('Blog'))
->setName('blog')
->setName('blogPHID')
->setOptions($options)
->setValue($selected_value));
->setValue($v_blog));
return $this->newDialog()
->setTitle(pht('Move Post'))
->appendChild($form)
->addSubmitButton(pht('Move Post'))
->addCancelButton($view_uri);
}
}

View file

@ -65,16 +65,24 @@ final class PhamePostEditEngine
}
protected function buildCustomEditFields($object) {
if ($this->blog) {
$blog_title = pht('Blog: %s', $this->blog->getName());
} else {
$blog_title = pht('Sample Blog Title');
}
$blog_phid = $object->getBlog()->getPHID();
return array(
id(new PhabricatorInstructionsEditField())
->setValue($blog_title),
id(new PhabricatorHandlesEditField())
->setKey('blog')
->setLabel(pht('Blog'))
->setDescription(pht('Blog to publish this post to.'))
->setConduitDescription(
pht('Choose a blog to create a post on (or move a post to).'))
->setConduitTypeDescription(pht('PHID of the blog.'))
->setAliases(array('blogPHID'))
->setTransactionType(PhamePostTransaction::TYPE_BLOG)
->setHandleParameterType(new AphrontPHIDListHTTPParameterType())
->setSingleValue($blog_phid)
->setIsReorderable(false)
->setIsDefaultable(false)
->setIsLockable(false)
->setIsLocked(true),
id(new PhabricatorTextEditField())
->setKey('title')
->setLabel(pht('Title'))

View file

@ -14,6 +14,7 @@ final class PhamePostEditor
public function getTransactionTypes() {
$types = parent::getTransactionTypes();
$types[] = PhamePostTransaction::TYPE_BLOG;
$types[] = PhamePostTransaction::TYPE_TITLE;
$types[] = PhamePostTransaction::TYPE_BODY;
$types[] = PhamePostTransaction::TYPE_VISIBILITY;
@ -27,6 +28,8 @@ final class PhamePostEditor
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhamePostTransaction::TYPE_BLOG:
return $object->getBlogPHID();
case PhamePostTransaction::TYPE_TITLE:
return $object->getTitle();
case PhamePostTransaction::TYPE_BODY:
@ -44,6 +47,7 @@ final class PhamePostEditor
case PhamePostTransaction::TYPE_TITLE:
case PhamePostTransaction::TYPE_BODY:
case PhamePostTransaction::TYPE_VISIBILITY:
case PhamePostTransaction::TYPE_BLOG:
return $xaction->getNewValue();
}
}
@ -57,6 +61,8 @@ final class PhamePostEditor
return $object->setTitle($xaction->getNewValue());
case PhamePostTransaction::TYPE_BODY:
return $object->setBody($xaction->getNewValue());
case PhamePostTransaction::TYPE_BLOG:
return $object->setBlogPHID($xaction->getNewValue());
case PhamePostTransaction::TYPE_VISIBILITY:
if ($xaction->getNewValue() == PhameConstants::VISIBILITY_DRAFT) {
$object->setDatePublished(0);
@ -77,6 +83,7 @@ final class PhamePostEditor
case PhamePostTransaction::TYPE_TITLE:
case PhamePostTransaction::TYPE_BODY:
case PhamePostTransaction::TYPE_VISIBILITY:
case PhamePostTransaction::TYPE_BLOG:
return;
}
@ -106,6 +113,53 @@ final class PhamePostEditor
$error->setIsMissingFieldError(true);
$errors[] = $error;
}
break;
case PhamePostTransaction::TYPE_BLOG:
if ($this->getIsNewObject()) {
if (!$xactions) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Required'),
pht(
'When creating a post, you must specify which blog it '.
'should belong to.'),
null);
$error->setIsMissingFieldError(true);
$errors[] = $error;
break;
}
}
foreach ($xactions as $xaction) {
$new_phid = $xaction->getNewValue();
$blog = id(new PhameBlogQuery())
->setViewer($this->getActor())
->withPHIDs(array($new_phid))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->execute();
if ($blog) {
continue;
}
$errors[] = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht(
'The specified blog PHID ("%s") is not valid. You can only '.
'create a post on (or move a post into) a blog which you '.
'have permission to see and edit.',
$new_phid),
$xaction);
}
break;
}
return $errors;

View file

@ -7,6 +7,7 @@ final class PhamePostTransaction
const TYPE_PHAME_TITLE = 'phame.post.phame.title';
const TYPE_BODY = 'phame.post.body';
const TYPE_VISIBILITY = 'phame.post.visibility';
const TYPE_BLOG = 'phame.post.blog';
const MAILTAG_CONTENT = 'phame-post-content';
const MAILTAG_SUBSCRIBERS = 'phame-post-subscribers';
@ -47,6 +48,28 @@ final class PhamePostTransaction
return parent::shouldHide();
}
public function getRequiredHandlePHIDs() {
$phids = parent::getRequiredHandlePHIDs();
switch ($this->getTransactionType()) {
case self::TYPE_BLOG:
$old = $this->getOldValue();
$new = $this->getNewValue();
if ($old) {
$phids[] = $old;
}
if ($new) {
$phids[] = $new;
}
break;
}
return $phids;
}
public function getIcon() {
$old = $this->getOldValue();
switch ($this->getTransactionType()) {
@ -98,6 +121,16 @@ final class PhamePostTransaction
$type = $this->getTransactionType();
switch ($type) {
case PhabricatorTransactions::TYPE_CREATE:
return pht(
'%s created this post.',
$this->renderHandleLink($author_phid));
case self::TYPE_BLOG:
return pht(
'%s moved this post from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($old),
$this->renderHandleLink($new));
case self::TYPE_TITLE:
if ($old === null) {
return pht(
@ -146,6 +179,13 @@ final class PhamePostTransaction
$type = $this->getTransactionType();
switch ($type) {
case self::TYPE_BLOG:
return pht(
'%s moved post "%s" from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$this->renderHandleLink($old),
$this->renderHandleLink($new));
case self::TYPE_TITLE:
if ($old === null) {
return pht(

View file

@ -1688,7 +1688,16 @@ abstract class PhabricatorEditEngine
// Let the parameter type interpret the value. This allows you to
// use usernames in list<user> fields, for example.
$parameter_type = $type->getConduitParameterType();
$xaction['value'] = $parameter_type->getValue($xaction, 'value');
try {
$xaction['value'] = $parameter_type->getValue($xaction, 'value');
} catch (Exception $ex) {
throw new PhutilProxyException(
pht(
'Exception when processing transaction of type "%s".',
$xaction['type']),
$ex);
}
$type_xactions = $type->generateTransactions(
clone $template,

View file

@ -35,7 +35,11 @@ abstract class PhabricatorPHIDListEditField
}
protected function newConduitParameterType() {
return new ConduitPHIDListParameterType();
if ($this->getIsSingleValue()) {
return new ConduitPHIDParameterType();
} else {
return new ConduitPHIDListParameterType();
}
}
protected function getValueFromRequest(AphrontRequest $request, $key) {