diff --git a/resources/celerity/map.php b/resources/celerity/map.php --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -79,7 +79,7 @@ 'rsrc/css/application/owners/owners-path-editor.css' => '2f00933b', 'rsrc/css/application/paste/paste.css' => 'aa1767d1', 'rsrc/css/application/people/people-profile.css' => 'ba7b2762', - 'rsrc/css/application/phame/phame.css' => '450826e1', + 'rsrc/css/application/phame/phame.css' => '19ecc703', 'rsrc/css/application/pholio/pholio-edit.css' => 'b9e59b6d', 'rsrc/css/application/pholio/pholio-inline-comments.css' => '52be33f0', 'rsrc/css/application/pholio/pholio.css' => '2fa97dbe', @@ -734,7 +734,7 @@ 'phabricator-uiexample-reactor-sendclass' => 'bf97561d', 'phabricator-uiexample-reactor-sendproperties' => '551add57', 'phabricator-zindex-css' => '0d89d53c', - 'phame-css' => '450826e1', + 'phame-css' => '19ecc703', 'pholio-css' => '2fa97dbe', 'pholio-edit-css' => 'b9e59b6d', 'pholio-inline-comments-css' => '52be33f0', diff --git a/src/applications/phame/controller/PhameController.php b/src/applications/phame/controller/PhameController.php --- a/src/applications/phame/controller/PhameController.php +++ b/src/applications/phame/controller/PhameController.php @@ -1,8 +1,5 @@ <?php -/** - * @group phame - */ abstract class PhameController extends PhabricatorController { protected function renderSideNavFilterView() { @@ -32,7 +29,7 @@ protected function renderPostList( array $posts, - PhabricatorUser $user, + PhabricatorUser $viewer, $nodata) { assert_instances_of($posts, 'PhamePost'); @@ -77,15 +74,33 @@ ->setImage($bloggerImage) ->setImageHref($bloggerURI) ->setAppIcon('phame-dark') - ->setUser($user) + ->setUser($viewer) ->setPontification($phame_post, $phame_title); + if (PhabricatorPolicyFilter::hasCapability( + $viewer, + $post, + PhabricatorPolicyCapability::CAN_EDIT)) { + + $story->addAction(id(new PHUIIconView()) + ->setHref($this->getApplicationURI('post/edit/'.$post->getID().'/')) + ->setText(pht('Edit')) + ->setIconFont('fa-pencil')); + } + if ($post->getDatePublished()) { $story->setEpoch($post->getDatePublished()); } + $stories[] = $story; } + if (empty($stories)) { + return id(new AphrontErrorView()) + ->setSeverity(AphrontErrorView::SEVERITY_NODATA) + ->appendChild($nodata); + } + return $stories; } diff --git a/src/applications/phame/controller/blog/PhameBlogEditController.php b/src/applications/phame/controller/blog/PhameBlogEditController.php --- a/src/applications/phame/controller/blog/PhameBlogEditController.php +++ b/src/applications/phame/controller/blog/PhameBlogEditController.php @@ -1,8 +1,5 @@ <?php -/** - * @group phame - */ final class PhameBlogEditController extends PhameController { @@ -66,19 +63,28 @@ $blog->setDescription($description); $blog->setDomain(nonempty($custom_domain, null)); $blog->setSkin($skin); + $blog->setViewPolicy($request->getStr('can_view')); + $blog->setEditPolicy($request->getStr('can_edit')); + $blog->setJoinPolicy($request->getStr('can_join')); if (!empty($custom_domain)) { - $error = $blog->validateCustomDomain($custom_domain); - if ($error) { - $errors[] = $error; - $e_custom_domain = pht('Invalid'); + list($error_label, $error_text) = + $blog->validateCustomDomain($custom_domain); + if ($error_label) { + $errors[] = $error_text; + $e_custom_domain = $error_label; + } + if ($blog->getJoinPolicy() != PhabricatorPolicies::POLICY_PUBLIC) { + $errors[] = pht( + 'For custom domains to work, the blog must have a view policy of '. + 'public.'); + // Prefer earlier labels for the multiple error scenario. + if (!$e_custom_domain) { + $e_custom_domain = pht('Invalid Policy'); + } } } - $blog->setViewPolicy($request->getStr('can_view')); - $blog->setEditPolicy($request->getStr('can_edit')); - $blog->setJoinPolicy($request->getStr('can_join')); - // Don't let users remove their ability to edit blogs. PhabricatorPolicyFilter::mustRetainCapability( $user, diff --git a/src/applications/phame/storage/PhameBlog.php b/src/applications/phame/storage/PhameBlog.php --- a/src/applications/phame/storage/PhameBlog.php +++ b/src/applications/phame/storage/PhameBlog.php @@ -1,8 +1,5 @@ <?php -/** - * @group phame - */ final class PhameBlog extends PhameDAO implements PhabricatorPolicyInterface, PhabricatorMarkupInterface { @@ -69,38 +66,59 @@ */ public function validateCustomDomain($custom_domain) { $example_domain = 'blog.example.com'; + $label = pht('Invalid'); // note this "uri" should be pretty busted given the desired input // so just use it to test if there's a protocol specified $uri = new PhutilURI($custom_domain); if ($uri->getProtocol()) { - return pht( - 'The custom domain should not include a protocol. Just provide '. - 'the bare domain name (for example, "%s").', - $example_domain); + return array($label, + pht( + 'The custom domain should not include a protocol. Just provide '. + 'the bare domain name (for example, "%s").', + $example_domain)); } if ($uri->getPort()) { - return pht( - 'The custom domain should not include a port number. Just provide '. - 'the bare domain name (for example, "%s").', - $example_domain); + return array($label, + pht( + 'The custom domain should not include a port number. Just provide '. + 'the bare domain name (for example, "%s").', + $example_domain)); } if (strpos($custom_domain, '/') !== false) { - return pht( - 'The custom domain should not specify a path (hosting a Phame '. - 'blog at a path is currently not supported). Instead, just provide '. - 'the bare domain name (for example, "%s").', - $example_domain); + return array($label, + pht( + 'The custom domain should not specify a path (hosting a Phame '. + 'blog at a path is currently not supported). Instead, just provide '. + 'the bare domain name (for example, "%s").', + $example_domain)); } if (strpos($custom_domain, '.') === false) { - return pht( - 'The custom domain should contain at least one dot (.) because '. - 'some browsers fail to set cookies on domains without a dot. Instead, '. - 'use a normal looking domain name like "%s".', - $example_domain); + return array($label, + pht( + 'The custom domain should contain at least one dot (.) because '. + 'some browsers fail to set cookies on domains without a dot. '. + 'Instead, use a normal looking domain name like "%s".', + $example_domain)); + } + + if (!PhabricatorEnv::getEnvConfig('policy.allow-public')) { + $href = PhabricatorEnv::getProductionURI( + '/config/edit/policy.allow-public/'); + return array(pht('Fix Configuration'), + pht( + 'For custom domains to work, this Phabricator instance must be '. + 'configured to allow the public access policy. Configure this '. + 'setting %s, or ask an administrator to configure this setting. '. + 'The domain can be specified later once this setting has been '. + 'changed.', + phutil_tag( + 'a', + array('href' => $href), + pht('here')))); } return null; diff --git a/src/applications/phame/storage/PhamePost.php b/src/applications/phame/storage/PhamePost.php --- a/src/applications/phame/storage/PhamePost.php +++ b/src/applications/phame/storage/PhamePost.php @@ -1,8 +1,5 @@ <?php -/** - * @group phame - */ final class PhamePost extends PhameDAO implements PhabricatorPolicyInterface, @@ -59,6 +56,10 @@ return PhabricatorEnv::getProductionURI($uri); } + public function getEditURI() { + return '/phame/post/edit/'.$this->getID().'/'; + } + public function isDraft() { return $this->getVisibility() == self::VISIBILITY_DRAFT; } diff --git a/src/docs/user/userguide/phame.diviner b/src/docs/user/userguide/phame.diviner --- a/src/docs/user/userguide/phame.diviner +++ b/src/docs/user/userguide/phame.diviner @@ -29,16 +29,22 @@ Each blogger can also edit metadata about the blog and delete the blog outright. -Soon, blogs will be useful for powering external websites, like +NOTE: removing a blogger from a given blog does not remove their posts that +are already associated with the blog. Rather, it removes their ability to edit +metadata about and add posts to the blog. + +Blogs can be useful for powering external websites, like blog.yourcompany.com by making pertinent configuration changes with your DNS authority and -Phabricator instance. +Phabricator instance. For the Phabricator instance, you must -NOTE: removing a blogger from a given blog does not remove their posts that -are already associated with the blog. Rather, it removes their ability to edit -metadata about and add posts to the blog. + - Enable `policy.allow-public` in Phabricator configuration. + - Configure the blog to have the view policy `public`. + +For your DNS authority, simply point the pertinent domain name at your +Phabricator instance. e.g. by IP address. = Comment Widgets = diff --git a/webroot/rsrc/css/application/phame/phame.css b/webroot/rsrc/css/application/phame/phame.css --- a/webroot/rsrc/css/application/phame/phame.css +++ b/webroot/rsrc/css/application/phame/phame.css @@ -25,6 +25,14 @@ max-width: 600px; } +.phame-post-list .aphront-error-view { + margin: 0; +} + +.phame-post-list .phui-icon-view:hover { + text-decoration: none; +} + .blog-post-list { clear: left; float: left;