| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  |  * Copyright 2011 Facebook, Inc. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  * you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  * You may obtain a copy of the License at | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *   http://www.apache.org/licenses/LICENSE-2.0 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  * distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  * See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  * limitations under the License. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class DifferentialRevisionViewController extends DifferentialController { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   private $revisionID; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   public function willProcessRequest(array $data) { | 
					
						
							|  |  |  |     $this->revisionID = $data['id']; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   public function processRequest() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $request = $this->getRequest(); | 
					
						
							| 
									
										
										
										
											2011-02-05 16:57:21 -08:00
										 |  |  |     $user = $request->getUser(); | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     $revision = id(new DifferentialRevision())->load($this->revisionID); | 
					
						
							|  |  |  |     if (!$revision) { | 
					
						
							|  |  |  |       return new Aphront404Response(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $revision->loadRelationships(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $diffs = $revision->loadDiffs(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-24 21:32:26 -07:00
										 |  |  |     if (!$diffs) { | 
					
						
							|  |  |  |       throw new Exception( | 
					
						
							|  |  |  |         "This revision has no diffs. Something has gone quite wrong."); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-03 15:41:58 -08:00
										 |  |  |     $diff_vs = $request->getInt('vs'); | 
					
						
							| 
									
										
										
										
											2011-04-11 12:32:08 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  |     $target = end($diffs); | 
					
						
							| 
									
										
										
										
											2011-04-11 12:32:08 -07:00
										 |  |  |     $target_id = $request->getInt('id'); | 
					
						
							|  |  |  |     if ($target_id) { | 
					
						
							|  |  |  |       if (isset($diffs[$target_id])) { | 
					
						
							|  |  |  |         $target = $diffs[$target_id]; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-03 15:41:58 -08:00
										 |  |  |     $diffs = mpull($diffs, null, 'getID'); | 
					
						
							|  |  |  |     if (empty($diffs[$diff_vs])) { | 
					
						
							|  |  |  |       $diff_vs = null; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     list($changesets, $vs_map) = | 
					
						
							|  |  |  |       $this->loadChangesetsAndVsMap($diffs, $diff_vs, $target); | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-30 10:37:36 -08:00
										 |  |  |     $comments = $revision->loadComments(); | 
					
						
							|  |  |  |     $comments = array_merge( | 
					
						
							|  |  |  |       $this->getImplicitComments($revision), | 
					
						
							|  |  |  |       $comments); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-07 22:01:33 -08:00
										 |  |  |     $all_changesets = $changesets; | 
					
						
							|  |  |  |     $inlines = $this->loadInlineComments($comments, $all_changesets); | 
					
						
							| 
									
										
										
										
											2011-02-02 19:38:43 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  |     $object_phids = array_merge( | 
					
						
							|  |  |  |       $revision->getReviewers(), | 
					
						
							|  |  |  |       $revision->getCCPHIDs(), | 
					
						
							| 
									
										
										
										
											2011-04-07 21:59:42 -07:00
										 |  |  |       $revision->loadCommitPHIDs(), | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  |       array( | 
					
						
							| 
									
										
										
										
											2011-01-30 10:37:36 -08:00
										 |  |  |         $revision->getAuthorPHID(), | 
					
						
							| 
									
										
										
										
											2011-02-05 16:57:21 -08:00
										 |  |  |         $user->getPHID(), | 
					
						
							| 
									
										
										
										
											2011-01-30 10:37:36 -08:00
										 |  |  |       ), | 
					
						
							|  |  |  |       mpull($comments, 'getAuthorPHID')); | 
					
						
							| 
									
										
										
										
											2011-02-17 14:32:01 -08:00
										 |  |  |     foreach ($revision->getAttached() as $type => $phids) { | 
					
						
							|  |  |  |       foreach ($phids as $phid => $info) { | 
					
						
							|  |  |  |         $object_phids[] = $phid; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-02-02 19:38:43 -08:00
										 |  |  |     $object_phids = array_unique($object_phids); | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     $handles = id(new PhabricatorObjectHandleData($object_phids)) | 
					
						
							|  |  |  |       ->loadHandles(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-05 16:43:28 -08:00
										 |  |  |     $request_uri = $request->getRequestURI(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $limit = 100; | 
					
						
							|  |  |  |     $large = $request->getStr('large'); | 
					
						
							|  |  |  |     if (count($changesets) > $limit && !$large) { | 
					
						
							|  |  |  |       $count = number_format(count($changesets)); | 
					
						
							|  |  |  |       $warning = new AphrontErrorView(); | 
					
						
							|  |  |  |       $warning->setTitle('Very Large Diff'); | 
					
						
							|  |  |  |       $warning->setSeverity(AphrontErrorView::SEVERITY_WARNING); | 
					
						
							|  |  |  |       $warning->setWidth(AphrontErrorView::WIDTH_WIDE); | 
					
						
							|  |  |  |       $warning->appendChild( | 
					
						
							|  |  |  |         "<p>This diff is very large and affects {$count} files. Only ". | 
					
						
							|  |  |  |         "the first {$limit} files are shown. ". | 
					
						
							|  |  |  |         "<strong>". | 
					
						
							|  |  |  |           phutil_render_tag( | 
					
						
							|  |  |  |             'a', | 
					
						
							|  |  |  |             array( | 
					
						
							|  |  |  |               'href' => $request_uri->alter('large', 'true'), | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |             'Show All Files'). | 
					
						
							|  |  |  |         "</strong>"); | 
					
						
							|  |  |  |       $warning = $warning->render(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       $visible_changesets = array_slice($changesets, 0, $limit, true); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       $warning = null; | 
					
						
							|  |  |  |       $visible_changesets = $changesets; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-10 15:50:26 -07:00
										 |  |  |     $diff_properties = id(new DifferentialDiffProperty())->loadAllWhere( | 
					
						
							|  |  |  |       'diffID = %d AND name IN (%Ls)', | 
					
						
							|  |  |  |       $target->getID(), | 
					
						
							|  |  |  |       array( | 
					
						
							|  |  |  |         'arc:lint', | 
					
						
							|  |  |  |         'arc:unit', | 
					
						
							|  |  |  |       )); | 
					
						
							|  |  |  |     $diff_properties = mpull($diff_properties, 'getData', 'getName'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  |     $revision_detail = new DifferentialRevisionDetailView(); | 
					
						
							|  |  |  |     $revision_detail->setRevision($revision); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-12 15:57:29 -07:00
										 |  |  |     $custom_renderer_class = PhabricatorEnv::getEnvConfig( | 
					
						
							|  |  |  |       'differential.revision-custom-detail-renderer'); | 
					
						
							|  |  |  |     if ($custom_renderer_class) { | 
					
						
							|  |  |  |       PhutilSymbolLoader::loadClass($custom_renderer_class); | 
					
						
							|  |  |  |       $custom_renderer = | 
					
						
							|  |  |  |         newv($custom_renderer_class, array()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-10 15:50:26 -07:00
										 |  |  |     $properties = $this->getRevisionProperties( | 
					
						
							|  |  |  |       $revision, | 
					
						
							|  |  |  |       $target, | 
					
						
							|  |  |  |       $handles, | 
					
						
							|  |  |  |       $diff_properties); | 
					
						
							| 
									
										
										
										
											2011-04-12 15:57:29 -07:00
										 |  |  |     if ($custom_renderer) { | 
					
						
							|  |  |  |       $properties = array_merge( | 
					
						
							|  |  |  |         $properties, | 
					
						
							|  |  |  |         $custom_renderer->generateProperties($revision, $target)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  |     $revision_detail->setProperties($properties); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $actions = $this->getRevisionActions($revision); | 
					
						
							| 
									
										
										
										
											2011-04-12 15:57:29 -07:00
										 |  |  |     if ($custom_renderer) { | 
					
						
							|  |  |  |       $actions = array_merge( | 
					
						
							|  |  |  |         $actions, | 
					
						
							|  |  |  |         $custom_renderer->generateActionLinks($revision, $target)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  |     $revision_detail->setActions($actions); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-30 10:37:36 -08:00
										 |  |  |     $comment_view = new DifferentialRevisionCommentListView(); | 
					
						
							|  |  |  |     $comment_view->setComments($comments); | 
					
						
							|  |  |  |     $comment_view->setHandles($handles); | 
					
						
							| 
									
										
										
										
											2011-02-02 19:38:43 -08:00
										 |  |  |     $comment_view->setInlineComments($inlines); | 
					
						
							| 
									
										
										
										
											2011-03-07 22:01:33 -08:00
										 |  |  |     $comment_view->setChangesets($all_changesets); | 
					
						
							| 
									
										
										
										
											2011-02-05 16:57:21 -08:00
										 |  |  |     $comment_view->setUser($user); | 
					
						
							| 
									
										
										
										
											2011-01-30 10:37:36 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     $diff_history = new DifferentialRevisionUpdateHistoryView(); | 
					
						
							|  |  |  |     $diff_history->setDiffs($diffs); | 
					
						
							| 
									
										
										
										
											2011-02-03 13:20:43 -08:00
										 |  |  |     $diff_history->setSelectedVersusDiffID($diff_vs); | 
					
						
							|  |  |  |     $diff_history->setSelectedDiffID($target->getID()); | 
					
						
							| 
									
										
										
										
											2011-01-30 10:37:36 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     $toc_view = new DifferentialDiffTableOfContentsView(); | 
					
						
							|  |  |  |     $toc_view->setChangesets($changesets); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $changeset_view = new DifferentialChangesetListView(); | 
					
						
							| 
									
										
										
										
											2011-02-05 16:43:28 -08:00
										 |  |  |     $changeset_view->setChangesets($visible_changesets); | 
					
						
							| 
									
										
										
										
											2011-02-01 15:52:04 -08:00
										 |  |  |     $changeset_view->setEditable(true); | 
					
						
							|  |  |  |     $changeset_view->setRevision($revision); | 
					
						
							| 
									
										
										
										
											2011-02-03 15:41:58 -08:00
										 |  |  |     $changeset_view->setVsMap($vs_map); | 
					
						
							| 
									
										
										
										
											2011-01-30 10:37:36 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-05 16:57:21 -08:00
										 |  |  |     $draft = id(new PhabricatorDraft())->loadOneWhere( | 
					
						
							|  |  |  |       'authorPHID = %s AND draftKey = %s', | 
					
						
							|  |  |  |       $user->getPHID(), | 
					
						
							|  |  |  |       'differential-comment-'.$revision->getID()); | 
					
						
							|  |  |  |     if ($draft) { | 
					
						
							|  |  |  |       $draft = $draft->getDraft(); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       $draft = null; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-30 11:02:22 -08:00
										 |  |  |     $comment_form = new DifferentialAddCommentView(); | 
					
						
							|  |  |  |     $comment_form->setRevision($revision); | 
					
						
							|  |  |  |     $comment_form->setActions($this->getRevisionCommentActions($revision)); | 
					
						
							| 
									
										
										
										
											2011-01-30 12:08:40 -08:00
										 |  |  |     $comment_form->setActionURI('/differential/comment/save/'); | 
					
						
							| 
									
										
										
										
											2011-02-05 16:57:21 -08:00
										 |  |  |     $comment_form->setUser($user); | 
					
						
							|  |  |  |     $comment_form->setDraft($draft); | 
					
						
							| 
									
										
										
										
											2011-01-30 11:02:22 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  |     return $this->buildStandardPageResponse( | 
					
						
							|  |  |  |       '<div class="differential-primary-pane">'. | 
					
						
							|  |  |  |         $revision_detail->render(). | 
					
						
							| 
									
										
										
										
											2011-01-30 10:37:36 -08:00
										 |  |  |         $comment_view->render(). | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  |         $diff_history->render(). | 
					
						
							|  |  |  |         $toc_view->render(). | 
					
						
							| 
									
										
										
										
											2011-02-05 16:43:28 -08:00
										 |  |  |         $warning. | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  |         $changeset_view->render(). | 
					
						
							| 
									
										
										
										
											2011-01-30 11:02:22 -08:00
										 |  |  |         $comment_form->render(). | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  |       '</div>', | 
					
						
							|  |  |  |       array( | 
					
						
							|  |  |  |         'title' => $revision->getTitle(), | 
					
						
							|  |  |  |       )); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-30 10:37:36 -08:00
										 |  |  |   private function getImplicitComments(DifferentialRevision $revision) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $template = new DifferentialComment(); | 
					
						
							|  |  |  |     $template->setAuthorPHID($revision->getAuthorPHID()); | 
					
						
							|  |  |  |     $template->setRevisionID($revision->getID()); | 
					
						
							|  |  |  |     $template->setDateCreated($revision->getDateCreated()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $comments = array(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (strlen($revision->getSummary())) { | 
					
						
							|  |  |  |       $summary_comment = clone $template; | 
					
						
							|  |  |  |       $summary_comment->setContent($revision->getSummary()); | 
					
						
							|  |  |  |       $summary_comment->setAction(DifferentialAction::ACTION_SUMMARIZE); | 
					
						
							|  |  |  |       $comments[] = $summary_comment; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (strlen($revision->getTestPlan())) { | 
					
						
							|  |  |  |       $testplan_comment = clone $template; | 
					
						
							|  |  |  |       $testplan_comment->setContent($revision->getTestPlan()); | 
					
						
							|  |  |  |       $testplan_comment->setAction(DifferentialAction::ACTION_TESTPLAN); | 
					
						
							|  |  |  |       $comments[] = $testplan_comment; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return $comments; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  |   private function getRevisionProperties( | 
					
						
							|  |  |  |     DifferentialRevision $revision, | 
					
						
							|  |  |  |     DifferentialDiff $diff, | 
					
						
							| 
									
										
										
										
											2011-04-10 15:50:26 -07:00
										 |  |  |     array $handles, | 
					
						
							|  |  |  |     array $diff_properties) { | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     $properties = array(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $status = $revision->getStatus(); | 
					
						
							|  |  |  |     $status = DifferentialRevisionStatus::getNameForRevisionStatus($status); | 
					
						
							|  |  |  |     $properties['Revision Status'] = '<strong>'.$status.'</strong>'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-30 10:37:36 -08:00
										 |  |  |     $author = $handles[$revision->getAuthorPHID()]; | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  |     $properties['Author'] = $author->renderLink(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $properties['Reviewers'] = $this->renderHandleLinkList( | 
					
						
							|  |  |  |       array_select_keys( | 
					
						
							|  |  |  |         $handles, | 
					
						
							|  |  |  |         $revision->getReviewers())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $properties['CCs'] = $this->renderHandleLinkList( | 
					
						
							|  |  |  |       array_select_keys( | 
					
						
							|  |  |  |         $handles, | 
					
						
							|  |  |  |         $revision->getCCPHIDs())); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-04 17:53:14 -08:00
										 |  |  |     $host = $diff->getSourceMachine(); | 
					
						
							|  |  |  |     if ($host) { | 
					
						
							|  |  |  |       $properties['Host'] = phutil_escape_html($host); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  |     $path = $diff->getSourcePath(); | 
					
						
							|  |  |  |     if ($path) { | 
					
						
							| 
									
										
										
										
											2011-02-04 17:53:14 -08:00
										 |  |  |       $branch = $diff->getBranch() ? ' ('.$diff->getBranch().')' : ''; | 
					
						
							|  |  |  |       $properties['Path'] = phutil_escape_html("{$path} {$branch}"); | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-04 17:53:14 -08:00
										 |  |  |     $lstar = DifferentialRevisionUpdateHistoryView::renderDiffLintStar($diff); | 
					
						
							|  |  |  |     $lmsg = DifferentialRevisionUpdateHistoryView::getDiffLintMessage($diff); | 
					
						
							| 
									
										
										
										
											2011-04-10 15:50:26 -07:00
										 |  |  |     $ldata = idx($diff_properties, 'arc:lint'); | 
					
						
							|  |  |  |     $ltail = null; | 
					
						
							|  |  |  |     if ($ldata) { | 
					
						
							|  |  |  |       $ldata = igroup($ldata, 'path'); | 
					
						
							|  |  |  |       $lint_messages = array(); | 
					
						
							|  |  |  |       foreach ($ldata as $path => $messages) { | 
					
						
							|  |  |  |         $message_markup = array(); | 
					
						
							|  |  |  |         foreach ($messages as $message) { | 
					
						
							|  |  |  |           $path = idx($message, 'path'); | 
					
						
							|  |  |  |           $line = idx($message, 'line'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           $code = idx($message, 'code'); | 
					
						
							|  |  |  |           $severity = idx($message, 'severity'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           $name = idx($message, 'name'); | 
					
						
							|  |  |  |           $description = idx($message, 'description'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           $message_markup[] = | 
					
						
							|  |  |  |             '<li>'. | 
					
						
							|  |  |  |               '<span class="lint-severity-'.phutil_escape_html($severity).'">'. | 
					
						
							|  |  |  |                 phutil_escape_html(ucwords($severity)). | 
					
						
							|  |  |  |               '</span>'. | 
					
						
							|  |  |  |               ' '. | 
					
						
							|  |  |  |               '('.phutil_escape_html($code).') '. | 
					
						
							|  |  |  |               phutil_escape_html($name). | 
					
						
							|  |  |  |               ' at line '.phutil_escape_html($line). | 
					
						
							|  |  |  |               '<p>'.phutil_escape_html($description).'</p>'. | 
					
						
							|  |  |  |             '</li>'; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         $lint_messages[] = | 
					
						
							|  |  |  |           '<li class="lint-file-block">'. | 
					
						
							|  |  |  |             'Lint for <strong>'.phutil_escape_html($path).'</strong>'. | 
					
						
							|  |  |  |             '<ul>'.implode("\n", $message_markup).'</ul>'. | 
					
						
							|  |  |  |           '</li>'; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       $ltail = | 
					
						
							|  |  |  |         '<div class="differential-lint-block">'. | 
					
						
							|  |  |  |           '<ul>'. | 
					
						
							|  |  |  |             implode("\n", $lint_messages). | 
					
						
							|  |  |  |           '</ul>'. | 
					
						
							|  |  |  |         '</div>'; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $properties['Lint'] = $lstar.' '.$lmsg.$ltail; | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-04 17:53:14 -08:00
										 |  |  |     $ustar = DifferentialRevisionUpdateHistoryView::renderDiffUnitStar($diff); | 
					
						
							|  |  |  |     $umsg = DifferentialRevisionUpdateHistoryView::getDiffUnitMessage($diff); | 
					
						
							| 
									
										
										
										
											2011-04-10 15:50:26 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     $udata = idx($diff_properties, 'arc:unit'); | 
					
						
							|  |  |  |     $utail = null; | 
					
						
							|  |  |  |     if ($udata) { | 
					
						
							|  |  |  |       $unit_messages = array(); | 
					
						
							|  |  |  |       foreach ($udata as $test) { | 
					
						
							|  |  |  |         $name = phutil_escape_html(idx($test, 'name')); | 
					
						
							|  |  |  |         $result = phutil_escape_html(idx($test, 'result')); | 
					
						
							|  |  |  |         $userdata = phutil_escape_html(idx($test, 'userdata')); | 
					
						
							| 
									
										
										
										
											2011-04-10 17:47:47 -07:00
										 |  |  |         if (strlen($userdata) > 256) { | 
					
						
							|  |  |  |           $userdata = substr($userdata, 0, 256).'...'; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         $userdata = str_replace("\n", '<br />', $userdata); | 
					
						
							| 
									
										
										
										
											2011-04-10 15:50:26 -07:00
										 |  |  |         $unit_messages[] = | 
					
						
							|  |  |  |           '<tr>'. | 
					
						
							|  |  |  |             '<th>'.$name.'</th>'. | 
					
						
							| 
									
										
										
										
											2011-04-10 17:47:47 -07:00
										 |  |  |             '<th class="unit-test-result">'. | 
					
						
							|  |  |  |               '<div class="result-'.$result.'">'. | 
					
						
							|  |  |  |                 strtoupper($result). | 
					
						
							|  |  |  |               '</div>'. | 
					
						
							| 
									
										
										
										
											2011-04-10 15:50:26 -07:00
										 |  |  |             '</th>'. | 
					
						
							|  |  |  |             '<td>'.$userdata.'</td>'. | 
					
						
							|  |  |  |           '</tr>'; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       $utail = | 
					
						
							|  |  |  |         '<div class="differential-unit-block">'. | 
					
						
							|  |  |  |           '<table class="differential-unit-table">'. | 
					
						
							|  |  |  |             implode("\n", $unit_messages). | 
					
						
							|  |  |  |           '</table>'. | 
					
						
							|  |  |  |         '</div>'; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $properties['Unit'] = $ustar.' '.$umsg.$utail; | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-02 18:58:21 -08:00
										 |  |  |     $tasks = $revision->getAttachedPHIDs( | 
					
						
							|  |  |  |       PhabricatorPHIDConstants::PHID_TYPE_TASK); | 
					
						
							| 
									
										
										
										
											2011-02-17 14:32:01 -08:00
										 |  |  |     if ($tasks) { | 
					
						
							|  |  |  |       $links = array(); | 
					
						
							|  |  |  |       foreach ($tasks as $task_phid) { | 
					
						
							|  |  |  |         $links[] = $handles[$task_phid]->renderLink(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       $properties['Maniphest Tasks'] = implode('<br />', $links); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-07 21:59:42 -07:00
										 |  |  |     $commit_phids = $revision->getCommitPHIDs(); | 
					
						
							|  |  |  |     if ($commit_phids) { | 
					
						
							|  |  |  |       $links = array(); | 
					
						
							|  |  |  |       foreach ($commit_phids as $commit_phid) { | 
					
						
							|  |  |  |         $links[] = $handles[$commit_phid]->renderLink(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       $properties['Commits'] = implode('<br />', $links); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  |     return $properties; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   private function getRevisionActions(DifferentialRevision $revision) { | 
					
						
							|  |  |  |     $viewer_phid = $this->getRequest()->getUser()->getPHID(); | 
					
						
							| 
									
										
										
										
											2011-01-30 10:37:36 -08:00
										 |  |  |     $viewer_is_owner = ($revision->getAuthorPHID() == $viewer_phid); | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  |     $viewer_is_reviewer = in_array($viewer_phid, $revision->getReviewers()); | 
					
						
							|  |  |  |     $viewer_is_cc = in_array($viewer_phid, $revision->getCCPHIDs()); | 
					
						
							|  |  |  |     $status = $revision->getStatus(); | 
					
						
							|  |  |  |     $revision_id = $revision->getID(); | 
					
						
							|  |  |  |     $revision_phid = $revision->getPHID(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $links = array(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ($viewer_is_owner) { | 
					
						
							|  |  |  |       $links[] = array( | 
					
						
							|  |  |  |         'class' => 'revision-edit', | 
					
						
							|  |  |  |         'href'  => "/differential/revision/edit/{$revision_id}/", | 
					
						
							|  |  |  |         'name'  => 'Edit Revision', | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!$viewer_is_owner && !$viewer_is_reviewer) { | 
					
						
							|  |  |  |       $action = $viewer_is_cc ? 'rem' : 'add'; | 
					
						
							|  |  |  |       $links[] = array( | 
					
						
							|  |  |  |         'class' => $viewer_is_cc ? 'subscribe-rem' : 'subscribe-add', | 
					
						
							|  |  |  |         'href'  => "/differential/subscribe/{$action}/{$revision_id}/", | 
					
						
							|  |  |  |         'name'  => $viewer_is_cc ? 'Unsubscribe' : 'Subscribe', | 
					
						
							| 
									
										
										
										
											2011-02-19 14:36:13 -08:00
										 |  |  |         'sigil' => 'workflow', | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  |       ); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       $links[] = array( | 
					
						
							|  |  |  |         'class' => 'subscribe-rem unavailable', | 
					
						
							|  |  |  |         'name'  => 'Automatically Subscribed', | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-17 14:32:01 -08:00
										 |  |  |     require_celerity_resource('phabricator-object-selector-css'); | 
					
						
							|  |  |  |     require_celerity_resource('javelin-behavior-phabricator-object-selector'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $links[] = array( | 
					
						
							|  |  |  |       'class' => 'attach-maniphest', | 
					
						
							|  |  |  |       'name'  => 'Edit Maniphest Tasks', | 
					
						
							|  |  |  |       'href'  => "/differential/attach/{$revision_id}/TASK/", | 
					
						
							|  |  |  |       'sigil' => 'workflow', | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  |     $links[] = array( | 
					
						
							|  |  |  |       'class' => 'transcripts-metamta', | 
					
						
							|  |  |  |       'name'  => 'MetaMTA Transcripts', | 
					
						
							|  |  |  |       'href'  => "/mail/?phid={$revision_phid}", | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-07 14:24:54 -07:00
										 |  |  |     $links[] = array( | 
					
						
							|  |  |  |       'class' => 'transcripts-herald', | 
					
						
							|  |  |  |       'name'  => 'Herald Transcripts', | 
					
						
							|  |  |  |       'href'  => "/herald/transcript/?phid={$revision_phid}", | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  |     return $links; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   private function renderHandleLinkList(array $list) { | 
					
						
							|  |  |  |     if (empty($list)) { | 
					
						
							|  |  |  |       return '<em>None</em>'; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return implode(', ', mpull($list, 'renderLink')); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-30 11:02:22 -08:00
										 |  |  |   private function getRevisionCommentActions(DifferentialRevision $revision) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $actions = array( | 
					
						
							|  |  |  |       DifferentialAction::ACTION_COMMENT => true, | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $viewer_phid = $this->getRequest()->getUser()->getPHID(); | 
					
						
							|  |  |  |     $viewer_is_owner = ($viewer_phid == $revision->getAuthorPHID()); | 
					
						
							| 
									
										
										
										
											2011-04-11 10:38:10 -07:00
										 |  |  |     $viewer_is_reviewer = in_array($viewer_phid, $revision->getReviewers()); | 
					
						
							| 
									
										
										
										
											2011-01-30 11:02:22 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if ($viewer_is_owner) { | 
					
						
							|  |  |  |       switch ($revision->getStatus()) { | 
					
						
							|  |  |  |         case DifferentialRevisionStatus::NEEDS_REVIEW: | 
					
						
							|  |  |  |           $actions[DifferentialAction::ACTION_ABANDON] = true; | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |         case DifferentialRevisionStatus::NEEDS_REVISION: | 
					
						
							|  |  |  |         case DifferentialRevisionStatus::ACCEPTED: | 
					
						
							|  |  |  |           $actions[DifferentialAction::ACTION_ABANDON] = true; | 
					
						
							|  |  |  |           $actions[DifferentialAction::ACTION_REQUEST] = true; | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |         case DifferentialRevisionStatus::COMMITTED: | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |         case DifferentialRevisionStatus::ABANDONED: | 
					
						
							|  |  |  |           $actions[DifferentialAction::ACTION_RECLAIM] = true; | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       switch ($revision->getStatus()) { | 
					
						
							|  |  |  |         case DifferentialRevisionStatus::NEEDS_REVIEW: | 
					
						
							|  |  |  |           $actions[DifferentialAction::ACTION_ACCEPT] = true; | 
					
						
							|  |  |  |           $actions[DifferentialAction::ACTION_REJECT] = true; | 
					
						
							| 
									
										
										
										
											2011-04-11 10:38:10 -07:00
										 |  |  |           $actions[DifferentialAction::ACTION_RESIGN] = $viewer_is_reviewer; | 
					
						
							| 
									
										
										
										
											2011-01-30 11:02:22 -08:00
										 |  |  |           break; | 
					
						
							|  |  |  |         case DifferentialRevisionStatus::NEEDS_REVISION: | 
					
						
							|  |  |  |           $actions[DifferentialAction::ACTION_ACCEPT] = true; | 
					
						
							| 
									
										
										
										
											2011-04-11 10:38:10 -07:00
										 |  |  |           $actions[DifferentialAction::ACTION_RESIGN] = $viewer_is_reviewer; | 
					
						
							| 
									
										
										
										
											2011-01-30 11:02:22 -08:00
										 |  |  |           break; | 
					
						
							|  |  |  |         case DifferentialRevisionStatus::ACCEPTED: | 
					
						
							|  |  |  |           $actions[DifferentialAction::ACTION_REJECT] = true; | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |         case DifferentialRevisionStatus::COMMITTED: | 
					
						
							|  |  |  |         case DifferentialRevisionStatus::ABANDONED: | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $actions[DifferentialAction::ACTION_ADDREVIEWERS] = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return array_keys($actions); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-02 19:38:43 -08:00
										 |  |  |   private function loadInlineComments(array $comments, array &$changesets) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $inline_comments = array(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $comment_ids = array_filter(mpull($comments, 'getID')); | 
					
						
							|  |  |  |     if (!$comment_ids) { | 
					
						
							|  |  |  |       return $inline_comments; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $inline_comments = id(new DifferentialInlineComment()) | 
					
						
							|  |  |  |       ->loadAllWhere( | 
					
						
							|  |  |  |         'commentID in (%Ld)', | 
					
						
							|  |  |  |         $comment_ids); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $load_changesets = array(); | 
					
						
							|  |  |  |     foreach ($inline_comments as $inline) { | 
					
						
							|  |  |  |       $changeset_id = $inline->getChangesetID(); | 
					
						
							|  |  |  |       if (isset($changesets[$changeset_id])) { | 
					
						
							|  |  |  |         continue; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       $load_changesets[$changeset_id] = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $more_changesets = array(); | 
					
						
							|  |  |  |     if ($load_changesets) { | 
					
						
							|  |  |  |       $changeset_ids = array_keys($load_changesets); | 
					
						
							|  |  |  |       $more_changesets += id(new DifferentialChangeset()) | 
					
						
							|  |  |  |         ->loadAllWhere( | 
					
						
							|  |  |  |           'id IN (%Ld)', | 
					
						
							|  |  |  |           $changeset_ids); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ($more_changesets) { | 
					
						
							|  |  |  |       $changesets += $more_changesets; | 
					
						
							|  |  |  |       $changesets = msort($changesets, 'getSortKey'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return $inline_comments; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-03 15:41:58 -08:00
										 |  |  |   private function loadChangesetsAndVsMap(array $diffs, $diff_vs, $target) { | 
					
						
							|  |  |  |     $load_ids = array(); | 
					
						
							|  |  |  |     if ($diff_vs) { | 
					
						
							|  |  |  |       $load_ids[] = $diff_vs; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     $load_ids[] = $target->getID(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $raw_changesets = id(new DifferentialChangeset()) | 
					
						
							|  |  |  |       ->loadAllWhere( | 
					
						
							|  |  |  |         'diffID IN (%Ld)', | 
					
						
							|  |  |  |         $load_ids); | 
					
						
							|  |  |  |     $changeset_groups = mgroup($raw_changesets, 'getDiffID'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $changesets = idx($changeset_groups, $target->getID(), array()); | 
					
						
							|  |  |  |     $changesets = mpull($changesets, null, 'getID'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $vs_map = array(); | 
					
						
							|  |  |  |     if ($diff_vs) { | 
					
						
							|  |  |  |       $vs_changesets = idx($changeset_groups, $diff_vs, array()); | 
					
						
							|  |  |  |       $vs_changesets = mpull($vs_changesets, null, 'getFilename'); | 
					
						
							|  |  |  |       foreach ($changesets as $key => $changeset) { | 
					
						
							|  |  |  |         $file = $changeset->getFilename(); | 
					
						
							|  |  |  |         if (isset($vs_changesets[$file])) { | 
					
						
							|  |  |  |           $vs_map[$changeset->getID()] = $vs_changesets[$file]->getID(); | 
					
						
							|  |  |  |           unset($vs_changesets[$file]); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       foreach ($vs_changesets as $changeset) { | 
					
						
							|  |  |  |         $changesets[$changeset->getID()] = $changeset; | 
					
						
							|  |  |  |         $vs_map[$changeset->getID()] = -1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $changesets = msort($changesets, 'getSortKey'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return array($changesets, $vs_map); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 14:55:52 -08:00
										 |  |  | } | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   protected function getSandcastleURI(Diff $diff) { | 
					
						
							|  |  |  |     $uri = $this->getDiffProperty($diff, 'facebook:sandcastle_uri'); | 
					
						
							|  |  |  |     if (!$uri) { | 
					
						
							|  |  |  |       $uri = $diff->getSandboxURL(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return $uri; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   protected function getDiffProperty(Diff $diff, $property, $default = null) { | 
					
						
							|  |  |  |     $diff_id = $diff->getID(); | 
					
						
							|  |  |  |     if (empty($this->diffProperties[$diff_id])) { | 
					
						
							|  |  |  |       $props = id(new DifferentialDiffProperty()) | 
					
						
							|  |  |  |         ->loadAllWhere('diffID = %s', $diff_id); | 
					
						
							|  |  |  |       $dict = array_pull($props, 'getData', 'getName'); | 
					
						
							|  |  |  |       $this->diffProperties[$diff_id] = $dict; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return idx($this->diffProperties[$diff_id], $property, $default); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $diff_table->appendChild( | 
					
						
							|  |  |  |       <tr> | 
					
						
							|  |  |  |         <td colspan="8" class="diff-differ-submit"> | 
					
						
							|  |  |  |           <label>Whitespace Changes:</label> | 
					
						
							|  |  |  |           {id(<select name="whitespace" />)->setOptions( | 
					
						
							|  |  |  |             array( | 
					
						
							|  |  |  |               'ignore-all'      => 'Ignore All', | 
					
						
							|  |  |  |               'ignore-trailing' => 'Ignore Trailing', | 
					
						
							|  |  |  |               'show-all'        => 'Show All', | 
					
						
							|  |  |  |             ), $request->getStr('whitespace'))}{' '} | 
					
						
							|  |  |  |           <button type="submit">Show Diff</button> | 
					
						
							|  |  |  |         </td> | 
					
						
							|  |  |  |       </tr>); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $load_ids = array_filter(array($old, $diff->getID())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $viewer_id = $this->getRequest()->getViewerContext()->getUserID(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $raw_objects = queryfx_all( | 
					
						
							|  |  |  |       smc_get_db('cdb.differential', 'r'), | 
					
						
							|  |  |  |       'SELECT * FROM changeset WHERE changeset.diffID IN (%Ld)', | 
					
						
							|  |  |  |       $load_ids); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $raw_objects = array_group($raw_objects, 'diffID'); | 
					
						
							|  |  |  |     $objects = $raw_objects[$diff->getID()]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!$objects) { | 
					
						
							|  |  |  |       $changesets = array(); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       $changesets = id(new DifferentialChangeset())->loadAllFromArray($objects); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $feedback = id(new DifferentialFeedback())->loadAllWithRevision($revision); | 
					
						
							|  |  |  |     $feedback = array_merge($implied_feedback, $feedback); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $inline_comments = $this->loadInlineComments($feedback, $changesets); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $diff_map = array(); | 
					
						
							|  |  |  |     $diffs = array_psort($diffs, 'getID'); | 
					
						
							|  |  |  |     foreach ($diffs as $diff) { | 
					
						
							|  |  |  |       $diff_map[$diff->getID()] = count($diff_map) + 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     $visible_changesets = array_fill_keys($visible_changesets, true); | 
					
						
							|  |  |  |     $hidden_changesets = array(); | 
					
						
							|  |  |  |     foreach ($changesets as $changeset) { | 
					
						
							|  |  |  |       $id = $changeset->getID(); | 
					
						
							|  |  |  |       if (isset($visible_changesets[$id])) { | 
					
						
							|  |  |  |         continue; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       $hidden_changesets[$id] = $diff_map[$changeset->getDiffID()]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $engine = new RemarkupEngine(); | 
					
						
							|  |  |  |     $engine->enableFeature(RemarkupEngine::FEATURE_GUESS_IMAGES); | 
					
						
							|  |  |  |     $engine->enableFeature(RemarkupEngine::FEATURE_YOUTUBE); | 
					
						
							|  |  |  |     $engine->setCurrentSandcastle($this->getSandcastleURI($target_diff)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $syntax_link = | 
					
						
							|  |  |  |       <a href={'http://www.intern.facebook.com/intern/wiki/index.php' . | 
					
						
							|  |  |  |                '/Articles/Remarkup_Syntax_Reference'} | 
					
						
							|  |  |  |          target="_blank" | 
					
						
							|  |  |  |          tabindex="4">Remarkup Reference</a>; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $notice = null; | 
					
						
							|  |  |  |     if ($this->getRequest()->getBool('diff_changed')) { | 
					
						
							|  |  |  |       $notice = | 
					
						
							|  |  |  |         <tools:notice title="Revision Updated Recently"> | 
					
						
							|  |  |  |           This revision was updated with a <strong>new diff</strong> while you | 
					
						
							|  |  |  |           were providing feedback. Your inline comments appear on the | 
					
						
							|  |  |  |           <strong>old diff</strong>. | 
					
						
							|  |  |  |         </tools:notice>; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $engineering_repository_id = RepositoryRef::getByCallsign('E')->getID(); | 
					
						
							|  |  |  |     $svn_revision = $revision->getSVNRevision(); | 
					
						
							|  |  |  |     if ($status == DifferentialConstants::COMMITTED && | 
					
						
							|  |  |  |         $svn_revision && | 
					
						
							|  |  |  |         $revision->getRepositoryID() == $engineering_repository_id) { | 
					
						
							|  |  |  |       $href = '/intern/push/request.php?rev='.$svn_revision; | 
					
						
							|  |  |  |       $href = RedirectURI($href)->setTier('intern'); | 
					
						
							|  |  |  |       $links[] = array( | 
					
						
							|  |  |  |         'merge', | 
					
						
							|  |  |  |         <a href={$href} id="ask_for_merge_link">Ask for Merge</a>, | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   protected function renderDiffPropertyMoreLink(Diff $diff, $name) { | 
					
						
							|  |  |  |     $target = <div class="star-more" | 
					
						
							|  |  |  |                    style="display: none;"> | 
					
						
							|  |  |  |                 <div class="star-loading">Loading...</div> | 
					
						
							|  |  |  |               </div>; | 
					
						
							|  |  |  |     $meta = array( | 
					
						
							|  |  |  |       'target'  => $target->requireUniqueID(), | 
					
						
							|  |  |  |       'uri'     => '/differential/diffprop/'.$diff->getID().'/'.$name.'/', | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |     $more = | 
					
						
							|  |  |  |       <span sigil="star-link-container"> | 
					
						
							|  |  |  |         · | 
					
						
							|  |  |  |         <a mustcapture="true" | 
					
						
							|  |  |  |                  sigil="star-more" | 
					
						
							|  |  |  |                   href="#" | 
					
						
							|  |  |  |                   meta={$meta}>Show Details</a> | 
					
						
							|  |  |  |       </span>; | 
					
						
							|  |  |  |     return <x:frag>{$more}{$target}</x:frag>; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   protected function getRevisionStatusDisplay(DifferentialRevision $revision) { | 
					
						
							|  |  |  |     $viewer_id = $this->getRequest()->getViewerContext()->getUserID(); | 
					
						
							|  |  |  |     $viewer_is_owner = ($viewer_id == $revision->getOwnerID()); | 
					
						
							|  |  |  |     $status = $revision->getStatus(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $more = null; | 
					
						
							|  |  |  |     switch ($status) { | 
					
						
							|  |  |  |       case DifferentialConstants::NEEDS_REVIEW: | 
					
						
							|  |  |  |         $message = 'Pending Review'; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case DifferentialConstants::NEEDS_REVISION: | 
					
						
							|  |  |  |         $message = 'Awaiting Revision'; | 
					
						
							|  |  |  |         if ($viewer_is_owner) { | 
					
						
							|  |  |  |           $more = 'Make the requested changes and update the revision.'; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case DifferentialConstants::ACCEPTED: | 
					
						
							|  |  |  |         $message = 'Ready for Commit'; | 
					
						
							|  |  |  |         if ($viewer_is_owner) { | 
					
						
							|  |  |  |           $more = | 
					
						
							|  |  |  |             <x:frag> | 
					
						
							|  |  |  |               Run <tt>arc commit</tt> (svn) or <tt>arc amend</tt> (git) to | 
					
						
							|  |  |  |               proceed. | 
					
						
							|  |  |  |             </x:frag>; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case DifferentialConstants::COMMITTED: | 
					
						
							|  |  |  |         $message = 'Committed'; | 
					
						
							|  |  |  |         $ref = $revision->getRevisionRef(); | 
					
						
							|  |  |  |         $more = $ref | 
					
						
							|  |  |  |                 ? (<a href={URI($ref->getDetailURL())}> | 
					
						
							|  |  |  |                      {$ref->getName()} | 
					
						
							|  |  |  |                    </a>) | 
					
						
							|  |  |  |                 : null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $engineering_repository_id = RepositoryRef::getByCallsign('E')->getID(); | 
					
						
							|  |  |  |         if ($revision->getSVNRevision() && | 
					
						
							|  |  |  |             $revision->getRepositoryID() == $engineering_repository_id) { | 
					
						
							|  |  |  |           Javelin::initBehavior( | 
					
						
							|  |  |  |             'differential-revtracker-status', | 
					
						
							|  |  |  |             array( | 
					
						
							|  |  |  |               'uri' => '/differential/revtracker/'.$revision->getID().'/', | 
					
						
							|  |  |  |               'statusId' => 'revtracker_status', | 
					
						
							|  |  |  |               'mergeLinkId' => 'ask_for_merge_link', | 
					
						
							|  |  |  |             )); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case DifferentialConstants::ABANDONED: | 
					
						
							|  |  |  |         $message = 'Abandoned'; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       default: | 
					
						
							|  |  |  |         throw new Exception("Unknown revision status."); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ($more) { | 
					
						
							|  |  |  |       $message = | 
					
						
							|  |  |  |         <x:frag> | 
					
						
							|  |  |  |           <strong id="revtracker_status">{$message}</strong> | 
					
						
							|  |  |  |           · {$more} | 
					
						
							|  |  |  |         </x:frag>; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       $message = <strong id="revtracker_status">{$message}</strong>; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return $message; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  |   protected function getDetailFields( | 
					
						
							|  |  |  |     DifferentialRevision $revision, | 
					
						
							|  |  |  |     Diff $diff, | 
					
						
							|  |  |  |     array $handles) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $sandcastle = $this->getSandcastleURI($diff); | 
					
						
							|  |  |  |     if ($sandcastle) { | 
					
						
							|  |  |  |       $fields['Sandcastle'] = <a href={$sandcastle}>{$sandcastle}</a>; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $blame_rev = $revision->getSvnBlameRevision(); | 
					
						
							|  |  |  |     if ($blame_rev) { | 
					
						
							|  |  |  |       if ($revision->getRepositoryRef() && is_numeric($blame_rev)) { | 
					
						
							|  |  |  |         $ref = new RevisionRef($revision->getRepositoryRef(), $blame_rev); | 
					
						
							|  |  |  |         $fields['Blame Revision'] = | 
					
						
							|  |  |  |           <a href={URI($ref->getDetailURL())}> | 
					
						
							|  |  |  |             {$ref->getName()} | 
					
						
							|  |  |  |           </a>; | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         $fields['Blame Revision'] = $blame_rev; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $bugzilla_id = $revision->getBugzillaID(); | 
					
						
							|  |  |  |     if ($bugzilla_id) { | 
					
						
							|  |  |  |       $href = 'http://bugs.developers.facebook.com/show_bug.cgi?id='. | 
					
						
							|  |  |  |         $bugzilla_id; | 
					
						
							|  |  |  |       $fields['Bugzilla'] = <a href={$href}>{'#'.$bugzilla_id}</a>; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $fields['Apply Patch'] = <tt>arc patch --revision {$revision->getID()}</tt>; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ($diff->getParentRevisionID()) { | 
					
						
							|  |  |  |       $parent = id(new DifferentialRevision())->load( | 
					
						
							|  |  |  |         $diff->getParentRevisionID()); | 
					
						
							|  |  |  |       if ($parent) { | 
					
						
							|  |  |  |         $fields['Depends On'] = | 
					
						
							|  |  |  |           <a href={$parent->getURI()}> | 
					
						
							|  |  |  |             D{$parent->getID()}: {$parent->getName()} | 
					
						
							|  |  |  |           </a>; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Javelin::initBehavior('differential-star-more'); | 
					
						
							|  |  |  |     if ($unit_details) { | 
					
						
							|  |  |  |       $fields['Unit Tests'] = | 
					
						
							|  |  |  |         <x:frag> | 
					
						
							|  |  |  |           {$fields['Unit Tests']} | 
					
						
							|  |  |  |           {$this->renderDiffPropertyMoreLink($diff, 'unit')} | 
					
						
							|  |  |  |         </x:frag>; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $platform_impact = $revision->getPlatformImpact(); | 
					
						
							|  |  |  |     if ($platform_impact) { | 
					
						
							|  |  |  |       $fields['Platform Impact'] = | 
					
						
							|  |  |  |         <text linebreaks="true">{$platform_impact}</text>; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return $fields; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | */ |