Correct a parameter order swap in "diffusion.historyquery" for Mercurial
[phabricator.git] / src / applications / phame / controller / post / PhamePostViewController.php
blob7bef0e6751a8d68848d498888a75d1ef9ade87bd
1 <?php
3 final class PhamePostViewController
4 extends PhameLiveController {
6 public function handleRequest(AphrontRequest $request) {
7 $response = $this->setupLiveEnvironment();
8 if ($response) {
9 return $response;
12 $viewer = $request->getViewer();
13 $moved = $request->getStr('moved');
15 $post = $this->getPost();
16 $blog = $this->getBlog();
18 $is_live = $this->getIsLive();
19 $is_external = $this->getIsExternal();
21 $header = id(new PHUIHeaderView())
22 ->addClass('phame-header-bar')
23 ->setUser($viewer);
25 $hero = $this->buildPhamePostHeader($post);
27 if (!$is_external && $viewer->isLoggedIn()) {
28 $actions = $this->renderActions($post);
29 $header->setPolicyObject($post);
30 $header->setActionList($actions);
33 $document = id(new PHUIDocumentView())
34 ->setHeader($header);
36 if ($moved) {
37 $document->appendChild(
38 id(new PHUIInfoView())
39 ->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
40 ->appendChild(pht('Post moved successfully.')));
43 if ($post->isDraft()) {
44 $document->appendChild(
45 id(new PHUIInfoView())
46 ->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
47 ->setTitle(pht('Draft Post'))
48 ->appendChild(
49 pht(
50 'This is a draft, and is only visible to you and other users '.
51 'who can edit %s. Use "Publish" to publish this post.',
52 $viewer->renderHandle($post->getBlogPHID()))));
55 if ($post->isArchived()) {
56 $document->appendChild(
57 id(new PHUIInfoView())
58 ->setSeverity(PHUIInfoView::SEVERITY_ERROR)
59 ->setTitle(pht('Archived Post'))
60 ->appendChild(
61 pht(
62 'This post has been archived, and is only visible to you and '.
63 'other users who can edit %s.',
64 $viewer->renderHandle($post->getBlogPHID()))));
67 if (!$post->getBlog()) {
68 $document->appendChild(
69 id(new PHUIInfoView())
70 ->setSeverity(PHUIInfoView::SEVERITY_WARNING)
71 ->setTitle(pht('Not On A Blog'))
72 ->appendChild(
73 pht('This post is not associated with a blog (the blog may have '.
74 'been deleted). Use "Move Post" to move it to a new blog.')));
77 $engine = id(new PhabricatorMarkupEngine())
78 ->setViewer($viewer)
79 ->addObject($post, PhamePost::MARKUP_FIELD_BODY)
80 ->process();
82 $document->appendChild(
83 phutil_tag(
84 'div',
85 array(
86 'class' => 'phabricator-remarkup',
88 $engine->getOutput($post, PhamePost::MARKUP_FIELD_BODY)));
90 $blogger = id(new PhabricatorPeopleQuery())
91 ->setViewer($viewer)
92 ->withPHIDs(array($post->getBloggerPHID()))
93 ->needProfileImage(true)
94 ->executeOne();
95 $blogger_profile = $blogger->loadUserProfile();
98 $author_uri = '/p/'.$blogger->getUsername().'/';
99 $author_uri = PhabricatorEnv::getURI($author_uri);
101 $author = phutil_tag(
102 'a',
103 array(
104 'href' => $author_uri,
106 $blogger->getUsername());
108 $date = phabricator_datetime($post->getDatePublished(), $viewer);
109 if ($post->isDraft()) {
110 $subtitle = pht('Unpublished draft by %s.', $author);
111 } else if ($post->isArchived()) {
112 $subtitle = pht('Archived post by %s.', $author);
113 } else {
114 $subtitle = pht('Written by %s on %s.', $author, $date);
117 $user_icon = $blogger_profile->getIcon();
118 $user_icon = PhabricatorPeopleIconSet::getIconIcon($user_icon);
119 $user_icon = id(new PHUIIconView())->setIcon($user_icon);
121 $about = id(new PhameDescriptionView())
122 ->setTitle($subtitle)
123 ->setDescription(
124 array(
125 $user_icon,
126 ' ',
127 $blogger_profile->getDisplayTitle(),
129 ->setImage($blogger->getProfileImageURI())
130 ->setImageHref($author_uri);
132 $monogram = $post->getMonogram();
133 $timeline = $this->buildTransactionTimeline(
134 $post,
135 id(new PhamePostTransactionQuery())
136 ->withTransactionTypes(array(PhabricatorTransactions::TYPE_COMMENT)));
137 $timeline->setQuoteRef($monogram);
139 if ($is_external || !$viewer->isLoggedIn()) {
140 $add_comment = null;
141 } else {
142 $add_comment = $this->buildCommentForm($post, $timeline);
143 $add_comment = phutil_tag_div('mlb mlt phame-comment-view', $add_comment);
146 $timeline = phutil_tag_div('phui-document-view-pro-box', $timeline);
148 list($prev, $next) = $this->loadAdjacentPosts($post);
150 $properties = id(new PHUIPropertyListView())
151 ->setUser($viewer)
152 ->setObject($post);
154 $is_live = $this->getIsLive();
155 $is_external = $this->getIsExternal();
156 $next_view = new PhameNextPostView();
157 if ($next) {
158 $next_view->setNext($next->getTitle(),
159 $next->getBestURI($is_live, $is_external));
161 if ($prev) {
162 $next_view->setPrevious($prev->getTitle(),
163 $prev->getBestURI($is_live, $is_external));
166 $document->setFoot($next_view);
167 $crumbs = $this->buildApplicationCrumbs();
168 $properties = phutil_tag_div('phui-document-view-pro-box', $properties);
170 $page = $this->newPage()
171 ->setTitle($post->getTitle())
172 ->setPageObjectPHIDs(array($post->getPHID()))
173 ->setCrumbs($crumbs)
174 ->appendChild(
175 array(
176 $hero,
177 $document,
178 $about,
179 $properties,
180 $timeline,
181 $add_comment,
184 if ($is_live) {
185 $page
186 ->setShowChrome(false)
187 ->setShowFooter(false);
190 return $page;
193 private function renderActions(PhamePost $post) {
194 $viewer = $this->getViewer();
196 $actions = id(new PhabricatorActionListView())
197 ->setObject($post)
198 ->setUser($viewer);
200 $can_edit = PhabricatorPolicyFilter::hasCapability(
201 $viewer,
202 $post,
203 PhabricatorPolicyCapability::CAN_EDIT);
205 $id = $post->getID();
207 $actions->addAction(
208 id(new PhabricatorActionView())
209 ->setIcon('fa-pencil')
210 ->setHref($this->getApplicationURI('post/edit/'.$id.'/'))
211 ->setName(pht('Edit Post'))
212 ->setDisabled(!$can_edit));
214 $actions->addAction(
215 id(new PhabricatorActionView())
216 ->setIcon('fa-camera-retro')
217 ->setHref($this->getApplicationURI('post/header/'.$id.'/'))
218 ->setName(pht('Edit Header Image'))
219 ->setDisabled(!$can_edit));
221 $actions->addAction(
222 id(new PhabricatorActionView())
223 ->setIcon('fa-arrows')
224 ->setHref($this->getApplicationURI('post/move/'.$id.'/'))
225 ->setName(pht('Move Post'))
226 ->setDisabled(!$can_edit)
227 ->setWorkflow(true));
229 $actions->addAction(
230 id(new PhabricatorActionView())
231 ->setIcon('fa-history')
232 ->setHref($this->getApplicationURI('post/history/'.$id.'/'))
233 ->setName(pht('View History')));
235 if ($post->isDraft()) {
236 $actions->addAction(
237 id(new PhabricatorActionView())
238 ->setIcon('fa-eye')
239 ->setHref($this->getApplicationURI('post/publish/'.$id.'/'))
240 ->setName(pht('Publish'))
241 ->setDisabled(!$can_edit)
242 ->setWorkflow(true));
243 $actions->addAction(
244 id(new PhabricatorActionView())
245 ->setIcon('fa-ban')
246 ->setHref($this->getApplicationURI('post/archive/'.$id.'/'))
247 ->setName(pht('Archive'))
248 ->setDisabled(!$can_edit)
249 ->setWorkflow(true));
250 } else if ($post->isArchived()) {
251 $actions->addAction(
252 id(new PhabricatorActionView())
253 ->setIcon('fa-eye')
254 ->setHref($this->getApplicationURI('post/publish/'.$id.'/'))
255 ->setName(pht('Publish'))
256 ->setDisabled(!$can_edit)
257 ->setWorkflow(true));
258 } else {
259 $actions->addAction(
260 id(new PhabricatorActionView())
261 ->setIcon('fa-eye-slash')
262 ->setHref($this->getApplicationURI('post/unpublish/'.$id.'/'))
263 ->setName(pht('Unpublish'))
264 ->setDisabled(!$can_edit)
265 ->setWorkflow(true));
266 $actions->addAction(
267 id(new PhabricatorActionView())
268 ->setIcon('fa-ban')
269 ->setHref($this->getApplicationURI('post/archive/'.$id.'/'))
270 ->setName(pht('Archive'))
271 ->setDisabled(!$can_edit)
272 ->setWorkflow(true));
275 if ($post->isDraft()) {
276 $live_name = pht('Preview');
277 } else {
278 $live_name = pht('View Live');
281 if (!$post->isArchived()) {
282 $actions->addAction(
283 id(new PhabricatorActionView())
284 ->setUser($viewer)
285 ->setIcon('fa-globe')
286 ->setHref($post->getLiveURI())
287 ->setName($live_name));
290 return $actions;
293 private function buildCommentForm(PhamePost $post, $timeline) {
294 $viewer = $this->getViewer();
296 $box = id(new PhamePostEditEngine())
297 ->setViewer($viewer)
298 ->buildEditEngineCommentView($post)
299 ->setTransactionTimeline($timeline);
301 return phutil_tag_div('phui-document-view-pro-box', $box);
304 private function loadAdjacentPosts(PhamePost $post) {
305 $viewer = $this->getViewer();
307 $pager = id(new AphrontCursorPagerView())
308 ->setPageSize(1);
310 $prev_pager = id(clone $pager)
311 ->setAfterID($post->getID());
313 $next_pager = id(clone $pager)
314 ->setBeforeID($post->getID());
316 $query = id(new PhamePostQuery())
317 ->setViewer($viewer)
318 ->withVisibility(array(PhameConstants::VISIBILITY_PUBLISHED))
319 ->withBlogPHIDs(array($post->getBlog()->getPHID()))
320 ->setLimit(1);
322 $prev = id(clone $query)
323 ->executeWithCursorPager($prev_pager);
325 $next = id(clone $query)
326 ->executeWithCursorPager($next_pager);
328 return array(head($prev), head($next));
331 private function buildPhamePostHeader(
332 PhamePost $post) {
334 $image = null;
335 if ($post->getHeaderImagePHID()) {
336 $image = phutil_tag(
337 'div',
338 array(
339 'class' => 'phame-header-hero',
341 phutil_tag(
342 'img',
343 array(
344 'src' => $post->getHeaderImageURI(),
345 'class' => 'phame-header-image',
346 )));
349 $title = phutil_tag_div('phame-header-title', $post->getTitle());
350 $subtitle = null;
351 if ($post->getSubtitle()) {
352 $subtitle = phutil_tag_div('phame-header-subtitle', $post->getSubtitle());
355 return phutil_tag_div(
356 'phame-mega-header', array($image, $title, $subtitle));