1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-03-08 02:19:34 +01:00

Merge and modernize Browse controllers in Diffusion

Summary:
Ref T4245. Browsing is huge and currently split across 5 files using controller delegation.

Although having a huge file isn't great, I think the way it is split up is currently worse, and it gets weird with more flexible repository identifiers.

So this is mostly merging five controllers into one, then a bit of modernization.

I think this can probably be split up better by pulling some of it out into views, instead of using delegation.

Test Plan: Browsed files, directories, and search results.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T4245

Differential Revision: https://secure.phabricator.com/D14942
This commit is contained in:
epriestley 2016-01-05 05:18:59 -08:00
parent 7de17fb75e
commit 8b6edaa4e2
7 changed files with 1480 additions and 1524 deletions

View file

@ -533,12 +533,8 @@ phutil_register_library_map(array(
'DiffusionBranchTableController' => 'applications/diffusion/controller/DiffusionBranchTableController.php',
'DiffusionBranchTableView' => 'applications/diffusion/view/DiffusionBranchTableView.php',
'DiffusionBrowseController' => 'applications/diffusion/controller/DiffusionBrowseController.php',
'DiffusionBrowseDirectoryController' => 'applications/diffusion/controller/DiffusionBrowseDirectoryController.php',
'DiffusionBrowseFileController' => 'applications/diffusion/controller/DiffusionBrowseFileController.php',
'DiffusionBrowseMainController' => 'applications/diffusion/controller/DiffusionBrowseMainController.php',
'DiffusionBrowseQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionBrowseQueryConduitAPIMethod.php',
'DiffusionBrowseResultSet' => 'applications/diffusion/data/DiffusionBrowseResultSet.php',
'DiffusionBrowseSearchController' => 'applications/diffusion/controller/DiffusionBrowseSearchController.php',
'DiffusionBrowseTableView' => 'applications/diffusion/view/DiffusionBrowseTableView.php',
'DiffusionCachedResolveRefsQuery' => 'applications/diffusion/query/DiffusionCachedResolveRefsQuery.php',
'DiffusionChangeController' => 'applications/diffusion/controller/DiffusionChangeController.php',
@ -4501,12 +4497,8 @@ phutil_register_library_map(array(
'DiffusionBranchTableController' => 'DiffusionController',
'DiffusionBranchTableView' => 'DiffusionView',
'DiffusionBrowseController' => 'DiffusionController',
'DiffusionBrowseDirectoryController' => 'DiffusionBrowseController',
'DiffusionBrowseFileController' => 'DiffusionBrowseController',
'DiffusionBrowseMainController' => 'DiffusionBrowseController',
'DiffusionBrowseQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
'DiffusionBrowseResultSet' => 'Phobject',
'DiffusionBrowseSearchController' => 'DiffusionBrowseController',
'DiffusionBrowseTableView' => 'DiffusionView',
'DiffusionCachedResolveRefsQuery' => 'DiffusionLowLevelQuery',
'DiffusionChangeController' => 'DiffusionController',

View file

@ -70,7 +70,7 @@ final class PhabricatorDiffusionApplication extends PhabricatorApplication {
'repository/(?P<dblob>.*)' => 'DiffusionRepositoryController',
'change/(?P<dblob>.*)' => 'DiffusionChangeController',
'history/(?P<dblob>.*)' => 'DiffusionHistoryController',
'browse/(?P<dblob>.*)' => 'DiffusionBrowseMainController',
'browse/(?P<dblob>.*)' => 'DiffusionBrowseController',
'lastmodified/(?P<dblob>.*)' => 'DiffusionLastModifiedController',
'diff/' => 'DiffusionDiffController',
'tags/(?P<dblob>.*)' => 'DiffusionTagListController',

View file

@ -1,106 +0,0 @@
<?php
final class DiffusionBrowseDirectoryController
extends DiffusionBrowseController {
private $browseQueryResults;
public function setBrowseQueryResults(DiffusionBrowseResultSet $results) {
$this->browseQueryResults = $results;
return $this;
}
public function getBrowseQueryResults() {
return $this->browseQueryResults;
}
protected function processDiffusionRequest(AphrontRequest $request) {
$drequest = $this->diffusionRequest;
$results = $this->getBrowseQueryResults();
$reason = $results->getReasonForEmptyResultSet();
$content = array();
$actions = $this->buildActionView($drequest);
$properties = $this->buildPropertyView($drequest, $actions);
$object_box = id(new PHUIObjectBoxView())
->setHeader($this->buildHeaderView($drequest))
->addPropertyList($properties);
$content[] = $object_box;
$content[] = $this->renderSearchForm($collapsed = true);
if (!$results->isValidResults()) {
$empty_result = new DiffusionEmptyResultView();
$empty_result->setDiffusionRequest($drequest);
$empty_result->setDiffusionBrowseResultSet($results);
$empty_result->setView($request->getStr('view'));
$content[] = $empty_result;
} else {
$phids = array();
foreach ($results->getPaths() as $result) {
$data = $result->getLastCommitData();
if ($data) {
if ($data->getCommitDetail('authorPHID')) {
$phids[$data->getCommitDetail('authorPHID')] = true;
}
}
}
$phids = array_keys($phids);
$handles = $this->loadViewerHandles($phids);
$browse_table = new DiffusionBrowseTableView();
$browse_table->setDiffusionRequest($drequest);
$browse_table->setHandles($handles);
$browse_table->setPaths($results->getPaths());
$browse_table->setUser($request->getUser());
$browse_panel = new PHUIObjectBoxView();
$browse_panel->setHeaderText($drequest->getPath(), '/');
$browse_panel->setTable($browse_table);
$content[] = $browse_panel;
}
$content[] = $this->buildOpenRevisions();
$readme_path = $results->getReadmePath();
if ($readme_path) {
$readme_content = $this->callConduitWithDiffusionRequest(
'diffusion.filecontentquery',
array(
'path' => $readme_path,
'commit' => $drequest->getStableCommit(),
));
if ($readme_content) {
$content[] = id(new DiffusionReadmeView())
->setUser($this->getViewer())
->setPath($readme_path)
->setContent($readme_content['corpus']);
}
}
$crumbs = $this->buildCrumbs(
array(
'branch' => true,
'path' => true,
'view' => 'browse',
));
return $this->buildApplicationPage(
array(
$crumbs,
$content,
),
array(
'title' => array(
nonempty(basename($drequest->getPath()), '/'),
$drequest->getRepository()->getDisplayName(),
),
));
}
}

View file

@ -1,39 +0,0 @@
<?php
final class DiffusionBrowseMainController extends DiffusionBrowseController {
protected function processDiffusionRequest(AphrontRequest $request) {
$drequest = $this->diffusionRequest;
// Figure out if we're browsing a directory, a file, or a search result
// list. Then delegate to the appropriate controller.
$grep = $request->getStr('grep');
$find = $request->getStr('find');
if (strlen($grep) || strlen($find)) {
$controller = new DiffusionBrowseSearchController();
} else {
$results = DiffusionBrowseResultSet::newFromConduit(
$this->callConduitWithDiffusionRequest(
'diffusion.browsequery',
array(
'path' => $drequest->getPath(),
'commit' => $drequest->getStableCommit(),
)));
$reason = $results->getReasonForEmptyResultSet();
$is_file = ($reason == DiffusionBrowseResultSet::REASON_IS_FILE);
if ($is_file) {
$controller = new DiffusionBrowseFileController($request);
} else {
$controller = new DiffusionBrowseDirectoryController($request);
$controller->setBrowseQueryResults($results);
}
}
$controller->setDiffusionRequest($drequest);
$controller->setCurrentApplication($this->getCurrentApplication());
return $this->delegateToController($controller);
}
}

View file

@ -1,231 +0,0 @@
<?php
final class DiffusionBrowseSearchController extends DiffusionBrowseController {
protected function processDiffusionRequest(AphrontRequest $request) {
$drequest = $this->diffusionRequest;
$actions = $this->buildActionView($drequest);
$properties = $this->buildPropertyView($drequest, $actions);
$object_box = id(new PHUIObjectBoxView())
->setHeader($this->buildHeaderView($drequest))
->addPropertyList($properties);
$content = array();
$content[] = $object_box;
$content[] = $this->renderSearchForm($collapsed = false);
$content[] = $this->renderSearchResults();
$crumbs = $this->buildCrumbs(
array(
'branch' => true,
'path' => true,
'view' => 'browse',
));
return $this->buildApplicationPage(
array(
$crumbs,
$content,
),
array(
'title' => array(
nonempty(basename($drequest->getPath()), '/'),
$drequest->getRepository()->getDisplayName(),
),
));
}
private function renderSearchResults() {
$drequest = $this->getDiffusionRequest();
$repository = $drequest->getRepository();
$results = array();
$limit = 100;
$page = $this->getRequest()->getInt('page', 0);
$pager = new PHUIPagerView();
$pager->setPageSize($limit);
$pager->setOffset($page);
$pager->setURI($this->getRequest()->getRequestURI(), 'page');
$search_mode = null;
switch ($repository->getVersionControlSystem()) {
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
$results = array();
break;
default:
if (strlen($this->getRequest()->getStr('grep'))) {
$search_mode = 'grep';
$query_string = $this->getRequest()->getStr('grep');
$results = $this->callConduitWithDiffusionRequest(
'diffusion.searchquery',
array(
'grep' => $query_string,
'commit' => $drequest->getStableCommit(),
'path' => $drequest->getPath(),
'limit' => $limit + 1,
'offset' => $page,
));
} else { // Filename search.
$search_mode = 'find';
$query_string = $this->getRequest()->getStr('find');
$results = $this->callConduitWithDiffusionRequest(
'diffusion.querypaths',
array(
'pattern' => $query_string,
'commit' => $drequest->getStableCommit(),
'path' => $drequest->getPath(),
'limit' => $limit + 1,
'offset' => $page,
));
}
break;
}
$results = $pager->sliceResults($results);
if ($search_mode == 'grep') {
$table = $this->renderGrepResults($results, $query_string);
$header = pht(
'File content matching "%s" under "%s"',
$query_string,
nonempty($drequest->getPath(), '/'));
} else {
$table = $this->renderFindResults($results);
$header = pht(
'Paths matching "%s" under "%s"',
$query_string,
nonempty($drequest->getPath(), '/'));
}
$box = id(new PHUIObjectBoxView())
->setHeaderText($header)
->setTable($table);
$pager_box = id(new PHUIBoxView())
->addMargin(PHUI::MARGIN_LARGE)
->appendChild($pager);
return array($box, $pager_box);
}
private function renderGrepResults(array $results, $pattern) {
$drequest = $this->getDiffusionRequest();
require_celerity_resource('phabricator-search-results-css');
$rows = array();
foreach ($results as $result) {
list($path, $line, $string) = $result;
$href = $drequest->generateURI(array(
'action' => 'browse',
'path' => $path,
'line' => $line,
));
$matches = null;
$count = @preg_match_all(
'('.$pattern.')u',
$string,
$matches,
PREG_OFFSET_CAPTURE);
if (!$count) {
$output = ltrim($string);
} else {
$output = array();
$cursor = 0;
$length = strlen($string);
foreach ($matches[0] as $match) {
$offset = $match[1];
if ($cursor != $offset) {
$output[] = array(
'text' => substr($string, $cursor, $offset),
'highlight' => false,
);
}
$output[] = array(
'text' => $match[0],
'highlight' => true,
);
$cursor = $offset + strlen($match[0]);
}
if ($cursor != $length) {
$output[] = array(
'text' => substr($string, $cursor),
'highlight' => false,
);
}
if ($output) {
$output[0]['text'] = ltrim($output[0]['text']);
}
foreach ($output as $key => $segment) {
if ($segment['highlight']) {
$output[$key] = phutil_tag('strong', array(), $segment['text']);
} else {
$output[$key] = $segment['text'];
}
}
}
$string = phutil_tag(
'pre',
array('class' => 'PhabricatorMonospaced phui-source-fragment'),
$output);
$path = Filesystem::readablePath($path, $drequest->getPath());
$rows[] = array(
phutil_tag('a', array('href' => $href), $path),
$line,
$string,
);
}
$table = id(new AphrontTableView($rows))
->setClassName('remarkup-code')
->setHeaders(array(pht('Path'), pht('Line'), pht('String')))
->setColumnClasses(array('', 'n', 'wide'))
->setNoDataString(
pht(
'The pattern you searched for was not found in the content of any '.
'files.'));
return $table;
}
private function renderFindResults(array $results) {
$drequest = $this->getDiffusionRequest();
$rows = array();
foreach ($results as $result) {
$href = $drequest->generateURI(array(
'action' => 'browse',
'path' => $result,
));
$readable = Filesystem::readablePath($result, $drequest->getPath());
$rows[] = array(
phutil_tag('a', array('href' => $href), $readable),
);
}
$table = id(new AphrontTableView($rows))
->setHeaders(array(pht('Path')))
->setColumnClasses(array('wide'))
->setNoDataString(
pht(
'The pattern you searched for did not match the names of any '.
'files.'));
return $table;
}
}