1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-01-11 23:31:03 +01:00

Ability to archive Phame Posts

Summary: Ref T9897. Adds ability to Archive a Phame Post (only visible under ApplicationSearch).

Test Plan: Archive a post, re-publish it, search for it, archive it again. View Home, Blog, Live pages.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

Maniphest Tasks: T9897

Differential Revision: https://secure.phabricator.com/D16104
This commit is contained in:
Chad Little 2016-06-13 10:34:13 -07:00
parent a5e29f3ffa
commit 72c57d36a3
14 changed files with 153 additions and 20 deletions

View file

@ -3771,6 +3771,7 @@ phutil_register_library_map(array(
'PhameLiveController' => 'applications/phame/controller/PhameLiveController.php', 'PhameLiveController' => 'applications/phame/controller/PhameLiveController.php',
'PhameNextPostView' => 'applications/phame/view/PhameNextPostView.php', 'PhameNextPostView' => 'applications/phame/view/PhameNextPostView.php',
'PhamePost' => 'applications/phame/storage/PhamePost.php', 'PhamePost' => 'applications/phame/storage/PhamePost.php',
'PhamePostArchiveController' => 'applications/phame/controller/post/PhamePostArchiveController.php',
'PhamePostCommentController' => 'applications/phame/controller/post/PhamePostCommentController.php', 'PhamePostCommentController' => 'applications/phame/controller/post/PhamePostCommentController.php',
'PhamePostController' => 'applications/phame/controller/post/PhamePostController.php', 'PhamePostController' => 'applications/phame/controller/post/PhamePostController.php',
'PhamePostEditConduitAPIMethod' => 'applications/phame/conduit/PhamePostEditConduitAPIMethod.php', 'PhamePostEditConduitAPIMethod' => 'applications/phame/conduit/PhamePostEditConduitAPIMethod.php',
@ -8627,6 +8628,7 @@ phutil_register_library_map(array(
'PhabricatorTokenReceiverInterface', 'PhabricatorTokenReceiverInterface',
'PhabricatorConduitResultInterface', 'PhabricatorConduitResultInterface',
), ),
'PhamePostArchiveController' => 'PhamePostController',
'PhamePostCommentController' => 'PhamePostController', 'PhamePostCommentController' => 'PhamePostController',
'PhamePostController' => 'PhameController', 'PhamePostController' => 'PhameController',
'PhamePostEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod', 'PhamePostEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod',

View file

@ -55,6 +55,7 @@ final class PhabricatorPhameApplication extends PhabricatorApplication {
'preview/' => 'PhabricatorMarkupPreviewController', 'preview/' => 'PhabricatorMarkupPreviewController',
'framed/(?P<id>\d+)/' => 'PhamePostFramedController', 'framed/(?P<id>\d+)/' => 'PhamePostFramedController',
'move/(?P<id>\d+)/' => 'PhamePostMoveController', 'move/(?P<id>\d+)/' => 'PhamePostMoveController',
'archive/(?P<id>\d+)/' => 'PhamePostArchiveController',
'comment/(?P<id>[1-9]\d*)/' => 'PhamePostCommentController', 'comment/(?P<id>[1-9]\d*)/' => 'PhamePostCommentController',
), ),
'blog/' => array( 'blog/' => array(

View file

@ -4,11 +4,13 @@ final class PhameConstants extends Phobject {
const VISIBILITY_DRAFT = 0; const VISIBILITY_DRAFT = 0;
const VISIBILITY_PUBLISHED = 1; const VISIBILITY_PUBLISHED = 1;
const VISIBILITY_ARCHIVED = 2;
public static function getPhamePostStatusMap() { public static function getPhamePostStatusMap() {
return array( return array(
self::VISIBILITY_PUBLISHED => pht('Published'), self::VISIBILITY_PUBLISHED => pht('Published'),
self::VISIBILITY_DRAFT => pht('Draft'), self::VISIBILITY_DRAFT => pht('Draft'),
self::VISIBILITY_ARCHIVED => pht('Archived'),
); );
} }
@ -16,6 +18,7 @@ final class PhameConstants extends Phobject {
$map = array( $map = array(
self::VISIBILITY_PUBLISHED => pht('Published'), self::VISIBILITY_PUBLISHED => pht('Published'),
self::VISIBILITY_DRAFT => pht('Draft'), self::VISIBILITY_DRAFT => pht('Draft'),
self::VISIBILITY_ARCHIVED => pht('Archived'),
); );
return idx($map, $status, pht('Unknown')); return idx($map, $status, pht('Unknown'));
} }

View file

@ -35,7 +35,7 @@ final class PhameHomeController extends PhamePostController {
$posts = id(new PhamePostQuery()) $posts = id(new PhamePostQuery())
->setViewer($viewer) ->setViewer($viewer)
->withBlogPHIDs($blog_phids) ->withBlogPHIDs($blog_phids)
->withVisibility(PhameConstants::VISIBILITY_PUBLISHED) ->withVisibility(array(PhameConstants::VISIBILITY_PUBLISHED))
->executeWithCursorPager($pager); ->executeWithCursorPager($pager);
if ($posts) { if ($posts) {
@ -97,7 +97,7 @@ final class PhameHomeController extends PhamePostController {
->setViewer($viewer) ->setViewer($viewer)
->withBloggerPHIDs(array($viewer->getPHID())) ->withBloggerPHIDs(array($viewer->getPHID()))
->withBlogPHIDs(mpull($blogs, 'getPHID')) ->withBlogPHIDs(mpull($blogs, 'getPHID'))
->withVisibility(PhameConstants::VISIBILITY_DRAFT) ->withVisibility(array(PhameConstants::VISIBILITY_DRAFT))
->setLimit(5) ->setLimit(5)
->execute(); ->execute();

View file

@ -97,7 +97,8 @@ abstract class PhameLiveController extends PhameController {
// Only show published posts on external domains. // Only show published posts on external domains.
if ($is_external) { if ($is_external) {
$post_query->withVisibility(PhameConstants::VISIBILITY_PUBLISHED); $post_query->withVisibility(
array(PhameConstants::VISIBILITY_PUBLISHED));
} }
$post = $post_query->executeOne(); $post = $post_query->executeOne();

View file

@ -21,7 +21,7 @@ final class PhameBlogFeedController extends PhameBlogController {
$posts = id(new PhamePostQuery()) $posts = id(new PhamePostQuery())
->setViewer($viewer) ->setViewer($viewer)
->withBlogPHIDs(array($blog->getPHID())) ->withBlogPHIDs(array($blog->getPHID()))
->withVisibility(PhameConstants::VISIBILITY_PUBLISHED) ->withVisibility(array(PhameConstants::VISIBILITY_PUBLISHED))
->execute(); ->execute();
$blog_uri = PhabricatorEnv::getProductionURI( $blog_uri = PhabricatorEnv::getProductionURI(

View file

@ -19,10 +19,14 @@ final class PhameBlogViewController extends PhameLiveController {
$post_query = id(new PhamePostQuery()) $post_query = id(new PhamePostQuery())
->setViewer($viewer) ->setViewer($viewer)
->withBlogPHIDs(array($blog->getPHID())); ->withBlogPHIDs(array($blog->getPHID()))
->withVisibility(array(
PhameConstants::VISIBILITY_PUBLISHED,
PhameConstants::VISIBILITY_DRAFT,
));
if ($is_live) { if ($is_live) {
$post_query->withVisibility(PhameConstants::VISIBILITY_PUBLISHED); $post_query->withVisibility(array(PhameConstants::VISIBILITY_PUBLISHED));
} }
$posts = $post_query->executeWithCursorPager($pager); $posts = $post_query->executeWithCursorPager($pager);

View file

@ -0,0 +1,56 @@
<?php
final class PhamePostArchiveController extends PhamePostController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
$post = id(new PhamePostQuery())
->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$post) {
return new Aphront404Response();
}
$cancel_uri = $post->getViewURI();
if ($request->isFormPost()) {
$xactions = array();
$new_value = PhameConstants::VISIBILITY_ARCHIVED;
$xactions[] = id(new PhamePostTransaction())
->setTransactionType(PhamePostTransaction::TYPE_VISIBILITY)
->setNewValue($new_value);
id(new PhamePostEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true)
->setContinueOnMissingFields(true)
->applyTransactions($post, $xactions);
return id(new AphrontRedirectResponse())
->setURI($cancel_uri);
}
$title = pht('Archive Post');
$body = pht(
'This post will revert to archived status and no longer be visible '.
'to other users or members of this blog.');
$button = pht('Archive Post');
return $this->newDialog()
->setTitle($title)
->appendParagraph($body)
->addSubmitButton($button)
->addCancelButton($cancel_uri);
}
}

View file

@ -48,6 +48,16 @@ final class PhamePostViewController
'Use "Publish" to publish this post.'))); 'Use "Publish" to publish this post.')));
} }
if ($post->isArchived()) {
$document->appendChild(
id(new PHUIInfoView())
->setSeverity(PHUIInfoView::SEVERITY_ERROR)
->setTitle(pht('Archived Post'))
->appendChild(
pht('Only you can see this archived post until you publish it. '.
'Use "Publish" to publish this post.')));
}
if (!$post->getBlog()) { if (!$post->getBlog()) {
$document->appendChild( $document->appendChild(
id(new PHUIInfoView()) id(new PHUIInfoView())
@ -92,6 +102,8 @@ final class PhamePostViewController
$date = phabricator_datetime($post->getDatePublished(), $viewer); $date = phabricator_datetime($post->getDatePublished(), $viewer);
if ($post->isDraft()) { if ($post->isDraft()) {
$subtitle = pht('Unpublished draft by %s.', $author); $subtitle = pht('Unpublished draft by %s.', $author);
} else if ($post->isArchived()) {
$subtitle = pht('Archived post by %s.', $author);
} else { } else {
$subtitle = pht('Written by %s on %s.', $author, $date); $subtitle = pht('Written by %s on %s.', $author, $date);
} }
@ -207,6 +219,21 @@ final class PhamePostViewController
->setName(pht('Publish')) ->setName(pht('Publish'))
->setDisabled(!$can_edit) ->setDisabled(!$can_edit)
->setWorkflow(true)); ->setWorkflow(true));
$actions->addAction(
id(new PhabricatorActionView())
->setIcon('fa-ban')
->setHref($this->getApplicationURI('post/archive/'.$id.'/'))
->setName(pht('Archive'))
->setDisabled(!$can_edit)
->setWorkflow(true));
} else if ($post->isArchived()) {
$actions->addAction(
id(new PhabricatorActionView())
->setIcon('fa-eye')
->setHref($this->getApplicationURI('post/publish/'.$id.'/'))
->setName(pht('Publish'))
->setDisabled(!$can_edit)
->setWorkflow(true));
} else { } else {
$actions->addAction( $actions->addAction(
id(new PhabricatorActionView()) id(new PhabricatorActionView())
@ -215,6 +242,13 @@ final class PhamePostViewController
->setName(pht('Unpublish')) ->setName(pht('Unpublish'))
->setDisabled(!$can_edit) ->setDisabled(!$can_edit)
->setWorkflow(true)); ->setWorkflow(true));
$actions->addAction(
id(new PhabricatorActionView())
->setIcon('fa-ban')
->setHref($this->getApplicationURI('post/archive/'.$id.'/'))
->setName(pht('Archive'))
->setDisabled(!$can_edit)
->setWorkflow(true));
} }
if ($post->isDraft()) { if ($post->isDraft()) {
@ -223,12 +257,14 @@ final class PhamePostViewController
$live_name = pht('View Live'); $live_name = pht('View Live');
} }
if (!$post->isArchived()) {
$actions->addAction( $actions->addAction(
id(new PhabricatorActionView()) id(new PhabricatorActionView())
->setUser($viewer) ->setUser($viewer)
->setIcon('fa-globe') ->setIcon('fa-globe')
->setHref($post->getLiveURI()) ->setHref($post->getLiveURI())
->setName($live_name)); ->setName($live_name));
}
return $actions; return $actions;
} }
@ -255,7 +291,7 @@ final class PhamePostViewController
$query = id(new PhamePostQuery()) $query = id(new PhamePostQuery())
->setViewer($viewer) ->setViewer($viewer)
->withVisibility(PhameConstants::VISIBILITY_PUBLISHED) ->withVisibility(array(PhameConstants::VISIBILITY_PUBLISHED))
->withBlogPHIDs(array($post->getBlog()->getPHID())) ->withBlogPHIDs(array($post->getBlog()->getPHID()))
->setLimit(1); ->setLimit(1);

