Changeset View
Changeset View
Standalone View
Standalone View
src/applications/diffusion/controller/DiffusionBrowseController.php
Show First 20 Lines • Show All 104 Lines • ▼ Show 20 Lines | private function browseFile() { | ||||
$repository = $drequest->getRepository(); | $repository = $drequest->getRepository(); | ||||
$before = $request->getStr('before'); | $before = $request->getStr('before'); | ||||
if ($before) { | if ($before) { | ||||
return $this->buildBeforeResponse($before); | return $this->buildBeforeResponse($before); | ||||
} | } | ||||
$path = $drequest->getPath(); | $path = $drequest->getPath(); | ||||
// We need the blame information if blame is on and this is an Ajax request. | |||||
// If blame is on and this is a colorized request, we don't show blame at | |||||
// first (we ajax it in afterward) so we don't need to query for it. | |||||
$needs_blame = $request->isAjax(); | |||||
$params = array( | $params = array( | ||||
'commit' => $drequest->getCommit(), | 'commit' => $drequest->getCommit(), | ||||
'path' => $drequest->getPath(), | 'path' => $drequest->getPath(), | ||||
); | ); | ||||
$view = $request->getStr('view'); | $view = $request->getStr('view'); | ||||
$byte_limit = null; | $byte_limit = null; | ||||
▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | if ($hit_byte_limit) { | ||||
// it. In storage, it just has a name like "lfs-13f9a94c0923...", | // it. In storage, it just has a name like "lfs-13f9a94c0923...", | ||||
// since we don't get any hints about possible human-readable names | // since we don't get any hints about possible human-readable names | ||||
// at upload time. | // at upload time. | ||||
$basename = basename($drequest->getPath()); | $basename = basename($drequest->getPath()); | ||||
$file->makeEphemeral(); | $file->makeEphemeral(); | ||||
$file->setName($basename); | $file->setName($basename); | ||||
return $file->getRedirectResponse(); | return $file->getRedirectResponse(); | ||||
} else { | |||||
$corpus = $this->buildGitLFSCorpus($lfs_ref); | |||||
} | } | ||||
$corpus = $this->buildGitLFSCorpus($lfs_ref); | |||||
} else { | } else { | ||||
$this->loadLintMessages(); | |||||
$this->coverage = $drequest->loadCoverage(); | $this->coverage = $drequest->loadCoverage(); | ||||
$show_editor = true; | $show_editor = true; | ||||
$ref = id(new PhabricatorDocumentRef()) | $ref = id(new PhabricatorDocumentRef()) | ||||
->setFile($file); | ->setFile($file); | ||||
$engine = id(new DiffusionDocumentRenderingEngine()) | $engine = id(new DiffusionDocumentRenderingEngine()) | ||||
->setRequest($request) | ->setRequest($request) | ||||
->setDiffusionRequest($drequest); | ->setDiffusionRequest($drequest); | ||||
$corpus = $engine->newDocumentView($ref); | $corpus = $engine->newDocumentView($ref); | ||||
$this->corpusButtons[] = $this->renderFileButton(); | $this->corpusButtons[] = $this->renderFileButton(); | ||||
} | } | ||||
} | } | ||||
if ($request->isAjax()) { | |||||
return id(new AphrontAjaxResponse())->setContent($corpus); | |||||
} | |||||
require_celerity_resource('diffusion-source-css'); | |||||
$bar = $this->buildButtonBar($drequest, $show_editor); | $bar = $this->buildButtonBar($drequest, $show_editor); | ||||
$header = $this->buildHeaderView($drequest); | $header = $this->buildHeaderView($drequest); | ||||
$header->setHeaderIcon('fa-file-code-o'); | $header->setHeaderIcon('fa-file-code-o'); | ||||
$follow = $request->getStr('follow'); | $follow = $request->getStr('follow'); | ||||
$follow_notice = null; | $follow_notice = null; | ||||
if ($follow) { | if ($follow) { | ||||
$follow_notice = id(new PHUIInfoView()) | $follow_notice = id(new PHUIInfoView()) | ||||
▲ Show 20 Lines • Show All 253 Lines • ▼ Show 20 Lines | foreach ($grouped as $path => $matches) { | ||||
->setPattern($pattern) | ->setPattern($pattern) | ||||
->setDiffusionRequest($drequest) | ->setDiffusionRequest($drequest) | ||||
->render(); | ->render(); | ||||
} | } | ||||
return $view; | return $view; | ||||
} | } | ||||
private function loadLintMessages() { | |||||
$drequest = $this->getDiffusionRequest(); | |||||
$branch = $drequest->loadBranch(); | |||||
if (!$branch || !$branch->getLintCommit()) { | |||||
return; | |||||
} | |||||
$this->lintCommit = $branch->getLintCommit(); | |||||
$conn = id(new PhabricatorRepository())->establishConnection('r'); | |||||
$where = ''; | |||||
if ($drequest->getLint()) { | |||||
$where = qsprintf( | |||||
$conn, | |||||
'AND code = %s', | |||||
$drequest->getLint()); | |||||
} | |||||
$this->lintMessages = queryfx_all( | |||||
$conn, | |||||
'SELECT * FROM %T WHERE branchID = %d %Q AND path = %s', | |||||
PhabricatorRepository::TABLE_LINTMESSAGE, | |||||
$branch->getID(), | |||||
$where, | |||||
'/'.$drequest->getPath()); | |||||
} | |||||
private function buildButtonBar( | private function buildButtonBar( | ||||
DiffusionRequest $drequest, | DiffusionRequest $drequest, | ||||
$show_editor) { | $show_editor) { | ||||
$viewer = $this->getViewer(); | $viewer = $this->getViewer(); | ||||
$base_uri = $this->getRequest()->getRequestURI(); | $base_uri = $this->getRequest()->getRequestURI(); | ||||
$user = $this->getRequest()->getUser(); | $user = $this->getRequest()->getUser(); | ||||
Show All 25 Lines | if ($editor_link) { | ||||
->setHref($editor_link) | ->setHref($editor_link) | ||||
->setIcon('fa-pencil') | ->setIcon('fa-pencil') | ||||
->setID('editor_link') | ->setID('editor_link') | ||||
->setMetadata(array('link_template' => $template)) | ->setMetadata(array('link_template' => $template)) | ||||
->setDisabled(!$editor_link) | ->setDisabled(!$editor_link) | ||||
->setColor(PHUIButtonView::GREY); | ->setColor(PHUIButtonView::GREY); | ||||
} | } | ||||
$href = null; | |||||
$show_lint = true; | |||||
if ($this->getRequest()->getStr('lint') !== null) { | |||||
$lint_text = pht('Hide Lint'); | |||||
$href = $base_uri->alter('lint', null); | |||||
} else if ($this->lintCommit === null) { | |||||
$show_lint = false; | |||||
} else { | |||||
$lint_text = pht('Show Lint'); | |||||
$href = $this->getDiffusionRequest()->generateURI(array( | |||||
'action' => 'browse', | |||||
'commit' => $this->lintCommit, | |||||
))->alter('lint', ''); | |||||
} | |||||
if ($show_lint) { | |||||
$buttons[] = | |||||
id(new PHUIButtonView()) | |||||
->setTag('a') | |||||
->setText($lint_text) | |||||
->setHref($href) | |||||
->setIcon('fa-exclamation-triangle') | |||||
->setDisabled(!$href) | |||||
->setColor(PHUIButtonView::GREY); | |||||
} | |||||
$bar = id(new PHUILeftRightView()) | $bar = id(new PHUILeftRightView()) | ||||
->setLeft($buttons) | ->setLeft($buttons) | ||||
->addClass('diffusion-action-bar full-mobile-buttons'); | ->addClass('diffusion-action-bar full-mobile-buttons'); | ||||
return $bar; | return $bar; | ||||
} | } | ||||
private function buildOwnersList(DiffusionRequest $drequest) { | private function buildOwnersList(DiffusionRequest $drequest) { | ||||
$viewer = $this->getViewer(); | $viewer = $this->getViewer(); | ||||
▲ Show 20 Lines • Show All 112 Lines • ▼ Show 20 Lines | private function renderGitLFSButton() { | ||||
return id(new PHUIButtonView()) | return id(new PHUIButtonView()) | ||||
->setTag('a') | ->setTag('a') | ||||
->setText($text) | ->setText($text) | ||||
->setHref($href) | ->setHref($href) | ||||
->setIcon($icon) | ->setIcon($icon) | ||||
->setColor(PHUIButtonView::GREY); | ->setColor(PHUIButtonView::GREY); | ||||
} | } | ||||
private function renderInlines( | |||||
array $inlines, | |||||
$has_coverage, | |||||
$engine) { | |||||
$rows = array(); | |||||
foreach ($inlines as $inline) { | |||||
// TODO: This should use modern scaffolding code. | |||||
$inline_view = id(new PHUIDiffInlineCommentDetailView()) | |||||
->setUser($this->getViewer()) | |||||
->setMarkupEngine($engine) | |||||
->setInlineComment($inline) | |||||
->render(); | |||||
$row = array_fill(0, 3, phutil_tag('th')); | |||||
$row[] = phutil_tag('td', array(), $inline_view); | |||||
if ($has_coverage) { | |||||
$row[] = phutil_tag( | |||||
'td', | |||||
array( | |||||
'class' => 'cov cov-I', | |||||
)); | |||||
} | |||||
$rows[] = phutil_tag('tr', array('class' => 'inline'), $row); | |||||
} | |||||
return $rows; | |||||
} | |||||
private function buildErrorCorpus($message) { | private function buildErrorCorpus($message) { | ||||
$text = id(new PHUIBoxView()) | $text = id(new PHUIBoxView()) | ||||
->addPadding(PHUI::PADDING_LARGE) | ->addPadding(PHUI::PADDING_LARGE) | ||||
->appendChild($message); | ->appendChild($message); | ||||
$header = id(new PHUIHeaderView()) | $header = id(new PHUIHeaderView()) | ||||
->setHeader(pht('Details')); | ->setHeader(pht('Details')); | ||||
▲ Show 20 Lines • Show All 143 Lines • ▼ Show 20 Lines | $parents = DiffusionQuery::callConduitWithDiffusionRequest( | ||||
'diffusion.commitparentsquery', | 'diffusion.commitparentsquery', | ||||
array( | array( | ||||
'commit' => $commit, | 'commit' => $commit, | ||||
)); | )); | ||||
return head($parents); | return head($parents); | ||||
} | } | ||||
private function renderRevisionTooltip( | |||||
DifferentialRevision $revision, | |||||
$handles) { | |||||
$viewer = $this->getRequest()->getUser(); | |||||
$date = phabricator_date($revision->getDateModified(), $viewer); | |||||
$id = $revision->getID(); | |||||
$title = $revision->getTitle(); | |||||
$header = "D{$id} {$title}"; | |||||
$author = $handles[$revision->getAuthorPHID()]->getName(); | |||||
return "{$header}\n{$date} \xC2\xB7 {$author}"; | |||||
} | |||||
private function renderCommitTooltip( | |||||
PhabricatorRepositoryCommit $commit, | |||||
$author) { | |||||
$viewer = $this->getRequest()->getUser(); | |||||
$date = phabricator_date($commit->getEpoch(), $viewer); | |||||
$summary = trim($commit->getSummary()); | |||||
return "{$summary}\n{$date} \xC2\xB7 {$author}"; | |||||
} | |||||
protected function markupText($text) { | protected function markupText($text) { | ||||
$engine = PhabricatorMarkupEngine::newDiffusionMarkupEngine(); | $engine = PhabricatorMarkupEngine::newDiffusionMarkupEngine(); | ||||
$engine->setConfig('viewer', $this->getRequest()->getUser()); | $engine->setConfig('viewer', $this->getRequest()->getUser()); | ||||
$text = $engine->markupText($text); | $text = $engine->markupText($text); | ||||
$text = phutil_tag( | $text = phutil_tag( | ||||
'div', | 'div', | ||||
array( | array( | ||||
▲ Show 20 Lines • Show All 167 Lines • ▼ Show 20 Lines | $view = id(new PHUIObjectBoxView()) | ||||
->setHeader($header) | ->setHeader($header) | ||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) | ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) | ||||
->addClass('diffusion-mobile-view') | ->addClass('diffusion-mobile-view') | ||||
->appendChild($list); | ->appendChild($list); | ||||
return $view; | return $view; | ||||
} | } | ||||
private function loadBlame($path, $commit, $timeout) { | |||||
$blame = $this->callConduitWithDiffusionRequest( | |||||
'diffusion.blame', | |||||
array( | |||||
'commit' => $commit, | |||||
'paths' => array($path), | |||||
'timeout' => $timeout, | |||||
)); | |||||
$identifiers = idx($blame, $path, null); | |||||
if ($identifiers) { | |||||
$viewer = $this->getViewer(); | |||||
$drequest = $this->getDiffusionRequest(); | |||||
$repository = $drequest->getRepository(); | |||||
$commits = id(new DiffusionCommitQuery()) | |||||
->setViewer($viewer) | |||||
->withRepository($repository) | |||||
->withIdentifiers($identifiers) | |||||
// TODO: We only fetch this to improve author display behavior, but | |||||
// shouldn't really need to? | |||||
->needCommitData(true) | |||||
->execute(); | |||||
$commits = mpull($commits, null, 'getCommitIdentifier'); | |||||
} else { | |||||
$commits = array(); | |||||
} | |||||
return array($identifiers, $commits); | |||||
} | |||||
private function renderAuthorLinks(array $authors, $handles) { | |||||
$links = array(); | |||||
foreach ($authors as $phid) { | |||||
if (!strlen($phid)) { | |||||
// This means we couldn't identify an author for the commit or the | |||||
// revision. We just render a blank for alignment. | |||||
$style = null; | |||||
$href = null; | |||||
$sigil = null; | |||||
$meta = null; | |||||
} else { | |||||
$src = $handles[$phid]->getImageURI(); | |||||
$style = 'background-image: url('.$src.');'; | |||||
$href = $handles[$phid]->getURI(); | |||||
$sigil = 'has-tooltip'; | |||||
$meta = array( | |||||
'tip' => $handles[$phid]->getName(), | |||||
'align' => 'E', | |||||
); | |||||
} | |||||
$links[$phid] = javelin_tag( | |||||
$href ? 'a' : 'span', | |||||
array( | |||||
'class' => 'diffusion-author-link', | |||||
'style' => $style, | |||||
'href' => $href, | |||||
'sigil' => $sigil, | |||||
'meta' => $meta, | |||||
)); | |||||
} | |||||
return $links; | |||||
} | |||||
private function renderCommitLinks(array $commits, $handles) { | |||||
$links = array(); | |||||
foreach ($commits as $identifier => $commit) { | |||||
$tooltip = $this->renderCommitTooltip( | |||||
$commit, | |||||
$commit->renderAuthorShortName($handles)); | |||||
$commit_link = javelin_tag( | |||||
'a', | |||||
array( | |||||
'href' => $commit->getURI(), | |||||
'sigil' => 'has-tooltip', | |||||
'meta' => array( | |||||
'tip' => $tooltip, | |||||
'align' => 'E', | |||||
'size' => 600, | |||||
), | |||||
), | |||||
$commit->getLocalName()); | |||||
$links[$identifier] = $commit_link; | |||||
} | |||||
return $links; | |||||
} | |||||
private function renderRevisionLinks(array $revisions, $handles) { | |||||
$links = array(); | |||||
foreach ($revisions as $revision) { | |||||
$revision_id = $revision->getID(); | |||||
$tooltip = $this->renderRevisionTooltip($revision, $handles); | |||||
$revision_link = javelin_tag( | |||||
'a', | |||||
array( | |||||
'href' => '/'.$revision->getMonogram(), | |||||
'sigil' => 'has-tooltip', | |||||
'meta' => array( | |||||
'tip' => $tooltip, | |||||
'align' => 'E', | |||||
'size' => 600, | |||||
), | |||||
), | |||||
$revision->getMonogram()); | |||||
$links[$revision_id] = $revision_link; | |||||
} | |||||
return $links; | |||||
} | |||||
private function getGitLFSRef(PhabricatorRepository $repository, $data) { | private function getGitLFSRef(PhabricatorRepository $repository, $data) { | ||||
if (!$repository->canUseGitLFS()) { | if (!$repository->canUseGitLFS()) { | ||||
return null; | return null; | ||||
} | } | ||||
$lfs_pattern = '(^version https://git-lfs\\.github\\.com/spec/v1[\r\n])'; | $lfs_pattern = '(^version https://git-lfs\\.github\\.com/spec/v1[\r\n])'; | ||||
if (!preg_match($lfs_pattern, $data)) { | if (!preg_match($lfs_pattern, $data)) { | ||||
return null; | return null; | ||||
▲ Show 20 Lines • Show All 130 Lines • ▼ Show 20 Lines | private function buildBranchTable() { | ||||
return id(new PHUIObjectBoxView()) | return id(new PHUIObjectBoxView()) | ||||
->setHeader($header) | ->setHeader($header) | ||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) | ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) | ||||
->addClass('diffusion-mobile-view') | ->addClass('diffusion-mobile-view') | ||||
->setTable($history_table); | ->setTable($history_table); | ||||
} | } | ||||
private function getLineNumberBaseURI() { | |||||
$drequest = $this->getDiffusionRequest(); | |||||
return (string)$drequest->generateURI( | |||||
array( | |||||
'action' => 'browse', | |||||
'stable' => true, | |||||
)); | |||||
} | |||||
} | } |