diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index b4dd3cea66..36ed121834 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1162,10 +1162,14 @@ phutil_register_library_map(array( 'PhamePostDeleteController' => 'applications/phame/controller/post/PhamePostDeleteController.php', 'PhamePostDetailView' => 'applications/phame/view/PhamePostDetailView.php', 'PhamePostEditController' => 'applications/phame/controller/post/PhamePostEditController.php', + 'PhamePostFramedController' => 'applications/phame/controller/post/PhamePostFramedController.php', 'PhamePostListController' => 'applications/phame/controller/post/PhamePostListController.php', 'PhamePostListView' => 'applications/phame/view/PhamePostListView.php', + 'PhamePostNewController' => 'applications/phame/controller/post/PhamePostNewController.php', 'PhamePostPreviewController' => 'applications/phame/controller/post/PhamePostPreviewController.php', + 'PhamePostPublishController' => 'applications/phame/controller/post/PhamePostPublishController.php', 'PhamePostQuery' => 'applications/phame/query/PhamePostQuery.php', + 'PhamePostUnpublishController' => 'applications/phame/controller/post/PhamePostUnpublishController.php', 'PhamePostViewController' => 'applications/phame/controller/post/PhamePostViewController.php', 'PhortuneMonthYearExpiryControl' => 'applications/phortune/control/PhortuneMonthYearExpiryControl.php', 'PhortuneStripeBaseController' => 'applications/phortune/stripe/controller/PhortuneStripeBaseController.php', @@ -2291,10 +2295,14 @@ phutil_register_library_map(array( 'PhamePostDeleteController' => 'PhameController', 'PhamePostDetailView' => 'AphrontView', 'PhamePostEditController' => 'PhameController', + 'PhamePostFramedController' => 'PhameController', 'PhamePostListController' => 'PhameController', 'PhamePostListView' => 'AphrontView', + 'PhamePostNewController' => 'PhameController', 'PhamePostPreviewController' => 'PhameController', + 'PhamePostPublishController' => 'PhameController', 'PhamePostQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', + 'PhamePostUnpublishController' => 'PhameController', 'PhamePostViewController' => 'PhameController', 'PhortuneMonthYearExpiryControl' => 'AphrontFormControl', 'PhortuneStripeBaseController' => 'PhabricatorController', diff --git a/src/applications/phame/application/PhabricatorApplicationPhame.php b/src/applications/phame/application/PhabricatorApplicationPhame.php index b588365c99..072dbd0255 100644 --- a/src/applications/phame/application/PhabricatorApplicationPhame.php +++ b/src/applications/phame/application/PhabricatorApplicationPhame.php @@ -49,11 +49,14 @@ final class PhabricatorApplicationPhame extends PhabricatorApplication { 'post/' => array( '(?:(?Pdraft|all)/)?' => 'PhamePostListController', 'blogger/(?P[\w\.-_]+)/' => 'PhamePostListController', - 'delete/(?P[^/]+)/' => 'PhamePostDeleteController', - 'edit/(?P[^/]+)/' => 'PhamePostEditController', - 'new/' => 'PhamePostEditController', + 'delete/(?P[^/]+)/' => 'PhamePostDeleteController', + 'edit/(?:(?P[^/]+)/)?' => 'PhamePostEditController', + 'view/(?P\d+)/' => 'PhamePostViewController', + 'publish/(?P\d+)/' => 'PhamePostPublishController', + 'unpublish/(?P\d+)/' => 'PhamePostUnpublishController', 'preview/' => 'PhamePostPreviewController', - 'view/(?P[^/]+)/' => 'PhamePostViewController', + 'framed/(?P\d+)/' => 'PhamePostFramedController', + 'new/' => 'PhamePostNewController', ), 'blog/' => array( '(?:(?Puser|all)/)?' => 'PhameBlogListController', diff --git a/src/applications/phame/controller/PhameController.php b/src/applications/phame/controller/PhameController.php index 034b8092c3..1e485e07fe 100644 --- a/src/applications/phame/controller/PhameController.php +++ b/src/applications/phame/controller/PhameController.php @@ -76,7 +76,7 @@ abstract class PhameController extends PhabricatorController { $nav = new AphrontSideNavFilterView(); $nav->setBaseURI($base_uri); $nav->addLabel('Create'); - $nav->addFilter('post/new', 'New Draft'); + $nav->addFilter('post/new', 'New Post'); $nav->addFilter('blog/new', 'New Blog'); $nav->addSpacer(); @@ -164,7 +164,7 @@ abstract class PhameController extends PhabricatorController { foreach ($posts as $post) { $item = id(new PhabricatorObjectItemView()) ->setHeader($post->getTitle()) - ->setHref($this->getApplicationURI('post/view/'.$post->getPHID())) + ->setHref($this->getApplicationURI('post/view/'.$post->getID().'/')) ->addDetail( pht('Blogger'), $this->getHandle($post->getBloggerPHID())->renderLink()) diff --git a/src/applications/phame/controller/blog/PhameBlogDeleteController.php b/src/applications/phame/controller/blog/PhameBlogDeleteController.php index f0f60269b6..2390e11970 100644 --- a/src/applications/phame/controller/blog/PhameBlogDeleteController.php +++ b/src/applications/phame/controller/blog/PhameBlogDeleteController.php @@ -23,20 +23,6 @@ final class PhameBlogDeleteController extends PhameController { private $id; - - protected function getSideNavFilter() { - return 'blog/delete/'.$this->getBlogPHID(); - } - - protected function getSideNavExtraBlogFilters() { - $filters = array( - array('key' => $this->getSideNavFilter(), - 'name' => 'Delete Blog') - ); - - return $filters; - } - public function willProcessRequest(array $data) { $this->id = $data['id']; } @@ -67,11 +53,11 @@ final class PhameBlogDeleteController extends PhameController { $dialog = id(new AphrontDialogView()) ->setUser($user) - ->setTitle(pht('Delete blog?')) + ->setTitle(pht('Delete Blog?')) ->appendChild( pht( 'Really delete the blog "%s"? It will be gone forever.', - $blog->getName())) + phutil_escape_html($blog->getName()))) ->addSubmitButton(pht('Delete')) ->addCancelButton($cancel_uri); diff --git a/src/applications/phame/controller/blog/PhameBlogEditController.php b/src/applications/phame/controller/blog/PhameBlogEditController.php index 754e810fde..7da19afdc3 100644 --- a/src/applications/phame/controller/blog/PhameBlogEditController.php +++ b/src/applications/phame/controller/blog/PhameBlogEditController.php @@ -24,11 +24,6 @@ final class PhameBlogEditController private $id; - protected function getSideNavFilter() { - return 'blog/edit/'.$this->id; - } - - public function willProcessRequest(array $data) { $this->id = idx($data, 'id'); } diff --git a/src/applications/phame/controller/blog/PhameBlogViewController.php b/src/applications/phame/controller/blog/PhameBlogViewController.php index 4bc1b38275..3ab5e528d2 100644 --- a/src/applications/phame/controller/blog/PhameBlogViewController.php +++ b/src/applications/phame/controller/blog/PhameBlogViewController.php @@ -23,19 +23,6 @@ final class PhameBlogViewController extends PhameController { private $id; - protected function getSideNavFilter() { - $filter = 'blog/view/'.$this->getBlogPHID(); - return $filter; - } - - protected function getSideNavExtraBlogFilters() { - $filters = array( - array('key' => $this->getSideNavFilter(), - 'name' => $this->getPhameTitle()) - ); - return $filters; - } - public function willProcessRequest(array $data) { $this->id = $data['id']; } diff --git a/src/applications/phame/controller/post/PhamePostDeleteController.php b/src/applications/phame/controller/post/PhamePostDeleteController.php index 0108756081..c54006750a 100644 --- a/src/applications/phame/controller/post/PhamePostDeleteController.php +++ b/src/applications/phame/controller/post/PhamePostDeleteController.php @@ -19,31 +19,21 @@ /** * @group phame */ -final class PhamePostDeleteController -extends PhameController { +final class PhamePostDeleteController extends PhameController { - private $phid; - - private function setPostPHID($phid) { - $this->phid = $phid; - return $this; - } - private function getPostPHID() { - return $this->phid; - } + private $id; public function willProcessRequest(array $data) { - $phid = $data['phid']; - $this->setPostPHID($phid); + $this->id = $data['id']; } public function processRequest() { - $request = $this->getRequest(); - $user = $request->getUser(); + $request = $this->getRequest(); + $user = $request->getUser(); $post = id(new PhamePostQuery()) ->setViewer($user) - ->withPHIDs(array($this->getPostPHID())) + ->withIDs(array($this->id)) ->requireCapabilities( array( PhabricatorPolicyCapability::CAN_EDIT, @@ -52,37 +42,24 @@ extends PhameController { if (!$post) { return new Aphront404Response(); } - $post_noun = $post->getHumanName(); if ($request->isFormPost()) { - $edge_type = PhabricatorEdgeConfig::TYPE_POST_HAS_BLOG; - $edges = id(new PhabricatorEdgeQuery()) - ->withSourcePHIDs(array($post->getPHID())) - ->withEdgeTypes(array($edge_type)) - ->execute(); - - $blog_edges = $edges[$post->getPHID()][$edge_type]; - $blog_phids = array_keys($blog_edges); - $editor = id(new PhabricatorEdgeEditor()) - ->setActor($user); - foreach ($blog_phids as $phid) { - $editor->removeEdge($post->getPHID(), $edge_type, $phid); - } - $editor->save(); - $post->delete(); return id(new AphrontRedirectResponse()) - ->setURI('/phame/'.$post_noun.'/?deleted'); + ->setURI('/phame/post/'); } - $edit_uri = $post->getEditURI(); - $dialog = id(new AphrontDialogView()) + $cancel_uri = $this->getApplicationURI('/post/view/'.$post->getID().'/'); + + $dialog = id(new AphrontDialogView()) ->setUser($user) - ->setTitle('Delete '.$post_noun.'?') - ->appendChild('Really delete this '.$post_noun.'? '. - 'It will be gone forever.') - ->addSubmitButton('Delete') - ->addCancelButton($edit_uri); + ->setTitle(pht('Delete Post?')) + ->appendChild( + pht( + 'Really delete the post "%s"? It will be gone forever.', + phutil_escape_html($post->getTitle()))) + ->addSubmitButton(pht('Delete')) + ->addCancelButton($cancel_uri); return id(new AphrontDialogResponse())->setDialog($dialog); } diff --git a/src/applications/phame/controller/post/PhamePostEditController.php b/src/applications/phame/controller/post/PhamePostEditController.php index 68e03c6ba7..8903d4a6b6 100644 --- a/src/applications/phame/controller/post/PhamePostEditController.php +++ b/src/applications/phame/controller/post/PhamePostEditController.php @@ -22,102 +22,20 @@ final class PhamePostEditController extends PhameController { - private $phid; - private $isPostEdit; - private $userBlogs; - private $postBlogs; - private $post; - - private function setPost(PhamePost $post) { - $this->post = $post; - return $this; - } - private function getPost() { - return $this->post; - } - - private function setPostPHID($phid) { - $this->phid = $phid; - return $this; - } - private function getPostPHID() { - return $this->phid; - } - private function setIsPostEdit($is_post_edit) { - $this->isPostEdit = $is_post_edit; - return $this; - } - private function isPostEdit() { - return $this->isPostEdit; - } - private function setUserBlogs(array $blogs) { - assert_instances_of($blogs, 'PhameBlog'); - $this->userBlogs = $blogs; - return $this; - } - private function getUserBlogs() { - return $this->userBlogs; - } - private function setPostBlogs(array $blogs) { - assert_instances_of($blogs, 'PhameBlog'); - $this->postBlogs = $blogs; - return $this; - } - private function getPostBlogs() { - return $this->postBlogs; - } - - protected function getSideNavFilter() { - if ($this->isPostEdit()) { - $post_noun = $this->getPost()->getHumanName(); - $filter = $post_noun.'/edit/'.$this->getPostPHID(); - } else { - $filter = 'post/new'; - } - return $filter; - } - protected function getSideNavExtraPostFilters() { - if ($this->isPostEdit() && !$this->getPost()->isDraft()) { - $filters = array( - array('key' => 'post/edit/'.$this->getPostPHID(), - 'name' => 'Edit Post') - ); - } else { - $filters = array(); - } - - return $filters; - } - protected function getSideNavExtraDraftFilters() { - if ($this->isPostEdit() && $this->getPost()->isDraft()) { - $filters = array( - array('key' => 'draft/edit/'.$this->getPostPHID(), - 'name' => 'Edit Draft') - ); - } else { - $filters = array(); - } - - return $filters; - } + private $id; public function willProcessRequest(array $data) { - $phid = idx($data, 'phid'); - $this->setPostPHID($phid); - $this->setIsPostEdit((bool) $phid); + $this->id = idx($data, 'id'); } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); - $e_phame_title = null; - $e_title = null; - $errors = array(); - if ($this->isPostEdit()) { + if ($this->id) { $post = id(new PhamePostQuery()) ->setViewer($user) - ->withPHIDs(array($this->getPostPHID())) + ->withIDs(array($this->id)) ->requireCapabilities( array( PhabricatorPolicyCapability::CAN_EDIT, @@ -127,45 +45,35 @@ final class PhamePostEditController return new Aphront404Response(); } - $post_noun = ucfirst($post->getHumanName()); - $cancel_uri = $post->getViewURI($user->getUsername()); - $submit_button = 'Save Changes'; - $delete_button = javelin_render_tag( - 'a', - array( - 'href' => $post->getDeleteURI(), - 'class' => 'grey button', - 'sigil' => 'workflow', - ), - 'Delete '.$post_noun); - $page_title = 'Edit '.$post_noun; + $cancel_uri = $this->getApplicationURI('/post/view/'.$this->id.'/'); + $submit_button = pht('Save Changes'); + $page_title = pht('Edit Post'); } 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()) + ->setBlog($blog) + ->setDatePublished(0) ->setVisibility(PhamePost::VISIBILITY_DRAFT); $cancel_uri = $this->getApplicationURI('/blog/view/'.$blog->getID().'/'); - $submit_button = pht('Create Draft'); - $delete_button = null; - $page_title = pht('Create Draft'); + $submit_button = pht('Save Draft'); + $page_title = pht('Create Post'); } - $this->setPost($post); + $e_phame_title = null; + $e_title = true; + $errors = array(); if ($request->isFormPost()) { - $saved = true; - $visibility = $request->getInt('visibility'); $comments = $request->getStr('comments_widget'); $data = array('comments_widget' => $comments); $phame_title = $request->getStr('phame_title'); @@ -174,34 +82,26 @@ final class PhamePostEditController $post->setTitle($title); $post->setPhameTitle($phame_title); $post->setBody($request->getStr('body')); - $post->setVisibility($visibility); $post->setConfigData($data); - // only publish once...! - if ($visibility == PhamePost::VISIBILITY_PUBLISHED) { - if (!$post->getDatePublished()) { - $post->setDatePublished(time()); - } - // this is basically a cast of null to 0 if its a new post - } else if (!$post->getDatePublished()) { - $post->setDatePublished(0); - } + if ($phame_title == '/') { $errors[] = 'Phame title must be nonempty.'; $e_phame_title = 'Required'; } - if (empty($title)) { + + if (!strlen($title)) { $errors[] = 'Title must be nonempty.'; $e_title = 'Required'; + } else { + $e_title = null; } if (!$errors) { try { $post->save(); - $uri = new PhutilURI($post->getViewURI($user->getUsername())); - $uri->setQueryParam('saved', true); - return id(new AphrontRedirectResponse()) - ->setURI($uri); + $uri = $this->getApplicationURI('/post/view/'.$post->getID().'/'); + return id(new AphrontRedirectResponse())->setURI($uri); } catch (AphrontQueryDuplicateKeyException $e) { $e_phame_title = 'Not Unique'; $errors[] = 'Another post already uses this slug. '. @@ -210,19 +110,14 @@ final class PhamePostEditController } } - $panel = new AphrontPanelView(); - $panel->setHeader($page_title); - $panel->setWidth(AphrontPanelView::WIDTH_FULL); - if ($delete_button) { - $panel->addButton($delete_button); - } - $handle = PhabricatorObjectHandleData::loadOneHandle( $post->getBlogPHID(), $user); $form = id(new AphrontFormView()) ->setUser($user) + ->setFlexible(true) + ->addHiddenInput('blog', $request->getInt('blog')) ->appendChild( id(new AphrontFormMarkupControl()) ->setLabel('Blog') @@ -254,14 +149,6 @@ final class PhamePostEditController ->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL) ->setID('post-body') ) - ->appendChild( - id(new AphrontFormSelectControl()) - ->setLabel('Visibility') - ->setName('visibility') - ->setValue($post->getVisibility()) - ->setOptions(PhamePost::getVisibilityOptionsForSelect()) - ->setID('post-visibility') - ) ->appendChild( id(new AphrontFormSelectControl()) ->setLabel('Comments Widget') @@ -275,10 +162,8 @@ final class PhamePostEditController ->setValue($submit_button) ); - $panel->appendChild($form); - $preview_panel = - '
+ '
Post Preview
@@ -300,6 +185,8 @@ final class PhamePostEditController 'uri' => '/phame/post/preview/', )); + $header = id(new PhabricatorHeaderView())->setHeader($page_title); + if ($errors) { $error_view = id(new AphrontErrorView()) ->setTitle('Errors saving post.') @@ -308,15 +195,20 @@ final class PhamePostEditController $error_view = null; } - $this->setShowSideNav(true); - return $this->buildStandardPageResponse( + $nav = $this->renderSideNavFilterView(null); + $nav->appendChild( array( + $header, $error_view, - $panel, + $form, $preview_panel, - ), + )); + + return $this->buildApplicationPage( + $nav, array( 'title' => $page_title, + 'device' => true, )); } diff --git a/src/applications/phame/controller/post/PhamePostFramedController.php b/src/applications/phame/controller/post/PhamePostFramedController.php new file mode 100644 index 0000000000..505069b5b4 --- /dev/null +++ b/src/applications/phame/controller/post/PhamePostFramedController.php @@ -0,0 +1,71 @@ +id = $data['id']; + } + + public function processRequest() { + $request = $this->getRequest(); + $user = $request->getUser(); + + $post = id(new PhamePostQuery()) + ->setViewer($user) + ->withIDs(array($this->id)) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->executeOne(); + if (!$post) { + return new Aphront404Response(); + } + + $skin = $post->getBlog()->getSkinRenderer(); + + $handles = $this->loadViewerHandles( + array( + $post->getBloggerPHID(), + )); + + $skin + ->setUser($user) + ->setBlog($post->getBlog()) + ->setPosts(array($post)) + ->setBloggers($handles) + ->setRequestURI($this->getRequest()->getRequestURI()); + + $page = $this->buildStandardPageView(); + $page->setFrameable(true); + $page->setShowChrome(false); + $page->appendChild($skin); + + $response = new AphrontWebpageResponse(); + $response->setFrameable(true); + $response->setContent($page->render()); + return $response; + + } +} diff --git a/src/applications/phame/controller/post/PhamePostNewController.php b/src/applications/phame/controller/post/PhamePostNewController.php new file mode 100644 index 0000000000..f181cc4654 --- /dev/null +++ b/src/applications/phame/controller/post/PhamePostNewController.php @@ -0,0 +1,70 @@ +getRequest(); + $user = $request->getUser(); + + $blogs = id(new PhameBlogQuery()) + ->setViewer($user) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_JOIN, + )) + ->execute(); + + $nav = $this->renderSideNavFilterView(null); + $nav->appendChild( + id(new PhabricatorHeaderView())->setHeader( + pht('Create Post'))); + + if (!$blogs) { + + } else { + $options = mpull($blogs, 'getName', 'getID'); + + $form = id(new AphrontFormView()) + ->setUser($user) + ->setMethod('GET') + ->setFlexible(true) + ->setAction($this->getApplicationURI('post/edit/')) + ->appendChild( + id(new AphrontFormSelectControl()) + ->setLabel('Blog') + ->setName('blog') + ->setOptions($options)) + ->appendChild( + id(new AphrontFormSubmitControl()) + ->setValue('Continue')); + + $nav->appendChild($form); + } + + return $this->buildApplicationPage( + $nav, + array( + 'title' => 'Create Post', + 'device' => true, + )); + } +} diff --git a/src/applications/phame/controller/post/PhamePostPublishController.php b/src/applications/phame/controller/post/PhamePostPublishController.php new file mode 100644 index 0000000000..05e8329615 --- /dev/null +++ b/src/applications/phame/controller/post/PhamePostPublishController.php @@ -0,0 +1,103 @@ +id = $data['id']; + } + + public function processRequest() { + $request = $this->getRequest(); + $user = $request->getUser(); + + $post = id(new PhamePostQuery()) + ->setViewer($user) + ->withIDs(array($this->id)) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->executeOne(); + if (!$post) { + return new Aphront404Response(); + } + + $view_uri = $this->getApplicationURI('/post/view/'.$post->getID().'/'); + + if ($request->isFormPost()) { + $post->setVisibility(PhamePost::VISIBILITY_PUBLISHED); + $post->setDatePublished(time()); + $post->save(); + + return id(new AphrontRedirectResponse())->setURI($view_uri); + } + + $header = id(new PhabricatorHeaderView()) + ->setHeader('Preview Post'); + + $form = id(new AphrontFormView()) + ->setUser($user) + ->setFlexible(true) + ->appendChild( + id(new AphrontFormSubmitControl()) + ->setValue(pht('Publish Post')) + ->addCancelButton($view_uri)); + + $frame = $this->renderPreviewFrame($post); + + $nav = $this->renderSideNavFilterView(null); + $nav->appendChild( + array( + $header, + $form, + $frame, + )); + + return $this->buildApplicationPage( + $nav, + array( + 'title' => pht('Preview Post'), + 'device' => true, + )); + } + + private function renderPreviewFrame(PhamePost $post) { + + // TODO: Clean up this CSS. + + return phutil_render_tag( + 'div', + array( + 'style' => 'text-align: center; padding: 1em;', + ), + phutil_render_tag( + 'iframe', + array( + 'style' => 'width: 100%; height: 600px; '. + 'border: 1px solid #303030; background: #303030;', + 'src' => $this->getApplicationURI('/post/framed/'.$post->getID().'/'), + ), + '')); + } +} diff --git a/src/applications/phame/controller/post/PhamePostUnpublishController.php b/src/applications/phame/controller/post/PhamePostUnpublishController.php new file mode 100644 index 0000000000..b9dfb5906e --- /dev/null +++ b/src/applications/phame/controller/post/PhamePostUnpublishController.php @@ -0,0 +1,70 @@ +id = $data['id']; + } + + public function processRequest() { + $request = $this->getRequest(); + $user = $request->getUser(); + + $post = id(new PhamePostQuery()) + ->setViewer($user) + ->withIDs(array($this->id)) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->executeOne(); + if (!$post) { + return new Aphront404Response(); + } + + if ($request->isFormPost()) { + $post->setVisibility(PhamePost::VISIBILITY_DRAFT); + $post->setDatePublished(0); + $post->save(); + + return id(new AphrontRedirectResponse()) + ->setURI($this->getApplicationURI('/post/view/'.$post->getID().'/')); + } + + $cancel_uri = $this->getApplicationURI('/post/view/'.$post->getID().'/'); + + $dialog = id(new AphrontDialogView()) + ->setUser($user) + ->setTitle(pht('Unpublish Post?')) + ->appendChild( + pht( + 'The post "%s" will no longer be visible to other users until you '. + 'republish it.', + phutil_escape_html($post->getTitle()))) + ->addSubmitButton(pht('Unpublish')) + ->addCancelButton($cancel_uri); + + return id(new AphrontDialogResponse())->setDialog($dialog); + } +} diff --git a/src/applications/phame/controller/post/PhamePostViewController.php b/src/applications/phame/controller/post/PhamePostViewController.php index 02c17a8f71..d0a2747a0f 100644 --- a/src/applications/phame/controller/post/PhamePostViewController.php +++ b/src/applications/phame/controller/post/PhamePostViewController.php @@ -21,111 +21,25 @@ */ final class PhamePostViewController extends PhameController { - private $postPHID; - private $phameTitle; - private $bloggerName; - - private function setPostPHID($post_phid) { - $this->postPHID = $post_phid; - return $this; - } - private function getPostPHID() { - return $this->postPHID; - } - private function setPhameTitle($phame_title) { - $this->phameTitle = $phame_title; - return $this; - } - private function getPhameTitle() { - return $this->phameTitle; - } - private function setBloggerName($blogger_name) { - $this->bloggerName = $blogger_name; - return $this; - } - private function getBloggerName() { - return $this->bloggerName; - } - - protected function getSideNavFilter() { - $filter = 'post/view/'.$this->getPostPHID(); - return $filter; - } - protected function getSideNavExtraPostFilters() { - $filters = array( - array('key' => $this->getSideNavFilter(), - 'name' => $this->getPhameTitle()) - ); - return $filters; - } - - public function shouldRequireLogin() { - // TODO -- get policy logic going - // return PhabricatorEnv::getEnvConfig('policy.allow-public'); - return true; - } + private $id; public function willProcessRequest(array $data) { - $this->setPostPHID(idx($data, 'phid')); - $this->setPhameTitle(idx($data, 'phametitle')); - $this->setBloggerName(idx($data, 'bloggername')); + $this->id = $data['id']; } public function processRequest() { - $request = $this->getRequest(); - $user = $request->getUser(); + $request = $this->getRequest(); + $user = $request->getUser(); - if ($this->getPostPHID()) { - $post = id(new PhamePostQuery()) - ->setViewer($user) - ->withPHIDs(array($this->getPostPHID())) - ->executeOne(); - - if (!$post) { - return new Aphront404Response(); - } - - $this->setPhameTitle($post->getPhameTitle()); - $blogger = PhabricatorObjectHandleData::loadOneHandle( - $post->getBloggerPHID(), - $user); - } else if ($this->getBloggerName() && $this->getPhameTitle()) { - $phame_title = $this->getPhameTitle(); - $phame_title = PhabricatorSlug::normalize($phame_title); - $blogger_user = id(new PhabricatorUser())->loadOneWhere( - 'username = %s', - $this->getBloggerName()); - if (!$blogger_user) { - return new Aphront404Response(); - } - $blogger = PhabricatorObjectHandleData::loadOneHandle( - $blogger_user->getPHID(), - $user); - if (!$blogger) { - return new Aphront404Response(); - } - $posts = id(new PhamePostQuery()) - ->setViewer($user) - ->withBloggerPHIDs(array($blogger->getPHID())) - ->withPhameTitles(array($phame_title)) - ->execute(); - $post = reset($posts); - - if ($post && $phame_title != $this->getPhameTitle()) { - $uri = $post->getViewURI($this->getBloggerName()); - return id(new AphrontRedirectResponse())->setURI($uri); - } - } + $post = id(new PhamePostQuery()) + ->setViewer($user) + ->withIDs(array($this->id)) + ->executeOne(); if (!$post) { return new Aphront404Response(); } - if ($post->isDraft() && - $post->getBloggerPHID() != $user->getPHID()) { - return new Aphront404Response(); - } - if ($post->isDraft()) { $notice = array( 'title' => 'You are previewing a draft.', @@ -150,32 +64,123 @@ final class PhamePostViewController extends PhameController { $notice = array(); } - $actions = array('more'); - if ($post->getBloggerPHID() == $user->getPHID()) { - $actions[] = 'edit'; - } - - $skin = new PhabricatorBlogSkin(); - - $skin - ->setUser($user) - ->setRequestURI($request->getRequestURI()) - ->setBloggers(array($blogger->getPHID() => $blogger)) - ->setPosts(array($post)) - ->setNotice($notice) - ->setShowPostComments(true) - ->setActions($actions); - - $this->setShowSideNav(false); - $this->setShowChrome($skin->getShowChrome()); - $this->setDeviceReady($skin->getDeviceReady()); - - return $this->buildStandardPageResponse( + $this->loadHandles( array( - $skin - ), + $post->getBlogPHID(), + $post->getBloggerPHID(), + )); + + $nav = $this->renderSideNavFilterView(null); + + $header = id(new PhabricatorHeaderView())->setHeader($post->getTitle()); + + $actions = $this->renderActions($post, $user); + $properties = $this->renderProperties($post, $user); + + $nav->appendChild( + array( + $header, + $actions, + $properties, + )); + + return $this->buildApplicationPage( + $nav, array( 'title' => $post->getTitle(), + 'device' => true, )); } + + private function renderActions( + PhamePost $post, + PhabricatorUser $user) { + + $actions = id(new PhabricatorActionListView()) + ->setObject($post) + ->setUser($user); + + $can_edit = PhabricatorPolicyFilter::hasCapability( + $user, + $post, + PhabricatorPolicyCapability::CAN_EDIT); + + $id = $post->getID(); + + $actions->addAction( + id(new PhabricatorActionView()) + ->setIcon('edit') + ->setHref($this->getApplicationURI('post/edit/'.$id.'/')) + ->setName('Edit Post') + ->setDisabled(!$can_edit) + ->setWorkflow(!$can_edit)); + + $can_view_live = $post->getBlog() && !$post->isDraft(); + + $actions->addAction( + id(new PhabricatorActionView()) + ->setIcon('world') + ->setHref($this->getApplicationURI('post/live/'.$id.'/')) + ->setName(pht('View Live')) + ->setDisabled(!$can_view_live) + ->setWorkflow(true)); + + if ($post->isDraft()) { + $actions->addAction( + id(new PhabricatorActionView()) + ->setIcon('world') + ->setHref($this->getApplicationURI('post/publish/'.$id.'/')) + ->setName(pht('Preview / Publish'))); + } else { + $actions->addAction( + id(new PhabricatorActionView()) + ->setIcon('delete') + ->setHref($this->getApplicationURI('post/unpublish/'.$id.'/')) + ->setName(pht('Unpublish')) + ->setWorkflow(true)); + } + + $actions->addAction( + id(new PhabricatorActionView()) + ->setIcon('delete') + ->setHref($this->getApplicationURI('post/delete/'.$id.'/')) + ->setName('Delete Post') + ->setDisabled(!$can_edit) + ->setWorkflow(true)); + + return $actions; + } + + private function renderProperties( + PhamePost $post, + PhabricatorUser $user) { + + $properties = new PhabricatorPropertyListView(); + + $descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions( + $user, + $post); + + $properties->addProperty( + pht('Blog'), + $post->getBlogPHID() + ? $this->getHandle($post->getBlogPHID())->renderLink() + : null); + + $properties->addProperty( + pht('Blogger'), + $this->getHandle($post->getBloggerPHID())->renderLink()); + + $properties->addProperty( + pht('Visible To'), + $descriptions[PhabricatorPolicyCapability::CAN_VIEW]); + + $properties->addProperty( + pht('Published'), + $post->isDraft() + ? pht('Draft') + : phabricator_datetime($post->getDatePublished(), $user)); + + return $properties; + } } diff --git a/src/applications/phame/query/PhamePostQuery.php b/src/applications/phame/query/PhamePostQuery.php index 85e6676e1a..045c3eaa58 100644 --- a/src/applications/phame/query/PhamePostQuery.php +++ b/src/applications/phame/query/PhamePostQuery.php @@ -21,12 +21,18 @@ */ final class PhamePostQuery extends PhabricatorCursorPagedPolicyAwareQuery { + private $ids; private $blogPHIDs; private $bloggerPHIDs; private $phameTitles; private $visibility; private $phids; + public function withIDs(array $ids) { + $this->ids = $ids; + return $this; + } + public function withPHIDs(array $phids) { $this->phids = $phids; return $this; @@ -91,6 +97,13 @@ final class PhamePostQuery extends PhabricatorCursorPagedPolicyAwareQuery { private function buildWhereClause(AphrontDatabaseConnection $conn_r) { $where = array(); + if ($this->ids) { + $where[] = qsprintf( + $conn_r, + 'p.id IN (%Ld)', + $this->ids); + } + if ($this->phids) { $where[] = qsprintf( $conn_r,