View file

@ -66,6 +66,9 @@ final class PhamePostEditor
case PhamePostTransaction::TYPE_VISIBILITY: case PhamePostTransaction::TYPE_VISIBILITY:
if ($xaction->getNewValue() == PhameConstants::VISIBILITY_DRAFT) { if ($xaction->getNewValue() == PhameConstants::VISIBILITY_DRAFT) {
$object->setDatePublished(0); $object->setDatePublished(0);
} else if ($xaction->getNewValue() ==
PhameConstants::VISIBILITY_ARCHIVED) {
$object->setDatePublished(0);
} else { } else {
$object->setDatePublished(PhabricatorTime::getNow()); $object->setDatePublished(PhabricatorTime::getNow());
} }

View file

@ -29,7 +29,7 @@ final class PhamePostQuery extends PhabricatorCursorPagedPolicyAwareQuery {
return $this; return $this;
} }
public function withVisibility($visibility) { public function withVisibility(array $visibility) {
$this->visibility = $visibility; $this->visibility = $visibility;
return $this; return $this;
} }
@ -98,10 +98,10 @@ final class PhamePostQuery extends PhabricatorCursorPagedPolicyAwareQuery {
$this->bloggerPHIDs); $this->bloggerPHIDs);
} }
if ($this->visibility !== null) { if ($this->visibility) {
$where[] = qsprintf( $where[] = qsprintf(
$conn, $conn,
'visibility = %d', 'visibility IN (%Ld)',
$this->visibility); $this->visibility);
} }

View file

@ -19,7 +19,7 @@ final class PhamePostSearchEngine
$query = $this->newQuery(); $query = $this->newQuery();
if (strlen($map['visibility'])) { if (strlen($map['visibility'])) {
$query->withVisibility($map['visibility']); $query->withVisibility(array($map['visibility']));
} }
return $query; return $query;
@ -35,6 +35,7 @@ final class PhamePostSearchEngine
'' => pht('All'), '' => pht('All'),
PhameConstants::VISIBILITY_PUBLISHED => pht('Published'), PhameConstants::VISIBILITY_PUBLISHED => pht('Published'),
PhameConstants::VISIBILITY_DRAFT => pht('Draft'), PhameConstants::VISIBILITY_DRAFT => pht('Draft'),
PhameConstants::VISIBILITY_ARCHIVED => pht('Archived'),
)), )),
); );
} }
@ -48,6 +49,7 @@ final class PhamePostSearchEngine
'all' => pht('All Posts'), 'all' => pht('All Posts'),
'live' => pht('Published Posts'), 'live' => pht('Published Posts'),
'draft' => pht('Draft Posts'), 'draft' => pht('Draft Posts'),
'archived' => pht('Archived Posts'),
); );
return $names; return $names;
} }
@ -65,6 +67,9 @@ final class PhamePostSearchEngine
case 'draft': case 'draft':
return $query->setParameter( return $query->setParameter(
'visibility', PhameConstants::VISIBILITY_DRAFT); 'visibility', PhameConstants::VISIBILITY_DRAFT);
case 'archived':
return $query->setParameter(
'visibility', PhameConstants::VISIBILITY_ARCHIVED);
} }
return parent::buildSavedQueryFromBuiltin($query_key); return parent::buildSavedQueryFromBuiltin($query_key);
@ -100,6 +105,10 @@ final class PhamePostSearchEngine
$item->setStatusIcon('fa-star-o grey'); $item->setStatusIcon('fa-star-o grey');
$item->setDisabled(true); $item->setDisabled(true);
$item->addIcon('none', pht('Draft Post')); $item->addIcon('none', pht('Draft Post'));
} else if ($post->isArchived()) {
$item->setStatusIcon('fa-ban grey');
$item->setDisabled(true);
$item->addIcon('none', pht('Archived Post'));
} else { } else {
$date = $post->getDatePublished(); $date = $post->getDatePublished();
$item->setEpoch($date); $item->setEpoch($date);

View file

@ -53,7 +53,8 @@ final class PhamePost extends PhameDAO
public function getLiveURI() { public function getLiveURI() {
$blog = $this->getBlog(); $blog = $this->getBlog();
$is_draft = $this->isDraft(); $is_draft = $this->isDraft();
if (strlen($blog->getDomain()) && !$is_draft) { $is_archived = $this->isArchived();
if (strlen($blog->getDomain()) && !$is_draft && !$is_archived) {
return $this->getExternalLiveURI(); return $this->getExternalLiveURI();
} else { } else {
return $this->getInternalLiveURI(); return $this->getInternalLiveURI();
@ -92,6 +93,10 @@ final class PhamePost extends PhameDAO
return ($this->getVisibility() == PhameConstants::VISIBILITY_DRAFT); return ($this->getVisibility() == PhameConstants::VISIBILITY_DRAFT);
} }
public function isArchived() {
return ($this->getVisibility() == PhameConstants::VISIBILITY_ARCHIVED);
}
protected function getConfiguration() { protected function getConfiguration() {
return array( return array(
self::CONFIG_AUX_PHID => true, self::CONFIG_AUX_PHID => true,
@ -165,7 +170,7 @@ final class PhamePost extends PhameDAO
switch ($capability) { switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW: case PhabricatorPolicyCapability::CAN_VIEW:
if (!$this->isDraft() && $this->getBlog()) { if (!$this->isDraft() && !$this->isArchived() && $this->getBlog()) {
return $this->getBlog()->getViewPolicy(); return $this->getBlog()->getViewPolicy();
} else if ($this->getBlog()) { } else if ($this->getBlog()) {
return $this->getBlog()->getEditPolicy(); return $this->getBlog()->getEditPolicy();
@ -319,6 +324,8 @@ final class PhamePost extends PhameDAO
public function getFieldValuesForConduit() { public function getFieldValuesForConduit() {
if ($this->isDraft()) { if ($this->isDraft()) {
$date_published = null; $date_published = null;
} else if ($this->isArchived()) {
$date_published = null;
} else { } else {
$date_published = (int)$this->getDatePublished(); $date_published = (int)$this->getDatePublished();
} }

View file

@ -73,6 +73,8 @@ final class PhamePostTransaction
case self::TYPE_VISIBILITY: case self::TYPE_VISIBILITY:
if ($new == PhameConstants::VISIBILITY_PUBLISHED) { if ($new == PhameConstants::VISIBILITY_PUBLISHED) {
return 'fa-globe'; return 'fa-globe';
} else if ($new == PhameConstants::VISIBILITY_ARCHIVED) {
return 'fa-ban';
} else { } else {
return 'fa-eye-slash'; return 'fa-eye-slash';
} }
@ -144,6 +146,10 @@ final class PhamePostTransaction
return pht( return pht(
'%s marked this post as a draft.', '%s marked this post as a draft.',
$this->renderHandleLink($author_phid)); $this->renderHandleLink($author_phid));
} else if ($new == PhameConstants::VISIBILITY_ARCHIVED) {
return pht(
'%s archived this post.',
$this->renderHandleLink($author_phid));
} else { } else {
return pht( return pht(
'%s published this post.', '%s published this post.',
@ -201,6 +207,11 @@ final class PhamePostTransaction
'%s marked %s as a draft.', '%s marked %s as a draft.',
$this->renderHandleLink($author_phid), $this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid)); $this->renderHandleLink($object_phid));
} else if ($new == PhameConstants::VISIBILITY_ARCHIVED) {
return pht(
'%s marked %s as archived.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
} else { } else {
return pht( return pht(
'%s published %s.', '%s published %s.',