Something went wrong. Try again.
@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
Something went wrong. Try again.
15 kB · 528 lines
PHP
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529<?php
final class DiffusionRepositoryController extends DiffusionController {
private $browseFuture; private $branchButton = null; 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();
// 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())) ->needPositions(true) ->execute();
// It's possible that this branch previously existed, but has been // deleted. Make sure we have valid cursor positions, not just cursors. $any_positions = false; foreach ($ref_cursors as $ref_cursor) { if ($ref_cursor->getPositions()) { $any_positions = true; break; } }
if ($any_positions) { // This is a valid branch, so we necessarily have some content. $page_has_content = true; } else { $default = $repository->getDefaultBranch(); if ($default != $drequest->getBranch()) { $empty_title = pht('No Such Branch'); $empty_message = pht( 'There is no branch named "%s" in this repository.', $drequest->getBranch()); } else { $empty_title = pht('No Default Branch'); $empty_message = pht( 'This repository is configured with default branch "%s" but '. 'there is no branch with that name in this repository.', $default); $branch_setup_uri = $this->getApplicationURI( 'edit/'.$repository->getID().'/page/branches/'); phlog('Repository "'.$repository->getName().'" is configured with '. 'default branch "'.$default.'" but there is no such branch in '. 'this repository. Correct the settings at '.$branch_setup_uri); } } }
// If we didn't find any branches, check if there are any commits at all. // This can tailor the message for empty repositories. $any_commit = null; 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 { // If we have a commit somewhere, find branches. // TODO: Evan will replace // $this->buildNormalContent($drequest); $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', ));
if ($repository->isSVN()) { $clone_text = pht('Checkout'); } else { $clone_text = pht('Clone'); }
$actions_button = id(new PHUIButtonView()) ->setTag('a') ->setText(pht('Actions')) ->setIcon('fa-bars') ->addClass('mmr') ->setColor(PHUIButtonView::GREY) ->setDropdown(true) ->setDropdownMenu($actions);
$clone_button = id(new PHUIButtonView()) ->setTag('a') ->setText($clone_text) ->setColor(PHUIButtonView::GREEN) ->setIcon('fa-download') ->setWorkflow(true) ->setHref($clone_uri);
$bar = id(new PHUILeftRightView()) ->setLeft($locate_file) ->setRight(array($this->branchButton, $actions_button, $clone_button)) ->addClass('diffusion-action-bar');
$status_view = null; if ($repository->isReadOnly()) { $status_view = id(new PHUIInfoView()) ->setSeverity(PHUIInfoView::SEVERITY_WARNING) ->setErrors( array( phutil_escape_html_newlines( $repository->getReadOnlyMessageForDisplay()), )); }
$view = id(new PHUITwoColumnView()) ->setHeader($header) ->setFooter( array( $status_view, $bar, $description, $content, ));
if ($page_has_content) { $view->setTabs($tabs); }
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();
$futures = array();
$browse_pager = id(new PHUIPagerView()) ->readFromRequest($request);
$this->browseFuture = $this->callConduitMethod( 'diffusion.browsequery', array( 'commit' => $commit, 'path' => $path, 'limit' => $browse_pager->getPageSize() + 1, )); $futures[] = $this->browseFuture;
if ($this->needBranchFuture()) { $branch_limit = $this->getBranchLimit(); $this->branchFuture = $this->callConduitMethod( 'diffusion.branchquery', array( 'closed' => false, 'limit' => $branch_limit + 1, )); $futures[] = $this->branchFuture; }
$futures = array_filter($futures); $futures = new FutureIterator($futures); foreach ($futures as $future) { // Just resolve all the futures before continuing. }
$content = array();
try { $browse_results = $this->browseFuture->resolve(); $browse_results = DiffusionBrowseResultSet::newFromConduit( $browse_results);
$browse_paths = $browse_results->getPaths(); $browse_paths = $browse_pager->sliceResults($browse_paths);
$browse_exception = null; } catch (Exception $ex) { $browse_results = null; $browse_paths = null; $browse_exception = $ex; }
if ($browse_results) { $readme = $this->renderDirectoryReadme($browse_results); } else { $readme = null; }
if ($readme) { $content[] = $readme; }
$content[] = $this->buildBrowseTable( $browse_results, $browse_paths, $browse_exception, $browse_pager);
try { $branch_button = $this->buildBranchList($drequest); $this->branchButton = $branch_button; } catch (Exception $ex) { if (!$repository->isImporting()) { $content[] = $this->renderStatusMessage( pht('Unable to Load Branches'), $ex->getMessage()); } }
return $content; }
private function buildHeaderView(PhabricatorRepository $repository) { $viewer = $this->getViewer(); $drequest = $this->getDiffusionRequest(); $search = $this->renderSearchForm();
$header = id(new PHUIHeaderView()) ->setHeader($repository->getName()) ->setViewer($viewer) ->setPolicyObject($repository) ->setProfileHeader(true) ->setImage($repository->getProfileImageURI()) ->setImageEditURL('/diffusion/picture/'.$repository->getID().'/') ->addActionItem($search) ->addClass('diffusion-profile-header');
if (!$repository->isTracked()) { $header->setStatus('fa-ban', 'dark', pht('Inactive')); } else if ($repository->isReadOnly()) { $header->setStatus('fa-wrench', 'indigo', pht('Under Maintenance')); } else if ($repository->isImporting()) { $ratio = $repository->loadImportProgress(); $percentage = sprintf('%.2f%%', 100 * $ratio); $header->setStatus( 'fa-clock-o', 'indigo', pht('Importing (%s)...', $percentage)); } else if ($repository->isPublishingDisabled()) { $header->setStatus('fa-minus', 'bluegrey', pht('Publishing Disabled')); } else { $header->setStatus('fa-check', 'bluegrey', pht('Active')); }
if (!$repository->isSVN()) { $default = $repository->getDefaultBranch(); if ($default != $drequest->getBranch()) { $branch_tag = $this->renderBranchTag($drequest); $header->addTag($branch_tag); } }
// Display associated projects as tags in repository browsing header $project_phids = $repository->getProjectPHIDs(); if ($project_phids) { $handles = id(new PhabricatorHandleQuery()) ->setViewer($viewer) ->withPHIDs($project_phids) ->execute(); $project_handles = array_select_keys( $handles, $project_phids); foreach ($project_handles as $handle) { $header->addTag($handle->renderTag()); } }
return $header; }
private function buildActionList(PhabricatorRepository $repository) { $viewer = $this->getViewer();
$edit_uri = $repository->getPathURI('manage/'); $action_view = id(new PhabricatorActionListView()) ->setViewer($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->getPHID());
$action_view->addAction( id(new PhabricatorActionView()) ->setName(pht('View Push Logs')) ->setIcon('fa-upload') ->setHref($push_uri));
$pull_uri = $this->getApplicationURI( 'synclog/?repositories='.$repository->getPHID());
$action_view->addAction( id(new PhabricatorActionView()) ->setName(pht('View Sync Logs')) ->setIcon('fa-exchange') ->setHref($pull_uri)); }
$pull_uri = $this->getApplicationURI( 'pulllog/?repositories='.$repository->getPHID());
$action_view->addAction( id(new PhabricatorActionView()) ->setName(pht('View Pull Logs')) ->setIcon('fa-download') ->setHref($pull_uri));
return $action_view; }
private function buildDescriptionView(PhabricatorRepository $repository) { $viewer = $this->getViewer(); $view = id(new PHUIPropertyListView()) ->setViewer($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 buildBranchList(DiffusionRequest $drequest) { $viewer = $this->getViewer();
if (!$this->needBranchFuture()) { return null; }
$branches = $this->branchFuture->resolve(); if (!$branches) { return null; }
$limit = $this->getBranchLimit(); $more_branches = (count($branches) > $limit); $branches = array_slice($branches, 0, $limit);
$branches = DiffusionRepositoryRef::loadAllFromDictionaries($branches);
$actions = id(new PhabricatorActionListView()) ->setViewer($viewer);
foreach ($branches as $branch) { $branch_uri = $drequest->generateURI( array( 'action' => 'branch', 'branch' => $branch->getShortname(), )); $actions->addAction( id(new PhabricatorActionView()) ->setName($branch->getShortname()) ->setIcon('fa-code-fork') ->setHref($branch_uri)); }
if ($more_branches) { $more_uri = $drequest->generateURI( array( 'action' => 'branches', )); $actions->addAction( id(new PhabricatorActionView()) ->setType(PhabricatorActionView::TYPE_DIVIDER)); $actions->addAction( id(new PhabricatorActionView()) ->setName(pht('See More Branches')) ->setIcon('fa-external-link') ->setHref($more_uri)); }
$button = id(new PHUIButtonView()) ->setText(pht('Branch: %s', $drequest->getBranch())) ->setTag('a') ->addClass('mmr') ->setIcon('fa-code-fork') ->setColor(PHUIButtonView::GREY) ->setDropdown(true) ->setDropdownMenu($actions);
return $button; }
private function buildBrowseTable( $browse_results, $browse_paths, $browse_exception, 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); 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');
$repository_name = $repository->getName(); $branch_name = $drequest->getBranch(); if (phutil_nonempty_string($branch_name)) { $repository_name .= ' ('.$branch_name.')'; }
$header = phutil_tag( 'a', array( 'href' => $browse_uri, 'class' => 'diffusion-view-browse-header', ), $repository_name);
return id(new PHUIObjectBoxView()) ->setHeaderText($header) ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setTable($browse_table) ->addClass('diffusion-mobile-view') ->setPager($pager); }
private function needBranchFuture() { $drequest = $this->getDiffusionRequest();
if ($drequest->getBranch() === null) { return false; }
return true; }
private function getBranchLimit() { return 15; }
}