1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-14 01:26:13 +01:00
phorge-phorge/src/applications/diffusion/controller/DiffusionRepositoryController.php

455 lines
13 KiB
PHP
Raw Normal View History

<?php
final class DiffusionRepositoryController extends DiffusionController {
private $historyFuture;
private $browseFuture;
private $tagFuture;
private $branchFuture;
public function shouldAllowPublic() {
return true;
}
public function handleRequest(AphrontRequest $request) {
$response = $this->loadDiffusionContext();
if ($response) {
return $response;
}
require_celerity_resource('diffusion-css');
$viewer = $this->getViewer();
$drequest = $this->getDiffusionRequest();
$repository = $drequest->getRepository();
$crumbs = $this->buildCrumbs();
$crumbs->setBorder(true);
$header = $this->buildHeaderView($repository);
$actions = $this->buildActionList($repository);
$description = $this->buildDescriptionView($repository);
$locate_file = $this->buildLocateFile();
$header->setActionList($actions);
// Before we do any work, make sure we're looking at a some content: we're
// on a valid branch, and the repository is not empty.
$page_has_content = false;
$empty_title = null;
$empty_message = null;
// If this VCS supports branches, check that the selected branch actually
// exists.
if ($drequest->supportsBranches()) {
// NOTE: Mercurial may have multiple branch heads with the same name.
$ref_cursors = id(new PhabricatorRepositoryRefCursorQuery())
->setViewer($viewer)
->withRepositoryPHIDs(array($repository->getPHID()))
->withRefTypes(array(PhabricatorRepositoryRefCursor::TYPE_BRANCH))
->withRefNames(array($drequest->getBranch()))
->execute();
if ($ref_cursors) {
// This is a valid branch, so we necessarily have some content.
$page_has_content = true;
} else {
$empty_title = pht('No Such Branch');
$empty_message = pht(
'There is no branch named "%s" in this repository.',
$drequest->getBranch());
}
}
// If we didn't find any branches, check if there are any commits at all.
// This can tailor the message for empty repositories.
if (!$page_has_content) {
$any_commit = id(new DiffusionCommitQuery())
->setViewer($viewer)
->withRepository($repository)
->setLimit(1)
->execute();
if ($any_commit) {
if (!$drequest->supportsBranches()) {
$page_has_content = true;
}
} else {
$empty_title = pht('Empty Repository');
$empty_message = pht('This repository does not have any commits yet.');
}
}
if ($page_has_content) {
$content = $this->buildNormalContent($drequest);
} else {
$content = id(new PHUIInfoView())
->setTitle($empty_title)
->setSeverity(PHUIInfoView::SEVERITY_WARNING)
->setErrors(array($empty_message));
}
$tabs = $this->buildTabsView('home');
$clone_uri = $drequest->generateURI(
array(
'action' => 'clone',
));
$clone_button = id(new PHUIButtonView())
->setTag('a')
->setText('Clone')
->setColor(PHUIButtonView::GREEN)
->setIcon('fa-download')
->setWorkflow(true)
->setHref($clone_uri);
$bar = id(new PHUILeftRightView())
->setLeft($locate_file)
->setRight($clone_button);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setTabs($tabs)
->setFooter(array(
$bar,
$description,
$content,
));
return $this->newPage()
->setTitle(
array(
$repository->getName(),
$repository->getDisplayName(),
))
->setCrumbs($crumbs)
->appendChild(array(
$view,
));
}
private function buildNormalContent(DiffusionRequest $drequest) {
$request = $this->getRequest();
$repository = $drequest->getRepository();
$commit = $drequest->getCommit();
$path = $drequest->getPath();
$this->historyFuture = $this->callConduitMethod(
'diffusion.historyquery',
array(
'commit' => $commit,
'path' => $path,
'offset' => 0,
'limit' => 15,
));
$browse_pager = id(new PHUIPagerView())
->readFromRequest($request);
$this->browseFuture = $this->callConduitMethod(
'diffusion.browsequery',
array(
'commit' => $commit,
'path' => $path,
'limit' => $browse_pager->getPageSize() + 1,
));
$futures = array(
$this->historyFuture,
$this->browseFuture,
);
$futures = array_filter($futures);
$futures = new FutureIterator($futures);
foreach ($futures as $future) {
// Just resolve all the futures before continuing.
}
$phids = array();
$content = array();
try {
$history_results = $this->historyFuture->resolve();
$history = DiffusionPathChange::newFromConduit(
$history_results['pathChanges']);
foreach ($history as $item) {
$data = $item->getCommitData();
if ($data) {
if ($data->getCommitDetail('authorPHID')) {
$phids[$data->getCommitDetail('authorPHID')] = true;
}
if ($data->getCommitDetail('committerPHID')) {
$phids[$data->getCommitDetail('committerPHID')] = true;
}
}
}
$history_exception = null;
} catch (Exception $ex) {
$history_results = null;
$history = null;
$history_exception = $ex;
}
try {
$browse_results = $this->browseFuture->resolve();
$browse_results = DiffusionBrowseResultSet::newFromConduit(
$browse_results);
$browse_paths = $browse_results->getPaths();
$browse_paths = $browse_pager->sliceResults($browse_paths);
foreach ($browse_paths as $item) {
$data = $item->getLastCommitData();
if ($data) {
if ($data->getCommitDetail('authorPHID')) {
$phids[$data->getCommitDetail('authorPHID')] = true;
}
if ($data->getCommitDetail('committerPHID')) {
$phids[$data->getCommitDetail('committerPHID')] = true;
}
}
}
$browse_exception = null;
} catch (Exception $ex) {
$browse_results = null;
$browse_paths = null;
$browse_exception = $ex;
}
$phids = array_keys($phids);
$handles = $this->loadViewerHandles($phids);
if ($browse_results) {
$readme = $this->renderDirectoryReadme($browse_results);
} else {
$readme = null;
}
$content[] = $this->buildBrowseTable(
$browse_results,
$browse_paths,
$browse_exception,
$handles,
$browse_pager);
$content[] = $this->buildHistoryTable(
$history_results,
$history,
$history_exception);
if ($readme) {
$content[] = $readme;
}
return $content;
}
private function buildHeaderView(PhabricatorRepository $repository) {
$viewer = $this->getViewer();
$header = id(new PHUIHeaderView())
->setHeader($repository->getName())
->setUser($viewer)
->setPolicyObject($repository)
->setProfileHeader(true)
->setImage($repository->getProfileImageURI())
->setImageEditURL('/diffusion/picture/'.$repository->getID().'/')
->addClass('diffusion-profile-header');
if (!$repository->isTracked()) {
$header->setStatus('fa-ban', 'dark', pht('Inactive'));
} else if ($repository->isImporting()) {
$ratio = $repository->loadImportProgress();
$percentage = sprintf('%.2f%%', 100 * $ratio);
$header->setStatus(
'fa-clock-o',
'indigo',
pht('Importing (%s)...', $percentage));
} else {
$header->setStatus('fa-check', 'bluegrey', pht('Active'));
}
return $header;
}
private function buildActionList(PhabricatorRepository $repository) {
$viewer = $this->getViewer();
$edit_uri = $repository->getPathURI('manage/');
$action_view = id(new PhabricatorActionListView())
->setUser($viewer)
->setObject($repository);
$action_view->addAction(
id(new PhabricatorActionView())
->setName(pht('Manage Repository'))
->setIcon('fa-cogs')
->setHref($edit_uri));
if ($repository->isHosted()) {
$push_uri = $this->getApplicationURI(
'pushlog/?repositories='.$repository->getMonogram());
$action_view->addAction(
id(new PhabricatorActionView())
->setName(pht('View Push Logs'))
->setIcon('fa-list-alt')
->setHref($push_uri));
}
return $action_view;
}
private function buildDescriptionView(PhabricatorRepository $repository) {
$viewer = $this->getViewer();
$view = id(new PHUIPropertyListView())
->setUser($viewer);
$description = $repository->getDetail('description');
if (strlen($description)) {
$description = new PHUIRemarkupView($viewer, $description);
$view->addTextContent($description);
return id(new PHUIObjectBoxView())
->appendChild($view)
->addClass('diffusion-profile-description');
}
return null;
}
private function buildHistoryTable(
$history_results,
$history,
$history_exception) {
$request = $this->getRequest();
$viewer = $request->getUser();
$drequest = $this->getDiffusionRequest();
$repository = $drequest->getRepository();
if ($history_exception) {
if ($repository->isImporting()) {
return $this->renderStatusMessage(
pht('Still Importing...'),
pht(
'This repository is still importing. History is not yet '.
'available.'));
} else {
return $this->renderStatusMessage(
pht('Unable to Retrieve History'),
$history_exception->getMessage());
}
}
$history_table = id(new DiffusionHistoryTableView())
->setUser($viewer)
->setDiffusionRequest($drequest)
->setHistory($history);
// TODO: Super sketchy.
$history_table->loadRevisions();
if ($history_results) {
$history_table->setParents($history_results['parents']);
}
$history_table->setIsHead(true);
$panel = id(new PHUIObjectBoxView())
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY);
$header = id(new PHUIHeaderView())
->setHeader(pht('Recent Commits'));
$panel->setHeader($header);
$panel->setTable($history_table);
return $panel;
}
private function buildLocateFile() {
$request = $this->getRequest();
$viewer = $request->getUser();
$drequest = $this->getDiffusionRequest();
$repository = $drequest->getRepository();
$locate_panel = null;
if ($repository->canUsePathTree()) {
Javelin::initBehavior(
'diffusion-locate-file',
array(
'controlID' => 'locate-control',
'inputID' => 'locate-input',
'browseBaseURI' => (string)$drequest->generateURI(
array(
'action' => 'browse',
)),
'uri' => (string)$drequest->generateURI(
array(
'action' => 'pathtree',
)),
));
$form = id(new AphrontFormView())
->setUser($viewer)
->appendChild(
id(new AphrontFormTypeaheadControl())
->setHardpointID('locate-control')
->setID('locate-input')
->setPlaceholder(pht('Locate File')));
$form_box = id(new PHUIBoxView())
->appendChild($form->buildLayoutView())
->addClass('diffusion-profile-locate');
}
return $form_box;
}
private function buildBrowseTable(
$browse_results,
$browse_paths,
$browse_exception,
array $handles,
PHUIPagerView $pager) {
require_celerity_resource('diffusion-icons-css');
$request = $this->getRequest();
$viewer = $request->getUser();
$drequest = $this->getDiffusionRequest();
$repository = $drequest->getRepository();
if ($browse_exception) {
if ($repository->isImporting()) {
// The history table renders a useful message.
return null;
} else {
return $this->renderStatusMessage(
pht('Unable to Retrieve Paths'),
$browse_exception->getMessage());
}
}
$browse_table = id(new DiffusionBrowseTableView())
->setUser($viewer)
->setDiffusionRequest($drequest)
->setHandles($handles);
if ($browse_paths) {
$browse_table->setPaths($browse_paths);
} else {
$browse_table->setPaths(array());
}
$browse_uri = $drequest->generateURI(array('action' => 'browse'));
$pager->setURI($browse_uri, 'offset');
return id(new PHUIObjectBoxView())
->setHeaderText($repository->getName())
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($browse_table)
->setPager($pager);
}
private function getTagLimit() {
return 15;
}
}