From f8b085c574aeb24f59ea58ddf378283126b646b3 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Sat, 7 Nov 2015 06:52:42 -0800 Subject: [PATCH] Add a transaction for PhamePost visibility Summary: Adds ability to set visibility when authoring a Post. New default is "Visible". If you write a post and save it as a Draft, and later click publish, a feed story and mail will go out. Test Plan: Write a new Post, see feed story and get email. Write a new Draft, get nothing. Click Publish, see story and email. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Maniphest Tasks: T9360 Differential Revision: https://secure.phabricator.com/D14429 --- src/__phutil_library_map__.php | 2 + .../PhameCreatePostConduitAPIMethod.php | 2 +- .../PhameQueryPostsConduitAPIMethod.php | 4 +- .../phame/constants/PhameConstants.php | 23 ++++++++ .../blog/PhameBlogFeedController.php | 2 +- .../post/PhamePostEditController.php | 31 ++++++---- .../post/PhamePostPublishController.php | 20 ++++++- .../post/PhamePostUnpublishController.php | 20 ++++++- .../phame/editor/PhamePostEditor.php | 12 ++++ .../phame/query/PhamePostSearchEngine.php | 10 ++-- src/applications/phame/storage/PhamePost.php | 15 +---- .../phame/storage/PhamePostTransaction.php | 56 ++++++++++++++++--- 12 files changed, 150 insertions(+), 47 deletions(-) create mode 100644 src/applications/phame/constants/PhameConstants.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index aaacc2cde4..fa57f18743 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -3262,6 +3262,7 @@ phutil_register_library_map(array( 'PhameBlogViewController' => 'applications/phame/controller/blog/PhameBlogViewController.php', 'PhameCelerityResources' => 'applications/phame/celerity/PhameCelerityResources.php', 'PhameConduitAPIMethod' => 'applications/phame/conduit/PhameConduitAPIMethod.php', + 'PhameConstants' => 'applications/phame/constants/PhameConstants.php', 'PhameController' => 'applications/phame/controller/PhameController.php', 'PhameCreatePostConduitAPIMethod' => 'applications/phame/conduit/PhameCreatePostConduitAPIMethod.php', 'PhameDAO' => 'applications/phame/storage/PhameDAO.php', @@ -7525,6 +7526,7 @@ phutil_register_library_map(array( 'PhameBlogViewController' => 'PhameBlogController', 'PhameCelerityResources' => 'CelerityResources', 'PhameConduitAPIMethod' => 'ConduitAPIMethod', + 'PhameConstants' => 'Phobject', 'PhameController' => 'PhabricatorController', 'PhameCreatePostConduitAPIMethod' => 'PhameConduitAPIMethod', 'PhameDAO' => 'PhabricatorLiskDAO', diff --git a/src/applications/phame/conduit/PhameCreatePostConduitAPIMethod.php b/src/applications/phame/conduit/PhameCreatePostConduitAPIMethod.php index bdee6e2829..425bf17353 100644 --- a/src/applications/phame/conduit/PhameCreatePostConduitAPIMethod.php +++ b/src/applications/phame/conduit/PhameCreatePostConduitAPIMethod.php @@ -85,7 +85,7 @@ final class PhameCreatePostConduitAPIMethod extends PhameConduitAPIMethod { $is_draft = $request->getValue('isDraft', false); if (!$is_draft) { $post->setDatePublished(time()); - $post->setVisibility(PhamePost::VISIBILITY_PUBLISHED); + $post->setVisibility(PhameConstants::VISIBILITY_PUBLISHED); } $post->setTitle($title); $phame_title = $request->getValue( diff --git a/src/applications/phame/conduit/PhameQueryPostsConduitAPIMethod.php b/src/applications/phame/conduit/PhameQueryPostsConduitAPIMethod.php index 06c20c7720..0ecb4d22eb 100644 --- a/src/applications/phame/conduit/PhameQueryPostsConduitAPIMethod.php +++ b/src/applications/phame/conduit/PhameQueryPostsConduitAPIMethod.php @@ -65,9 +65,9 @@ final class PhameQueryPostsConduitAPIMethod extends PhameConduitAPIMethod { $published = $request->getValue('published', null); if ($published === true) { - $query->withVisibility(PhamePost::VISIBILITY_PUBLISHED); + $query->withVisibility(PhameConstants::VISIBILITY_PUBLISHED); } else if ($published === false) { - $query->withVisibility(PhamePost::VISIBILITY_DRAFT); + $query->withVisibility(PhameConstants::VISIBILITY_DRAFT); } $published_after = $request->getValue('publishedAfter', null); diff --git a/src/applications/phame/constants/PhameConstants.php b/src/applications/phame/constants/PhameConstants.php new file mode 100644 index 0000000000..c9444411f0 --- /dev/null +++ b/src/applications/phame/constants/PhameConstants.php @@ -0,0 +1,23 @@ + pht('Published'), + self::VISIBILITY_DRAFT => pht('Draft'), + ); + } + + public static function getPhamePostStatusName($status) { + $map = array( + self::VISIBILITY_PUBLISHED => pht('Published'), + self::VISIBILITY_DRAFT => pht('Draft'), + ); + return idx($map, $status, pht('Unknown')); + } + +} diff --git a/src/applications/phame/controller/blog/PhameBlogFeedController.php b/src/applications/phame/controller/blog/PhameBlogFeedController.php index 0941555ed2..b74465ef5e 100644 --- a/src/applications/phame/controller/blog/PhameBlogFeedController.php +++ b/src/applications/phame/controller/blog/PhameBlogFeedController.php @@ -21,7 +21,7 @@ final class PhameBlogFeedController extends PhameBlogController { $posts = id(new PhamePostQuery()) ->setViewer($viewer) ->withBlogPHIDs(array($blog->getPHID())) - ->withVisibility(PhamePost::VISIBILITY_PUBLISHED) + ->withVisibility(PhameConstants::VISIBILITY_PUBLISHED) ->execute(); $blog_uri = PhabricatorEnv::getProductionURI( diff --git a/src/applications/phame/controller/post/PhamePostEditController.php b/src/applications/phame/controller/post/PhamePostEditController.php index 3de92906a8..44368b3207 100644 --- a/src/applications/phame/controller/post/PhamePostEditController.php +++ b/src/applications/phame/controller/post/PhamePostEditController.php @@ -45,25 +45,27 @@ final class PhamePostEditController extends PhamePostController { $post = PhamePost::initializePost($viewer, $blog); $cancel_uri = $this->getApplicationURI('/blog/view/'.$blog->getID().'/'); - $submit_button = pht('Save Draft'); - $page_title = pht('Create Post'); + $submit_button = pht('Create Post'); + $page_title = pht('Create Post'); } - $title = $post->getTitle(); - $phame_title = $post->getPhameTitle(); - $body = $post->getBody(); + $title = $post->getTitle(); + $phame_title = $post->getPhameTitle(); + $body = $post->getBody(); $comments_widget = $post->getCommentsWidget(); + $visibility = $post->getVisibility(); $e_title = true; $e_phame_title = true; $validation_exception = null; if ($request->isFormPost()) { - $title = $request->getStr('title'); - $phame_title = $request->getStr('phame_title'); - $phame_title = PhabricatorSlug::normalize($phame_title); - $body = $request->getStr('body'); + $title = $request->getStr('title'); + $phame_title = $request->getStr('phame_title'); + $phame_title = PhabricatorSlug::normalize($phame_title); + $body = $request->getStr('body'); $comments_widget = $request->getStr('comments_widget'); - $v_projects = $request->getArr('projects'); + $v_projects = $request->getArr('projects'); + $visibility = $request->getInt('visibility'); $xactions = array( id(new PhamePostTransaction()) @@ -75,6 +77,9 @@ final class PhamePostEditController extends PhamePostController { id(new PhamePostTransaction()) ->setTransactionType(PhamePostTransaction::TYPE_BODY) ->setNewValue($body), + id(new PhamePostTransaction()) + ->setTransactionType(PhamePostTransaction::TYPE_VISIBILITY) + ->setNewValue($visibility), id(new PhamePostTransaction()) ->setTransactionType(PhamePostTransaction::TYPE_COMMENTS_WIDGET) ->setNewValue($comments_widget), @@ -134,6 +139,12 @@ final class PhamePostEditController extends PhamePostController { 'with underscores for spaces. '. 'Formatting is enforced.')) ->setError($e_phame_title)) + ->appendChild( + id(new AphrontFormSelectControl()) + ->setLabel(pht('Visibility')) + ->setName('visibility') + ->setvalue($visibility) + ->setOptions(PhameConstants::getPhamePostStatusMap())) ->appendChild( id(new PhabricatorRemarkupControl()) ->setLabel(pht('Body')) diff --git a/src/applications/phame/controller/post/PhamePostPublishController.php b/src/applications/phame/controller/post/PhamePostPublishController.php index 6ca8ff5d54..0d612d193e 100644 --- a/src/applications/phame/controller/post/PhamePostPublishController.php +++ b/src/applications/phame/controller/post/PhamePostPublishController.php @@ -21,9 +21,23 @@ final class PhamePostPublishController extends PhamePostController { $view_uri = $this->getApplicationURI('/post/view/'.$post->getID().'/'); if ($request->isFormPost()) { - $post->setVisibility(PhamePost::VISIBILITY_PUBLISHED); - $post->setDatePublished(time()); - $post->save(); + $xactions = array(); + $xactions[] = id(new PhamePostTransaction()) + ->setTransactionType(PhamePostTransaction::TYPE_TITLE) + ->setNewValue($post->getTitle()); + $xactions[] = id(new PhamePostTransaction()) + ->setTransactionType(PhamePostTransaction::TYPE_PHAME_TITLE) + ->setNewValue($post->getPhameTitle()); + $xactions[] = id(new PhamePostTransaction()) + ->setTransactionType(PhamePostTransaction::TYPE_VISIBILITY) + ->setNewValue(PhameConstants::VISIBILITY_PUBLISHED); + + id(new PhamePostEditor()) + ->setActor($viewer) + ->setContentSourceFromRequest($request) + ->setContinueOnNoEffect(true) + ->setContinueOnMissingFields(true) + ->applyTransactions($post, $xactions); return id(new AphrontRedirectResponse())->setURI($view_uri); } diff --git a/src/applications/phame/controller/post/PhamePostUnpublishController.php b/src/applications/phame/controller/post/PhamePostUnpublishController.php index 80a320344d..8e95cfe75b 100644 --- a/src/applications/phame/controller/post/PhamePostUnpublishController.php +++ b/src/applications/phame/controller/post/PhamePostUnpublishController.php @@ -19,9 +19,23 @@ final class PhamePostUnpublishController extends PhamePostController { } if ($request->isFormPost()) { - $post->setVisibility(PhamePost::VISIBILITY_DRAFT); - $post->setDatePublished(0); - $post->save(); + $xactions = array(); + $xactions[] = id(new PhamePostTransaction()) + ->setTransactionType(PhamePostTransaction::TYPE_TITLE) + ->setNewValue($post->getTitle()); + $xactions[] = id(new PhamePostTransaction()) + ->setTransactionType(PhamePostTransaction::TYPE_PHAME_TITLE) + ->setNewValue($post->getPhameTitle()); + $xactions[] = id(new PhamePostTransaction()) + ->setTransactionType(PhamePostTransaction::TYPE_VISIBILITY) + ->setNewValue(PhameConstants::VISIBILITY_DRAFT); + + id(new PhamePostEditor()) + ->setActor($viewer) + ->setContentSourceFromRequest($request) + ->setContinueOnNoEffect(true) + ->setContinueOnMissingFields(true) + ->applyTransactions($post, $xactions); return id(new AphrontRedirectResponse()) ->setURI($this->getApplicationURI('/post/view/'.$post->getID().'/')); diff --git a/src/applications/phame/editor/PhamePostEditor.php b/src/applications/phame/editor/PhamePostEditor.php index ab4b1a1465..475b0c67c3 100644 --- a/src/applications/phame/editor/PhamePostEditor.php +++ b/src/applications/phame/editor/PhamePostEditor.php @@ -17,6 +17,7 @@ final class PhamePostEditor $types[] = PhamePostTransaction::TYPE_TITLE; $types[] = PhamePostTransaction::TYPE_PHAME_TITLE; $types[] = PhamePostTransaction::TYPE_BODY; + $types[] = PhamePostTransaction::TYPE_VISIBILITY; $types[] = PhamePostTransaction::TYPE_COMMENTS_WIDGET; return $types; @@ -33,6 +34,8 @@ final class PhamePostEditor return $object->getPhameTitle(); case PhamePostTransaction::TYPE_BODY: return $object->getBody(); + case PhamePostTransaction::TYPE_VISIBILITY: + return $object->getVisibility(); case PhamePostTransaction::TYPE_COMMENTS_WIDGET: return $object->getCommentsWidget(); } @@ -46,6 +49,7 @@ final class PhamePostEditor case PhamePostTransaction::TYPE_TITLE: case PhamePostTransaction::TYPE_PHAME_TITLE: case PhamePostTransaction::TYPE_BODY: + case PhamePostTransaction::TYPE_VISIBILITY: case PhamePostTransaction::TYPE_COMMENTS_WIDGET: return $xaction->getNewValue(); } @@ -62,6 +66,13 @@ final class PhamePostEditor return $object->setPhameTitle($xaction->getNewValue()); case PhamePostTransaction::TYPE_BODY: return $object->setBody($xaction->getNewValue()); + case PhamePostTransaction::TYPE_VISIBILITY: + if ($xaction->getNewValue() == PhameConstants::VISIBILITY_DRAFT) { + $object->setDatePublished(time()); + } else { + $object->setDatePublished(0); + } + return $object->setVisibility($xaction->getNewValue()); case PhamePostTransaction::TYPE_COMMENTS_WIDGET: return $object->setCommentsWidget($xaction->getNewValue()); } @@ -77,6 +88,7 @@ final class PhamePostEditor case PhamePostTransaction::TYPE_TITLE: case PhamePostTransaction::TYPE_PHAME_TITLE: case PhamePostTransaction::TYPE_BODY: + case PhamePostTransaction::TYPE_VISIBILITY: case PhamePostTransaction::TYPE_COMMENTS_WIDGET: return; } diff --git a/src/applications/phame/query/PhamePostSearchEngine.php b/src/applications/phame/query/PhamePostSearchEngine.php index d832b08192..84fec54df0 100644 --- a/src/applications/phame/query/PhamePostSearchEngine.php +++ b/src/applications/phame/query/PhamePostSearchEngine.php @@ -32,8 +32,8 @@ final class PhamePostSearchEngine ->setLabel(pht('Visibility')) ->setOptions(array( '' => pht('All'), - PhamePost::VISIBILITY_PUBLISHED => pht('Live'), - PhamePost::VISIBILITY_DRAFT => pht('Draft'), + PhameConstants::VISIBILITY_PUBLISHED => pht('Published'), + PhameConstants::VISIBILITY_DRAFT => pht('Draft'), )), ); } @@ -45,7 +45,7 @@ final class PhamePostSearchEngine protected function getBuiltinQueryNames() { $names = array( 'all' => pht('All Posts'), - 'live' => pht('Live Posts'), + 'live' => pht('Published Posts'), 'draft' => pht('Draft Posts'), ); return $names; @@ -60,10 +60,10 @@ final class PhamePostSearchEngine return $query; case 'live': return $query->setParameter( - 'visibility', PhamePost::VISIBILITY_PUBLISHED); + 'visibility', PhameConstants::VISIBILITY_PUBLISHED); case 'draft': return $query->setParameter( - 'visibility', PhamePost::VISIBILITY_DRAFT); + 'visibility', PhameConstants::VISIBILITY_DRAFT); } return parent::buildSavedQueryFromBuiltin($query_key); diff --git a/src/applications/phame/storage/PhamePost.php b/src/applications/phame/storage/PhamePost.php index eecb27b566..ef39d20544 100644 --- a/src/applications/phame/storage/PhamePost.php +++ b/src/applications/phame/storage/PhamePost.php @@ -13,9 +13,6 @@ final class PhamePost extends PhameDAO const MARKUP_FIELD_BODY = 'markup:body'; const MARKUP_FIELD_SUMMARY = 'markup:summary'; - const VISIBILITY_DRAFT = 0; - const VISIBILITY_PUBLISHED = 1; - protected $bloggerPHID; protected $title; protected $phameTitle; @@ -37,7 +34,7 @@ final class PhamePost extends PhameDAO ->setBlogPHID($blog->getPHID()) ->setBlog($blog) ->setDatePublished(0) - ->setVisibility(self::VISIBILITY_DRAFT); + ->setVisibility(PhameConstants::VISIBILITY_PUBLISHED); return $post; } @@ -66,7 +63,7 @@ final class PhamePost extends PhameDAO } public function isDraft() { - return $this->getVisibility() == self::VISIBILITY_DRAFT; + return $this->getVisibility() == PhameConstants::VISIBILITY_DRAFT; } public function getHumanName() { @@ -165,14 +162,6 @@ final class PhamePost extends PhameDAO ); } - public static function getVisibilityOptionsForSelect() { - return array( - self::VISIBILITY_DRAFT => pht('Draft: visible only to me.'), - self::VISIBILITY_PUBLISHED => pht( - 'Published: visible to the whole world.'), - ); - } - public function getCommentsWidgetOptionsForSelect() { $current = $this->getCommentsWidget(); $options = array(); diff --git a/src/applications/phame/storage/PhamePostTransaction.php b/src/applications/phame/storage/PhamePostTransaction.php index 38910c9845..f1b2d22583 100644 --- a/src/applications/phame/storage/PhamePostTransaction.php +++ b/src/applications/phame/storage/PhamePostTransaction.php @@ -6,6 +6,7 @@ final class PhamePostTransaction const TYPE_TITLE = 'phame.post.title'; const TYPE_PHAME_TITLE = 'phame.post.phame.title'; const TYPE_BODY = 'phame.post.body'; + const TYPE_VISIBILITY = 'phame.post.visibility'; const TYPE_COMMENTS_WIDGET = 'phame.post.comments.widget'; const MAILTAG_CONTENT = 'phame-post-content'; @@ -54,6 +55,7 @@ final class PhamePostTransaction break; case self::TYPE_PHAME_TITLE: case self::TYPE_BODY: + case self::TYPE_VISIBILITY: case self::TYPE_COMMENTS_WIDGET: return 'fa-pencil'; break; @@ -108,6 +110,17 @@ final class PhamePostTransaction '%s updated the blog post.', $this->renderHandleLink($author_phid)); break; + case self::TYPE_VISIBILITY: + if ($new == PhameConstants::VISIBILITY_DRAFT) { + return pht( + '%s marked this post as a draft.', + $this->renderHandleLink($author_phid)); + } else { + return pht( + '%s published this post.', + $this->renderHandleLink($author_phid)); + } + break; case self::TYPE_PHAME_TITLE: return pht( '%s updated the post\'s Phame title to "%s".', @@ -153,6 +166,19 @@ final class PhamePostTransaction $this->renderHandleLink($author_phid), $this->renderHandleLink($object_phid)); break; + case self::TYPE_VISIBILITY: + if ($new == PhameConstants::VISIBILITY_DRAFT) { + return pht( + '%s marked %s as a draft.', + $this->renderHandleLink($author_phid), + $this->renderHandleLink($object_phid)); + } else { + return pht( + '%s published %s.', + $this->renderHandleLink($author_phid), + $this->renderHandleLink($object_phid)); + } + break; case self::TYPE_PHAME_TITLE: return pht( '%s updated the Phame title for %s.', @@ -171,19 +197,32 @@ final class PhamePostTransaction } public function getBodyForFeed(PhabricatorFeedStory $story) { - $new = $this->getNewValue(); - - $body = null; - + $text = null; switch ($this->getTransactionType()) { case self::TYPE_TITLE: + if ($this->getOldValue() === null) { + $post = $story->getPrimaryObject(); + $text = $post->getBody(); + } + break; + case self::TYPE_VISIBILITY: + if ($this->getNewValue() == PhameConstants::VISIBILITY_PUBLISHED) { + $post = $story->getPrimaryObject(); + $text = $post->getBody(); + } + break; case self::TYPE_BODY: - return phutil_escape_html_newlines( - id(new PhutilUTF8StringTruncator()) - ->setMaximumGlyphs(128) - ->truncateString($new)); + $text = $this->getNewValue(); break; } + + if (strlen($text)) { + return phutil_escape_html_newlines( + id(new PhutilUTF8StringTruncator()) + ->setMaximumGlyphs(128) + ->truncateString($text)); + } + return parent::getBodyForFeed($story); } @@ -201,7 +240,6 @@ final class PhamePostTransaction return parent::getColor(); } - public function hasChangeDetails() { switch ($this->getTransactionType()) { case self::TYPE_BODY: