mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-18 04:42:40 +01:00
Remove skins from Phame
Summary: Ref T9897. Purge a bunch of stuff: - Remove skins. - Remove all custom sites for skin resources. - Remove "framed", "notlive", "preview", separate "live" controllers (see below). - Merge "publish" and "unpublish" controllers into one. New behavior: - Blogs and posts have three views: - "View": Internal view URI, which is a normal detail page. - "Internal Live": Internal view URI which is a little prettier. - "External Live": External view URI for an external domain. Right now, the differences are pretty minor (basically, different crumbs/chrome). This mostly gives us room to put some milder flavor of skins back later (photography or more "presentation" elements, for example). This removes 9 million lines of code so I probably missed a couple of things, but I think it's like 95% of the way there. Test Plan: Here are some examples of what the "view", "internal" and "external" views look like for blogs (posts are similar): "View": Unchanged {F1021634} "Internal": No chrome or footer. Still write actions (edit, post commments). Has crumbs to get back into Phame. {F1021635} "External": No chrome or footer. No write actions. No Phabricator crumbs. No policy/status information. {F1021638} I figure we'll probably tweak these a bit to figure out what makes sense (like: maybe no actions on "internal, live"? and "external, live" probably needs a way to set a root "Company >" crumb?) but that they're reasonable-ish as a first cut? Reviewers: chad Reviewed By: chad Maniphest Tasks: T9897 Differential Revision: https://secure.phabricator.com/D14740
This commit is contained in:
parent
c62e0a10f6
commit
8a906b0e18
35 changed files with 450 additions and 1731 deletions
1
externals/skins/oblivious/404.php
vendored
1
externals/skins/oblivious/404.php
vendored
|
@ -1 +0,0 @@
|
|||
<h2>404 Not Found</h2>
|
76
externals/skins/oblivious/css/oblivious.css
vendored
76
externals/skins/oblivious/css/oblivious.css
vendored
|
@ -1,76 +0,0 @@
|
|||
html, body, p, h1, h2, h3 {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: "Helvetica Neue", "Arial", sans-serif;
|
||||
font-size: 16px;
|
||||
overflow-y: scroll;
|
||||
color: #555555;
|
||||
}
|
||||
|
||||
.oblivious-info {
|
||||
position: fixed;
|
||||
width: 15%;
|
||||
border-right: 1px solid #dfdfdf;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
padding: 140px 2% 0;
|
||||
overflow: hidden;
|
||||
|
||||
background: url(/image/badge.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 20px 20px;
|
||||
}
|
||||
|
||||
.oblivious-content {
|
||||
padding-top: 3%;
|
||||
margin-left: 22%;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #2980b9;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 24px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.phame-post {
|
||||
margin: 0 0 2em;
|
||||
}
|
||||
|
||||
.phame-post-title {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.phame-post-date {
|
||||
font-size: 12px;
|
||||
margin: .25em 0 2em;
|
||||
}
|
||||
|
||||
.oblivious-content .phabricator-remarkup ul.remarkup-list {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.fb-comments,
|
||||
.fb-comments span,
|
||||
.fb-comments iframe[style] {
|
||||
width: 100% !important;
|
||||
}
|
3
externals/skins/oblivious/footer.php
vendored
3
externals/skins/oblivious/footer.php
vendored
|
@ -1,3 +0,0 @@
|
|||
</div>
|
||||
</body>
|
||||
</html>
|
18
externals/skins/oblivious/header.php
vendored
18
externals/skins/oblivious/header.php
vendored
|
@ -1,18 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title><?php echo _e($title); ?></title>
|
||||
|
||||
<?php echo $skin->getCSSResources(); ?>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="oblivious-info">
|
||||
<h1>
|
||||
<a href="<?php echo _e($home_uri); ?>"><?php
|
||||
echo _e($blog->getName());
|
||||
?></a>
|
||||
</h1>
|
||||
<p><?php echo $skin->remarkup($blog->getDescription()); ?></p>
|
||||
</div>
|
||||
<div class="oblivious-content">
|
BIN
externals/skins/oblivious/image/badge.png
vendored
BIN
externals/skins/oblivious/image/badge.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 1.8 KiB |
1
externals/skins/oblivious/post-detail.php
vendored
1
externals/skins/oblivious/post-detail.php
vendored
|
@ -1 +0,0 @@
|
|||
<?php echo $post->render(); ?>
|
13
externals/skins/oblivious/post-list.php
vendored
13
externals/skins/oblivious/post-list.php
vendored
|
@ -1,13 +0,0 @@
|
|||
<div class="oblivious-post-list">
|
||||
<?php
|
||||
|
||||
foreach ($posts as $post) {
|
||||
echo $post->renderWithSummary();
|
||||
}
|
||||
|
||||
?>
|
||||
</div>
|
||||
<div class="oblivious-pager">
|
||||
<?php echo $older; ?>
|
||||
<?php echo $newer; ?>
|
||||
</div>
|
3
externals/skins/oblivious/skin.json
vendored
3
externals/skins/oblivious/skin.json
vendored
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"name": "Oblivious"
|
||||
}
|
|
@ -2928,7 +2928,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorRepositoryVCSPassword' => 'applications/repository/storage/PhabricatorRepositoryVCSPassword.php',
|
||||
'PhabricatorRepositoryVersion' => 'applications/repository/constants/PhabricatorRepositoryVersion.php',
|
||||
'PhabricatorRequestExceptionHandler' => 'aphront/handler/PhabricatorRequestExceptionHandler.php',
|
||||
'PhabricatorResourceSite' => 'aphront/site/PhabricatorResourceSite.php',
|
||||
'PhabricatorRobotsController' => 'applications/system/controller/PhabricatorRobotsController.php',
|
||||
'PhabricatorS3FileStorageEngine' => 'applications/files/engine/PhabricatorS3FileStorageEngine.php',
|
||||
'PhabricatorSMS' => 'infrastructure/sms/storage/PhabricatorSMS.php',
|
||||
|
@ -3308,8 +3307,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorXHProfSample' => 'applications/xhprof/storage/PhabricatorXHProfSample.php',
|
||||
'PhabricatorXHProfSampleListController' => 'applications/xhprof/controller/PhabricatorXHProfSampleListController.php',
|
||||
'PhabricatorYoutubeRemarkupRule' => 'infrastructure/markup/rule/PhabricatorYoutubeRemarkupRule.php',
|
||||
'PhameBasicBlogSkin' => 'applications/phame/skins/PhameBasicBlogSkin.php',
|
||||
'PhameBasicTemplateBlogSkin' => 'applications/phame/skins/PhameBasicTemplateBlogSkin.php',
|
||||
'PhameBlog' => 'applications/phame/storage/PhameBlog.php',
|
||||
'PhameBlogArchiveController' => 'applications/phame/controller/blog/PhameBlogArchiveController.php',
|
||||
'PhameBlogController' => 'applications/phame/controller/blog/PhameBlogController.php',
|
||||
|
@ -3318,18 +3315,15 @@ phutil_register_library_map(array(
|
|||
'PhameBlogEditor' => 'applications/phame/editor/PhameBlogEditor.php',
|
||||
'PhameBlogFeedController' => 'applications/phame/controller/blog/PhameBlogFeedController.php',
|
||||
'PhameBlogListController' => 'applications/phame/controller/blog/PhameBlogListController.php',
|
||||
'PhameBlogLiveController' => 'applications/phame/controller/blog/PhameBlogLiveController.php',
|
||||
'PhameBlogManageController' => 'applications/phame/controller/blog/PhameBlogManageController.php',
|
||||
'PhameBlogProfilePictureController' => 'applications/phame/controller/blog/PhameBlogProfilePictureController.php',
|
||||
'PhameBlogQuery' => 'applications/phame/query/PhameBlogQuery.php',
|
||||
'PhameBlogReplyHandler' => 'applications/phame/mail/PhameBlogReplyHandler.php',
|
||||
'PhameBlogSearchEngine' => 'applications/phame/query/PhameBlogSearchEngine.php',
|
||||
'PhameBlogSite' => 'applications/phame/site/PhameBlogSite.php',
|
||||
'PhameBlogSkin' => 'applications/phame/skins/PhameBlogSkin.php',
|
||||
'PhameBlogTransaction' => 'applications/phame/storage/PhameBlogTransaction.php',
|
||||
'PhameBlogTransactionQuery' => 'applications/phame/query/PhameBlogTransactionQuery.php',
|
||||
'PhameBlogViewController' => 'applications/phame/controller/blog/PhameBlogViewController.php',
|
||||
'PhameCelerityResources' => 'applications/phame/celerity/PhameCelerityResources.php',
|
||||
'PhameConduitAPIMethod' => 'applications/phame/conduit/PhameConduitAPIMethod.php',
|
||||
'PhameConstants' => 'applications/phame/constants/PhameConstants.php',
|
||||
'PhameController' => 'applications/phame/controller/PhameController.php',
|
||||
|
@ -3337,20 +3331,18 @@ phutil_register_library_map(array(
|
|||
'PhameDAO' => 'applications/phame/storage/PhameDAO.php',
|
||||
'PhameDescriptionView' => 'applications/phame/view/PhameDescriptionView.php',
|
||||
'PhameHomeController' => 'applications/phame/controller/PhameHomeController.php',
|
||||
'PhameLiveController' => 'applications/phame/controller/PhameLiveController.php',
|
||||
'PhamePost' => 'applications/phame/storage/PhamePost.php',
|
||||
'PhamePostCommentController' => 'applications/phame/controller/post/PhamePostCommentController.php',
|
||||
'PhamePostController' => 'applications/phame/controller/post/PhamePostController.php',
|
||||
'PhamePostEditController' => 'applications/phame/controller/post/PhamePostEditController.php',
|
||||
'PhamePostEditor' => 'applications/phame/editor/PhamePostEditor.php',
|
||||
'PhamePostFramedController' => 'applications/phame/controller/post/PhamePostFramedController.php',
|
||||
'PhamePostHistoryController' => 'applications/phame/controller/post/PhamePostHistoryController.php',
|
||||
'PhamePostListController' => 'applications/phame/controller/post/PhamePostListController.php',
|
||||
'PhamePostListView' => 'applications/phame/view/PhamePostListView.php',
|
||||
'PhamePostMailReceiver' => 'applications/phame/mail/PhamePostMailReceiver.php',
|
||||
'PhamePostMoveController' => 'applications/phame/controller/post/PhamePostMoveController.php',
|
||||
'PhamePostNewController' => 'applications/phame/controller/post/PhamePostNewController.php',
|
||||
'PhamePostNotLiveController' => 'applications/phame/controller/post/PhamePostNotLiveController.php',
|
||||
'PhamePostPreviewController' => 'applications/phame/controller/post/PhamePostPreviewController.php',
|
||||
'PhamePostPublishController' => 'applications/phame/controller/post/PhamePostPublishController.php',
|
||||
'PhamePostQuery' => 'applications/phame/query/PhamePostQuery.php',
|
||||
'PhamePostReplyHandler' => 'applications/phame/mail/PhamePostReplyHandler.php',
|
||||
|
@ -3358,15 +3350,11 @@ phutil_register_library_map(array(
|
|||
'PhamePostTransaction' => 'applications/phame/storage/PhamePostTransaction.php',
|
||||
'PhamePostTransactionComment' => 'applications/phame/storage/PhamePostTransactionComment.php',
|
||||
'PhamePostTransactionQuery' => 'applications/phame/query/PhamePostTransactionQuery.php',
|
||||
'PhamePostUnpublishController' => 'applications/phame/controller/post/PhamePostUnpublishController.php',
|
||||
'PhamePostView' => 'applications/phame/view/PhamePostView.php',
|
||||
'PhamePostViewController' => 'applications/phame/controller/post/PhamePostViewController.php',
|
||||
'PhameQueryConduitAPIMethod' => 'applications/phame/conduit/PhameQueryConduitAPIMethod.php',
|
||||
'PhameQueryPostsConduitAPIMethod' => 'applications/phame/conduit/PhameQueryPostsConduitAPIMethod.php',
|
||||
'PhameResourceController' => 'applications/phame/controller/PhameResourceController.php',
|
||||
'PhameSchemaSpec' => 'applications/phame/storage/PhameSchemaSpec.php',
|
||||
'PhameSite' => 'applications/phame/site/PhameSite.php',
|
||||
'PhameSkinSpecification' => 'applications/phame/skins/PhameSkinSpecification.php',
|
||||
'PhluxController' => 'applications/phlux/controller/PhluxController.php',
|
||||
'PhluxDAO' => 'applications/phlux/storage/PhluxDAO.php',
|
||||
'PhluxEditController' => 'applications/phlux/controller/PhluxEditController.php',
|
||||
|
@ -7222,7 +7210,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorRepositoryVCSPassword' => 'PhabricatorRepositoryDAO',
|
||||
'PhabricatorRepositoryVersion' => 'Phobject',
|
||||
'PhabricatorRequestExceptionHandler' => 'AphrontRequestExceptionHandler',
|
||||
'PhabricatorResourceSite' => 'PhabricatorSite',
|
||||
'PhabricatorRobotsController' => 'PhabricatorController',
|
||||
'PhabricatorS3FileStorageEngine' => 'PhabricatorFileStorageEngine',
|
||||
'PhabricatorSMS' => 'PhabricatorSMSDAO',
|
||||
|
@ -7650,8 +7637,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorXHProfSample' => 'PhabricatorXHProfDAO',
|
||||
'PhabricatorXHProfSampleListController' => 'PhabricatorXHProfController',
|
||||
'PhabricatorYoutubeRemarkupRule' => 'PhutilRemarkupRule',
|
||||
'PhameBasicBlogSkin' => 'PhameBlogSkin',
|
||||
'PhameBasicTemplateBlogSkin' => 'PhameBasicBlogSkin',
|
||||
'PhameBlog' => array(
|
||||
'PhameDAO',
|
||||
'PhabricatorPolicyInterface',
|
||||
|
@ -7669,18 +7654,15 @@ phutil_register_library_map(array(
|
|||
'PhameBlogEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhameBlogFeedController' => 'PhameBlogController',
|
||||
'PhameBlogListController' => 'PhameBlogController',
|
||||
'PhameBlogLiveController' => 'PhameBlogController',
|
||||
'PhameBlogManageController' => 'PhameBlogController',
|
||||
'PhameBlogProfilePictureController' => 'PhameBlogController',
|
||||
'PhameBlogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhameBlogReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
|
||||
'PhameBlogSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhameBlogSite' => 'PhameSite',
|
||||
'PhameBlogSkin' => 'PhabricatorController',
|
||||
'PhameBlogTransaction' => 'PhabricatorApplicationTransaction',
|
||||
'PhameBlogTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhameBlogViewController' => 'PhameBlogController',
|
||||
'PhameCelerityResources' => 'CelerityResources',
|
||||
'PhameBlogViewController' => 'PhameLiveController',
|
||||
'PhameConduitAPIMethod' => 'ConduitAPIMethod',
|
||||
'PhameConstants' => 'Phobject',
|
||||
'PhameController' => 'PhabricatorController',
|
||||
|
@ -7688,6 +7670,7 @@ phutil_register_library_map(array(
|
|||
'PhameDAO' => 'PhabricatorLiskDAO',
|
||||
'PhameDescriptionView' => 'AphrontTagView',
|
||||
'PhameHomeController' => 'PhamePostController',
|
||||
'PhameLiveController' => 'PhameController',
|
||||
'PhamePost' => array(
|
||||
'PhameDAO',
|
||||
'PhabricatorPolicyInterface',
|
||||
|
@ -7703,15 +7686,12 @@ phutil_register_library_map(array(
|
|||
'PhamePostController' => 'PhameController',
|
||||
'PhamePostEditController' => 'PhamePostController',
|
||||
'PhamePostEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhamePostFramedController' => 'PhamePostController',
|
||||
'PhamePostHistoryController' => 'PhamePostController',
|
||||
'PhamePostListController' => 'PhamePostController',
|
||||
'PhamePostListView' => 'AphrontTagView',
|
||||
'PhamePostMailReceiver' => 'PhabricatorObjectMailReceiver',
|
||||
'PhamePostMoveController' => 'PhamePostController',
|
||||
'PhamePostNewController' => 'PhamePostController',
|
||||
'PhamePostNotLiveController' => 'PhamePostController',
|
||||
'PhamePostPreviewController' => 'PhamePostController',
|
||||
'PhamePostPublishController' => 'PhamePostController',
|
||||
'PhamePostQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhamePostReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
|
||||
|
@ -7719,15 +7699,11 @@ phutil_register_library_map(array(
|
|||
'PhamePostTransaction' => 'PhabricatorApplicationTransaction',
|
||||
'PhamePostTransactionComment' => 'PhabricatorApplicationTransactionComment',
|
||||
'PhamePostTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhamePostUnpublishController' => 'PhamePostController',
|
||||
'PhamePostView' => 'AphrontView',
|
||||
'PhamePostViewController' => 'PhamePostController',
|
||||
'PhamePostViewController' => 'PhameLiveController',
|
||||
'PhameQueryConduitAPIMethod' => 'PhameConduitAPIMethod',
|
||||
'PhameQueryPostsConduitAPIMethod' => 'PhameConduitAPIMethod',
|
||||
'PhameResourceController' => 'CelerityResourceController',
|
||||
'PhameSchemaSpec' => 'PhabricatorConfigSchemaSpec',
|
||||
'PhameSite' => 'PhabricatorSite',
|
||||
'PhameSkinSpecification' => 'Phobject',
|
||||
'PhluxController' => 'PhabricatorController',
|
||||
'PhluxDAO' => 'PhabricatorLiskDAO',
|
||||
'PhluxEditController' => 'PhluxController',
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorResourceSite extends PhabricatorSite {
|
||||
|
||||
public function getDescription() {
|
||||
return pht('Serves static resources like images, CSS and JS.');
|
||||
}
|
||||
|
||||
public function getPriority() {
|
||||
return 2000;
|
||||
}
|
||||
|
||||
public function newSiteForRequest(AphrontRequest $request) {
|
||||
$host = $request->getHost();
|
||||
|
||||
$uri = PhabricatorEnv::getEnvConfig('security.alternate-file-domain');
|
||||
if (!strlen($uri)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->isHostMatch($host, array($uri))) {
|
||||
return new PhabricatorResourceSite();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getRoutingMaps() {
|
||||
$applications = PhabricatorApplication::getAllInstalledApplications();
|
||||
|
||||
$maps = array();
|
||||
foreach ($applications as $application) {
|
||||
$maps[] = $this->newRoutingMap()
|
||||
->setApplication($application)
|
||||
->setRoutes($application->getResourceRoutes());
|
||||
}
|
||||
|
||||
return $maps;
|
||||
}
|
||||
|
||||
}
|
|
@ -39,19 +39,19 @@ final class PhabricatorPhameApplication extends PhabricatorApplication {
|
|||
return array(
|
||||
'/phame/' => array(
|
||||
'' => 'PhameHomeController',
|
||||
'live/(?P<id>[^/]+)/(?P<more>.*)' => 'PhameBlogLiveController',
|
||||
|
||||
// NOTE: The live routes include an initial "/", so leave it off
|
||||
// this route.
|
||||
'(?P<live>live)/(?P<blogID>[^/]+)' => $this->getLiveRoutes(),
|
||||
'post/' => array(
|
||||
'(?:(?P<filter>draft|all)/)?' => 'PhamePostListController',
|
||||
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhamePostListController',
|
||||
'blogger/(?P<bloggername>[\w\.-_]+)/' => 'PhamePostListController',
|
||||
'edit/(?:(?P<id>[^/]+)/)?' => 'PhamePostEditController',
|
||||
'history/(?P<id>\d+)/' => 'PhamePostHistoryController',
|
||||
'view/(?P<id>\d+)/' => 'PhamePostViewController',
|
||||
'view/(?P<id>\d+)/(?P<slug>[^/]+)/' => 'PhamePostViewController',
|
||||
'publish/(?P<id>\d+)/' => 'PhamePostPublishController',
|
||||
'view/(?P<id>\d+)/(?:(?P<slug>[^/]+)/)?' => 'PhamePostViewController',
|
||||
'(?P<action>publish|unpublish)/(?P<id>\d+)/'
|
||||
=> 'PhamePostPublishController',
|
||||
'preview/(?P<id>\d+)/' => 'PhamePostPreviewController',
|
||||
'unpublish/(?P<id>\d+)/' => 'PhamePostUnpublishController',
|
||||
'notlive/(?P<id>\d+)/' => 'PhamePostNotLiveController',
|
||||
'preview/' => 'PhabricatorMarkupPreviewController',
|
||||
'framed/(?P<id>\d+)/' => 'PhamePostFramedController',
|
||||
'new/' => 'PhamePostNewController',
|
||||
|
@ -59,11 +59,10 @@ final class PhabricatorPhameApplication extends PhabricatorApplication {
|
|||
'comment/(?P<id>[1-9]\d*)/' => 'PhamePostCommentController',
|
||||
),
|
||||
'blog/' => array(
|
||||
'(?:(?P<filter>user|all)/)?' => 'PhameBlogListController',
|
||||
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhameBlogListController',
|
||||
'archive/(?P<id>[^/]+)/' => 'PhameBlogArchiveController',
|
||||
'edit/(?P<id>[^/]+)/' => 'PhameBlogEditController',
|
||||
'view/(?P<id>[^/]+)/' => 'PhameBlogViewController',
|
||||
'view/(?P<blogID>[^/]+)/' => 'PhameBlogViewController',
|
||||
'manage/(?P<id>[^/]+)/' => 'PhameBlogManageController',
|
||||
'feed/(?P<id>[^/]+)/' => 'PhameBlogFeedController',
|
||||
'new/' => 'PhameBlogEditController',
|
||||
|
@ -87,16 +86,14 @@ final class PhabricatorPhameApplication extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getBlogRoutes() {
|
||||
return array(
|
||||
'/(?P<more>.*)' => 'PhameBlogLiveController',
|
||||
);
|
||||
return $this->getLiveRoutes();
|
||||
}
|
||||
|
||||
public function getBlogCDNRoutes() {
|
||||
private function getLiveRoutes() {
|
||||
return array(
|
||||
'/phame/' => array(
|
||||
'r/(?P<id>\d+)/(?P<hash>[^/]+)/(?P<name>.*)' =>
|
||||
'PhameResourceController',
|
||||
'/' => array(
|
||||
'' => 'PhameBlogViewController',
|
||||
'post/(?P<id>[^/]+)/(?:(?P<slug>[^/]+)/)?' => 'PhamePostViewController',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Defines Phabricator's static resources.
|
||||
*/
|
||||
final class PhameCelerityResources extends CelerityResources {
|
||||
|
||||
private $skin;
|
||||
|
||||
public function setSkin($skin) {
|
||||
$this->skin = $skin;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSkin() {
|
||||
return $this->skin;
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return 'phame:'.$this->getSkin()->getName();
|
||||
}
|
||||
|
||||
public function getResourceData($name) {
|
||||
$resource_path = $this->skin->getRootDirectory().DIRECTORY_SEPARATOR.$name;
|
||||
return Filesystem::readFile($resource_path);
|
||||
}
|
||||
|
||||
}
|
182
src/applications/phame/controller/PhameLiveController.php
Normal file
182
src/applications/phame/controller/PhameLiveController.php
Normal file
|
@ -0,0 +1,182 @@
|
|||
<?php
|
||||
|
||||
abstract class PhameLiveController extends PhameController {
|
||||
|
||||
private $isExternal;
|
||||
private $isLive;
|
||||
private $blog;
|
||||
private $post;
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function getIsExternal() {
|
||||
return $this->isExternal;
|
||||
}
|
||||
|
||||
protected function getIsLive() {
|
||||
return $this->isLive;
|
||||
}
|
||||
|
||||
protected function getBlog() {
|
||||
return $this->blog;
|
||||
}
|
||||
|
||||
protected function getPost() {
|
||||
return $this->post;
|
||||
}
|
||||
|
||||
protected function setupLiveEnvironment() {
|
||||
$request = $this->getRequest();
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$site = $request->getSite();
|
||||
$blog_id = $request->getURIData('blogID');
|
||||
$post_id = $request->getURIData('id');
|
||||
|
||||
if ($site instanceof PhameBlogSite) {
|
||||
// This is a live page on a custom domain. We already looked up the blog
|
||||
// in the Site handler by examining the domain, so we don't need to do
|
||||
// more lookups.
|
||||
|
||||
$blog = $site->getBlog();
|
||||
$is_external = true;
|
||||
$is_live = true;
|
||||
} else if ($blog_id) {
|
||||
// This is a blog detail view, an internal blog live view, or an
|
||||
// internal post live view The internal post detail view is handled
|
||||
// below.
|
||||
|
||||
$is_external = false;
|
||||
if ($request->getURIData('live')) {
|
||||
$is_live = true;
|
||||
} else {
|
||||
$is_live = false;
|
||||
}
|
||||
|
||||
$blog_query = id(new PhameBlogQuery())
|
||||
->setViewer($viewer)
|
||||
->needProfileImage(true)
|
||||
->withIDs(array($blog_id));
|
||||
|
||||
// If this is a live view, only show active blogs.
|
||||
if ($is_live) {
|
||||
$blog_query->withStatuses(
|
||||
array(
|
||||
PhameBlog::STATUS_ACTIVE,
|
||||
));
|
||||
}
|
||||
|
||||
$blog = $blog_query->executeOne();
|
||||
if (!$blog) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
} else {
|
||||
// This is a post detail page, so we'll figure out the blog by loading
|
||||
// the post first.
|
||||
$is_external = false;
|
||||
$is_live = false;
|
||||
$blog = null;
|
||||
}
|
||||
|
||||
if ($post_id) {
|
||||
$post_query = id(new PhamePostQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($post_id));
|
||||
|
||||
if ($blog) {
|
||||
$post_query->withBlogPHIDs(array($blog->getPHID()));
|
||||
}
|
||||
|
||||
// Only show published posts on external domains.
|
||||
if ($is_external) {
|
||||
$post_query->withVisibility(PhameConstants::VISIBILITY_PUBLISHED);
|
||||
}
|
||||
|
||||
$post = $post_query->executeOne();
|
||||
if (!$post) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
// If this is a post detail page, the URI didn't come with a blog ID,
|
||||
// so fill that in.
|
||||
if (!$blog) {
|
||||
$blog = $post->getBlog();
|
||||
}
|
||||
} else {
|
||||
$post = null;
|
||||
}
|
||||
|
||||
$this->isExternal = $is_external;
|
||||
$this->isLive = $is_live;
|
||||
$this->blog = $blog;
|
||||
$this->post = $post;
|
||||
|
||||
// If we have a post, canonicalize the URI to the post's current slug and
|
||||
// redirect the user if it isn't correct.
|
||||
if ($post) {
|
||||
$slug = $request->getURIData('slug');
|
||||
if ($post->getSlug() != $slug) {
|
||||
if ($is_live) {
|
||||
if ($is_external) {
|
||||
$uri = $post->getExternalLiveURI();
|
||||
} else {
|
||||
$uri = $post->getInternalLiveURI();
|
||||
}
|
||||
} else {
|
||||
$uri = $post->getViewURI();
|
||||
}
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($uri);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function buildApplicationCrumbs() {
|
||||
$blog = $this->getBlog();
|
||||
$post = $this->getPost();
|
||||
|
||||
$is_live = $this->getIsLive();
|
||||
$is_external = $this->getIsExternal();
|
||||
|
||||
// If this is an external view, don't put the "Phame" crumb or the
|
||||
// "Blogs" crumb into the crumbs list.
|
||||
if ($is_external) {
|
||||
$crumbs = new PHUICrumbsView();
|
||||
} else {
|
||||
$crumbs = parent::buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(
|
||||
pht('Blogs'),
|
||||
$this->getApplicationURI('blog/'));
|
||||
}
|
||||
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
if ($post) {
|
||||
if ($is_live) {
|
||||
if ($is_external) {
|
||||
$blog_uri = $blog->getExternalLiveURI();
|
||||
} else {
|
||||
$blog_uri = $blog->getInternalLiveURI();
|
||||
}
|
||||
} else {
|
||||
$blog_uri = $blog->getViewURI();
|
||||
}
|
||||
} else {
|
||||
$blog_uri = null;
|
||||
}
|
||||
|
||||
$crumbs->addTextCrumb($blog->getName(), $blog_uri);
|
||||
|
||||
if ($post) {
|
||||
$crumbs->addTextCrumb($post->getTitle());
|
||||
}
|
||||
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhameResourceController extends CelerityResourceController {
|
||||
|
||||
private $id;
|
||||
private $hash;
|
||||
private $name;
|
||||
private $root;
|
||||
private $celerityResourceMap;
|
||||
|
||||
public function getCelerityResourceMap() {
|
||||
return $this->celerityResourceMap;
|
||||
}
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->id = $data['id'];
|
||||
$this->hash = $data['hash'];
|
||||
$this->name = $data['name'];
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
||||
// We require a visible blog associated with a given skin to serve
|
||||
// resources, so you can't go fishing around where you shouldn't be.
|
||||
// However, since these resources may be served off a CDN domain, we're
|
||||
// bypassing the actual policy check. The blog needs to exist, but you
|
||||
// don't necessarily need to be able to see it in order to see static
|
||||
// resources on it.
|
||||
|
||||
$blog = id(new PhameBlogQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withIDs(array($this->id))
|
||||
->executeOne();
|
||||
if (!$blog) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$skin = $blog->getSkinRenderer($request);
|
||||
$spec = $skin->getSpecification();
|
||||
|
||||
$resources = new PhameCelerityResources();
|
||||
$resources->setSkin($spec);
|
||||
|
||||
$this->root = $spec->getRootDirectory();
|
||||
$this->celerityResourceMap = new CelerityResourceMap($resources);
|
||||
|
||||
return $this->serveResource($this->name);
|
||||
}
|
||||
|
||||
protected function buildResourceTransformer() {
|
||||
$xformer = new CelerityResourceTransformer();
|
||||
$xformer->setMinify(false);
|
||||
$xformer->setTranslateURICallback(array($this, 'translateResourceURI'));
|
||||
return $xformer;
|
||||
}
|
||||
|
||||
public function translateResourceURI(array $matches) {
|
||||
$uri = trim($matches[1], "'\" \r\t\n");
|
||||
|
||||
if (Filesystem::pathExists($this->root.$uri)) {
|
||||
$hash = filemtime($this->root.$uri);
|
||||
} else {
|
||||
$hash = '-';
|
||||
}
|
||||
|
||||
$uri = '/phame/r/'.$this->id.'/'.$hash.'/'.$uri;
|
||||
return 'url('.$uri.')';
|
||||
}
|
||||
|
||||
}
|
|
@ -46,7 +46,6 @@ final class PhameBlogEditController
|
|||
$name = $blog->getName();
|
||||
$description = $blog->getDescription();
|
||||
$custom_domain = $blog->getDomain();
|
||||
$skin = $blog->getSkin();
|
||||
$can_view = $blog->getViewPolicy();
|
||||
$can_edit = $blog->getEditPolicy();
|
||||
|
||||
|
@ -58,7 +57,6 @@ final class PhameBlogEditController
|
|||
$name = $request->getStr('name');
|
||||
$description = $request->getStr('description');
|
||||
$custom_domain = nonempty($request->getStr('custom_domain'), null);
|
||||
$skin = $request->getStr('skin');
|
||||
$can_view = $request->getStr('can_view');
|
||||
$can_edit = $request->getStr('can_edit');
|
||||
$v_projects = $request->getArr('projects');
|
||||
|
@ -74,9 +72,6 @@ final class PhameBlogEditController
|
|||
id(new PhameBlogTransaction())
|
||||
->setTransactionType(PhameBlogTransaction::TYPE_DOMAIN)
|
||||
->setNewValue($custom_domain),
|
||||
id(new PhameBlogTransaction())
|
||||
->setTransactionType(PhameBlogTransaction::TYPE_SKIN)
|
||||
->setNewValue($skin),
|
||||
id(new PhameBlogTransaction())
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
|
||||
->setNewValue($can_view),
|
||||
|
@ -120,9 +115,6 @@ final class PhameBlogEditController
|
|||
->setObject($blog)
|
||||
->execute();
|
||||
|
||||
$skins = PhameSkinSpecification::loadAllSkinSpecifications();
|
||||
$skins = mpull($skins, 'getName');
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->appendChild(
|
||||
|
@ -179,12 +171,6 @@ final class PhameBlogEditController
|
|||
->setCaption(
|
||||
pht('Must include at least one dot (.), e.g. %s', 'blog.example.com'))
|
||||
->setError($e_custom_domain))
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setLabel(pht('Skin'))
|
||||
->setName('skin')
|
||||
->setValue($skin)
|
||||
->setOptions($skins))
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->addCancelButton($cancel_uri)
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhameBlogLiveController extends PhameBlogController {
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
|
||||
$site = $request->getSite();
|
||||
if ($site instanceof PhameBlogSite) {
|
||||
$blog = $site->getBlog();
|
||||
} else {
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$blog = id(new PhameBlogQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->executeOne();
|
||||
if (!$blog) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
}
|
||||
|
||||
if ($blog->getDomain() && ($request->getHost() != $blog->getDomain())) {
|
||||
$base_uri = $blog->getLiveURI();
|
||||
|
||||
// Don't redirect directly, since the domain is user-controlled and there
|
||||
// are a bevy of security issues associated with automatic redirects to
|
||||
// external domains.
|
||||
|
||||
// Previously we CSRF'd this and someone found a way to pass OAuth
|
||||
// information through it using anchors. Just make users click a normal
|
||||
// link so that this is no more dangerous than any other external link
|
||||
// on the site.
|
||||
|
||||
$dialog = id(new AphrontDialogView())
|
||||
->setTitle(pht('Blog Moved'))
|
||||
->setUser($viewer)
|
||||
->appendParagraph(pht('This blog is now hosted here:'))
|
||||
->appendParagraph(
|
||||
phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $base_uri,
|
||||
),
|
||||
$base_uri))
|
||||
->addCancelButton('/');
|
||||
|
||||
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||
}
|
||||
|
||||
$phame_request = clone $request;
|
||||
$more = $phame_request->getURIData('more', '');
|
||||
$phame_request->setPath('/'.ltrim($more, '/'));
|
||||
|
||||
$uri = $blog->getLiveURI();
|
||||
|
||||
$skin = $blog->getSkinRenderer($phame_request);
|
||||
$skin
|
||||
->setBlog($blog)
|
||||
->setBaseURI($uri);
|
||||
|
||||
$skin->willProcessRequest(array());
|
||||
return $skin->processRequest();
|
||||
}
|
||||
|
||||
}
|
|
@ -80,17 +80,11 @@ final class PhameBlogManageController extends PhameBlogController {
|
|||
->setObject($blog)
|
||||
->setActionList($actions);
|
||||
|
||||
$skin = $blog->getSkin();
|
||||
if (!$skin) {
|
||||
$skin = phutil_tag('em', array(), pht('No external skin'));
|
||||
}
|
||||
|
||||
$domain = $blog->getDomain();
|
||||
if (!$domain) {
|
||||
$domain = phutil_tag('em', array(), pht('No external domain'));
|
||||
}
|
||||
|
||||
$properties->addProperty(pht('Skin'), $skin);
|
||||
$properties->addProperty(pht('Domain'), $domain);
|
||||
|
||||
$feed_uri = PhabricatorEnv::getProductionURI(
|
||||
|
|
|
@ -1,84 +1,78 @@
|
|||
<?php
|
||||
|
||||
final class PhameBlogViewController extends PhameBlogController {
|
||||
|
||||
private $blog;
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
final class PhameBlogViewController extends PhameLiveController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$blog = id(new PhameBlogQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->needProfileImage(true)
|
||||
->executeOne();
|
||||
if (!$blog) {
|
||||
return new Aphront404Response();
|
||||
$response = $this->setupLiveEnvironment();
|
||||
if ($response) {
|
||||
return $response;
|
||||
}
|
||||
$this->blog = $blog;
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
$blog = $this->getBlog();
|
||||
|
||||
$is_live = $this->getIsLive();
|
||||
$is_external = $this->getIsExternal();
|
||||
|
||||
$pager = id(new AphrontCursorPagerView())
|
||||
->readFromRequest($request);
|
||||
|
||||
$posts = id(new PhamePostQuery())
|
||||
$post_query = id(new PhamePostQuery())
|
||||
->setViewer($viewer)
|
||||
->withBlogPHIDs(array($blog->getPHID()))
|
||||
->executeWithCursorPager($pager);
|
||||
->withBlogPHIDs(array($blog->getPHID()));
|
||||
|
||||
if ($blog->isArchived()) {
|
||||
$header_icon = 'fa-ban';
|
||||
$header_name = pht('Archived');
|
||||
$header_color = 'dark';
|
||||
} else {
|
||||
$header_icon = 'fa-check';
|
||||
$header_name = pht('Active');
|
||||
$header_color = 'bluegrey';
|
||||
if ($is_live) {
|
||||
$post_query->withVisibility(PhameConstants::VISIBILITY_PUBLISHED);
|
||||
}
|
||||
|
||||
$actions = $this->renderActions($blog, $viewer);
|
||||
$action_button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setText(pht('Actions'))
|
||||
->setHref('#')
|
||||
->setIconFont('fa-bars')
|
||||
->addClass('phui-mobile-menu')
|
||||
->setDropdownMenu($actions);
|
||||
$posts = $post_query->executeWithCursorPager($pager);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($blog->getName())
|
||||
->setUser($viewer)
|
||||
->setPolicyObject($blog)
|
||||
->setStatus($header_icon, $header_color, $header_name)
|
||||
->addActionLink($action_button);
|
||||
->setUser($viewer);
|
||||
|
||||
if (!$is_external) {
|
||||
if ($blog->isArchived()) {
|
||||
$header_icon = 'fa-ban';
|
||||
$header_name = pht('Archived');
|
||||
$header_color = 'dark';
|
||||
} else {
|
||||
$header_icon = 'fa-check';
|
||||
$header_name = pht('Active');
|
||||
$header_color = 'bluegrey';
|
||||
}
|
||||
$header->setStatus($header_icon, $header_color, $header_name);
|
||||
|
||||
$actions = $this->renderActions($blog);
|
||||
$action_button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setText(pht('Actions'))
|
||||
->setHref('#')
|
||||
->setIconFont('fa-bars')
|
||||
->addClass('phui-mobile-menu')
|
||||
->setDropdownMenu($actions);
|
||||
|
||||
$header->addActionLink($action_button);
|
||||
|
||||
$header->setPolicyObject($blog);
|
||||
}
|
||||
|
||||
$post_list = id(new PhamePostListView())
|
||||
->setPosts($posts)
|
||||
->setViewer($viewer)
|
||||
->setIsExternal($is_external)
|
||||
->setIsLive($is_live)
|
||||
->setNodata(pht('This blog has no visible posts.'));
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->setBorder(true);
|
||||
$crumbs->addTextCrumb(
|
||||
pht('Blogs'),
|
||||
$this->getApplicationURI('blog/'));
|
||||
$crumbs->addTextCrumb(
|
||||
$blog->getName());
|
||||
|
||||
$page = id(new PHUIDocumentViewPro())
|
||||
->setHeader($header)
|
||||
->appendChild($post_list);
|
||||
|
||||
$description = null;
|
||||
if (strlen($blog->getDescription())) {
|
||||
$description = PhabricatorMarkupEngine::renderOneObject(
|
||||
id(new PhabricatorMarkupOneOff())->setContent($blog->getDescription()),
|
||||
'default',
|
||||
$viewer);
|
||||
$description = new PHUIRemarkupView(
|
||||
$viewer,
|
||||
$blog->getDescription());
|
||||
} else {
|
||||
$description = phutil_tag('em', array(), pht('No description.'));
|
||||
}
|
||||
|
@ -88,17 +82,30 @@ final class PhameBlogViewController extends PhameBlogController {
|
|||
->setDescription($description)
|
||||
->setImage($blog->getProfileImageURI());
|
||||
|
||||
return $this->newPage()
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
|
||||
$page = $this->newPage()
|
||||
->setTitle($blog->getName())
|
||||
->setPageObjectPHIDs(array($blog->getPHID()))
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild(
|
||||
array(
|
||||
$page,
|
||||
$about,
|
||||
));
|
||||
|
||||
if ($is_live) {
|
||||
$page
|
||||
->setShowChrome(false)
|
||||
->setShowFooter(false);
|
||||
}
|
||||
|
||||
return $page;
|
||||
}
|
||||
|
||||
private function renderActions(PhameBlog $blog, PhabricatorUser $viewer) {
|
||||
private function renderActions(PhameBlog $blog) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$actions = id(new PhabricatorActionListView())
|
||||
->setObject($blog)
|
||||
->setObjectURI($this->getRequest()->getRequestURI())
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhamePostFramedController extends PhamePostController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$post = id(new PhamePostQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$post) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$blog = $post->getBlog();
|
||||
|
||||
$phame_request = $request->setPath('/post/'.$post->getPhameTitle());
|
||||
$skin = $post->getBlog()->getSkinRenderer($phame_request);
|
||||
|
||||
$uri = clone $request->getRequestURI();
|
||||
$uri->setPath('/phame/live/'.$blog->getID().'/');
|
||||
|
||||
$skin
|
||||
->setPreview(true)
|
||||
->setBlog($post->getBlog())
|
||||
->setBaseURI((string)$uri);
|
||||
|
||||
$response = $skin->processRequest();
|
||||
$response->setFrameable(true);
|
||||
return $response;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhamePostNotLiveController extends PhamePostController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$post = id(new PhamePostQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->executeOne();
|
||||
if (!$post) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$reasons = array();
|
||||
if ($post->isDraft()) {
|
||||
$reasons[] = phutil_tag('p', array(), pht(
|
||||
'You can not view the live version of this post because it '.
|
||||
'is still a draft. Use "Preview" or "Publish" to publish the post.'));
|
||||
}
|
||||
|
||||
if ($reasons) {
|
||||
$cancel_uri = $this->getApplicationURI('/post/view/'.$post->getID().'/');
|
||||
|
||||
$dialog = id(new AphrontDialogView())
|
||||
->setUser($viewer)
|
||||
->setTitle(pht('Post Not Live'))
|
||||
->addCancelButton($cancel_uri);
|
||||
|
||||
foreach ($reasons as $reason) {
|
||||
$dialog->appendChild($reason);
|
||||
}
|
||||
|
||||
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||
}
|
||||
|
||||
// No reason this can't go live, maybe an old link. Kick them live and see
|
||||
// what happens.
|
||||
$live_uri = $post->getLiveURI();
|
||||
return id(new AphrontRedirectResponse())->setURI($live_uri);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhamePostPreviewController extends PhamePostController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$post = id(new PhamePostQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$post) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$view_uri = $this->getApplicationURI('/post/view/'.$post->getID().'/');
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$xactions = array();
|
||||
$xactions[] = id(new PhamePostTransaction())
|
||||
->setTransactionType(PhamePostTransaction::TYPE_VISIBILITY)
|
||||
->setNewValue(PhameConstants::VISIBILITY_PUBLISHED);
|
||||
|
||||
id(new PhamePostEditor())
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContinueOnMissingFields(true)
|
||||
->applyTransactions($post, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($view_uri);
|
||||
}
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue(pht('Publish Post'))
|
||||
->addCancelButton($view_uri));
|
||||
|
||||
$frame = $this->renderPreviewFrame($post);
|
||||
|
||||
$form_box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Preview Post'))
|
||||
->setForm($form);
|
||||
|
||||
$blog = $post->getBlog();
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(
|
||||
$blog->getName(),
|
||||
$this->getApplicationURI('blog/view/'.$blog->getID().'/'));
|
||||
$crumbs->addTextCrumb(pht('Preview Post'), $view_uri);
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle(pht('Preview Post'))
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild(
|
||||
array(
|
||||
$form_box,
|
||||
$frame,
|
||||
));
|
||||
}
|
||||
|
||||
private function renderPreviewFrame(PhamePost $post) {
|
||||
|
||||
return phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'style' => 'text-align: center; padding: 16px;',
|
||||
),
|
||||
phutil_tag(
|
||||
'iframe',
|
||||
array(
|
||||
'style' => 'width: 100%; height: 800px; '.
|
||||
'border: 1px solid #BFCFDA; '.
|
||||
'background-color: #fff; '.
|
||||
'border-radius: 3px; ',
|
||||
'src' => $this->getApplicationURI('/post/framed/'.$post->getID().'/'),
|
||||
),
|
||||
''));
|
||||
}
|
||||
|
||||
}
|
|
@ -4,13 +4,14 @@ final class PhamePostPublishController extends PhamePostController {
|
|||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$id = $request->getURIData('id');
|
||||
$post = id(new PhamePostQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
|
@ -18,11 +19,23 @@ final class PhamePostPublishController extends PhamePostController {
|
|||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$cancel_uri = $post->getViewURI();
|
||||
|
||||
$action = $request->getURIData('action');
|
||||
$is_publish = ($action == 'publish');
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$xactions = array();
|
||||
|
||||
if ($is_publish) {
|
||||
$new_value = PhameConstants::VISIBILITY_PUBLISHED;
|
||||
} else {
|
||||
$new_value = PhameConstants::VISIBILITY_DRAFT;
|
||||
}
|
||||
|
||||
$xactions[] = id(new PhamePostTransaction())
|
||||
->setTransactionType(PhamePostTransaction::TYPE_VISIBILITY)
|
||||
->setNewValue(PhameConstants::VISIBILITY_PUBLISHED);
|
||||
->setNewValue($new_value);
|
||||
|
||||
id(new PhamePostEditor())
|
||||
->setActor($viewer)
|
||||
|
@ -32,21 +45,26 @@ final class PhamePostPublishController extends PhamePostController {
|
|||
->applyTransactions($post, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($this->getApplicationURI('/post/view/'.$post->getID().'/'));
|
||||
->setURI($cancel_uri);
|
||||
}
|
||||
|
||||
$cancel_uri = $this->getApplicationURI('/post/view/'.$post->getID().'/');
|
||||
if ($is_publish) {
|
||||
$title = pht('Publish Post');
|
||||
$body = pht('This post will go live once you publish it.');
|
||||
$button = pht('Publish');
|
||||
} else {
|
||||
$title = pht('Unpublish Post');
|
||||
$body = pht(
|
||||
'This post will revert to draft status and no longer be visible '.
|
||||
'to other users.');
|
||||
$button = pht('Unpublish');
|
||||
}
|
||||
|
||||
$dialog = $this->newDialog()
|
||||
->setTitle(pht('Publish Post?'))
|
||||
->appendChild(
|
||||
pht(
|
||||
'The post "%s" will go live once you publish it.',
|
||||
$post->getTitle()))
|
||||
->addSubmitButton(pht('Publish'))
|
||||
return $this->newDialog()
|
||||
->setTitle($title)
|
||||
->appendParagraph($body)
|
||||
->addSubmitButton($button)
|
||||
->addCancelButton($cancel_uri);
|
||||
|
||||
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhamePostUnpublishController extends PhamePostController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$post = id(new PhamePostQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$post) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$xactions = array();
|
||||
$xactions[] = id(new PhamePostTransaction())
|
||||
->setTransactionType(PhamePostTransaction::TYPE_VISIBILITY)
|
||||
->setNewValue(PhameConstants::VISIBILITY_DRAFT);
|
||||
|
||||
id(new PhamePostEditor())
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContinueOnMissingFields(true)
|
||||
->applyTransactions($post, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($this->getApplicationURI('/post/view/'.$post->getID().'/'));
|
||||
}
|
||||
|
||||
$cancel_uri = $this->getApplicationURI('/post/view/'.$post->getID().'/');
|
||||
|
||||
$dialog = $this->newDialog()
|
||||
->setTitle(pht('Unpublish Post?'))
|
||||
->appendChild(
|
||||
pht(
|
||||
'The post "%s" will no longer be visible to other users until you '.
|
||||
'republish it.',
|
||||
$post->getTitle()))
|
||||
->addSubmitButton(pht('Unpublish'))
|
||||
->addCancelButton($cancel_uri);
|
||||
|
||||
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,53 +1,41 @@
|
|||
<?php
|
||||
|
||||
final class PhamePostViewController extends PhamePostController {
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
final class PhamePostViewController
|
||||
extends PhameLiveController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$response = $this->setupLiveEnvironment();
|
||||
if ($response) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$viewer = $request->getViewer();
|
||||
$moved = $request->getStr('moved');
|
||||
|
||||
$post = id(new PhamePostQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($request->getURIData('id')))
|
||||
->executeOne();
|
||||
$post = $this->getPost();
|
||||
$blog = $this->getBlog();
|
||||
|
||||
if (!$post) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$blog = $post->getBlog();
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(
|
||||
pht('Blogs'),
|
||||
$this->getApplicationURI('blog/'));
|
||||
$crumbs->addTextCrumb(
|
||||
$blog->getName(),
|
||||
$this->getApplicationURI('blog/view/'.$blog->getID().'/'));
|
||||
$crumbs->addTextCrumb(
|
||||
$post->getTitle(),
|
||||
$this->getApplicationURI('post/view/'.$post->getID().'/'));
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
$actions = $this->renderActions($post, $viewer);
|
||||
|
||||
$action_button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setText(pht('Actions'))
|
||||
->setHref('#')
|
||||
->setIconFont('fa-bars')
|
||||
->addClass('phui-mobile-menu')
|
||||
->setDropdownMenu($actions);
|
||||
$is_live = $this->getIsLive();
|
||||
$is_external = $this->getIsExternal();
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($post->getTitle())
|
||||
->setUser($viewer)
|
||||
->setPolicyObject($post)
|
||||
->addActionLink($action_button);
|
||||
->setUser($viewer);
|
||||
|
||||
if (!$is_external) {
|
||||
$actions = $this->renderActions($post);
|
||||
|
||||
$action_button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setText(pht('Actions'))
|
||||
->setHref('#')
|
||||
->setIconFont('fa-bars')
|
||||
->addClass('phui-mobile-menu')
|
||||
->setDropdownMenu($actions);
|
||||
|
||||
$header->setPolicyObject($post);
|
||||
$header->addActionLink($action_button);
|
||||
}
|
||||
|
||||
$document = id(new PHUIDocumentViewPro())
|
||||
->setHeader($header);
|
||||
|
@ -66,7 +54,7 @@ final class PhamePostViewController extends PhamePostController {
|
|||
->setTitle(pht('Draft Post'))
|
||||
->appendChild(
|
||||
pht('Only you can see this draft until you publish it. '.
|
||||
'Use "Preview" or "Publish" to publish this post.')));
|
||||
'Use "Publish" to publish this post.')));
|
||||
}
|
||||
|
||||
if (!$post->getBlog()) {
|
||||
|
@ -125,8 +113,12 @@ final class PhamePostViewController extends PhamePostController {
|
|||
->withTransactionTypes(array(PhabricatorTransactions::TYPE_COMMENT)));
|
||||
$timeline = phutil_tag_div('phui-document-view-pro-box', $timeline);
|
||||
|
||||
$add_comment = $this->buildCommentForm($post);
|
||||
$add_comment = phutil_tag_div('mlb mlt', $add_comment);
|
||||
if ($is_external) {
|
||||
$add_comment = null;
|
||||
} else {
|
||||
$add_comment = $this->buildCommentForm($post);
|
||||
$add_comment = phutil_tag_div('mlb mlt', $add_comment);
|
||||
}
|
||||
|
||||
$properties = id(new PHUIPropertyListView())
|
||||
->setUser($viewer)
|
||||
|
@ -134,7 +126,9 @@ final class PhamePostViewController extends PhamePostController {
|
|||
|
||||
$properties->invokeWillRenderEvent();
|
||||
|
||||
return $this->newPage()
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
|
||||
$page = $this->newPage()
|
||||
->setTitle($post->getTitle())
|
||||
->setPageObjectPHIDs(array($post->getPHID()))
|
||||
->setCrumbs($crumbs)
|
||||
|
@ -146,16 +140,23 @@ final class PhamePostViewController extends PhamePostController {
|
|||
$timeline,
|
||||
$add_comment,
|
||||
));
|
||||
|
||||
if ($is_live) {
|
||||
$page
|
||||
->setShowChrome(false)
|
||||
->setShowFooter(false);
|
||||
}
|
||||
|
||||
return $page;
|
||||
}
|
||||
|
||||
private function renderActions(
|
||||
PhamePost $post,
|
||||
PhabricatorUser $viewer) {
|
||||
private function renderActions(PhamePost $post) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$actions = id(new PhabricatorActionListView())
|
||||
->setObject($post)
|
||||
->setObjectURI($this->getRequest()->getRequestURI())
|
||||
->setUser($viewer);
|
||||
$actions = id(new PhabricatorActionListView())
|
||||
->setObject($post)
|
||||
->setObjectURI($this->getRequest()->getRequestURI())
|
||||
->setUser($viewer);
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
|
@ -190,15 +191,9 @@ final class PhamePostViewController extends PhamePostController {
|
|||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-eye')
|
||||
->setHref($this->getApplicationURI('post/publish/'.$id.'/'))
|
||||
->setDisabled(!$can_edit)
|
||||
->setName(pht('Publish'))
|
||||
->setWorkflow(true));
|
||||
$actions->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-desktop')
|
||||
->setHref($this->getApplicationURI('post/preview/'.$id.'/'))
|
||||
->setDisabled(!$can_edit)
|
||||
->setName(pht('Preview in Skin')));
|
||||
->setWorkflow(true));
|
||||
} else {
|
||||
$actions->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
|
@ -209,24 +204,18 @@ final class PhamePostViewController extends PhamePostController {
|
|||
->setWorkflow(true));
|
||||
}
|
||||
|
||||
$blog = $post->getBlog();
|
||||
$can_view_live = $blog && !$post->isDraft();
|
||||
|
||||
if ($can_view_live) {
|
||||
$live_uri = $blog->getLiveURI($post);
|
||||
if ($post->isDraft()) {
|
||||
$live_name = pht('Preview');
|
||||
} else {
|
||||
$live_uri = 'post/notlive/'.$post->getID().'/';
|
||||
$live_uri = $this->getApplicationURI($live_uri);
|
||||
$live_name = pht('View Live');
|
||||
}
|
||||
|
||||
$actions->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setUser($viewer)
|
||||
->setIcon('fa-globe')
|
||||
->setHref($live_uri)
|
||||
->setName(pht('View Live'))
|
||||
->setDisabled(!$can_view_live)
|
||||
->setWorkflow(!$can_view_live));
|
||||
->setHref($post->getLiveURI())
|
||||
->setName($live_name));
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ final class PhameBlogEditor
|
|||
$types[] = PhameBlogTransaction::TYPE_NAME;
|
||||
$types[] = PhameBlogTransaction::TYPE_DESCRIPTION;
|
||||
$types[] = PhameBlogTransaction::TYPE_DOMAIN;
|
||||
$types[] = PhameBlogTransaction::TYPE_SKIN;
|
||||
$types[] = PhameBlogTransaction::TYPE_STATUS;
|
||||
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
||||
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
|
||||
|
@ -36,8 +35,6 @@ final class PhameBlogEditor
|
|||
return $object->getDescription();
|
||||
case PhameBlogTransaction::TYPE_DOMAIN:
|
||||
return $object->getDomain();
|
||||
case PhameBlogTransaction::TYPE_SKIN:
|
||||
return $object->getSkin();
|
||||
case PhameBlogTransaction::TYPE_STATUS:
|
||||
return $object->getStatus();
|
||||
}
|
||||
|
@ -51,7 +48,6 @@ final class PhameBlogEditor
|
|||
case PhameBlogTransaction::TYPE_NAME:
|
||||
case PhameBlogTransaction::TYPE_DESCRIPTION:
|
||||
case PhameBlogTransaction::TYPE_DOMAIN:
|
||||
case PhameBlogTransaction::TYPE_SKIN:
|
||||
case PhameBlogTransaction::TYPE_STATUS:
|
||||
return $xaction->getNewValue();
|
||||
}
|
||||
|
@ -68,8 +64,6 @@ final class PhameBlogEditor
|
|||
return $object->setDescription($xaction->getNewValue());
|
||||
case PhameBlogTransaction::TYPE_DOMAIN:
|
||||
return $object->setDomain($xaction->getNewValue());
|
||||
case PhameBlogTransaction::TYPE_SKIN:
|
||||
return $object->setSkin($xaction->getNewValue());
|
||||
case PhameBlogTransaction::TYPE_STATUS:
|
||||
return $object->setStatus($xaction->getNewValue());
|
||||
}
|
||||
|
@ -85,7 +79,6 @@ final class PhameBlogEditor
|
|||
case PhameBlogTransaction::TYPE_NAME:
|
||||
case PhameBlogTransaction::TYPE_DESCRIPTION:
|
||||
case PhameBlogTransaction::TYPE_DOMAIN:
|
||||
case PhameBlogTransaction::TYPE_SKIN:
|
||||
case PhameBlogTransaction::TYPE_STATUS:
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,11 @@ final class PhameBlogSite extends PhameSite {
|
|||
$blog = id(new PhameBlogQuery())
|
||||
->setViewer(new PhabricatorUser())
|
||||
->withDomain($host)
|
||||
->needProfileImage(true)
|
||||
->withStatuses(
|
||||
array(
|
||||
PhameBlog::STATUS_ACTIVE,
|
||||
))
|
||||
->executeOne();
|
||||
} catch (PhabricatorPolicyException $ex) {
|
||||
throw new Exception(
|
||||
|
|
|
@ -1,325 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @task paging Paging
|
||||
* @task internal Internals
|
||||
*/
|
||||
abstract class PhameBasicBlogSkin extends PhameBlogSkin {
|
||||
|
||||
private $pager;
|
||||
private $title;
|
||||
private $description;
|
||||
private $oGType;
|
||||
private $uriPath;
|
||||
|
||||
public function setURIPath($uri_path) {
|
||||
$this->uriPath = $uri_path;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getURIPath() {
|
||||
return $this->uriPath;
|
||||
}
|
||||
|
||||
protected function setOGType($og_type) {
|
||||
$this->oGType = $og_type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function getOGType() {
|
||||
return $this->oGType;
|
||||
}
|
||||
|
||||
protected function setDescription($description) {
|
||||
$this->description = $description;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function getDescription() {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
protected function setTitle($title) {
|
||||
$this->title = $title;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function getTitle() {
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$content = $this->renderContent($request);
|
||||
|
||||
if (!$content) {
|
||||
$content = $this->render404Page();
|
||||
}
|
||||
|
||||
$content = array(
|
||||
$this->renderHeader(),
|
||||
$content,
|
||||
$this->renderFooter(),
|
||||
);
|
||||
|
||||
$view = id(new PhabricatorBarePageView())
|
||||
->setRequest($request)
|
||||
->setController($this)
|
||||
->setDeviceReady(true)
|
||||
->setTitle($this->getBlog()->getName());
|
||||
|
||||
if ($this->getPreview()) {
|
||||
$view->setFrameable(true);
|
||||
}
|
||||
|
||||
$view->appendChild($content);
|
||||
|
||||
$response = new AphrontWebpageResponse();
|
||||
$response->setContent($view->render());
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function getSkinName() {
|
||||
return get_class($this);
|
||||
}
|
||||
|
||||
abstract protected function renderHeader();
|
||||
abstract protected function renderFooter();
|
||||
|
||||
protected function renderPostDetail(PhamePostView $post) {
|
||||
return $post;
|
||||
}
|
||||
|
||||
protected function renderPostList(array $posts) {
|
||||
$summaries = array();
|
||||
foreach ($posts as $post) {
|
||||
$summaries[] = $post->renderWithSummary();
|
||||
}
|
||||
|
||||
$list = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phame-post-list',
|
||||
),
|
||||
id(new AphrontNullView())->appendChild($summaries)->render());
|
||||
|
||||
$pager = null;
|
||||
if ($this->renderOlderPageLink() || $this->renderNewerPageLink()) {
|
||||
$pager = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phame-pager',
|
||||
),
|
||||
array(
|
||||
$this->renderOlderPageLink(),
|
||||
$this->renderNewerPageLink(),
|
||||
));
|
||||
}
|
||||
|
||||
return array(
|
||||
$list,
|
||||
$pager,
|
||||
);
|
||||
}
|
||||
|
||||
protected function render404Page() {
|
||||
return phutil_tag('h2', array(), pht('404 Not Found'));
|
||||
}
|
||||
|
||||
final public function getResourceURI($resource) {
|
||||
$root = $this->getSpecification()->getRootDirectory();
|
||||
$path = $root.DIRECTORY_SEPARATOR.$resource;
|
||||
|
||||
$data = Filesystem::readFile($path);
|
||||
$hash = PhabricatorHash::digest($data);
|
||||
$hash = substr($hash, 0, 6);
|
||||
$id = $this->getBlog()->getID();
|
||||
|
||||
$uri = '/phame/r/'.$id.'/'.$hash.'/'.$resource;
|
||||
$uri = PhabricatorEnv::getCDNURI($uri);
|
||||
|
||||
return $uri;
|
||||
}
|
||||
|
||||
/* -( Paging )------------------------------------------------------------- */
|
||||
|
||||
|
||||
/**
|
||||
* @task paging
|
||||
*/
|
||||
public function getPageSize() {
|
||||
return 100;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @task paging
|
||||
*/
|
||||
protected function getOlderPageURI() {
|
||||
if ($this->pager) {
|
||||
$next = $this->pager->getNextPageID();
|
||||
if ($next) {
|
||||
return $this->getURI('older/'.$next.'/');
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @task paging
|
||||
*/
|
||||
protected function renderOlderPageLink() {
|
||||
$uri = $this->getOlderPageURI();
|
||||
if (!$uri) {
|
||||
return null;
|
||||
}
|
||||
return phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'class' => 'phame-page-link phame-page-older',
|
||||
'href' => $uri,
|
||||
),
|
||||
pht("\xE2\x80\xB9 Older"));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @task paging
|
||||
*/
|
||||
protected function getNewerPageURI() {
|
||||
if ($this->pager) {
|
||||
$next = $this->pager->getPrevPageID();
|
||||
if ($next) {
|
||||
return $this->getURI('newer/'.$next.'/');
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @task paging
|
||||
*/
|
||||
protected function renderNewerPageLink() {
|
||||
$uri = $this->getNewerPageURI();
|
||||
if (!$uri) {
|
||||
return null;
|
||||
}
|
||||
return phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'class' => 'phame-page-link phame-page-newer',
|
||||
'href' => $uri,
|
||||
),
|
||||
pht("Newer \xE2\x80\xBA"));
|
||||
}
|
||||
|
||||
|
||||
/* -( Internals )---------------------------------------------------------- */
|
||||
|
||||
|
||||
/**
|
||||
* @task internal
|
||||
*/
|
||||
protected function renderContent(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
|
||||
$matches = null;
|
||||
$path = $request->getPath();
|
||||
// default to the blog-wide values
|
||||
$this->setTitle($this->getBlog()->getName());
|
||||
$this->setDescription($this->getBlog()->getDescription());
|
||||
$this->setOGType('website');
|
||||
$this->setURIPath('');
|
||||
if (preg_match('@^/post/(?P<name>.*)$@', $path, $matches)) {
|
||||
$post = id(new PhamePostQuery())
|
||||
->setViewer($viewer)
|
||||
->withBlogPHIDs(array($this->getBlog()->getPHID()))
|
||||
->withPhameTitles(array($matches['name']))
|
||||
->executeOne();
|
||||
|
||||
if ($post) {
|
||||
$description = $post->getMarkupText(PhamePost::MARKUP_FIELD_SUMMARY);
|
||||
$this->setTitle($post->getTitle());
|
||||
$this->setDescription($description);
|
||||
$this->setOGType('article');
|
||||
$this->setURIPath('post/'.$post->getPhameTitle());
|
||||
$view = head($this->buildPostViews(array($post)));
|
||||
return $this->renderPostDetail($view);
|
||||
}
|
||||
} else {
|
||||
$pager = new AphrontCursorPagerView();
|
||||
|
||||
if (preg_match('@^/older/(?P<before>\d+)/$@', $path, $matches)) {
|
||||
$pager->setAfterID($matches['before']);
|
||||
} else if (preg_match('@^/newer/(?P<after>\d)/$@', $path, $matches)) {
|
||||
$pager->setBeforeID($matches['after']);
|
||||
} else if (preg_match('@^/$@', $path, $matches)) {
|
||||
// Just show the first page.
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
$pager->setPageSize($this->getPageSize());
|
||||
|
||||
$posts = id(new PhamePostQuery())
|
||||
->setViewer($viewer)
|
||||
->withBlogPHIDs(array($this->getBlog()->getPHID()))
|
||||
->executeWithCursorPager($pager);
|
||||
|
||||
$this->pager = $pager;
|
||||
|
||||
if ($posts) {
|
||||
$views = $this->buildPostViews($posts);
|
||||
return $this->renderPostList($views);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function buildPostViews(array $posts) {
|
||||
assert_instances_of($posts, 'PhamePost');
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$engine = id(new PhabricatorMarkupEngine())
|
||||
->setViewer($viewer);
|
||||
|
||||
$phids = array();
|
||||
foreach ($posts as $post) {
|
||||
$engine->addObject($post, PhamePost::MARKUP_FIELD_BODY);
|
||||
$engine->addObject($post, PhamePost::MARKUP_FIELD_SUMMARY);
|
||||
|
||||
$phids[] = $post->getBloggerPHID();
|
||||
}
|
||||
|
||||
$handles = id(new PhabricatorHandleQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs($phids)
|
||||
->execute();
|
||||
|
||||
$engine->process();
|
||||
|
||||
$views = array();
|
||||
foreach ($posts as $post) {
|
||||
$view = id(new PhamePostView())
|
||||
->setUser($viewer)
|
||||
->setSkin($this)
|
||||
->setPost($post)
|
||||
->setBody($engine->getOutput($post, PhamePost::MARKUP_FIELD_BODY))
|
||||
->setSummary($engine->getOutput($post, PhamePost::MARKUP_FIELD_SUMMARY))
|
||||
->setAuthor($handles[$post->getBloggerPHID()]);
|
||||
|
||||
$post->makeEphemeral();
|
||||
if (!$post->getDatePublished()) {
|
||||
$post->setDatePublished(time());
|
||||
}
|
||||
|
||||
$views[] = $view;
|
||||
}
|
||||
|
||||
return $views;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,161 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhameBasicTemplateBlogSkin extends PhameBasicBlogSkin {
|
||||
|
||||
private $cssResources;
|
||||
|
||||
public function processRequest() {
|
||||
$root = dirname(phutil_get_library_root('phabricator'));
|
||||
require_once $root.'/support/phame/libskin.php';
|
||||
|
||||
$this->cssResources = array();
|
||||
$css = $this->getPath('css/');
|
||||
|
||||
if (Filesystem::pathExists($css)) {
|
||||
foreach (Filesystem::listDirectory($css) as $path) {
|
||||
if (!preg_match('/.css$/', $path)) {
|
||||
continue;
|
||||
}
|
||||
$this->cssResources[] = phutil_tag(
|
||||
'link',
|
||||
array(
|
||||
'rel' => 'stylesheet',
|
||||
'type' => 'text/css',
|
||||
'href' => $this->getResourceURI('css/'.$path),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
$map = CelerityResourceMap::getNamedInstance('phabricator');
|
||||
$highlight_symbol = 'syntax-highlighting-css';
|
||||
$highlight_uri = $map->getURIForSymbol($highlight_symbol);
|
||||
|
||||
$this->cssResources[] = phutil_tag(
|
||||
'link',
|
||||
array(
|
||||
'rel' => 'stylesheet',
|
||||
'type' => 'text/css',
|
||||
'href' => PhabricatorEnv::getCDNURI($highlight_uri),
|
||||
));
|
||||
|
||||
$remarkup_symbol = 'phabricator-remarkup-css';
|
||||
$remarkup_uri = $map->getURIForSymbol($remarkup_symbol);
|
||||
|
||||
$this->cssResources[] = phutil_tag(
|
||||
'link',
|
||||
array(
|
||||
'rel' => 'stylesheet',
|
||||
'type' => 'text/css',
|
||||
'href' => PhabricatorEnv::getCDNURI($remarkup_uri),
|
||||
));
|
||||
|
||||
$this->cssResources = phutil_implode_html("\n", $this->cssResources);
|
||||
|
||||
$request = $this->getRequest();
|
||||
|
||||
// Render page parts in order so the templates execute in order, if we're
|
||||
// using templates.
|
||||
$header = $this->renderHeader();
|
||||
$content = $this->renderContent($request);
|
||||
$footer = $this->renderFooter();
|
||||
|
||||
if (!$content) {
|
||||
$content = $this->render404Page();
|
||||
}
|
||||
|
||||
$content = array(
|
||||
$header,
|
||||
$content,
|
||||
$footer,
|
||||
);
|
||||
|
||||
$response = new AphrontWebpageResponse();
|
||||
$response->setContent(phutil_implode_html("\n", $content));
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function getCSSResources() {
|
||||
return $this->cssResources;
|
||||
}
|
||||
|
||||
public function remarkup($corpus) {
|
||||
$view = id(new PHUIRemarkupView($this->getViewer(), $corpus));
|
||||
|
||||
return hsprintf('%s', $view);
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return $this->getSpecification()->getName();
|
||||
}
|
||||
|
||||
public function getPath($to_file = null) {
|
||||
$path = $this->getSpecification()->getRootDirectory();
|
||||
if ($to_file) {
|
||||
$path = $path.DIRECTORY_SEPARATOR.$to_file;
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
|
||||
private function renderTemplate($__template__, array $__scope__) {
|
||||
chdir($this->getPath());
|
||||
ob_start();
|
||||
|
||||
if (Filesystem::pathExists($this->getPath($__template__))) {
|
||||
// Fool lint.
|
||||
$__evil__ = 'extract';
|
||||
$__evil__($__scope__ + $this->getDefaultScope());
|
||||
require $this->getPath($__template__);
|
||||
}
|
||||
|
||||
return phutil_safe_html(ob_get_clean());
|
||||
}
|
||||
|
||||
private function getDefaultScope() {
|
||||
return array(
|
||||
'skin' => $this,
|
||||
'blog' => $this->getBlog(),
|
||||
'uri' => $this->getURI($this->getURIPath()),
|
||||
'home_uri' => $this->getURI(''),
|
||||
|
||||
// TODO: This is wrong for detail pages, which should show the post
|
||||
// title, but getting it right is a pain and this is better than nothing.
|
||||
'title' => $this->getBlog()->getName(),
|
||||
'description' => $this->getDescription(),
|
||||
'og_type' => $this->getOGType(),
|
||||
);
|
||||
}
|
||||
|
||||
protected function renderHeader() {
|
||||
return $this->renderTemplate(
|
||||
'header.php',
|
||||
array());
|
||||
}
|
||||
|
||||
protected function renderFooter() {
|
||||
return $this->renderTemplate('footer.php', array());
|
||||
}
|
||||
|
||||
protected function render404Page() {
|
||||
return $this->renderTemplate('404.php', array());
|
||||
}
|
||||
|
||||
protected function renderPostDetail(PhamePostView $post) {
|
||||
return $this->renderTemplate(
|
||||
'post-detail.php',
|
||||
array(
|
||||
'post' => $post,
|
||||
));
|
||||
}
|
||||
|
||||
protected function renderPostList(array $posts) {
|
||||
return $this->renderTemplate(
|
||||
'post-list.php',
|
||||
array(
|
||||
'posts' => $posts,
|
||||
'older' => $this->renderOlderPageLink(),
|
||||
'newer' => $this->renderNewerPageLink(),
|
||||
));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
|
||||
abstract class PhameBlogSkin extends PhabricatorController {
|
||||
|
||||
private $blog;
|
||||
private $baseURI;
|
||||
private $preview;
|
||||
private $specification;
|
||||
|
||||
public function setSpecification(PhameSkinSpecification $specification) {
|
||||
$this->specification = $specification;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSpecification() {
|
||||
return $this->specification;
|
||||
}
|
||||
|
||||
public function setPreview($preview) {
|
||||
$this->preview = $preview;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPreview() {
|
||||
return $this->preview;
|
||||
}
|
||||
|
||||
final public function setBaseURI($base_uri) {
|
||||
$this->baseURI = $base_uri;
|
||||
return $this;
|
||||
}
|
||||
|
||||
final public function getURI($path) {
|
||||
return $this->baseURI.$path;
|
||||
}
|
||||
|
||||
final public function setBlog(PhameBlog $blog) {
|
||||
$this->blog = $blog;
|
||||
return $this;
|
||||
}
|
||||
|
||||
final public function getBlog() {
|
||||
return $this->blog;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,198 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhameSkinSpecification extends Phobject {
|
||||
|
||||
const TYPE_ADVANCED = 'advanced';
|
||||
const TYPE_BASIC = 'basic';
|
||||
const SKIN_PATH = 'externals/skins/';
|
||||
|
||||
private $type;
|
||||
private $rootDirectory;
|
||||
private $skinClass;
|
||||
private $phutilLibraries = array();
|
||||
private $name;
|
||||
private $config;
|
||||
|
||||
public static function loadAllSkinSpecifications() {
|
||||
static $specs;
|
||||
|
||||
if ($specs === null) {
|
||||
$paths = array(self::SKIN_PATH);
|
||||
$base = dirname(phutil_get_library_root('phabricator'));
|
||||
|
||||
$specs = array();
|
||||
|
||||
foreach ($paths as $path) {
|
||||
$path = Filesystem::resolvePath($path, $base);
|
||||
foreach (Filesystem::listDirectory($path) as $skin_directory) {
|
||||
$skin_path = $path.DIRECTORY_SEPARATOR.$skin_directory;
|
||||
|
||||
if (!is_dir($skin_path)) {
|
||||
continue;
|
||||
}
|
||||
$spec = self::loadSkinSpecification($skin_path);
|
||||
if (!$spec) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$name = trim($skin_directory, DIRECTORY_SEPARATOR);
|
||||
|
||||
$spec->setName($name);
|
||||
|
||||
if (isset($specs[$name])) {
|
||||
$that_dir = $specs[$name]->getRootDirectory();
|
||||
$this_dir = $spec->getRootDirectory();
|
||||
throw new Exception(
|
||||
pht(
|
||||
"Two skins have the same name ('%s'), in '%s' and '%s'. ".
|
||||
"Rename one or adjust your '%s' configuration.",
|
||||
$name,
|
||||
$this_dir,
|
||||
$that_dir,
|
||||
self::SKIN_PATH));
|
||||
}
|
||||
|
||||
$specs[$name] = $spec;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $specs;
|
||||
}
|
||||
|
||||
public static function loadOneSkinSpecification($name) {
|
||||
// Only allow skins which we know to exist to load. This prevents loading
|
||||
// skins like "../../secrets/evil/".
|
||||
$all = self::loadAllSkinSpecifications();
|
||||
if (empty($all[$name])) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Blog skin "%s" is not a valid skin!',
|
||||
$name));
|
||||
}
|
||||
|
||||
$paths = array(self::SKIN_PATH);
|
||||
$base = dirname(phutil_get_library_root('phabricator'));
|
||||
foreach ($paths as $path) {
|
||||
$path = Filesystem::resolvePath($path, $base);
|
||||
$skin_path = $path.DIRECTORY_SEPARATOR.$name;
|
||||
if (is_dir($skin_path)) {
|
||||
|
||||
// Double check that the skin really lives in the skin directory.
|
||||
if (!Filesystem::isDescendant($skin_path, $path)) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Blog skin "%s" is not located in path "%s"!',
|
||||
$name,
|
||||
$path));
|
||||
}
|
||||
|
||||
$spec = self::loadSkinSpecification($skin_path);
|
||||
if ($spec) {
|
||||
$spec->setName($name);
|
||||
return $spec;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static function loadSkinSpecification($path) {
|
||||
$config_path = $path.DIRECTORY_SEPARATOR.'skin.json';
|
||||
$config = array();
|
||||
if (Filesystem::pathExists($config_path)) {
|
||||
$config = Filesystem::readFile($config_path);
|
||||
try {
|
||||
$config = phutil_json_decode($config);
|
||||
} catch (PhutilJSONParserException $ex) {
|
||||
throw new PhutilProxyException(
|
||||
pht(
|
||||
"Skin configuration file '%s' is not a valid JSON file.",
|
||||
$config_path),
|
||||
$ex);
|
||||
}
|
||||
$type = idx($config, 'type', self::TYPE_BASIC);
|
||||
} else {
|
||||
$type = self::TYPE_BASIC;
|
||||
}
|
||||
|
||||
$spec = new PhameSkinSpecification();
|
||||
$spec->setRootDirectory($path);
|
||||
$spec->setConfig($config);
|
||||
|
||||
switch ($type) {
|
||||
case self::TYPE_BASIC:
|
||||
$spec->setSkinClass('PhameBasicTemplateBlogSkin');
|
||||
break;
|
||||
case self::TYPE_ADVANCED:
|
||||
$spec->setSkinClass($config['class']);
|
||||
$spec->addPhutilLibrary($path.DIRECTORY_SEPARATOR.'src');
|
||||
break;
|
||||
default:
|
||||
throw new Exception(pht('Unknown skin type!'));
|
||||
}
|
||||
|
||||
$spec->setType($type);
|
||||
|
||||
return $spec;
|
||||
}
|
||||
|
||||
public function setConfig(array $config) {
|
||||
$this->config = $config;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getConfig($key, $default = null) {
|
||||
return idx($this->config, $key, $default);
|
||||
}
|
||||
|
||||
public function setName($name) {
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return $this->getConfig('name', $this->name);
|
||||
}
|
||||
|
||||
public function setRootDirectory($root_directory) {
|
||||
$this->rootDirectory = $root_directory;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRootDirectory() {
|
||||
return $this->rootDirectory;
|
||||
}
|
||||
|
||||
public function setType($type) {
|
||||
$this->type = $type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getType() {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function setSkinClass($skin_class) {
|
||||
$this->skinClass = $skin_class;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSkinClass() {
|
||||
return $this->skinClass;
|
||||
}
|
||||
|
||||
public function addPhutilLibrary($library) {
|
||||
$this->phutilLibraries[] = $library;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function buildSkin(AphrontRequest $request) {
|
||||
foreach ($this->phutilLibraries as $library) {
|
||||
phutil_load_library($library);
|
||||
}
|
||||
|
||||
return newv($this->getSkinClass(), array($request, $this));
|
||||
}
|
||||
|
||||
}
|
|
@ -11,7 +11,6 @@ final class PhameBlog extends PhameDAO
|
|||
PhabricatorApplicationTransactionInterface {
|
||||
|
||||
const MARKUP_FIELD_DESCRIPTION = 'markup:description';
|
||||
const SKIN_DEFAULT = 'oblivious';
|
||||
|
||||
protected $name;
|
||||
protected $description;
|
||||
|
@ -25,7 +24,6 @@ final class PhameBlog extends PhameDAO
|
|||
protected $profileImagePHID;
|
||||
|
||||
private $profileImageFile = self::ATTACHABLE;
|
||||
private static $requestBlog;
|
||||
|
||||
const STATUS_ACTIVE = 'active';
|
||||
const STATUS_ARCHIVED = 'archived';
|
||||
|
@ -84,29 +82,6 @@ final class PhameBlog extends PhameDAO
|
|||
return $blog;
|
||||
}
|
||||
|
||||
public function getSkinRenderer(AphrontRequest $request) {
|
||||
$spec = PhameSkinSpecification::loadOneSkinSpecification(
|
||||
$this->getSkin());
|
||||
|
||||
if (!$spec) {
|
||||
$spec = PhameSkinSpecification::loadOneSkinSpecification(
|
||||
self::SKIN_DEFAULT);
|
||||
}
|
||||
|
||||
if (!$spec) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'This blog has an invalid skin, and the default skin failed to '.
|
||||
'load.'));
|
||||
}
|
||||
|
||||
$skin = newv($spec->getSkinClass(), array());
|
||||
$skin->setRequest($request);
|
||||
$skin->setSpecification($spec);
|
||||
|
||||
return $skin;
|
||||
}
|
||||
|
||||
public function isArchived() {
|
||||
return ($this->getStatus() == self::STATUS_ARCHIVED);
|
||||
}
|
||||
|
@ -196,53 +171,26 @@ final class PhameBlog extends PhameDAO
|
|||
return null;
|
||||
}
|
||||
|
||||
public function getSkin() {
|
||||
$config = coalesce($this->getConfigData(), array());
|
||||
return idx($config, 'skin', self::SKIN_DEFAULT);
|
||||
}
|
||||
|
||||
public function setSkin($skin) {
|
||||
$config = coalesce($this->getConfigData(), array());
|
||||
$config['skin'] = $skin;
|
||||
return $this->setConfigData($config);
|
||||
}
|
||||
|
||||
public static function getSkinOptionsForSelect() {
|
||||
$classes = id(new PhutilSymbolLoader())
|
||||
->setAncestorClass('PhameBlogSkin')
|
||||
->setType('class')
|
||||
->setConcreteOnly(true)
|
||||
->selectSymbolsWithoutLoading();
|
||||
|
||||
return ipull($classes, 'name', 'name');
|
||||
}
|
||||
|
||||
public static function setRequestBlog(PhameBlog $blog) {
|
||||
self::$requestBlog = $blog;
|
||||
}
|
||||
|
||||
public static function getRequestBlog() {
|
||||
return self::$requestBlog;
|
||||
}
|
||||
|
||||
public function getLiveURI(PhamePost $post = null) {
|
||||
if ($this->getDomain()) {
|
||||
$base = new PhutilURI('http://'.$this->getDomain().'/');
|
||||
public function getLiveURI() {
|
||||
if (strlen($this->getDomain())) {
|
||||
return $this->getExternalLiveURI();
|
||||
} else {
|
||||
$base = '/phame/live/'.$this->getID().'/';
|
||||
$base = PhabricatorEnv::getURI($base);
|
||||
return $this->getInternalLiveURI();
|
||||
}
|
||||
}
|
||||
|
||||
if ($post) {
|
||||
$base .= '/post/'.$post->getPhameTitle();
|
||||
}
|
||||
public function getExternalLiveURI() {
|
||||
$domain = $this->getDomain();
|
||||
$uri = new PhutilURI('http://'.$this->getDomain().'/');
|
||||
return (string)$uri;
|
||||
}
|
||||
|
||||
return $base;
|
||||
public function getInternalLiveURI() {
|
||||
return '/phame/live/'.$this->getID().'/';
|
||||
}
|
||||
|
||||
public function getViewURI() {
|
||||
$uri = '/phame/blog/view/'.$this->getID().'/';
|
||||
return PhabricatorEnv::getProductionURI($uri);
|
||||
return '/phame/blog/view/'.$this->getID().'/';
|
||||
}
|
||||
|
||||
public function getProfileImageURI() {
|
||||
|
|
|
@ -6,7 +6,6 @@ final class PhameBlogTransaction
|
|||
const TYPE_NAME = 'phame.blog.name';
|
||||
const TYPE_DESCRIPTION = 'phame.blog.description';
|
||||
const TYPE_DOMAIN = 'phame.blog.domain';
|
||||
const TYPE_SKIN = 'phame.blog.skin';
|
||||
const TYPE_STATUS = 'phame.blog.status';
|
||||
|
||||
const MAILTAG_DETAILS = 'phame-blog-details';
|
||||
|
@ -43,7 +42,6 @@ final class PhameBlogTransaction
|
|||
break;
|
||||
case self::TYPE_DESCRIPTION:
|
||||
case self::TYPE_DOMAIN:
|
||||
case self::TYPE_SKIN:
|
||||
return 'fa-pencil';
|
||||
case self::TYPE_STATUS:
|
||||
if ($new == PhameBlog::STATUS_ARCHIVED) {
|
||||
|
@ -82,7 +80,6 @@ final class PhameBlogTransaction
|
|||
case self::TYPE_NAME:
|
||||
case self::TYPE_DESCRIPTION:
|
||||
case self::TYPE_DOMAIN:
|
||||
case self::TYPE_SKIN:
|
||||
$tags[] = self::MAILTAG_DETAILS;
|
||||
break;
|
||||
default:
|
||||
|
@ -124,12 +121,6 @@ final class PhameBlogTransaction
|
|||
$this->renderHandleLink($author_phid),
|
||||
$new);
|
||||
break;
|
||||
case self::TYPE_SKIN:
|
||||
return pht(
|
||||
'%s updated the blog\'s skin to "%s".',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$new);
|
||||
break;
|
||||
case self::TYPE_STATUS:
|
||||
switch ($new) {
|
||||
case PhameBlog::STATUS_ACTIVE:
|
||||
|
@ -181,12 +172,6 @@ final class PhameBlogTransaction
|
|||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
break;
|
||||
case self::TYPE_SKIN:
|
||||
return pht(
|
||||
'%s updated the skin for %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
break;
|
||||
case self::TYPE_STATUS:
|
||||
switch ($new) {
|
||||
case PhameBlog::STATUS_ACTIVE:
|
||||
|
|
|
@ -49,19 +49,37 @@ final class PhamePost extends PhameDAO
|
|||
}
|
||||
|
||||
public function getLiveURI() {
|
||||
// go for the pretty uri if we can
|
||||
$domain = ($this->blog ? $this->blog->getDomain() : '');
|
||||
if ($domain) {
|
||||
$phame_title = PhabricatorSlug::normalize($this->getPhameTitle());
|
||||
return 'http://'.$domain.'/post/'.$phame_title;
|
||||
$blog = $this->getBlog();
|
||||
$is_draft = $this->isDraft();
|
||||
if (strlen($blog->getDomain()) && !$is_draft) {
|
||||
return $this->getExternalLiveURI();
|
||||
} else {
|
||||
return $this->getInternalLiveURI();
|
||||
}
|
||||
$uri = '/phame/post/view/'.$this->getID().'/';
|
||||
return PhabricatorEnv::getProductionURI($uri);
|
||||
}
|
||||
|
||||
public function getExternalLiveURI() {
|
||||
$id = $this->getID();
|
||||
$slug = $this->getSlug();
|
||||
$path = "/post/{$id}/{$slug}/";
|
||||
|
||||
$domain = $this->getBlog()->getDomain();
|
||||
|
||||
return (string)id(new PhutilURI('http://'.$domain))
|
||||
->setPath($path);
|
||||
}
|
||||
|
||||
public function getInternalLiveURI() {
|
||||
$id = $this->getID();
|
||||
$slug = $this->getSlug();
|
||||
$blog_id = $this->getBlog()->getID();
|
||||
return "/phame/live/{$blog_id}/post/{$id}/{$slug}/";
|
||||
}
|
||||
|
||||
public function getViewURI() {
|
||||
$phame_title = PhabricatorSlug::normalize($this->getPhameTitle());
|
||||
return '/phame/post/view/'.$this->getID().'/'.$phame_title;
|
||||
$id = $this->getID();
|
||||
$slug = $this->getSlug();
|
||||
return "/phame/post/view/{$id}/{$slug}/";
|
||||
}
|
||||
|
||||
public function getEditURI() {
|
||||
|
@ -69,17 +87,7 @@ final class PhamePost extends PhameDAO
|
|||
}
|
||||
|
||||
public function isDraft() {
|
||||
return $this->getVisibility() == PhameConstants::VISIBILITY_DRAFT;
|
||||
}
|
||||
|
||||
public function getHumanName() {
|
||||
if ($this->isDraft()) {
|
||||
$name = 'draft';
|
||||
} else {
|
||||
$name = 'post';
|
||||
}
|
||||
|
||||
return $name;
|
||||
return ($this->getVisibility() == PhameConstants::VISIBILITY_DRAFT);
|
||||
}
|
||||
|
||||
protected function getConfiguration() {
|
||||
|
@ -138,6 +146,10 @@ final class PhamePost extends PhameDAO
|
|||
PhabricatorPhamePostPHIDType::TYPECONST);
|
||||
}
|
||||
|
||||
public function getSlug() {
|
||||
return rtrim($this->getPhameTitle(), '/');
|
||||
}
|
||||
|
||||
public function toDictionary() {
|
||||
return array(
|
||||
'id' => $this->getID(),
|
||||
|
|
|
@ -6,6 +6,8 @@ final class PhamePostListView extends AphrontTagView {
|
|||
private $nodata;
|
||||
private $viewer;
|
||||
private $showBlog = false;
|
||||
private $isExternal;
|
||||
private $isLive;
|
||||
|
||||
public function setPosts($posts) {
|
||||
assert_instances_of($posts, 'PhamePost');
|
||||
|
@ -28,6 +30,24 @@ final class PhamePostListView extends AphrontTagView {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function setIsExternal($is_external) {
|
||||
$this->isExternal = $is_external;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getIsExternal() {
|
||||
return $this->isExternal;
|
||||
}
|
||||
|
||||
public function setIsLive($is_live) {
|
||||
$this->isLive = $is_live;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getIsLive() {
|
||||
return $this->isLive;
|
||||
}
|
||||
|
||||
protected function getTagAttributes() {
|
||||
return array();
|
||||
}
|
||||
|
@ -63,21 +83,40 @@ final class PhamePostListView extends AphrontTagView {
|
|||
$blogger = phutil_tag('strong', array(), $blogger);
|
||||
$date = phabricator_datetime($post->getDatePublished(), $viewer);
|
||||
|
||||
$blog = null;
|
||||
if ($post->getBlog()) {
|
||||
$blog = phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => '/phame/blog/view/'.$post->getBlog()->getID().'/',
|
||||
),
|
||||
$post->getBlog()->getName());
|
||||
$blog = $post->getBlog();
|
||||
|
||||
if ($this->getIsLive()) {
|
||||
if ($this->getIsExternal()) {
|
||||
$blog_uri = $blog->getExternalLiveURI();
|
||||
$post_uri = $post->getExternalLiveURI();
|
||||
} else {
|
||||
$blog_uri = $blog->getInternalLiveURI();
|
||||
$post_uri = $post->getInternalLiveURI();
|
||||
}
|
||||
} else {
|
||||
$blog_uri = $blog->getViewURI();
|
||||
$post_uri = $post->getViewURI();
|
||||
}
|
||||
|
||||
if ($this->showBlog && $blog) {
|
||||
$blog_link = phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $blog_uri,
|
||||
),
|
||||
$blog->getName());
|
||||
|
||||
if ($this->showBlog) {
|
||||
if ($post->isDraft()) {
|
||||
$subtitle = pht('Unpublished draft by %s in %s.', $blogger, $blog);
|
||||
$subtitle = pht(
|
||||
'Unpublished draft by %s in %s.',
|
||||
$blogger,
|
||||
$blog_link);
|
||||
} else {
|
||||
$subtitle = pht('By %s on %s in %s.', $blogger, $date, $blog);
|
||||
$subtitle = pht(
|
||||
'Written by %s on %s in %s.',
|
||||
$blogger,
|
||||
$date,
|
||||
$blog_link);
|
||||
}
|
||||
} else {
|
||||
if ($post->isDraft()) {
|
||||
|
@ -89,7 +128,7 @@ final class PhamePostListView extends AphrontTagView {
|
|||
|
||||
$item = id(new PHUIDocumentSummaryView())
|
||||
->setTitle($post->getTitle())
|
||||
->setHref($post->getViewURI())
|
||||
->setHref($post_uri)
|
||||
->setSubtitle($subtitle)
|
||||
->setImage($blogger_image)
|
||||
->setImageHref($blogger_uri)
|
||||
|
|
|
@ -1,130 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhamePostView extends AphrontView {
|
||||
|
||||
private $post;
|
||||
private $author;
|
||||
private $body;
|
||||
private $skin;
|
||||
private $summary;
|
||||
|
||||
|
||||
public function setSkin(PhameBlogSkin $skin) {
|
||||
$this->skin = $skin;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSkin() {
|
||||
return $this->skin;
|
||||
}
|
||||
|
||||
public function setAuthor(PhabricatorObjectHandle $author) {
|
||||
$this->author = $author;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAuthor() {
|
||||
return $this->author;
|
||||
}
|
||||
|
||||
public function setPost(PhamePost $post) {
|
||||
$this->post = $post;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPost() {
|
||||
return $this->post;
|
||||
}
|
||||
|
||||
public function setBody($body) {
|
||||
$this->body = $body;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBody() {
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
public function setSummary($summary) {
|
||||
$this->summary = $summary;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSummary() {
|
||||
return $this->summary;
|
||||
}
|
||||
|
||||
public function renderTitle() {
|
||||
$href = $this->getSkin()->getURI('post/'.$this->getPost()->getPhameTitle());
|
||||
return phutil_tag(
|
||||
'h2',
|
||||
array(
|
||||
'class' => 'phame-post-title',
|
||||
),
|
||||
phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $href,
|
||||
),
|
||||
$this->getPost()->getTitle()));
|
||||
}
|
||||
|
||||
public function renderDatePublished() {
|
||||
return phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phame-post-date',
|
||||
),
|
||||
pht(
|
||||
'Published on %s by %s',
|
||||
phabricator_datetime(
|
||||
$this->getPost()->getDatePublished(),
|
||||
$this->getUser()),
|
||||
$this->getAuthor()->getName()));
|
||||
}
|
||||
|
||||
public function renderBody() {
|
||||
return phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phame-post-body phabricator-remarkup',
|
||||
),
|
||||
$this->getBody());
|
||||
}
|
||||
|
||||
public function renderSummary() {
|
||||
return phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phame-post-body phabricator-remarkup',
|
||||
),
|
||||
$this->getSummary());
|
||||
}
|
||||
|
||||
public function render() {
|
||||
return phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phame-post',
|
||||
),
|
||||
array(
|
||||
$this->renderTitle(),
|
||||
$this->renderDatePublished(),
|
||||
$this->renderBody(),
|
||||
));
|
||||
}
|
||||
|
||||
public function renderWithSummary() {
|
||||
return phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phame-post',
|
||||
),
|
||||
array(
|
||||
$this->renderTitle(),
|
||||
$this->renderDatePublished(),
|
||||
$this->renderSummary(),
|
||||
));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue