private function handleHovercardEvent($event) { $viewer = $event->getUser(); $hovercard = $event->getValue('hovercard'); $object_handle = $event->getValue('handle'); $commit = $event->getValue('object'); if (!$commit instanceof PhabricatorRepositoryCommit) { return; } $commit_data = $commit->loadCommitData(); $revision = PhabricatorEdgeQuery::loadDestinationPHIDs($commit->getPHID(), PhabricatorEdgeConfig::TYPE_COMMIT_HAS_DREV); $revision = reset($revision); $author = $commit->getAuthorPHID(); $phids = array_filter(array($revision, $author)); $handles = id(new PhabricatorHandleQuery())->setViewer($viewer)->withPHIDs($phids)->execute(); if ($author) { $author = $handles[$author]->renderLink(); } else { $author = phutil_tag('em', array(), $commit_data->getAuthorName()); } $hovercard->setTitle($object_handle->getName()); $hovercard->setDetail($commit->getSummary()); $hovercard->addField(pht('Author'), $author); $hovercard->addField(pht('Date'), phabricator_date($commit->getEpoch(), $viewer)); if ($commit->getAuditStatus() != PhabricatorAuditCommitStatusConstants::NONE) { $hovercard->addField(pht('Audit Status'), PhabricatorAuditCommitStatusConstants::getStatusName($commit->getAuditStatus())); } if ($revision) { $rev_handle = $handles[$revision]; $hovercard->addField(pht('Revision'), $rev_handle->renderLink()); } $event->setValue('hovercard', $hovercard); }
public function renderHovercard(PhabricatorHovercardView $hovercard, PhabricatorObjectHandle $handle, $commit, $data) { $viewer = $this->getViewer(); $author_phid = $commit->getAuthorPHID(); if ($author_phid) { $author = $viewer->renderHandle($author_phid); } else { $commit_data = $commit->loadCommitData(); $author = phutil_tag('em', array(), $commit_data->getAuthorName()); } $hovercard->setTitle($handle->getName()); $hovercard->setDetail($commit->getSummary()); $hovercard->addField(pht('Author'), $author); $hovercard->addField(pht('Date'), phabricator_date($commit->getEpoch(), $viewer)); if ($commit->getAuditStatus() != PhabricatorAuditCommitStatusConstants::NONE) { $hovercard->addField(pht('Audit Status'), PhabricatorAuditCommitStatusConstants::getStatusName($commit->getAuditStatus())); } }
public function render() { $rows = array(); foreach ($this->commits as $commit) { $commit_name = $this->getHandle($commit->getPHID())->renderLink(); $author_name = null; if ($commit->getAuthorPHID()) { $author_name = $this->getHandle($commit->getAuthorPHID())->renderLink(); } $rows[] = array($commit_name, $author_name, phutil_escape_html($commit->getCommitData()->getSummary()), PhabricatorAuditCommitStatusConstants::getStatusName($commit->getAuditStatus()), phabricator_datetime($commit->getEpoch(), $this->user)); } $table = new AphrontTableView($rows); $table->setHeaders(array('Commit', 'Author', 'Summary', 'Audit Status', 'Date')); $table->setColumnClasses(array('n', '', 'wide', '', '')); if ($this->noDataString) { $table->setNoDataString($this->noDataString); } return $table->render(); }
private function loadCommitProperties(PhabricatorRepositoryCommit $commit, PhabricatorRepositoryCommitData $data, array $parents, array $audit_requests) { assert_instances_of($parents, 'PhabricatorRepositoryCommit'); $viewer = $this->getRequest()->getUser(); $commit_phid = $commit->getPHID(); $drequest = $this->getDiffusionRequest(); $repository = $drequest->getRepository(); $edge_query = id(new PhabricatorEdgeQuery())->withSourcePHIDs(array($commit_phid))->withEdgeTypes(array(DiffusionCommitHasTaskEdgeType::EDGECONST, DiffusionCommitHasRevisionEdgeType::EDGECONST, DiffusionCommitRevertsCommitEdgeType::EDGECONST, DiffusionCommitRevertedByCommitEdgeType::EDGECONST)); $edges = $edge_query->execute(); $task_phids = array_keys($edges[$commit_phid][DiffusionCommitHasTaskEdgeType::EDGECONST]); $revision_phid = key($edges[$commit_phid][DiffusionCommitHasRevisionEdgeType::EDGECONST]); $reverts_phids = array_keys($edges[$commit_phid][DiffusionCommitRevertsCommitEdgeType::EDGECONST]); $reverted_by_phids = array_keys($edges[$commit_phid][DiffusionCommitRevertedByCommitEdgeType::EDGECONST]); $phids = $edge_query->getDestinationPHIDs(array($commit_phid)); if ($data->getCommitDetail('authorPHID')) { $phids[] = $data->getCommitDetail('authorPHID'); } if ($data->getCommitDetail('reviewerPHID')) { $phids[] = $data->getCommitDetail('reviewerPHID'); } if ($data->getCommitDetail('committerPHID')) { $phids[] = $data->getCommitDetail('committerPHID'); } if ($parents) { foreach ($parents as $parent) { $phids[] = $parent->getPHID(); } } // NOTE: We should never normally have more than a single push log, but // it can occur naturally if a commit is pushed, then the branch it was // on is deleted, then the commit is pushed again (or through other similar // chains of events). This should be rare, but does not indicate a bug // or data issue. // NOTE: We never query push logs in SVN because the commiter is always // the pusher and the commit time is always the push time; the push log // is redundant and we save a query by skipping it. $push_logs = array(); if ($repository->isHosted() && !$repository->isSVN()) { $push_logs = id(new PhabricatorRepositoryPushLogQuery())->setViewer($viewer)->withRepositoryPHIDs(array($repository->getPHID()))->withNewRefs(array($commit->getCommitIdentifier()))->withRefTypes(array(PhabricatorRepositoryPushLog::REFTYPE_COMMIT))->execute(); foreach ($push_logs as $log) { $phids[] = $log->getPusherPHID(); } } $handles = array(); if ($phids) { $handles = $this->loadViewerHandles($phids); } $props = array(); if ($commit->getAuditStatus()) { $status = PhabricatorAuditCommitStatusConstants::getStatusName($commit->getAuditStatus()); $tag = id(new PHUITagView())->setType(PHUITagView::TYPE_STATE)->setName($status); switch ($commit->getAuditStatus()) { case PhabricatorAuditCommitStatusConstants::NEEDS_AUDIT: $tag->setBackgroundColor(PHUITagView::COLOR_ORANGE); break; case PhabricatorAuditCommitStatusConstants::CONCERN_RAISED: $tag->setBackgroundColor(PHUITagView::COLOR_RED); break; case PhabricatorAuditCommitStatusConstants::PARTIALLY_AUDITED: $tag->setBackgroundColor(PHUITagView::COLOR_BLUE); break; case PhabricatorAuditCommitStatusConstants::FULLY_AUDITED: $tag->setBackgroundColor(PHUITagView::COLOR_GREEN); break; } $props['Status'] = $tag; } if ($audit_requests) { $user_requests = array(); $other_requests = array(); foreach ($audit_requests as $audit_request) { if ($audit_request->isUser()) { $user_requests[] = $audit_request; } else { $other_requests[] = $audit_request; } } if ($user_requests) { $props['Auditors'] = $this->renderAuditStatusView($user_requests); } if ($other_requests) { $props['Project/Package Auditors'] = $this->renderAuditStatusView($other_requests); } } $author_phid = $data->getCommitDetail('authorPHID'); $author_name = $data->getAuthorName(); if (!$repository->isSVN()) { $authored_info = id(new PHUIStatusItemView()); // TODO: In Git, a distinct authorship date is available. When present, // we should show it here. if ($author_phid) { $authored_info->setTarget($handles[$author_phid]->renderLink()); } else { if (strlen($author_name)) { $authored_info->setTarget($author_name); } } $props['Authored'] = id(new PHUIStatusListView())->addItem($authored_info); } $committed_info = id(new PHUIStatusItemView())->setNote(phabricator_datetime($commit->getEpoch(), $viewer)); $committer_phid = $data->getCommitDetail('committerPHID'); $committer_name = $data->getCommitDetail('committer'); if ($committer_phid) { $committed_info->setTarget($handles[$committer_phid]->renderLink()); } else { if (strlen($committer_name)) { $committed_info->setTarget($committer_name); } else { if ($author_phid) { $committed_info->setTarget($handles[$author_phid]->renderLink()); } else { if (strlen($author_name)) { $committed_info->setTarget($author_name); } } } } $props['Committed'] = id(new PHUIStatusListView())->addItem($committed_info); if ($push_logs) { $pushed_list = new PHUIStatusListView(); foreach ($push_logs as $push_log) { $pushed_item = id(new PHUIStatusItemView())->setTarget($handles[$push_log->getPusherPHID()]->renderLink())->setNote(phabricator_datetime($push_log->getEpoch(), $viewer)); $pushed_list->addItem($pushed_item); } $props['Pushed'] = $pushed_list; } $reviewer_phid = $data->getCommitDetail('reviewerPHID'); if ($reviewer_phid) { $props['Reviewer'] = $handles[$reviewer_phid]->renderLink(); } if ($revision_phid) { $props['Differential Revision'] = $handles[$revision_phid]->renderLink(); } if ($parents) { $parent_links = array(); foreach ($parents as $parent) { $parent_links[] = $handles[$parent->getPHID()]->renderLink(); } $props['Parents'] = phutil_implode_html(" · ", $parent_links); } $props['Branches'] = phutil_tag('span', array('id' => 'commit-branches'), pht('Unknown')); $props['Tags'] = phutil_tag('span', array('id' => 'commit-tags'), pht('Unknown')); $callsign = $repository->getCallsign(); $root = '/diffusion/' . $callsign . '/commit/' . $commit->getCommitIdentifier(); Javelin::initBehavior('diffusion-commit-branches', array($root . '/branches/' => 'commit-branches', $root . '/tags/' => 'commit-tags')); $refs = $this->buildRefs($drequest); if ($refs) { $props['References'] = $refs; } if ($reverts_phids) { $props[pht('Reverts')] = $viewer->renderHandleList($reverts_phids); } if ($reverted_by_phids) { $props[pht('Reverted By')] = $viewer->renderHandleList($reverted_by_phids); } if ($task_phids) { $task_list = array(); foreach ($task_phids as $phid) { $task_list[] = $handles[$phid]->renderLink(); } $task_list = phutil_implode_html(phutil_tag('br'), $task_list); $props['Tasks'] = $task_list; } return $props; }
private function getCommitProperties(PhabricatorRepositoryCommit $commit, PhabricatorRepositoryCommitData $data, array $parents) { assert_instances_of($parents, 'PhabricatorRepositoryCommit'); $user = $this->getRequest()->getUser(); $task_phids = PhabricatorEdgeQuery::loadDestinationPHIDs($commit->getPHID(), PhabricatorEdgeConfig::TYPE_COMMIT_HAS_TASK); $phids = $task_phids; if ($data->getCommitDetail('authorPHID')) { $phids[] = $data->getCommitDetail('authorPHID'); } if ($data->getCommitDetail('reviewerPHID')) { $phids[] = $data->getCommitDetail('reviewerPHID'); } if ($data->getCommitDetail('differential.revisionPHID')) { $phids[] = $data->getCommitDetail('differential.revisionPHID'); } if ($parents) { foreach ($parents as $parent) { $phids[] = $parent->getPHID(); } } $handles = array(); if ($phids) { $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles(); } $props = array(); if ($commit->getAuditStatus()) { $status = PhabricatorAuditCommitStatusConstants::getStatusName($commit->getAuditStatus()); $props['Status'] = phutil_render_tag('strong', array(), phutil_escape_html($status)); } $props['Committed'] = phabricator_datetime($commit->getEpoch(), $user); $author_phid = $data->getCommitDetail('authorPHID'); if ($data->getCommitDetail('authorPHID')) { $props['Author'] = $handles[$author_phid]->renderLink(); } else { $props['Author'] = phutil_escape_html($data->getAuthorName()); } $reviewer_phid = $data->getCommitDetail('reviewerPHID'); $reviewer_name = $data->getCommitDetail('reviewerName'); if ($reviewer_phid) { $props['Reviewer'] = $handles[$reviewer_phid]->renderLink(); } else { if ($reviewer_name) { $props['Reviewer'] = phutil_escape_html($reviewer_name); } } $revision_phid = $data->getCommitDetail('differential.revisionPHID'); if ($revision_phid) { $props['Differential Revision'] = $handles[$revision_phid]->renderLink(); } if ($parents) { $parent_links = array(); foreach ($parents as $parent) { $parent_links[] = $handles[$parent->getPHID()]->renderLink(); } $props['Parents'] = implode(' · ', $parent_links); } $request = $this->getDiffusionRequest(); $contains = DiffusionContainsQuery::newFromDiffusionRequest($request); $branches = $contains->loadContainingBranches(); if ($branches) { // TODO: Separate these into 'tracked' and other; link tracked branches. $branches = implode(', ', array_keys($branches)); $branches = phutil_escape_html($branches); $props['Branches'] = $branches; } if ($task_phids) { $task_list = array(); foreach ($task_phids as $phid) { $task_list[] = $handles[$phid]->renderLink(); } $task_list = implode('<br />', $task_list); $props['Tasks'] = $task_list; } return $props; }
public function render() { $rows = array(); foreach ($this->commits as $commit) { $commit_name = $this->getHandle($commit->getPHID())->renderLink(); $author_name = null; if ($commit->getAuthorPHID()) { $author_name = $this->getHandle($commit->getAuthorPHID())->renderLink(); } $auditors = array(); if ($commit->getAudits()) { foreach ($commit->getAudits() as $audit) { $actor_phid = $audit->getActorPHID(); $auditors[$actor_phid] = $this->getHandle($actor_phid)->renderLink(); } } $rows[] = array($commit_name, $author_name, phutil_escape_html($commit->getCommitData()->getSummary()), PhabricatorAuditCommitStatusConstants::getStatusName($commit->getAuditStatus()), implode(', ', $auditors), phabricator_datetime($commit->getEpoch(), $this->user)); } $table = new AphrontTableView($rows); $table->setHeaders(array('Commit', 'Author', 'Summary', 'Audit Status', 'Auditors', 'Date')); $table->setColumnClasses(array('n', '', 'wide', '', '', '')); if ($this->commits && reset($this->commits)->getAudits() === null) { $table->setColumnVisibility(array(true, true, true, true, false, true)); } if ($this->noDataString) { $table->setNoDataString($this->noDataString); } return $table->render(); }
private function getCommitProperties(PhabricatorRepositoryCommit $commit, PhabricatorRepositoryCommitData $data, array $parents) { assert_instances_of($parents, 'PhabricatorRepositoryCommit'); $user = $this->getRequest()->getUser(); $commit_phid = $commit->getPHID(); $edges = id(new PhabricatorEdgeQuery())->withSourcePHIDs(array($commit_phid))->withEdgeTypes(array(PhabricatorEdgeConfig::TYPE_COMMIT_HAS_TASK, PhabricatorEdgeConfig::TYPE_COMMIT_HAS_PROJECT))->execute(); $task_phids = array_keys($edges[$commit_phid][PhabricatorEdgeConfig::TYPE_COMMIT_HAS_TASK]); $proj_phids = array_keys($edges[$commit_phid][PhabricatorEdgeConfig::TYPE_COMMIT_HAS_PROJECT]); $phids = array_merge($task_phids, $proj_phids); if ($data->getCommitDetail('authorPHID')) { $phids[] = $data->getCommitDetail('authorPHID'); } if ($data->getCommitDetail('reviewerPHID')) { $phids[] = $data->getCommitDetail('reviewerPHID'); } if ($data->getCommitDetail('committerPHID')) { $phids[] = $data->getCommitDetail('committerPHID'); } if ($data->getCommitDetail('differential.revisionPHID')) { $phids[] = $data->getCommitDetail('differential.revisionPHID'); } if ($parents) { foreach ($parents as $parent) { $phids[] = $parent->getPHID(); } } $handles = array(); if ($phids) { $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles(); } $props = array(); if ($commit->getAuditStatus()) { $status = PhabricatorAuditCommitStatusConstants::getStatusName($commit->getAuditStatus()); $props['Status'] = phutil_render_tag('strong', array(), phutil_escape_html($status)); } $props['Committed'] = phabricator_datetime($commit->getEpoch(), $user); $author_phid = $data->getCommitDetail('authorPHID'); if ($data->getCommitDetail('authorPHID')) { $props['Author'] = $handles[$author_phid]->renderLink(); } else { $props['Author'] = phutil_escape_html($data->getAuthorName()); } $reviewer_phid = $data->getCommitDetail('reviewerPHID'); $reviewer_name = $data->getCommitDetail('reviewerName'); if ($reviewer_phid) { $props['Reviewer'] = $handles[$reviewer_phid]->renderLink(); } else { if ($reviewer_name) { $props['Reviewer'] = phutil_escape_html($reviewer_name); } } $committer = $data->getCommitDetail('committer'); if ($committer) { $committer_phid = $data->getCommitDetail('committerPHID'); if ($data->getCommitDetail('committerPHID')) { $props['Committer'] = $handles[$committer_phid]->renderLink(); } else { $props['Committer'] = phutil_escape_html($committer); } } $revision_phid = $data->getCommitDetail('differential.revisionPHID'); if ($revision_phid) { $props['Differential Revision'] = $handles[$revision_phid]->renderLink(); } if ($parents) { $parent_links = array(); foreach ($parents as $parent) { $parent_links[] = $handles[$parent->getPHID()]->renderLink(); } $props['Parents'] = implode(' · ', $parent_links); } $request = $this->getDiffusionRequest(); $props['Branches'] = '<span id="commit-branches">Unknown</span>'; $props['Tags'] = '<span id="commit-tags">Unknown</span>'; $callsign = $request->getRepository()->getCallsign(); $root = '/diffusion/' . $callsign . '/commit/' . $commit->getCommitIdentifier(); Javelin::initBehavior('diffusion-commit-branches', array($root . '/branches/' => 'commit-branches', $root . '/tags/' => 'commit-tags')); $refs = $this->buildRefs($request); if ($refs) { $props['References'] = $refs; } if ($task_phids) { $task_list = array(); foreach ($task_phids as $phid) { $task_list[] = $handles[$phid]->renderLink(); } $task_list = implode('<br />', $task_list); $props['Tasks'] = $task_list; } if ($proj_phids) { $proj_list = array(); foreach ($proj_phids as $phid) { $proj_list[] = $handles[$phid]->renderLink(); } $proj_list = implode('<br />', $proj_list); $props['Projects'] = $proj_list; } return $props; }
public function handleRequest(AphrontRequest $request) { $response = $this->loadDiffusionContext(); if ($response) { return $response; } $drequest = $this->getDiffusionRequest(); $viewer = $request->getUser(); if ($request->getStr('diff')) { return $this->buildRawDiffResponse($drequest); } $repository = $drequest->getRepository(); $commit = id(new DiffusionCommitQuery())->setViewer($viewer)->withRepository($repository)->withIdentifiers(array($drequest->getCommit()))->needCommitData(true)->needAuditRequests(true)->executeOne(); $crumbs = $this->buildCrumbs(array('commit' => true)); $crumbs->setBorder(true); if (!$commit) { if (!$this->getCommitExists()) { return new Aphront404Response(); } $error = id(new PHUIInfoView())->setTitle(pht('Commit Still Parsing'))->appendChild(pht('Failed to load the commit because the commit has not been ' . 'parsed yet.')); $title = pht('Commit Still Parsing'); return $this->newPage()->setTitle($title)->setCrumbs($crumbs)->appendChild($error); } $audit_requests = $commit->getAudits(); $this->auditAuthorityPHIDs = PhabricatorAuditCommentEditor::loadAuditPHIDsForUser($viewer); $commit_data = $commit->getCommitData(); $is_foreign = $commit_data->getCommitDetail('foreign-svn-stub'); $error_panel = null; if ($is_foreign) { $subpath = $commit_data->getCommitDetail('svn-subpath'); $error_panel = new PHUIInfoView(); $error_panel->setTitle(pht('Commit Not Tracked')); $error_panel->setSeverity(PHUIInfoView::SEVERITY_WARNING); $error_panel->appendChild(pht("This Diffusion repository is configured to track only one " . "subdirectory of the entire Subversion repository, and this commit " . "didn't affect the tracked subdirectory ('%s'), so no " . "information is available.", $subpath)); } else { $engine = PhabricatorMarkupEngine::newDifferentialMarkupEngine(); $engine->setConfig('viewer', $viewer); $commit_tag = $this->renderCommitHashTag($drequest); $header = id(new PHUIHeaderView())->setHeader(nonempty($commit->getSummary(), pht('Commit Detail')))->setHeaderIcon('fa-code-fork')->addTag($commit_tag); if ($commit->getAuditStatus()) { $icon = PhabricatorAuditCommitStatusConstants::getStatusIcon($commit->getAuditStatus()); $color = PhabricatorAuditCommitStatusConstants::getStatusColor($commit->getAuditStatus()); $status = PhabricatorAuditCommitStatusConstants::getStatusName($commit->getAuditStatus()); $header->setStatus($icon, $color, $status); } $curtain = $this->buildCurtain($commit, $repository); $subheader = $this->buildSubheaderView($commit, $commit_data); $details = $this->buildPropertyListView($commit, $commit_data, $audit_requests); $message = $commit_data->getCommitMessage(); $revision = $commit->getCommitIdentifier(); $message = $this->linkBugtraq($message); $message = $engine->markupText($message); $detail_list = new PHUIPropertyListView(); $detail_list->addTextContent(phutil_tag('div', array('class' => 'diffusion-commit-message phabricator-remarkup'), $message)); if ($this->getCommitErrors()) { $error_panel = id(new PHUIInfoView())->appendChild($this->getCommitErrors())->setSeverity(PHUIInfoView::SEVERITY_WARNING); } } $timeline = $this->buildComments($commit); $hard_limit = 1000; if ($commit->isImported()) { $change_query = DiffusionPathChangeQuery::newFromDiffusionRequest($drequest); $change_query->setLimit($hard_limit + 1); $changes = $change_query->loadChanges(); } else { $changes = array(); } $was_limited = count($changes) > $hard_limit; if ($was_limited) { $changes = array_slice($changes, 0, $hard_limit); } $merge_table = $this->buildMergesTable($commit); $highlighted_audits = $commit->getAuthorityAudits($viewer, $this->auditAuthorityPHIDs); $count = count($changes); $bad_commit = null; if ($count == 0) { $bad_commit = queryfx_one(id(new PhabricatorRepository())->establishConnection('r'), 'SELECT * FROM %T WHERE fullCommitName = %s', PhabricatorRepository::TABLE_BADCOMMIT, $commit->getMonogram()); } $show_changesets = false; $info_panel = null; $change_list = null; $change_table = null; if ($bad_commit) { $info_panel = $this->renderStatusMessage(pht('Bad Commit'), $bad_commit['description']); } else { if ($is_foreign) { // Don't render anything else. } else { if (!$commit->isImported()) { $info_panel = $this->renderStatusMessage(pht('Still Importing...'), pht('This commit is still importing. Changes will be visible once ' . 'the import finishes.')); } else { if (!count($changes)) { $info_panel = $this->renderStatusMessage(pht('Empty Commit'), pht('This commit is empty and does not affect any paths.')); } else { if ($was_limited) { $info_panel = $this->renderStatusMessage(pht('Enormous Commit'), pht('This commit is enormous, and affects more than %d files. ' . 'Changes are not shown.', $hard_limit)); } else { if (!$this->getCommitExists()) { $info_panel = $this->renderStatusMessage(pht('Commit No Longer Exists'), pht('This commit no longer exists in the repository.')); } else { $show_changesets = true; // The user has clicked "Show All Changes", and we should show all the // changes inline even if there are more than the soft limit. $show_all_details = $request->getBool('show_all'); $change_header = id(new PHUIHeaderView())->setHeader(pht('Changes (%s)', new PhutilNumber($count))); $warning_view = null; if ($count > self::CHANGES_LIMIT && !$show_all_details) { $button = id(new PHUIButtonView())->setText(pht('Show All Changes'))->setHref('?show_all=true')->setTag('a')->setIcon('fa-files-o'); $warning_view = id(new PHUIInfoView())->setSeverity(PHUIInfoView::SEVERITY_WARNING)->setTitle(pht('Very Large Commit'))->appendChild(pht('This commit is very large. Load each file individually.')); $change_header->addActionLink($button); } $changesets = DiffusionPathChange::convertToDifferentialChangesets($viewer, $changes); // TODO: This table and panel shouldn't really be separate, but we need // to clean up the "Load All Files" interaction first. $change_table = $this->buildTableOfContents($changesets, $change_header, $warning_view); $vcs = $repository->getVersionControlSystem(); switch ($vcs) { case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: $vcs_supports_directory_changes = true; break; case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: $vcs_supports_directory_changes = false; break; default: throw new Exception(pht('Unknown VCS.')); } $references = array(); foreach ($changesets as $key => $changeset) { $file_type = $changeset->getFileType(); if ($file_type == DifferentialChangeType::FILE_DIRECTORY) { if (!$vcs_supports_directory_changes) { unset($changesets[$key]); continue; } } $references[$key] = $drequest->generateURI(array('action' => 'rendering-ref', 'path' => $changeset->getFilename())); } // TODO: Some parts of the views still rely on properties of the // DifferentialChangeset. Make the objects ephemeral to make sure we don't // accidentally save them, and then set their ID to the appropriate ID for // this application (the path IDs). $path_ids = array_flip(mpull($changes, 'getPath')); foreach ($changesets as $changeset) { $changeset->makeEphemeral(); $changeset->setID($path_ids[$changeset->getFilename()]); } if ($count <= self::CHANGES_LIMIT || $show_all_details) { $visible_changesets = $changesets; } else { $visible_changesets = array(); $inlines = PhabricatorAuditInlineComment::loadDraftAndPublishedComments($viewer, $commit->getPHID()); $path_ids = mpull($inlines, null, 'getPathID'); foreach ($changesets as $key => $changeset) { if (array_key_exists($changeset->getID(), $path_ids)) { $visible_changesets[$key] = $changeset; } } } $change_list_title = $commit->getDisplayName(); $change_list = new DifferentialChangesetListView(); $change_list->setTitle($change_list_title); $change_list->setChangesets($changesets); $change_list->setVisibleChangesets($visible_changesets); $change_list->setRenderingReferences($references); $change_list->setRenderURI($repository->getPathURI('diff/')); $change_list->setRepository($repository); $change_list->setUser($viewer); $change_list->setBackground(PHUIObjectBoxView::BLUE_PROPERTY); // TODO: Try to setBranch() to something reasonable here? $change_list->setStandaloneURI($repository->getPathURI('diff/')); $change_list->setRawFileURIs(null, $repository->getPathURI('diff/?view=r')); $change_list->setInlineCommentControllerURI('/diffusion/inline/edit/' . phutil_escape_uri($commit->getPHID()) . '/'); } } } } } } $add_comment = $this->renderAddCommentPanel($commit, $audit_requests); $filetree_on = $viewer->compareUserSetting(PhabricatorShowFiletreeSetting::SETTINGKEY, PhabricatorShowFiletreeSetting::VALUE_ENABLE_FILETREE); $pref_collapse = PhabricatorFiletreeVisibleSetting::SETTINGKEY; $collapsed = $viewer->getUserSetting($pref_collapse); $nav = null; if ($show_changesets && $filetree_on) { $nav = id(new DifferentialChangesetFileTreeSideNavBuilder())->setTitle($commit->getDisplayName())->setBaseURI(new PhutilURI($commit->getURI()))->build($changesets)->setCrumbs($crumbs)->setCollapsed((bool) $collapsed); } $view = id(new PHUITwoColumnView())->setHeader($header)->setSubheader($subheader)->setMainColumn(array($error_panel, $timeline, $merge_table, $info_panel))->setFooter(array($change_table, $change_list, $add_comment))->addPropertySection(pht('Description'), $detail_list)->addPropertySection(pht('Details'), $details)->setCurtain($curtain); $page = $this->newPage()->setTitle($commit->getDisplayName())->setCrumbs($crumbs)->setPageObjectPHIDS(array($commit->getPHID()))->appendChild(array($view)); if ($nav) { $page->setNavigation($nav); } return $page; }