mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-26 00:32:42 +01:00
Modernize blog UI
Summary: Cleans up some of the mess I made in D3694. Basically: - All blogs have an "internal" view with posts that uses mobile-friendly UIs, etc., so we don't have to do as much work with skins -- they just have to look pretty. - Blogs now have a separate "live" view that we use to handle domains / skins. - Simplified some views and use IDs in some URLs for consistency. - Delete a bunch of edge/blogger/multi-blog code that's now obsolete. Test Plan: Will attach screenshots. Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T1373 Differential Revision: https://secure.phabricator.com/D3695
This commit is contained in:
parent
a50b8e39b1
commit
b072e937b5
23 changed files with 524 additions and 751 deletions
|
@ -218,6 +218,9 @@ $action_map = array(
|
|||
'subscribe-auto' => 'icon/unsubscribe.png',
|
||||
'subscribe-add' => 'icon/subscribe.png',
|
||||
'subscribe-delete' => 'icon/unsubscribe.png',
|
||||
'new' => 'icon/page_white_put.png',
|
||||
'world' => 'icon/world.png',
|
||||
'delete' => 'icon/delete.png',
|
||||
);
|
||||
|
||||
foreach ($action_map as $icon => $source) {
|
||||
|
|
|
@ -51,8 +51,8 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'/rsrc/image/autosprite.png' =>
|
||||
array(
|
||||
'hash' => '005c7630a31cb2ef6b1782d4eca08cd7',
|
||||
'uri' => '/res/005c7630/rsrc/image/autosprite.png',
|
||||
'hash' => 'b1a2597ab1d245a52e5c8783dffa5e26',
|
||||
'uri' => '/res/b1a2597a/rsrc/image/autosprite.png',
|
||||
'disk' => '/rsrc/image/autosprite.png',
|
||||
'type' => 'png',
|
||||
),
|
||||
|
@ -462,27 +462,6 @@ celerity_register_resource_map(array(
|
|||
'disk' => '/rsrc/image/nyan.gif',
|
||||
'type' => 'gif',
|
||||
),
|
||||
'/rsrc/image/phacility/phacility_logo.jpg' =>
|
||||
array(
|
||||
'hash' => '88000de28b8741acc584b24560bd3d4f',
|
||||
'uri' => '/res/88000de2/rsrc/image/phacility/phacility_logo.jpg',
|
||||
'disk' => '/rsrc/image/phacility/phacility_logo.jpg',
|
||||
'type' => 'jpg',
|
||||
),
|
||||
'/rsrc/image/phacility/sprites.png' =>
|
||||
array(
|
||||
'hash' => 'b018a070d120f689a2beb8ece67e1b1e',
|
||||
'uri' => '/res/b018a070/rsrc/image/phacility/sprites.png',
|
||||
'disk' => '/rsrc/image/phacility/sprites.png',
|
||||
'type' => 'png',
|
||||
),
|
||||
'/rsrc/image/phacility/tactile_noise.png' =>
|
||||
array(
|
||||
'hash' => '7fb4ca90b8b0919153770b6badb982f0',
|
||||
'uri' => '/res/7fb4ca90/rsrc/image/phacility/tactile_noise.png',
|
||||
'disk' => '/rsrc/image/phacility/tactile_noise.png',
|
||||
'type' => 'png',
|
||||
),
|
||||
'/rsrc/image/search.png' =>
|
||||
array(
|
||||
'hash' => 'ff7da044e6f923b8f569dec11f97e5e5',
|
||||
|
@ -678,7 +657,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'autosprite-css' =>
|
||||
array(
|
||||
'uri' => '/res/6c0c2948/rsrc/css/autosprite.css',
|
||||
'uri' => '/res/95e8f847/rsrc/css/autosprite.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -1633,17 +1612,6 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'disk' => '/rsrc/js/application/core/behavior-watch-anchor.js',
|
||||
),
|
||||
'javelin-behavior-phame-post-blogs' =>
|
||||
array(
|
||||
'uri' => '/res/a7f7756c/rsrc/js/application/phame/phame-post-blogs.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
0 => 'javelin-behavior',
|
||||
1 => 'javelin-dom',
|
||||
),
|
||||
'disk' => '/rsrc/js/application/phame/phame-post-blogs.js',
|
||||
),
|
||||
'javelin-behavior-phame-post-preview' =>
|
||||
array(
|
||||
'uri' => '/res/ac4c503a/rsrc/js/application/phame/phame-post-preview.js',
|
||||
|
@ -2203,15 +2171,6 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'disk' => '/rsrc/js/javelin/lib/Workflow.js',
|
||||
),
|
||||
'jquery-js' =>
|
||||
array(
|
||||
'uri' => '/res/7f0dd213/rsrc/js/application/phame/skins/phacility/jquery/jquery.min.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
),
|
||||
'disk' => '/rsrc/js/application/phame/skins/phacility/jquery/jquery.min.js',
|
||||
),
|
||||
'maniphest-batch-editor' =>
|
||||
array(
|
||||
'uri' => '/res/fb15d744/rsrc/css/application/maniphest/batch-editor.css',
|
||||
|
@ -2918,38 +2877,9 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'disk' => '/rsrc/js/application/uiexample/ReactorSendPropertiesExample.js',
|
||||
),
|
||||
'phacility-bootstrap-css' =>
|
||||
array(
|
||||
'uri' => '/res/28f0ad0e/rsrc/css/application/phame/skins/phacility/bootstrap/bootstrap.min.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
),
|
||||
'disk' => '/rsrc/css/application/phame/skins/phacility/bootstrap/bootstrap.min.css',
|
||||
),
|
||||
'phacility-css' =>
|
||||
array(
|
||||
'uri' => '/res/f55275c2/rsrc/css/application/phame/skins/phacility/phacility.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
0 => 'phacility-bootstrap-css',
|
||||
),
|
||||
'disk' => '/rsrc/css/application/phame/skins/phacility/phacility.css',
|
||||
),
|
||||
'phacility-js' =>
|
||||
array(
|
||||
'uri' => '/res/f441bc88/rsrc/js/application/phame/skins/phacility/bootstrap/bootstrap.min.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
0 => 'jquery-js',
|
||||
),
|
||||
'disk' => '/rsrc/js/application/phame/skins/phacility/bootstrap/bootstrap.min.js',
|
||||
),
|
||||
'phame-css' =>
|
||||
array(
|
||||
'uri' => '/res/2d18adca/rsrc/css/application/phame/phame.css',
|
||||
'uri' => '/res/2e4c86eb/rsrc/css/application/phame/phame.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
|
|
|
@ -1147,14 +1147,13 @@ phutil_register_library_map(array(
|
|||
'PhabricatorXHProfSample' => 'applications/xhprof/storage/PhabricatorXHProfSample.php',
|
||||
'PhabricatorXHProfSampleListController' => 'applications/xhprof/controller/PhabricatorXHProfSampleListController.php',
|
||||
'PhabricatorXHProfSampleListView' => 'applications/xhprof/view/PhabricatorXHProfSampleListView.php',
|
||||
'PhameAllBlogListController' => 'applications/phame/controller/blog/list/PhameAllBlogListController.php',
|
||||
'PhameAllPostListController' => 'applications/phame/controller/post/list/PhameAllPostListController.php',
|
||||
'PhameBlog' => 'applications/phame/storage/PhameBlog.php',
|
||||
'PhameBlogDeleteController' => 'applications/phame/controller/blog/PhameBlogDeleteController.php',
|
||||
'PhameBlogDetailView' => 'applications/phame/view/PhameBlogDetailView.php',
|
||||
'PhameBlogEditController' => 'applications/phame/controller/blog/PhameBlogEditController.php',
|
||||
'PhameBlogListBaseController' => 'applications/phame/controller/blog/list/PhameBlogListBaseController.php',
|
||||
'PhameBlogListView' => 'applications/phame/view/PhameBlogListView.php',
|
||||
'PhameBlogListController' => 'applications/phame/controller/blog/PhameBlogListController.php',
|
||||
'PhameBlogLiveController' => 'applications/phame/controller/blog/PhameBlogLiveController.php',
|
||||
'PhameBlogQuery' => 'applications/phame/query/PhameBlogQuery.php',
|
||||
'PhameBlogSkin' => 'applications/phame/view/skins/PhameBlogSkin.php',
|
||||
'PhameBlogViewController' => 'applications/phame/controller/blog/PhameBlogViewController.php',
|
||||
|
@ -1171,7 +1170,6 @@ phutil_register_library_map(array(
|
|||
'PhamePostPreviewController' => 'applications/phame/controller/post/PhamePostPreviewController.php',
|
||||
'PhamePostQuery' => 'applications/phame/query/PhamePostQuery.php',
|
||||
'PhamePostViewController' => 'applications/phame/controller/post/PhamePostViewController.php',
|
||||
'PhameUserBlogListController' => 'applications/phame/controller/blog/list/PhameUserBlogListController.php',
|
||||
'PhameUserPostListController' => 'applications/phame/controller/post/list/PhameUserPostListController.php',
|
||||
'PhortuneMonthYearExpiryControl' => 'applications/phortune/control/PhortuneMonthYearExpiryControl.php',
|
||||
'PhortuneStripeBaseController' => 'applications/phortune/stripe/controller/PhortuneStripeBaseController.php',
|
||||
|
@ -2274,7 +2272,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorXHProfSample' => 'PhabricatorXHProfDAO',
|
||||
'PhabricatorXHProfSampleListController' => 'PhabricatorXHProfController',
|
||||
'PhabricatorXHProfSampleListView' => 'AphrontView',
|
||||
'PhameAllBlogListController' => 'PhameBlogListBaseController',
|
||||
'PhameAllPostListController' => 'PhamePostListBaseController',
|
||||
'PhameBlog' =>
|
||||
array(
|
||||
|
@ -2284,8 +2281,8 @@ phutil_register_library_map(array(
|
|||
'PhameBlogDeleteController' => 'PhameController',
|
||||
'PhameBlogDetailView' => 'AphrontView',
|
||||
'PhameBlogEditController' => 'PhameController',
|
||||
'PhameBlogListBaseController' => 'PhameController',
|
||||
'PhameBlogListView' => 'AphrontView',
|
||||
'PhameBlogListController' => 'PhameController',
|
||||
'PhameBlogLiveController' => 'PhameController',
|
||||
'PhameBlogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhameBlogSkin' => 'AphrontView',
|
||||
'PhameBlogViewController' => 'PhameController',
|
||||
|
@ -2293,16 +2290,19 @@ phutil_register_library_map(array(
|
|||
'PhameController' => 'PhabricatorController',
|
||||
'PhameDAO' => 'PhabricatorLiskDAO',
|
||||
'PhameDraftListController' => 'PhamePostListBaseController',
|
||||
'PhamePost' => 'PhameDAO',
|
||||
'PhamePost' =>
|
||||
array(
|
||||
0 => 'PhameDAO',
|
||||
1 => 'PhabricatorPolicyInterface',
|
||||
),
|
||||
'PhamePostDeleteController' => 'PhameController',
|
||||
'PhamePostDetailView' => 'AphrontView',
|
||||
'PhamePostEditController' => 'PhameController',
|
||||
'PhamePostListBaseController' => 'PhameController',
|
||||
'PhamePostListView' => 'AphrontView',
|
||||
'PhamePostPreviewController' => 'PhameController',
|
||||
'PhamePostQuery' => 'PhabricatorOffsetPagedQuery',
|
||||
'PhamePostQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhamePostViewController' => 'PhameController',
|
||||
'PhameUserBlogListController' => 'PhameBlogListBaseController',
|
||||
'PhameUserPostListController' => 'PhamePostListBaseController',
|
||||
'PhortuneMonthYearExpiryControl' => 'AphrontFormControl',
|
||||
'PhortuneStripeBaseController' => 'PhabricatorController',
|
||||
|
|
|
@ -140,7 +140,7 @@ abstract class AphrontApplicationConfiguration {
|
|||
|
||||
try {
|
||||
$blog = id(new PhameBlogQuery())
|
||||
->setViewer($request->getUser())
|
||||
->setViewer(new PhabricatorUser())
|
||||
->withDomain($host)
|
||||
->executeOne();
|
||||
} catch (PhabricatorPolicyException $ex) {
|
||||
|
@ -161,18 +161,10 @@ abstract class AphrontApplicationConfiguration {
|
|||
);
|
||||
}
|
||||
|
||||
// 2 basic cases
|
||||
// -- looking at a list of blog posts, path is nothing or '/'
|
||||
// -- we have to fudge the URI in this case
|
||||
// -- looking at an actual blog post, path is like
|
||||
// /phame/posts/<author>/post_title
|
||||
// NOTE: it is possible to get other phame pages, we just do
|
||||
// not link to them at this time.
|
||||
if (!$path || $path == '/') {
|
||||
$path = $blog->getViewURI();
|
||||
}
|
||||
// TODO: Make this more flexible and modular so any application can
|
||||
// do crazy stuff here if it wants.
|
||||
|
||||
PhameBlog::setRequestBlog($blog);
|
||||
$path = '/phame/blog/live/'.$blog->getID().'/'.$path;
|
||||
|
||||
$celerity = CelerityAPI::getStaticResourceResponse();
|
||||
$celerity->setUseFullURI(true);
|
||||
|
|
|
@ -58,13 +58,13 @@ final class PhabricatorApplicationPhame extends PhabricatorApplication {
|
|||
'' => 'PhameDraftListController',
|
||||
'new/' => 'PhamePostEditController',
|
||||
),
|
||||
'blog/(?:(?P<filter>user|all)/)?' => 'PhameBlogListController',
|
||||
'blog/' => array(
|
||||
'' => 'PhameUserBlogListController',
|
||||
'all/' => 'PhameAllBlogListController',
|
||||
'delete/(?P<id>[^/]+)/' => 'PhameBlogDeleteController',
|
||||
'edit/(?P<id>[^/]+)/' => 'PhameBlogEditController',
|
||||
'view/(?P<id>[^/]+)/' => 'PhameBlogViewController',
|
||||
'live/(?P<id>[^/]+)/(?P<more>.*)' => 'PhameBlogLiveController',
|
||||
'new/' => 'PhameBlogEditController',
|
||||
'delete/(?P<phid>[^/]+)/' => 'PhameBlogDeleteController',
|
||||
'edit/(?P<phid>[^/]+)/' => 'PhameBlogEditController',
|
||||
'view/(?P<phid>[^/]+)/' => 'PhameBlogViewController',
|
||||
),
|
||||
'posts/' => array(
|
||||
'' => 'PhameUserPostListController',
|
||||
|
|
|
@ -71,13 +71,16 @@ abstract class PhameController extends PhabricatorController {
|
|||
return $response->setContent($page->render());
|
||||
}
|
||||
|
||||
private function renderSideNavFilterView($filter) {
|
||||
protected function renderSideNavFilterView($filter) {
|
||||
$base_uri = new PhutilURI('/phame/');
|
||||
$nav = new AphrontSideNavFilterView();
|
||||
$nav->setBaseURI($base_uri);
|
||||
$nav->addLabel('Drafts');
|
||||
$nav->addFilter('post/new',
|
||||
'New Draft');
|
||||
$nav->addLabel('Create');
|
||||
$nav->addFilter('post/new', 'New Draft');
|
||||
$nav->addFilter('blog/new', 'New Blog');
|
||||
|
||||
$nav->addSpacer();
|
||||
$nav->addLabel('Posts');
|
||||
$nav->addFilter('draft',
|
||||
'My Drafts');
|
||||
foreach ($this->getSideNavExtraDraftFilters() as $draft_filter) {
|
||||
|
@ -85,9 +88,6 @@ abstract class PhameController extends PhabricatorController {
|
|||
$draft_filter['name'],
|
||||
idx($draft_filter, 'uri'));
|
||||
}
|
||||
|
||||
$nav->addSpacer();
|
||||
$nav->addLabel('Posts');
|
||||
$nav->addFilter('post',
|
||||
'My Posts');
|
||||
$nav->addFilter('post/all',
|
||||
|
@ -123,7 +123,7 @@ abstract class PhameController extends PhabricatorController {
|
|||
protected function getSideNavBlogFilters() {
|
||||
return array(
|
||||
array(
|
||||
'key' => 'blog',
|
||||
'key' => 'blog/user',
|
||||
'name' => 'My Blogs',
|
||||
),
|
||||
array(
|
||||
|
@ -154,4 +154,24 @@ abstract class PhameController extends PhabricatorController {
|
|||
->setTitle('Meta thoughts and feelings');
|
||||
return $notice_view;
|
||||
}
|
||||
|
||||
protected function renderPostList(
|
||||
array $posts,
|
||||
PhabricatorUser $user,
|
||||
$nodata) {
|
||||
assert_instances_of($posts, 'PhamePost');
|
||||
|
||||
$list = id(new PhabricatorObjectItemListView())
|
||||
->setNoDataString($nodata);
|
||||
|
||||
foreach ($posts as $post) {
|
||||
$item = id(new PhabricatorObjectItemView())
|
||||
->setHeader($post->getTitle())
|
||||
->setHref($this->getApplicationURI('post/view/'.$post->getPHID()));
|
||||
|
||||
$list->addItem($item);
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,18 +19,10 @@
|
|||
/**
|
||||
* @group phame
|
||||
*/
|
||||
final class PhameBlogDeleteController
|
||||
extends PhameController {
|
||||
final class PhameBlogDeleteController extends PhameController {
|
||||
|
||||
private $phid;
|
||||
private $id;
|
||||
|
||||
private function setBlogPHID($phid) {
|
||||
$this->phid = $phid;
|
||||
return $this;
|
||||
}
|
||||
private function getBlogPHID() {
|
||||
return $this->phid;
|
||||
}
|
||||
|
||||
protected function getSideNavFilter() {
|
||||
return 'blog/delete/'.$this->getBlogPHID();
|
||||
|
@ -46,8 +38,7 @@ extends PhameController {
|
|||
}
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$phid = $data['phid'];
|
||||
$this->setBlogPHID($phid);
|
||||
$this->id = $data['id'];
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
|
@ -56,13 +47,12 @@ extends PhameController {
|
|||
|
||||
$blog = id(new PhameBlogQuery())
|
||||
->setViewer($user)
|
||||
->withPHIDs(array($this->getBlogPHID()))
|
||||
->withIDs(array($this->id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
|
||||
if (!$blog) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
@ -70,15 +60,20 @@ extends PhameController {
|
|||
if ($request->isFormPost()) {
|
||||
$blog->delete();
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/phame/blog/?deleted');
|
||||
->setURI($this->getApplicationURI());
|
||||
}
|
||||
|
||||
$cancel_uri = $this->getApplicationURI('/blog/view/'.$blog->getID().'/');
|
||||
|
||||
$dialog = id(new AphrontDialogView())
|
||||
->setUser($user)
|
||||
->setTitle('Delete blog?')
|
||||
->appendChild('Really delete this blog? It will be gone forever.')
|
||||
->addSubmitButton('Delete')
|
||||
->addCancelButton($blog->getEditURI());
|
||||
->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,69 +22,25 @@
|
|||
final class PhameBlogEditController
|
||||
extends PhameController {
|
||||
|
||||
private $phid;
|
||||
private $isBlogEdit;
|
||||
|
||||
private function setBlogPHID($phid) {
|
||||
$this->phid = $phid;
|
||||
return $this;
|
||||
}
|
||||
private function getBlogPHID() {
|
||||
return $this->phid;
|
||||
}
|
||||
private function setIsBlogEdit($is_blog_edit) {
|
||||
$this->isBlogEdit = $is_blog_edit;
|
||||
return $this;
|
||||
}
|
||||
private function isBlogEdit() {
|
||||
return $this->isBlogEdit;
|
||||
}
|
||||
private $id;
|
||||
|
||||
protected function getSideNavFilter() {
|
||||
if ($this->isBlogEdit()) {
|
||||
$filter = 'blog/edit/'.$this->getBlogPHID();
|
||||
} else {
|
||||
$filter = 'blog/new';
|
||||
}
|
||||
return $filter;
|
||||
return 'blog/edit/'.$this->id;
|
||||
}
|
||||
|
||||
protected function getSideNavBlogFilters() {
|
||||
$filters = parent::getSideNavBlogFilters();
|
||||
|
||||
if ($this->isBlogEdit()) {
|
||||
$filter =
|
||||
array('key' => 'blog/edit/'.$this->getBlogPHID(),
|
||||
'name' => 'Edit Blog');
|
||||
$filters[] = $filter;
|
||||
} else {
|
||||
$filter =
|
||||
array('key' => 'blog/new',
|
||||
'name' => 'New Blog');
|
||||
array_unshift($filters, $filter);
|
||||
}
|
||||
|
||||
return $filters;
|
||||
}
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$phid = idx($data, 'phid');
|
||||
$this->setBlogPHID($phid);
|
||||
$this->setIsBlogEdit((bool)$phid);
|
||||
$this->id = idx($data, 'id');
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
||||
$e_name = true;
|
||||
$e_custom_domain = null;
|
||||
$errors = array();
|
||||
|
||||
if ($this->isBlogEdit()) {
|
||||
if ($this->id) {
|
||||
$blog = id(new PhameBlogQuery())
|
||||
->setViewer($user)
|
||||
->withPHIDs(array($this->getBlogPHID()))
|
||||
->withIDs(array($this->id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_EDIT
|
||||
|
@ -94,25 +50,26 @@ final class PhameBlogEditController
|
|||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$submit_button = 'Save Changes';
|
||||
$delete_button = javelin_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $blog->getDeleteURI(),
|
||||
'class' => 'grey button',
|
||||
'sigil' => 'workflow',
|
||||
),
|
||||
'Delete Blog');
|
||||
$page_title = 'Edit Blog';
|
||||
$submit_button = pht('Save Changes');
|
||||
$page_title = pht('Edit Blog');
|
||||
$cancel_uri = $this->getApplicationURI('blog/view/'.$blog->getID().'/');
|
||||
} else {
|
||||
$blog = id(new PhameBlog())
|
||||
->setCreatorPHID($user->getPHID());
|
||||
$blogger_tokens = array($user->getPHID() => $user->getFullName());
|
||||
$submit_button = 'Create Blog';
|
||||
$delete_button = null;
|
||||
$page_title = 'Create Blog';
|
||||
|
||||
$blog->setViewPolicy(PhabricatorPolicies::POLICY_USER);
|
||||
$blog->setEditPolicy(PhabricatorPolicies::POLICY_USER);
|
||||
$blog->setJoinPolicy(PhabricatorPolicies::POLICY_USER);
|
||||
|
||||
$submit_button = pht('Create Blog');
|
||||
$page_title = pht('Create Blog');
|
||||
$cancel_uri = $this->getApplicationURI();
|
||||
}
|
||||
|
||||
$e_name = true;
|
||||
$e_custom_domain = null;
|
||||
$errors = array();
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$name = $request->getStr('name');
|
||||
$description = $request->getStr('description');
|
||||
|
@ -122,9 +79,13 @@ final class PhameBlogEditController
|
|||
if (empty($name)) {
|
||||
$errors[] = 'You must give the blog a name.';
|
||||
$e_name = 'Required';
|
||||
} else {
|
||||
$e_name = null;
|
||||
}
|
||||
|
||||
$blog->setName($name);
|
||||
$blog->setDescription($description);
|
||||
|
||||
if (!empty($custom_domain)) {
|
||||
$error = $blog->validateCustomDomain($custom_domain);
|
||||
if ($error) {
|
||||
|
@ -147,25 +108,11 @@ final class PhameBlogEditController
|
|||
|
||||
if (!$errors) {
|
||||
$blog->save();
|
||||
|
||||
$uri = new PhutilURI($blog->getViewURI());
|
||||
if ($this->isBlogEdit()) {
|
||||
$uri->setQueryParam('edit', true);
|
||||
} else {
|
||||
$uri->setQueryParam('new', true);
|
||||
}
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($uri);
|
||||
->setURI($this->getApplicationURI('blog/view/'.$blog->getID().'/'));
|
||||
}
|
||||
}
|
||||
|
||||
$panel = new AphrontPanelView();
|
||||
$panel->setHeader($page_title);
|
||||
$panel->setWidth(AphrontPanelView::WIDTH_FULL);
|
||||
if ($delete_button) {
|
||||
$panel->addButton($delete_button);
|
||||
}
|
||||
|
||||
$policies = id(new PhabricatorPolicyQuery())
|
||||
->setViewer($user)
|
||||
->setObject($blog)
|
||||
|
@ -173,6 +120,7 @@ final class PhameBlogEditController
|
|||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($user)
|
||||
->setFlexible(true)
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel('Name')
|
||||
|
@ -227,12 +175,10 @@ final class PhameBlogEditController
|
|||
)
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->addCancelButton('/phame/blog/')
|
||||
->addCancelButton($cancel_uri)
|
||||
->setValue($submit_button)
|
||||
);
|
||||
|
||||
$panel->appendChild($form);
|
||||
|
||||
if ($errors) {
|
||||
$error_view = id(new AphrontErrorView())
|
||||
->setTitle('Form Errors')
|
||||
|
@ -241,12 +187,15 @@ final class PhameBlogEditController
|
|||
$error_view = null;
|
||||
}
|
||||
|
||||
$this->setShowSideNav(true);
|
||||
return $this->buildStandardPageResponse(
|
||||
$nav = $this->renderSideNavFilterView(null);
|
||||
$nav->appendChild(
|
||||
array(
|
||||
$error_view,
|
||||
$panel,
|
||||
),
|
||||
$form,
|
||||
));
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
$nav,
|
||||
array(
|
||||
'title' => $page_title,
|
||||
));
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group phame
|
||||
*/
|
||||
final class PhameBlogListController extends PhameController {
|
||||
|
||||
private $filter;
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->filter = idx($data, 'filter');
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
||||
$nav = $this->renderSideNavFilterView(null);
|
||||
$filter = $nav->selectFilter('blog/'.$this->filter, 'blog/user');
|
||||
|
||||
$query = id(new PhameBlogQuery())
|
||||
->setViewer($user);
|
||||
|
||||
switch ($filter) {
|
||||
case 'blog/all':
|
||||
$title = 'All Blogs';
|
||||
$nodata = 'No blogs have been created.';
|
||||
break;
|
||||
case 'blog/user':
|
||||
$title = 'My Blogs';
|
||||
$nodata = 'There are no blogs you can contribute to.';
|
||||
$query->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_JOIN,
|
||||
));
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Unknown filter '{$filter}'!");
|
||||
}
|
||||
|
||||
$pager = id(new AphrontPagerView())
|
||||
->setURI($request->getRequestURI(), 'offset')
|
||||
->setOffset($request->getInt('offset'));
|
||||
|
||||
$blogs = $query->executeWithOffsetPager($pager);
|
||||
|
||||
$header = id(new PhabricatorHeaderView())
|
||||
->setHeader($title);
|
||||
|
||||
$blog_list = $this->renderBlogList($blogs, $user, $nodata);
|
||||
$blog_list->setPager($pager);
|
||||
|
||||
$nav->appendChild(
|
||||
array(
|
||||
$header,
|
||||
$blog_list,
|
||||
));
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
$nav,
|
||||
array(
|
||||
'title' => $title,
|
||||
'device' => true,
|
||||
));
|
||||
}
|
||||
|
||||
private function renderBlogList(
|
||||
array $blogs,
|
||||
PhabricatorUser $user,
|
||||
$nodata) {
|
||||
|
||||
$view = new PhabricatorObjectItemListView();
|
||||
$view->setNoDataString($nodata);
|
||||
foreach ($blogs as $blog) {
|
||||
|
||||
$item = id(new PhabricatorObjectItemView())
|
||||
->setHeader($blog->getName())
|
||||
->setHref($this->getApplicationURI('blog/view/'.$blog->getID().'/'))
|
||||
->addDetail(
|
||||
'Custom Domain',
|
||||
phutil_escape_html($blog->getDomain()));
|
||||
|
||||
$view->addItem($item);
|
||||
}
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group phame
|
||||
*/
|
||||
final class PhameBlogLiveController extends PhameController {
|
||||
|
||||
private $id;
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->id = idx($data, 'id');
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
||||
// NOTE: We're loading with the logged-out user so we can raise the right
|
||||
// error if the blog permissions aren't set correctly.
|
||||
|
||||
$blog = null;
|
||||
$policy_exception = null;
|
||||
|
||||
try {
|
||||
$blog = id(new PhameBlogQuery())
|
||||
->setViewer(new PhabricatorUser())
|
||||
->withIDs(array($this->id))
|
||||
->executeOne();
|
||||
} catch (PhabricatorPolicyException $ex) {
|
||||
$policy_exception = $ex;
|
||||
}
|
||||
|
||||
if (!$blog && !$policy_exception) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$errors = array();
|
||||
if ($policy_exception) {
|
||||
$errors[] = pht('"Visible To" must be set to "Public".');
|
||||
}
|
||||
|
||||
if ($blog && !$blog->getDomain()) {
|
||||
$errors[] = pht('You must configure a custom domain.');
|
||||
}
|
||||
|
||||
if ($errors) {
|
||||
if ($blog) {
|
||||
$cancel_uri = $this->getApplicationURI('/blog/view/'.$blog->getID());
|
||||
} else {
|
||||
$cancel_uri = $this->getApplicationURI();
|
||||
}
|
||||
|
||||
$dialog = id(new AphrontDialogView())
|
||||
->setUser($user)
|
||||
->addCancelButton($cancel_uri)
|
||||
->setTitle(pht('Live Blog Unavailable'));
|
||||
|
||||
foreach ($errors as $error) {
|
||||
$dialog->appendChild('<p>'.$error.'</p>');
|
||||
}
|
||||
|
||||
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||
}
|
||||
|
||||
if ($request->getHost() != $blog->getDomain()) {
|
||||
$uri = 'http://'.$blog->getDomain().'/';
|
||||
return id(new AphrontRedirectResponse())->setURI($uri);
|
||||
}
|
||||
|
||||
$pager = id(new AphrontCursorPagerView())
|
||||
->readFromRequest($request);
|
||||
|
||||
$posts = id(new PhamePostQuery())
|
||||
->setViewer($user)
|
||||
->withBlogPHIDs(array($blog->getPHID()))
|
||||
->executeWithCursorPager($pager);
|
||||
|
||||
$skin = $blog->getSkinRenderer();
|
||||
$skin
|
||||
->setUser($user)
|
||||
->setPosts($posts)
|
||||
->setBloggers($this->loadViewerHandles(mpull($posts, 'getBloggerPHID')))
|
||||
->setBlog($blog)
|
||||
->setRequestURI($this->getRequest()->getRequestURI());
|
||||
|
||||
$page = $this->buildStandardPageView();
|
||||
$page->appendChild($skin);
|
||||
$page->setShowChrome(false);
|
||||
|
||||
$response = new AphrontWebpageResponse();
|
||||
$response->setContent($page->render());
|
||||
return $response;
|
||||
}
|
||||
|
||||
}
|
|
@ -21,15 +21,7 @@
|
|||
*/
|
||||
final class PhameBlogViewController extends PhameController {
|
||||
|
||||
private $blogPHID;
|
||||
|
||||
private function setBlogPHID($blog_phid) {
|
||||
$this->blogPHID = $blog_phid;
|
||||
return $this;
|
||||
}
|
||||
private function getBlogPHID() {
|
||||
return $this->blogPHID;
|
||||
}
|
||||
private $id;
|
||||
|
||||
protected function getSideNavFilter() {
|
||||
$filter = 'blog/view/'.$this->getBlogPHID();
|
||||
|
@ -45,7 +37,7 @@ final class PhameBlogViewController extends PhameController {
|
|||
}
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->setBlogPHID(idx($data, 'phid'));
|
||||
$this->id = $data['id'];
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
|
@ -54,36 +46,128 @@ final class PhameBlogViewController extends PhameController {
|
|||
|
||||
$blog = id(new PhameBlogQuery())
|
||||
->setViewer($user)
|
||||
->withPHIDs(array($this->getBlogPHID()))
|
||||
->withIDs(array($this->id))
|
||||
->executeOne();
|
||||
if (!$blog) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$pager = id(new AphrontCursorPagerView())
|
||||
->readFromRequest($request);
|
||||
|
||||
$posts = id(new PhamePostQuery())
|
||||
->setViewer($user)
|
||||
->withBlogPHIDs(array($blog->getPHID()))
|
||||
->execute();
|
||||
->executeWithCursorPager($pager);
|
||||
|
||||
$skin = $blog->getSkinRenderer();
|
||||
$skin
|
||||
->setUser($this->getRequest()->getUser())
|
||||
->setBloggers($this->loadViewerHandles(mpull($posts, 'getBloggerPHID')))
|
||||
->setPosts($posts)
|
||||
->setBlog($blog)
|
||||
->setRequestURI($this->getRequest()->getRequestURI());
|
||||
$nav = $this->renderSideNavFilterView(null);
|
||||
|
||||
$this->setShowSideNav(false);
|
||||
$this->setShowChrome($skin->getShowChrome());
|
||||
$this->setDeviceReady($skin->getDeviceReady());
|
||||
$skin->setIsExternalDomain($blog->getDomain() == $request->getHost());
|
||||
$header = id(new PhabricatorHeaderView())
|
||||
->setHeader($blog->getName());
|
||||
|
||||
return $this->buildStandardPageResponse(
|
||||
$actions = $this->renderActions($blog, $user);
|
||||
$properties = $this->renderProperties($blog, $user);
|
||||
$post_list = $this->renderPostList(
|
||||
$posts,
|
||||
$user,
|
||||
pht('This blog has no visible posts.'));
|
||||
|
||||
$nav->appendChild(
|
||||
array(
|
||||
$skin
|
||||
),
|
||||
$header,
|
||||
$actions,
|
||||
$properties,
|
||||
$post_list,
|
||||
));
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
$nav,
|
||||
array(
|
||||
'device' => true,
|
||||
'title' => $blog->getName(),
|
||||
));
|
||||
}
|
||||
|
||||
private function renderProperties(PhameBlog $blog, PhabricatorUser $user) {
|
||||
$properties = new PhabricatorPropertyListView();
|
||||
|
||||
$properties->addProperty(
|
||||
pht('Skin'),
|
||||
phutil_escape_html($blog->getSkin()));
|
||||
|
||||
$properties->addProperty(
|
||||
pht('Domain'),
|
||||
phutil_escape_html($blog->getDomain()));
|
||||
|
||||
$descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions(
|
||||
$user,
|
||||
$blog);
|
||||
|
||||
$properties->addProperty(
|
||||
pht('Visible To'),
|
||||
$descriptions[PhabricatorPolicyCapability::CAN_VIEW]);
|
||||
|
||||
$properties->addProperty(
|
||||
pht('Editable By'),
|
||||
$descriptions[PhabricatorPolicyCapability::CAN_EDIT]);
|
||||
|
||||
$properties->addProperty(
|
||||
pht('Joinable By'),
|
||||
$descriptions[PhabricatorPolicyCapability::CAN_JOIN]);
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
||||
private function renderActions(PhameBlog $blog, PhabricatorUser $user) {
|
||||
|
||||
$actions = id(new PhabricatorActionListView())
|
||||
->setObject($blog)
|
||||
->setUser($user);
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$user,
|
||||
$blog,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$can_join = PhabricatorPolicyFilter::hasCapability(
|
||||
$user,
|
||||
$blog,
|
||||
PhabricatorPolicyCapability::CAN_JOIN);
|
||||
|
||||
$actions->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('new')
|
||||
->setHref($this->getApplicationURI('post/new/?blog='.$blog->getID()))
|
||||
->setName(pht('Write Post'))
|
||||
->setDisabled(!$can_join)
|
||||
->setWorkflow(!$can_join));
|
||||
|
||||
$has_domain = $blog->getDomain();
|
||||
$actions->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('world')
|
||||
->setHref($this->getApplicationURI('blog/live/'.$blog->getID().'/'))
|
||||
->setName(pht('View Live'))
|
||||
->setDisabled(!$has_domain)
|
||||
->setWorkflow(true));
|
||||
|
||||
$actions->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('edit')
|
||||
->setHref($this->getApplicationURI('blog/edit/'.$blog->getID().'/'))
|
||||
->setName('Edit Blog')
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
|
||||
$actions->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('delete')
|
||||
->setHref($this->getApplicationURI('blog/delete/'.$blog->getID().'/'))
|
||||
->setName('Delete Blog')
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true));
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group phame
|
||||
*/
|
||||
final class PhameAllBlogListController
|
||||
extends PhameBlogListBaseController {
|
||||
|
||||
protected function getSideNavFilter() {
|
||||
return 'blog/all';
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$user = $this->getRequest()->getUser();
|
||||
|
||||
$pager = id(new AphrontCursorPagerView())
|
||||
->readFromRequest($this->getRequest());
|
||||
|
||||
$blogs = id(new PhameBlogQuery())
|
||||
->setViewer($user)
|
||||
->needBloggers(true)
|
||||
->executeWithCursorPager($pager);
|
||||
$this->setBlogs($blogs);
|
||||
|
||||
$page_title = 'All Blogs';
|
||||
$this->setPageTitle($page_title);
|
||||
|
||||
$this->setShowSideNav(true);
|
||||
|
||||
return $this->buildBlogListPageResponse();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group phame
|
||||
*/
|
||||
abstract class PhameBlogListBaseController
|
||||
extends PhameController {
|
||||
|
||||
private $blogs;
|
||||
private $pageTitle;
|
||||
|
||||
protected function setBlogs(array $blogs) {
|
||||
assert_instances_of($blogs, 'PhameBlog');
|
||||
$this->blogs = $blogs;
|
||||
return $this;
|
||||
}
|
||||
private function getBlogs() {
|
||||
return $this->blogs;
|
||||
}
|
||||
|
||||
protected function setPageTitle($page_title) {
|
||||
$this->pageTitle = $page_title;
|
||||
return $this;
|
||||
}
|
||||
private function getPageTitle() {
|
||||
return $this->pageTitle;
|
||||
}
|
||||
|
||||
protected function getNoticeView() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getBlogListPanel() {
|
||||
$blogs = $this->getBlogs();
|
||||
|
||||
$panel = id(new PhameBlogListView())
|
||||
->setUser($this->getRequest()->getUser())
|
||||
->setBlogs($blogs)
|
||||
->setHeader($this->getPageTitle());
|
||||
|
||||
return $panel;
|
||||
}
|
||||
|
||||
protected function buildBlogListPageResponse() {
|
||||
return $this->buildStandardPageResponse(
|
||||
array(
|
||||
$this->getNoticeView(),
|
||||
$this->getBlogListPanel(),
|
||||
$this->getPager(),
|
||||
),
|
||||
array(
|
||||
'title' => $this->getPageTitle(),
|
||||
));
|
||||
}
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group phame
|
||||
*/
|
||||
final class PhameUserBlogListController
|
||||
extends PhameBlogListBaseController {
|
||||
|
||||
protected function getNoticeView() {
|
||||
$request = $this->getRequest();
|
||||
|
||||
if ($request->getExists('deleted')) {
|
||||
$notice_view = $this->buildNoticeView()
|
||||
->appendChild('Successfully deleted blog.');
|
||||
} else {
|
||||
$notice_view = null;
|
||||
}
|
||||
|
||||
return $notice_view;
|
||||
}
|
||||
|
||||
protected function getSideNavFilter() {
|
||||
return 'blog';
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$user = $this->getRequest()->getUser();
|
||||
$phid = $user->getPHID();
|
||||
|
||||
$blog_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
|
||||
$phid,
|
||||
PhabricatorEdgeConfig::TYPE_BLOGGER_HAS_BLOG
|
||||
);
|
||||
|
||||
$pager = id(new AphrontCursorPagerView())
|
||||
->readFromRequest($this->getRequest());
|
||||
|
||||
$blogs = id(new PhameBlogQuery())
|
||||
->setViewer($user)
|
||||
->withPHIDs($blog_phids)
|
||||
->needBloggers(true)
|
||||
->executeWithCursorPager($pager);
|
||||
|
||||
$this->setBlogs($blogs);
|
||||
|
||||
$this->setPageTitle('My Blogs');
|
||||
|
||||
$this->setShowSideNav(true);
|
||||
|
||||
return $this->buildBlogListPageResponse();
|
||||
}
|
||||
|
||||
}
|
|
@ -140,16 +140,28 @@ final class PhamePostEditController
|
|||
'Delete '.$post_noun);
|
||||
$page_title = 'Edit '.$post_noun;
|
||||
} else {
|
||||
$blog = id(new PhameBlogQuery())
|
||||
->setViewer($user)
|
||||
->withIDs(array($request->getInt('blog')))
|
||||
->executeOne();
|
||||
|
||||
if (!$blog) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$post = id(new PhamePost())
|
||||
->setBloggerPHID($user->getPHID())
|
||||
->setBlog($blog)
|
||||
->setBlogPHID($blog->getPHID())
|
||||
->setVisibility(PhamePost::VISIBILITY_DRAFT);
|
||||
$cancel_uri = '/phame/draft/';
|
||||
$submit_button = 'Create Draft';
|
||||
$cancel_uri = $this->getApplicationURI('/blog/view/'.$blog->getID().'/');
|
||||
|
||||
$submit_button = pht('Create Draft');
|
||||
$delete_button = null;
|
||||
$page_title = 'Create Draft';
|
||||
$page_title = pht('Create Draft');
|
||||
}
|
||||
|
||||
$this->setPost($post);
|
||||
$this->loadEdgesAndBlogs();
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$saved = true;
|
||||
|
@ -182,48 +194,19 @@ final class PhamePostEditController
|
|||
$e_title = 'Required';
|
||||
}
|
||||
|
||||
$blogs_published = array_keys($this->getPostBlogs());
|
||||
$blogs_to_publish = array();
|
||||
$blogs_to_depublish = array();
|
||||
if ($visibility == PhamePost::VISIBILITY_PUBLISHED) {
|
||||
$blogs_arr = $request->getArr('blogs');
|
||||
$blogs_to_publish = array_values($blogs_arr);
|
||||
$blogs_to_depublish = array_diff($blogs_published,
|
||||
$blogs_to_publish);
|
||||
} else {
|
||||
$blogs_to_depublish = $blogs_published;
|
||||
}
|
||||
|
||||
if (empty($errors)) {
|
||||
if (!$errors) {
|
||||
try {
|
||||
$post->save();
|
||||
|
||||
$editor = new PhabricatorEdgeEditor();
|
||||
$edge_type = PhabricatorEdgeConfig::TYPE_POST_HAS_BLOG;
|
||||
$editor->setActor($user);
|
||||
foreach ($blogs_to_publish as $phid) {
|
||||
$editor->addEdge($post->getPHID(), $edge_type, $phid);
|
||||
}
|
||||
foreach ($blogs_to_depublish as $phid) {
|
||||
$editor->removeEdge($post->getPHID(), $edge_type, $phid);
|
||||
}
|
||||
$editor->save();
|
||||
|
||||
} catch (AphrontQueryDuplicateKeyException $e) {
|
||||
$saved = false;
|
||||
$e_phame_title = 'Not Unique';
|
||||
$errors[] = 'Another post already uses this slug. '.
|
||||
'Each post must have a unique slug.';
|
||||
}
|
||||
} else {
|
||||
$saved = false;
|
||||
}
|
||||
|
||||
if ($saved) {
|
||||
$uri = new PhutilURI($post->getViewURI($user->getUsername()));
|
||||
$uri->setQueryParam('saved', true);
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($uri);
|
||||
} catch (AphrontQueryDuplicateKeyException $e) {
|
||||
$e_phame_title = 'Not Unique';
|
||||
$errors[] = 'Another post already uses this slug. '.
|
||||
'Each post must have a unique slug.';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -234,8 +217,16 @@ final class PhamePostEditController
|
|||
$panel->addButton($delete_button);
|
||||
}
|
||||
|
||||
$handle = PhabricatorObjectHandleData::loadOneHandle(
|
||||
$post->getBlogPHID(),
|
||||
$user);
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($user)
|
||||
->appendChild(
|
||||
id(new AphrontFormMarkupControl())
|
||||
->setLabel('Blog')
|
||||
->setValue($handle->renderLink()))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel('Title')
|
||||
|
@ -271,9 +262,6 @@ final class PhamePostEditController
|
|||
->setOptions(PhamePost::getVisibilityOptionsForSelect())
|
||||
->setID('post-visibility')
|
||||
)
|
||||
->appendChild(
|
||||
$this->getBlogCheckboxControl($post)
|
||||
)
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setLabel('Comments Widget')
|
||||
|
@ -312,26 +300,6 @@ final class PhamePostEditController
|
|||
'uri' => '/phame/post/preview/',
|
||||
));
|
||||
|
||||
$visibility_data = array(
|
||||
'select_id' => 'post-visibility',
|
||||
'current' => $post->getVisibility(),
|
||||
'published' => PhamePost::VISIBILITY_PUBLISHED,
|
||||
'draft' => PhamePost::VISIBILITY_DRAFT,
|
||||
'change_uri' => $post->getChangeVisibilityURI(),
|
||||
);
|
||||
|
||||
$blogs_data = array(
|
||||
'checkbox_id' => 'post-blogs',
|
||||
'have_published' => (bool) count($this->getPostBlogs())
|
||||
);
|
||||
|
||||
Javelin::initBehavior(
|
||||
'phame-post-blogs',
|
||||
array(
|
||||
'blogs' => $blogs_data,
|
||||
'visibility' => $visibility_data,
|
||||
));
|
||||
|
||||
if ($errors) {
|
||||
$error_view = id(new AphrontErrorView())
|
||||
->setTitle('Errors saving post.')
|
||||
|
@ -352,76 +320,4 @@ final class PhamePostEditController
|
|||
));
|
||||
}
|
||||
|
||||
private function getBlogCheckboxControl(PhamePost $post) {
|
||||
if ($post->getVisibility() == PhamePost::VISIBILITY_PUBLISHED) {
|
||||
$control_style = null;
|
||||
} else {
|
||||
$control_style = 'display: none';
|
||||
}
|
||||
|
||||
$control = id(new AphrontFormCheckboxControl())
|
||||
->setLabel('Blogs')
|
||||
->setControlID('post-blogs')
|
||||
->setControlStyle($control_style);
|
||||
|
||||
$post_blogs = $this->getPostBlogs();
|
||||
$user_blogs = $this->getUserBlogs();
|
||||
$all_blogs = $post_blogs + $user_blogs;
|
||||
$all_blogs = msort($all_blogs, 'getName');
|
||||
foreach ($all_blogs as $phid => $blog) {
|
||||
$control->addCheckbox(
|
||||
'blogs[]',
|
||||
$blog->getPHID(),
|
||||
$blog->getName(),
|
||||
isset($post_blogs[$phid])
|
||||
);
|
||||
}
|
||||
|
||||
return $control;
|
||||
}
|
||||
|
||||
private function loadEdgesAndBlogs() {
|
||||
$edge_types = array(PhabricatorEdgeConfig::TYPE_BLOGGER_HAS_BLOG);
|
||||
$blogger_phid = $this->getRequest()->getUser()->getPHID();
|
||||
$phids = array($blogger_phid);
|
||||
if ($this->isPostEdit()) {
|
||||
$edge_types[] = PhabricatorEdgeConfig::TYPE_POST_HAS_BLOG;
|
||||
$phids[] = $this->getPostPHID();
|
||||
}
|
||||
|
||||
$edges = id(new PhabricatorEdgeQuery())
|
||||
->withSourcePHIDs($phids)
|
||||
->withEdgeTypes($edge_types)
|
||||
->execute();
|
||||
|
||||
$all_blogs_assoc = array();
|
||||
foreach ($phids as $phid) {
|
||||
foreach ($edge_types as $type) {
|
||||
$all_blogs_assoc += $edges[$phid][$type];
|
||||
}
|
||||
}
|
||||
|
||||
$blogs = id(new PhameBlogQuery())
|
||||
->setViewer($this->getRequest()->getUser())
|
||||
->withPHIDs(array_keys($all_blogs_assoc))
|
||||
->execute();
|
||||
$blogs = mpull($blogs, null, 'getPHID');
|
||||
|
||||
$user_blogs = array_intersect_key(
|
||||
$blogs,
|
||||
$edges[$blogger_phid][PhabricatorEdgeConfig::TYPE_BLOGGER_HAS_BLOG]
|
||||
);
|
||||
|
||||
if ($this->isPostEdit()) {
|
||||
$post_blogs = array_intersect_key(
|
||||
$blogs,
|
||||
$edges[$this->getPostPHID()][PhabricatorEdgeConfig::TYPE_POST_HAS_BLOG]
|
||||
);
|
||||
} else {
|
||||
$post_blogs = array();
|
||||
}
|
||||
|
||||
$this->setUserBlogs($user_blogs);
|
||||
$this->setPostBlogs($post_blogs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -155,14 +155,8 @@ final class PhamePostViewController extends PhameController {
|
|||
$actions[] = 'edit';
|
||||
}
|
||||
|
||||
$blog = PhameBlog::getRequestBlog();
|
||||
if ($blog) {
|
||||
$skin = $blog->getSkinRenderer();
|
||||
$skin->setBlog($blog);
|
||||
$skin->setIsExternalDomain(true);
|
||||
} else {
|
||||
$skin = new PhabricatorBlogSkin();
|
||||
}
|
||||
|
||||
$skin
|
||||
->setUser($user)
|
||||
->setRequestURI($request->getRequestURI())
|
||||
|
|
|
@ -21,11 +21,17 @@
|
|||
*/
|
||||
final class PhameBlogQuery extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||
|
||||
private $ids;
|
||||
private $phids;
|
||||
private $domain;
|
||||
private $needBloggers;
|
||||
|
||||
public function withPHIDs($phids) {
|
||||
public function withIDs(array $ids) {
|
||||
$this->ids = $ids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withPHIDs(array $phids) {
|
||||
$this->phids = $phids;
|
||||
return $this;
|
||||
}
|
||||
|
@ -35,11 +41,6 @@ final class PhameBlogQuery extends PhabricatorCursorPagedPolicyAwareQuery {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function needBloggers($need_bloggers) {
|
||||
$this->needBloggers = $need_bloggers;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function loadPage() {
|
||||
$table = new PhameBlog();
|
||||
$conn_r = $table->establishConnection('r');
|
||||
|
@ -58,46 +59,19 @@ final class PhameBlogQuery extends PhabricatorCursorPagedPolicyAwareQuery {
|
|||
|
||||
$blogs = $table->loadAllFromArray($data);
|
||||
|
||||
if ($blogs) {
|
||||
if ($this->needBloggers) {
|
||||
$this->loadBloggers($blogs);
|
||||
}
|
||||
}
|
||||
|
||||
return $blogs;
|
||||
}
|
||||
|
||||
private function loadBloggers(array $blogs) {
|
||||
assert_instances_of($blogs, 'PhameBlog');
|
||||
$blog_phids = mpull($blogs, 'getPHID');
|
||||
|
||||
$edge_types = array(PhabricatorEdgeConfig::TYPE_BLOG_HAS_BLOGGER);
|
||||
|
||||
$query = new PhabricatorEdgeQuery();
|
||||
$query->withSourcePHIDs($blog_phids)
|
||||
->withEdgeTypes($edge_types)
|
||||
->execute();
|
||||
|
||||
$all_blogger_phids = $query->getDestinationPHIDs(
|
||||
$blog_phids,
|
||||
$edge_types
|
||||
);
|
||||
|
||||
$handles = id(new PhabricatorObjectHandleData($all_blogger_phids))
|
||||
->loadHandles();
|
||||
|
||||
foreach ($blogs as $blog) {
|
||||
$blogger_phids = $query->getDestinationPHIDs(
|
||||
array($blog->getPHID()),
|
||||
$edge_types
|
||||
);
|
||||
$blog->attachBloggers(array_select_keys($handles, $blogger_phids));
|
||||
}
|
||||
}
|
||||
|
||||
private function buildWhereClause($conn_r) {
|
||||
$where = array();
|
||||
|
||||
if ($this->ids) {
|
||||
$where[] = qsprintf(
|
||||
$conn_r,
|
||||
'id IN (%Ls)',
|
||||
$this->ids);
|
||||
}
|
||||
|
||||
if ($this->phids) {
|
||||
$where[] = qsprintf(
|
||||
$conn_r,
|
||||
|
|
|
@ -186,10 +186,6 @@ final class PhameBlog extends PhameDAO implements PhabricatorPolicyInterface {
|
|||
return $this->getActionURI('posts');
|
||||
}
|
||||
|
||||
public function getViewURI() {
|
||||
return $this->getActionURI('view');
|
||||
}
|
||||
|
||||
public function getEditURI() {
|
||||
return $this->getActionURI('edit');
|
||||
}
|
||||
|
|
|
@ -1,103 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group phame
|
||||
*/
|
||||
final class PhameBlogListView extends AphrontView {
|
||||
|
||||
private $user;
|
||||
private $blogs;
|
||||
private $header;
|
||||
|
||||
public function setHeader($header) {
|
||||
$this->header = $header;
|
||||
return $this;
|
||||
}
|
||||
private function getHeader() {
|
||||
return $this->header;
|
||||
}
|
||||
|
||||
public function setUser(PhabricatorUser $user) {
|
||||
$this->user = $user;
|
||||
return $this;
|
||||
}
|
||||
private function getUser() {
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
public function setBlogs(array $blogs) {
|
||||
assert_instances_of($blogs, 'PhameBlog');
|
||||
$this->blogs = $blogs;
|
||||
return $this;
|
||||
}
|
||||
private function getBlogs() {
|
||||
return $this->blogs;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$user = $this->getUser();
|
||||
$blogs = $this->getBlogs();
|
||||
$panel = new AphrontPanelView();
|
||||
|
||||
if (empty($blogs)) {
|
||||
$panel = id(new AphrontPanelView())
|
||||
->setHeader('No blogs... Yet!')
|
||||
->setCaption('Will you answer the call to phame?')
|
||||
->setCreateButton('New Blog',
|
||||
'/phame/blog/new');
|
||||
return $panel->render();
|
||||
}
|
||||
|
||||
$view = new PhabricatorObjectItemListView();
|
||||
foreach ($blogs as $blog) {
|
||||
$bloggers = $blog->getBloggers();
|
||||
|
||||
$item = id(new PhabricatorObjectItemView())
|
||||
->setHeader($blog->getName())
|
||||
->setHref($blog->getViewURI())
|
||||
->addDetail(
|
||||
'Custom Domain',
|
||||
phutil_escape_html($blog->getDomain()));
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$user,
|
||||
$blog,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
if ($can_edit) {
|
||||
$item->addAttribute(
|
||||
phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'class' => 'button small grey',
|
||||
'href' => $blog->getEditURI(),
|
||||
),
|
||||
'Edit'));
|
||||
}
|
||||
|
||||
$view->addItem($item);
|
||||
}
|
||||
|
||||
$panel->setCreateButton('Create a Blog', '/phame/blog/new/');
|
||||
$panel->setHeader($this->getHeader());
|
||||
$panel->appendChild($view);
|
||||
|
||||
return $panel->render();
|
||||
}
|
||||
}
|
|
@ -516,6 +516,29 @@ final class PhabricatorObjectHandleData {
|
|||
$handles[$phid] = $handle;
|
||||
}
|
||||
break;
|
||||
case PhabricatorPHIDConstants::PHID_TYPE_BLOG:
|
||||
$blogs = id(new PhameBlogQuery())
|
||||
->withPHIDs($phids)
|
||||
->setViewer($this->viewer)
|
||||
->execute();
|
||||
$blogs = mpull($blogs, null, 'getPHID');
|
||||
|
||||
foreach ($phids as $phid) {
|
||||
$handle = new PhabricatorObjectHandle();
|
||||
$handle->setPHID($phid);
|
||||
$handle->setType($type);
|
||||
if (empty($blogs[$phid])) {
|
||||
$handle->setName('Unknown Blog');
|
||||
} else {
|
||||
$blog = $blogs[$phid];
|
||||
$handle->setName($blog->getName());
|
||||
$handle->setFullName($blog->getName());
|
||||
$handle->setURI('/phame/blog/view/'.$blog->getID().'/');
|
||||
$handle->setComplete(true);
|
||||
}
|
||||
$handles[$phid] = $handle;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$loader = null;
|
||||
if (isset($external_loaders[$type])) {
|
||||
|
|
|
@ -748,38 +748,50 @@
|
|||
background-position: 0px -7308px;
|
||||
}
|
||||
|
||||
.remarkup-assist-b {
|
||||
.action-new {
|
||||
background-position: 0px -7325px;
|
||||
}
|
||||
|
||||
.action-world {
|
||||
background-position: 0px -7342px;
|
||||
}
|
||||
|
||||
.action-delete {
|
||||
background-position: 0px -7359px;
|
||||
}
|
||||
|
||||
.remarkup-assist-b {
|
||||
background-position: 0px -7376px;
|
||||
}
|
||||
|
||||
.remarkup-assist-code {
|
||||
background-position: 0px -7340px;
|
||||
background-position: 0px -7391px;
|
||||
}
|
||||
|
||||
.remarkup-assist-i {
|
||||
background-position: 0px -7355px;
|
||||
background-position: 0px -7406px;
|
||||
}
|
||||
|
||||
.remarkup-assist-image {
|
||||
background-position: 0px -7370px;
|
||||
background-position: 0px -7421px;
|
||||
}
|
||||
|
||||
.remarkup-assist-ol {
|
||||
background-position: 0px -7385px;
|
||||
background-position: 0px -7436px;
|
||||
}
|
||||
|
||||
.remarkup-assist-tag {
|
||||
background-position: 0px -7400px;
|
||||
background-position: 0px -7451px;
|
||||
}
|
||||
|
||||
.remarkup-assist-tt {
|
||||
background-position: 0px -7415px;
|
||||
background-position: 0px -7466px;
|
||||
}
|
||||
|
||||
.remarkup-assist-ul {
|
||||
background-position: 0px -7430px;
|
||||
background-position: 0px -7481px;
|
||||
}
|
||||
|
||||
.remarkup-assist-help {
|
||||
background-position: 0px -7445px;
|
||||
background-position: 0px -7496px;
|
||||
}
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 140 KiB After Width: | Height: | Size: 142 KiB |
|
@ -1,23 +0,0 @@
|
|||
/**
|
||||
* @provides javelin-behavior-phame-post-blogs
|
||||
* @requires javelin-behavior
|
||||
* javelin-dom
|
||||
*/
|
||||
|
||||
JX.behavior('phame-post-blogs', function(config) {
|
||||
|
||||
var visibility_select = JX.$(config.visibility.select_id);
|
||||
var blogs_widget = JX.$(config.blogs.checkbox_id);
|
||||
|
||||
var visibilityCallback = function(e) {
|
||||
if (visibility_select.value == config.visibility.published) {
|
||||
JX.DOM.show(blogs_widget);
|
||||
} else {
|
||||
JX.DOM.hide(blogs_widget);
|
||||
}
|
||||
e.kill();
|
||||
}
|
||||
|
||||
JX.DOM.listen(visibility_select, 'change', null, visibilityCallback);
|
||||
|
||||
});
|
Loading…
Reference in a new issue