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:
parent
00f1389f72
commit
e0a97c88db
10 changed files with 197 additions and 38 deletions
|
@ -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',
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
final class ConduitPHIDParameterType
|
||||
extends ConduitListParameterType {
|
||||
extends ConduitParameterType {
|
||||
|
||||
protected function getParameterValue(array $request, $key) {
|
||||
$value = parent::getParameterValue($request, $key);
|
||||
|
|
|
@ -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.');
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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'))
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue