mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-27 07:50:57 +01:00
Allow Phame Blogs to be archived instead of deleted
Summary: Removes "delete" and uses "archive/activate" instead for Phame Blogs. Ref T9756 Test Plan: Archive a blog, see in search, activate blog, see in other search. Reviewers: epriestley Reviewed By: epriestley Subscribers: joshuaspence, Korvin Maniphest Tasks: T9756 Differential Revision: https://secure.phabricator.com/D14465
This commit is contained in:
parent
4d362ddcee
commit
62e129d7a6
12 changed files with 199 additions and 55 deletions
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE {$NAMESPACE}_phame.phame_blog
|
||||
ADD status VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,2 @@
|
|||
UPDATE {$NAMESPACE}_phame.phame_blog
|
||||
SET status = 'active' WHERE status = '';
|
|
@ -3271,9 +3271,9 @@ phutil_register_library_map(array(
|
|||
'PhameBasicBlogSkin' => 'applications/phame/skins/PhameBasicBlogSkin.php',
|
||||
'PhameBasicTemplateBlogSkin' => 'applications/phame/skins/PhameBasicTemplateBlogSkin.php',
|
||||
'PhameBlog' => 'applications/phame/storage/PhameBlog.php',
|
||||
'PhameBlogArchiveController' => 'applications/phame/controller/blog/PhameBlogArchiveController.php',
|
||||
'PhameBlogController' => 'applications/phame/controller/blog/PhameBlogController.php',
|
||||
'PhameBlogCreateCapability' => 'applications/phame/capability/PhameBlogCreateCapability.php',
|
||||
'PhameBlogDeleteController' => 'applications/phame/controller/blog/PhameBlogDeleteController.php',
|
||||
'PhameBlogEditController' => 'applications/phame/controller/blog/PhameBlogEditController.php',
|
||||
'PhameBlogEditor' => 'applications/phame/editor/PhameBlogEditor.php',
|
||||
'PhameBlogFeedController' => 'applications/phame/controller/blog/PhameBlogFeedController.php',
|
||||
|
@ -7573,9 +7573,9 @@ phutil_register_library_map(array(
|
|||
'PhabricatorProjectInterface',
|
||||
'PhabricatorApplicationTransactionInterface',
|
||||
),
|
||||
'PhameBlogArchiveController' => 'PhameBlogController',
|
||||
'PhameBlogController' => 'PhameController',
|
||||
'PhameBlogCreateCapability' => 'PhabricatorPolicyCapability',
|
||||
'PhameBlogDeleteController' => 'PhameBlogController',
|
||||
'PhameBlogEditController' => 'PhameBlogController',
|
||||
'PhameBlogEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhameBlogFeedController' => 'PhameBlogController',
|
||||
|
|
|
@ -59,7 +59,7 @@ final class PhabricatorPhameApplication extends PhabricatorApplication {
|
|||
'blog/' => array(
|
||||
'(?:(?P<filter>user|all)/)?' => 'PhameBlogListController',
|
||||
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhameBlogListController',
|
||||
'delete/(?P<id>[^/]+)/' => 'PhameBlogDeleteController',
|
||||
'archive/(?P<id>[^/]+)/' => 'PhameBlogArchiveController',
|
||||
'edit/(?P<id>[^/]+)/' => 'PhameBlogEditController',
|
||||
'view/(?P<id>[^/]+)/' => 'PhameBlogViewController',
|
||||
'feed/(?P<id>[^/]+)/' => 'PhameBlogFeedController',
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
final class PhameBlogArchiveController
|
||||
extends PhameBlogController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$blog = id(new PhameBlogQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$blog) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$view_uri = $this->getApplicationURI('blog/view/'.$blog->getID().'/');
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
if ($blog->isArchived()) {
|
||||
$new_status = PhameBlog::STATUS_ACTIVE;
|
||||
} else {
|
||||
$new_status = PhameBlog::STATUS_ARCHIVED;
|
||||
}
|
||||
|
||||
$xactions = array();
|
||||
|
||||
$xactions[] = id(new PhameBlogTransaction())
|
||||
->setTransactionType(PhameBlogTransaction::TYPE_STATUS)
|
||||
->setNewValue($new_status);
|
||||
|
||||
id(new PhameBlogEditor())
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContinueOnMissingFields(true)
|
||||
->applyTransactions($blog, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($view_uri);
|
||||
}
|
||||
|
||||
if ($blog->isArchived()) {
|
||||
$title = pht('Activate Blog');
|
||||
$body = pht('This blog will become active again.');
|
||||
$button = pht('Activate Blog');
|
||||
} else {
|
||||
$title = pht('Archive Blog');
|
||||
$body = pht('This blog will be marked as archived.');
|
||||
$button = pht('Archive Blog');
|
||||
}
|
||||
|
||||
$dialog = id(new AphrontDialogView())
|
||||
->setUser($viewer)
|
||||
->setTitle($title)
|
||||
->appendChild($body)
|
||||
->addCancelButton($view_uri)
|
||||
->addSubmitButton($button);
|
||||
|
||||
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhameBlogDeleteController extends PhameBlogController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$blog = id(new PhameBlogQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$blog) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$blog->delete();
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($this->getApplicationURI());
|
||||
}
|
||||
|
||||
$cancel_uri = $this->getApplicationURI('/blog/view/'.$blog->getID().'/');
|
||||
|
||||
$dialog = id(new AphrontDialogView())
|
||||
->setUser($viewer)
|
||||
->setTitle(pht('Delete Blog?'))
|
||||
->appendChild(
|
||||
pht(
|
||||
'Really delete the blog "%s"? It will be gone forever.',
|
||||
$blog->getName()))
|
||||
->addSubmitButton(pht('Delete'))
|
||||
->addCancelButton($cancel_uri);
|
||||
|
||||
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||
}
|
||||
|
||||
}
|
|
@ -22,10 +22,21 @@ final class PhameBlogViewController extends PhameBlogController {
|
|||
->withBlogPHIDs(array($blog->getPHID()))
|
||||
->executeWithCursorPager($pager);
|
||||
|
||||
if ($blog->isArchived()) {
|
||||
$header_icon = 'fa-ban';
|
||||
$header_name = pht('Archived');
|
||||
$header_color = 'dark';
|
||||
} else {
|
||||
$header_icon = 'fa-check';
|
||||
$header_name = pht('Active');
|
||||
$header_color = 'bluegrey';
|
||||
}
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($blog->getName())
|
||||
->setUser($viewer)
|
||||
->setPolicyObject($blog);
|
||||
->setPolicyObject($blog)
|
||||
->setStatus($header_icon, $header_color, $header_name);
|
||||
|
||||
$actions = $this->renderActions($blog, $viewer);
|
||||
$properties = $this->renderProperties($blog, $viewer, $actions);
|
||||
|
@ -158,13 +169,25 @@ final class PhameBlogViewController extends PhameBlogController {
|
|||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
|
||||
if ($blog->isArchived()) {
|
||||
$actions->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-times')
|
||||
->setHref($this->getApplicationURI('blog/delete/'.$blog->getID().'/'))
|
||||
->setName(pht('Delete Blog'))
|
||||
->setName(pht('Activate Blog'))
|
||||
->setIcon('fa-check')
|
||||
->setHref(
|
||||
$this->getApplicationURI('blog/archive/'.$blog->getID().'/'))
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true));
|
||||
} else {
|
||||
$actions->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Archive Blog'))
|
||||
->setIcon('fa-ban')
|
||||
->setHref(
|
||||
$this->getApplicationURI('blog/archive/'.$blog->getID().'/'))
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true));
|
||||
}
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ final class PhameBlogEditor
|
|||
$types[] = PhameBlogTransaction::TYPE_DESCRIPTION;
|
||||
$types[] = PhameBlogTransaction::TYPE_DOMAIN;
|
||||
$types[] = PhameBlogTransaction::TYPE_SKIN;
|
||||
$types[] = PhameBlogTransaction::TYPE_STATUS;
|
||||
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
||||
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
|
||||
|
||||
|
@ -37,6 +38,8 @@ final class PhameBlogEditor
|
|||
return $object->getDomain();
|
||||
case PhameBlogTransaction::TYPE_SKIN:
|
||||
return $object->getSkin();
|
||||
case PhameBlogTransaction::TYPE_STATUS:
|
||||
return $object->getStatus();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,6 +52,7 @@ final class PhameBlogEditor
|
|||
case PhameBlogTransaction::TYPE_DESCRIPTION:
|
||||
case PhameBlogTransaction::TYPE_DOMAIN:
|
||||
case PhameBlogTransaction::TYPE_SKIN:
|
||||
case PhameBlogTransaction::TYPE_STATUS:
|
||||
return $xaction->getNewValue();
|
||||
}
|
||||
}
|
||||
|
@ -66,6 +70,8 @@ final class PhameBlogEditor
|
|||
return $object->setDomain($xaction->getNewValue());
|
||||
case PhameBlogTransaction::TYPE_SKIN:
|
||||
return $object->setSkin($xaction->getNewValue());
|
||||
case PhameBlogTransaction::TYPE_STATUS:
|
||||
return $object->setStatus($xaction->getNewValue());
|
||||
}
|
||||
|
||||
return parent::applyCustomInternalTransaction($object, $xaction);
|
||||
|
@ -80,6 +86,7 @@ final class PhameBlogEditor
|
|||
case PhameBlogTransaction::TYPE_DESCRIPTION:
|
||||
case PhameBlogTransaction::TYPE_DOMAIN:
|
||||
case PhameBlogTransaction::TYPE_SKIN:
|
||||
case PhameBlogTransaction::TYPE_STATUS:
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ final class PhameBlogQuery extends PhabricatorCursorPagedPolicyAwareQuery {
|
|||
private $ids;
|
||||
private $phids;
|
||||
private $domain;
|
||||
private $statuses;
|
||||
private $needBloggers;
|
||||
|
||||
public function withIDs(array $ids) {
|
||||
|
@ -22,6 +23,11 @@ final class PhameBlogQuery extends PhabricatorCursorPagedPolicyAwareQuery {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function withStatuses(array $status) {
|
||||
$this->statuses = $status;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function newResultObject() {
|
||||
return new PhameBlog();
|
||||
}
|
||||
|
@ -33,6 +39,13 @@ final class PhameBlogQuery extends PhabricatorCursorPagedPolicyAwareQuery {
|
|||
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
|
||||
$where = parent::buildWhereClauseParts($conn);
|
||||
|
||||
if ($this->statuses !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'status IN (%Ls)',
|
||||
$this->statuses);
|
||||
}
|
||||
|
||||
if ($this->ids !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
|
|
|
@ -17,11 +17,23 @@ final class PhameBlogSearchEngine
|
|||
|
||||
protected function buildQueryFromParameters(array $map) {
|
||||
$query = $this->newQuery();
|
||||
if ($map['statuses']) {
|
||||
$query->withStatuses(array($map['statuses']));
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
protected function buildCustomSearchFields() {
|
||||
return array();
|
||||
return array(
|
||||
id(new PhabricatorSearchSelectField())
|
||||
->setKey('statuses')
|
||||
->setLabel(pht('Status'))
|
||||
->setOptions(array(
|
||||
'' => pht('All'),
|
||||
PhameBlog::STATUS_ACTIVE => pht('Active'),
|
||||
PhameBlog::STATUS_ARCHIVED => pht('Archived'),
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
protected function getURI($path) {
|
||||
|
@ -30,6 +42,8 @@ final class PhameBlogSearchEngine
|
|||
|
||||
protected function getBuiltinQueryNames() {
|
||||
$names = array(
|
||||
'active' => pht('Active Blogs'),
|
||||
'archived' => pht('Archived Blogs'),
|
||||
'all' => pht('All Blogs'),
|
||||
);
|
||||
return $names;
|
||||
|
@ -42,6 +56,12 @@ final class PhameBlogSearchEngine
|
|||
switch ($query_key) {
|
||||
case 'all':
|
||||
return $query;
|
||||
case 'active':
|
||||
return $query->setParameter(
|
||||
'statuses', PhameBlog::STATUS_ACTIVE);
|
||||
case 'archived':
|
||||
return $query->setParameter(
|
||||
'statuses', PhameBlog::STATUS_ARCHIVED);
|
||||
}
|
||||
|
||||
return parent::buildSavedQueryFromBuiltin($query_key);
|
||||
|
@ -58,12 +78,19 @@ final class PhameBlogSearchEngine
|
|||
$list->setUser($viewer);
|
||||
|
||||
foreach ($blogs as $blog) {
|
||||
$archived = false;
|
||||
$icon = 'fa-star';
|
||||
if ($blog->isArchived()) {
|
||||
$archived = true;
|
||||
$icon = 'fa-ban';
|
||||
}
|
||||
$id = $blog->getID();
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setUser($viewer)
|
||||
->setObject($blog)
|
||||
->setHeader($blog->getName())
|
||||
->setStatusIcon('fa-star')
|
||||
->setStatusIcon($icon)
|
||||
->setDisabled($archived)
|
||||
->setHref($this->getApplicationURI("/blog/view/{$id}/"))
|
||||
->addAttribute($blog->getSkin())
|
||||
->addAttribute($blog->getDomain());
|
||||
|
|
|
@ -20,10 +20,14 @@ final class PhameBlog extends PhameDAO
|
|||
protected $creatorPHID;
|
||||
protected $viewPolicy;
|
||||
protected $editPolicy;
|
||||
protected $status;
|
||||
protected $mailKey;
|
||||
|
||||
private static $requestBlog;
|
||||
|
||||
const STATUS_ACTIVE = 'active';
|
||||
const STATUS_ARCHIVED = 'archived';
|
||||
|
||||
protected function getConfiguration() {
|
||||
return array(
|
||||
self::CONFIG_AUX_PHID => true,
|
||||
|
@ -34,6 +38,7 @@ final class PhameBlog extends PhameDAO
|
|||
'name' => 'text64',
|
||||
'description' => 'text',
|
||||
'domain' => 'text128?',
|
||||
'status' => 'text32',
|
||||
'mailKey' => 'bytes20',
|
||||
|
||||
// T6203/NULLABILITY
|
||||
|
@ -98,6 +103,17 @@ final class PhameBlog extends PhameDAO
|
|||
return $skin;
|
||||
}
|
||||
|
||||
public function isArchived() {
|
||||
return ($this->getStatus() == self::STATUS_ARCHIVED);
|
||||
}
|
||||
|
||||
public static function getStatusNameMap() {
|
||||
return array(
|
||||
self::STATUS_ACTIVE => pht('Active'),
|
||||
self::STATUS_ARCHIVED => pht('Archived'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure a given custom blog uri is properly configured in DNS
|
||||
* to point at this Phabricator instance. If there is an error in
|
||||
|
|
|
@ -7,6 +7,7 @@ final class PhameBlogTransaction
|
|||
const TYPE_DESCRIPTION = 'phame.blog.description';
|
||||
const TYPE_DOMAIN = 'phame.blog.domain';
|
||||
const TYPE_SKIN = 'phame.blog.skin';
|
||||
const TYPE_STATUS = 'phame.blog.status';
|
||||
|
||||
const MAILTAG_DETAILS = 'phame-blog-details';
|
||||
const MAILTAG_SUBSCRIBERS = 'phame-blog-subscribers';
|
||||
|
@ -106,6 +107,18 @@ final class PhameBlogTransaction
|
|||
$this->renderHandleLink($author_phid),
|
||||
$new);
|
||||
break;
|
||||
case self::TYPE_STATUS:
|
||||
switch ($new) {
|
||||
case self::STATUS_OPEN:
|
||||
return pht(
|
||||
'%s published this blog.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
case self::STATUS_CLOSED:
|
||||
return pht(
|
||||
'%s archived this blog.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return parent::getTitle();
|
||||
|
@ -151,6 +164,21 @@ final class PhameBlogTransaction
|
|||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
break;
|
||||
case self::TYPE_STATUS:
|
||||
switch ($new) {
|
||||
case self::STATUS_OPEN:
|
||||
return pht(
|
||||
'%s published the blog %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
case self::STATUS_CLOSED:
|
||||
return pht(
|
||||
'%s archived the blog %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return parent::getTitleForFeed();
|
||||
|
|
Loading…
Reference in a new issue