Improve organization of Diffusion browse controllers
Summary:
Currently we have this:
  - DiffusionController (abstract, has some random shared browse code)
    - DiffusionBrowseController (concrete, Handles routing, directories, and search)
    - DiffusionBrowseFileController (concrete, handles files)
Instead, do this:
  - DiffusionController (no browse-related code)
    - DiffusionBrowseController (abstract, shared browse code)
      - DiffusionBrowseMainController (concrete, handles routing)
      - DiffusionBrowseDirectoryController (concrete, handles directories)
      - DiffusionBrowseFileController (concrete, handles files)
      - DiffusionBrowseSearchController (concrete, handles search)
Feels a lot cleaner.
Test Plan: Looked at directories, searches, and files.
Reviewers: btrahan
Reviewed By: btrahan
CC: aran
Differential Revision: https://secure.phabricator.com/D7045
			
			
This commit is contained in:
		| @@ -433,8 +433,11 @@ phutil_register_library_map(array( | |||||||
|     'DiffusionBranchTableController' => 'applications/diffusion/controller/DiffusionBranchTableController.php', |     'DiffusionBranchTableController' => 'applications/diffusion/controller/DiffusionBranchTableController.php', | ||||||
|     'DiffusionBranchTableView' => 'applications/diffusion/view/DiffusionBranchTableView.php', |     'DiffusionBranchTableView' => 'applications/diffusion/view/DiffusionBranchTableView.php', | ||||||
|     'DiffusionBrowseController' => 'applications/diffusion/controller/DiffusionBrowseController.php', |     'DiffusionBrowseController' => 'applications/diffusion/controller/DiffusionBrowseController.php', | ||||||
|  |     'DiffusionBrowseDirectoryController' => 'applications/diffusion/controller/DiffusionBrowseDirectoryController.php', | ||||||
|     'DiffusionBrowseFileController' => 'applications/diffusion/controller/DiffusionBrowseFileController.php', |     'DiffusionBrowseFileController' => 'applications/diffusion/controller/DiffusionBrowseFileController.php', | ||||||
|  |     'DiffusionBrowseMainController' => 'applications/diffusion/controller/DiffusionBrowseMainController.php', | ||||||
|     'DiffusionBrowseResultSet' => 'applications/diffusion/data/DiffusionBrowseResultSet.php', |     'DiffusionBrowseResultSet' => 'applications/diffusion/data/DiffusionBrowseResultSet.php', | ||||||
|  |     'DiffusionBrowseSearchController' => 'applications/diffusion/controller/DiffusionBrowseSearchController.php', | ||||||
|     'DiffusionBrowseTableView' => 'applications/diffusion/view/DiffusionBrowseTableView.php', |     'DiffusionBrowseTableView' => 'applications/diffusion/view/DiffusionBrowseTableView.php', | ||||||
|     'DiffusionChangeController' => 'applications/diffusion/controller/DiffusionChangeController.php', |     'DiffusionChangeController' => 'applications/diffusion/controller/DiffusionChangeController.php', | ||||||
|     'DiffusionCommentListView' => 'applications/diffusion/view/DiffusionCommentListView.php', |     'DiffusionCommentListView' => 'applications/diffusion/view/DiffusionCommentListView.php', | ||||||
| @@ -2498,7 +2501,10 @@ phutil_register_library_map(array( | |||||||
|     'DiffusionBranchTableController' => 'DiffusionController', |     'DiffusionBranchTableController' => 'DiffusionController', | ||||||
|     'DiffusionBranchTableView' => 'DiffusionView', |     'DiffusionBranchTableView' => 'DiffusionView', | ||||||
|     'DiffusionBrowseController' => 'DiffusionController', |     'DiffusionBrowseController' => 'DiffusionController', | ||||||
|     'DiffusionBrowseFileController' => 'DiffusionController', |     'DiffusionBrowseDirectoryController' => 'DiffusionBrowseController', | ||||||
|  |     'DiffusionBrowseFileController' => 'DiffusionBrowseController', | ||||||
|  |     'DiffusionBrowseMainController' => 'DiffusionBrowseController', | ||||||
|  |     'DiffusionBrowseSearchController' => 'DiffusionBrowseController', | ||||||
|     'DiffusionBrowseTableView' => 'DiffusionView', |     'DiffusionBrowseTableView' => 'DiffusionView', | ||||||
|     'DiffusionChangeController' => 'DiffusionController', |     'DiffusionChangeController' => 'DiffusionController', | ||||||
|     'DiffusionCommentListView' => 'AphrontView', |     'DiffusionCommentListView' => 'AphrontView', | ||||||
|   | |||||||
| @@ -50,7 +50,7 @@ final class PhabricatorApplicationDiffusion extends PhabricatorApplication { | |||||||
|           'repository/(?P<dblob>.*)'    => 'DiffusionRepositoryController', |           'repository/(?P<dblob>.*)'    => 'DiffusionRepositoryController', | ||||||
|           'change/(?P<dblob>.*)'        => 'DiffusionChangeController', |           'change/(?P<dblob>.*)'        => 'DiffusionChangeController', | ||||||
|           'history/(?P<dblob>.*)'       => 'DiffusionHistoryController', |           'history/(?P<dblob>.*)'       => 'DiffusionHistoryController', | ||||||
|           'browse/(?P<dblob>.*)'        => 'DiffusionBrowseController', |           'browse/(?P<dblob>.*)'        => 'DiffusionBrowseMainController', | ||||||
|           'lastmodified/(?P<dblob>.*)'  => 'DiffusionLastModifiedController', |           'lastmodified/(?P<dblob>.*)'  => 'DiffusionLastModifiedController', | ||||||
|           'diff/'                       => 'DiffusionDiffController', |           'diff/'                       => 'DiffusionDiffController', | ||||||
|           'tags/(?P<dblob>.*)'          => 'DiffusionTagListController', |           'tags/(?P<dblob>.*)'          => 'DiffusionTagListController', | ||||||
|   | |||||||
| @@ -1,123 +1,8 @@ | |||||||
| <?php | <?php | ||||||
|  |  | ||||||
| final class DiffusionBrowseController extends DiffusionController { | abstract class DiffusionBrowseController extends DiffusionController { | ||||||
|  |  | ||||||
|   public function processRequest() { |   protected function renderSearchForm($collapsed) { | ||||||
|     $drequest = $this->diffusionRequest; |  | ||||||
|     $is_file = false; |  | ||||||
|  |  | ||||||
|     if ($this->getRequest()->getStr('before')) { |  | ||||||
|       $is_file = true; |  | ||||||
|     } else if ($this->getRequest()->getStr('grep') == '') { |  | ||||||
|       $results = DiffusionBrowseResultSet::newFromConduit( |  | ||||||
|         $this->callConduitWithDiffusionRequest( |  | ||||||
|           'diffusion.browsequery', |  | ||||||
|           array( |  | ||||||
|             'path' => $drequest->getPath(), |  | ||||||
|             'commit' => $drequest->getCommit(), |  | ||||||
|           ))); |  | ||||||
|       $reason = $results->getReasonForEmptyResultSet(); |  | ||||||
|       $is_file = ($reason == DiffusionBrowseResultSet::REASON_IS_FILE); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if ($is_file) { |  | ||||||
|       $controller = new DiffusionBrowseFileController($this->getRequest()); |  | ||||||
|       $controller->setDiffusionRequest($drequest); |  | ||||||
|       $controller->setCurrentApplication($this->getCurrentApplication()); |  | ||||||
|       return $this->delegateToController($controller); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     $content = array(); |  | ||||||
|  |  | ||||||
|     $content[] = $this->buildHeaderView($drequest); |  | ||||||
|     $content[] = $this->buildBrowseActionView($drequest); |  | ||||||
|     $content[] = $this->buildPropertyView($drequest); |  | ||||||
|  |  | ||||||
|     $content[] = $this->renderSearchForm(); |  | ||||||
|  |  | ||||||
|     if ($this->getRequest()->getStr('grep') != '') { |  | ||||||
|       $content[] = $this->renderSearchResults(); |  | ||||||
|     } else { |  | ||||||
|       if (!$results->isValidResults()) { |  | ||||||
|         $empty_result = new DiffusionEmptyResultView(); |  | ||||||
|         $empty_result->setDiffusionRequest($drequest); |  | ||||||
|         $empty_result->setDiffusionBrowseResultSet($results); |  | ||||||
|         $empty_result->setView($this->getRequest()->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($this->getRequest()->getUser()); |  | ||||||
|  |  | ||||||
|         $browse_panel = new AphrontPanelView(); |  | ||||||
|         $browse_panel->appendChild($browse_table); |  | ||||||
|         $browse_panel->setNoBackground(); |  | ||||||
|  |  | ||||||
|         $content[] = $browse_panel; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       $content[] = $this->buildOpenRevisions(); |  | ||||||
|  |  | ||||||
|       $readme = $this->callConduitWithDiffusionRequest( |  | ||||||
|         'diffusion.readmequery', |  | ||||||
|         array( |  | ||||||
|           'paths' => $results->getPathDicts(), |  | ||||||
|         )); |  | ||||||
|       if ($readme) { |  | ||||||
|         $box = new PHUIBoxView(); |  | ||||||
|         $box->setShadow(true); |  | ||||||
|         $box->appendChild($readme); |  | ||||||
|         $box->addPadding(PHUI::PADDING_LARGE); |  | ||||||
|         $box->addMargin(PHUI::MARGIN_LARGE); |  | ||||||
|  |  | ||||||
|         $header = id(new PHUIHeaderView()) |  | ||||||
|           ->setHeader(pht('README')); |  | ||||||
|  |  | ||||||
|         $content[] = array( |  | ||||||
|           $header, |  | ||||||
|           $box, |  | ||||||
|         ); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     $crumbs = $this->buildCrumbs( |  | ||||||
|       array( |  | ||||||
|         'branch' => true, |  | ||||||
|         'path'   => true, |  | ||||||
|         'view'   => 'browse', |  | ||||||
|       )); |  | ||||||
|  |  | ||||||
|     return $this->buildApplicationPage( |  | ||||||
|       array( |  | ||||||
|         $crumbs, |  | ||||||
|         $content, |  | ||||||
|       ), |  | ||||||
|       array( |  | ||||||
|         'device' => true, |  | ||||||
|         'title' => array( |  | ||||||
|           nonempty(basename($drequest->getPath()), '/'), |  | ||||||
|           $drequest->getRepository()->getCallsign().' Repository', |  | ||||||
|         ), |  | ||||||
|       )); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   private function renderSearchForm() { |  | ||||||
|     $drequest = $this->getDiffusionRequest(); |     $drequest = $this->getDiffusionRequest(); | ||||||
|     $form = id(new AphrontFormView()) |     $form = id(new AphrontFormView()) | ||||||
|       ->setUser($this->getRequest()->getUser()) |       ->setUser($this->getRequest()->getUser()) | ||||||
| @@ -145,7 +30,7 @@ final class DiffusionBrowseController extends DiffusionController { | |||||||
|     $filter = new AphrontListFilterView(); |     $filter = new AphrontListFilterView(); | ||||||
|     $filter->appendChild($form); |     $filter->appendChild($form); | ||||||
|  |  | ||||||
|     if (!strlen($this->getRequest()->getStr('grep'))) { |     if ($collapsed) { | ||||||
|       $filter->setCollapsed( |       $filter->setCollapsed( | ||||||
|         pht('Show Search'), |         pht('Show Search'), | ||||||
|         pht('Hide Search'), |         pht('Hide Search'), | ||||||
| @@ -156,103 +41,7 @@ final class DiffusionBrowseController extends DiffusionController { | |||||||
|     return $filter; |     return $filter; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private function renderSearchResults() { |   protected function markupText($text) { | ||||||
|     $drequest = $this->getDiffusionRequest(); |  | ||||||
|     $repository = $drequest->getRepository(); |  | ||||||
|     $results = array(); |  | ||||||
|     $no_data = pht('No results found.'); |  | ||||||
|  |  | ||||||
|     $limit = 100; |  | ||||||
|     $page = $this->getRequest()->getInt('page', 0); |  | ||||||
|     $pager = new AphrontPagerView(); |  | ||||||
|     $pager->setPageSize($limit); |  | ||||||
|     $pager->setOffset($page); |  | ||||||
|     $pager->setURI($this->getRequest()->getRequestURI(), 'page'); |  | ||||||
|  |  | ||||||
|     try { |  | ||||||
|  |  | ||||||
|       $results = $this->callConduitWithDiffusionRequest( |  | ||||||
|         'diffusion.searchquery', |  | ||||||
|         array( |  | ||||||
|           'grep' => $this->getRequest()->getStr('grep'), |  | ||||||
|           'stableCommitName' => $drequest->getStableCommitName(), |  | ||||||
|           'path' => $drequest->getPath(), |  | ||||||
|           'limit' => $limit + 1, |  | ||||||
|           'offset' => $page)); |  | ||||||
|  |  | ||||||
|     } catch (ConduitException $ex) { |  | ||||||
|       $err = $ex->getErrorDescription(); |  | ||||||
|       if ($err != '') { |  | ||||||
|         return id(new AphrontErrorView()) |  | ||||||
|           ->setTitle(pht('Search Error')) |  | ||||||
|           ->appendChild($err); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     $results = $pager->sliceResults($results); |  | ||||||
|  |  | ||||||
|     require_celerity_resource('syntax-highlighting-css'); |  | ||||||
|  |  | ||||||
|     // NOTE: This can be wrong because we may find the string inside the |  | ||||||
|     // comment. But it's correct in most cases and highlighting the whole file |  | ||||||
|     // would be too expensive. |  | ||||||
|     $futures = array(); |  | ||||||
|     $engine = PhabricatorSyntaxHighlighter::newEngine(); |  | ||||||
|     foreach ($results as $result) { |  | ||||||
|       list($path, $line, $string) = $result; |  | ||||||
|       $futures["{$path}:{$line}"] = $engine->getHighlightFuture( |  | ||||||
|         $engine->getLanguageFromFilename($path), |  | ||||||
|         ltrim($string)); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     try { |  | ||||||
|       Futures($futures)->limit(8)->resolveAll(); |  | ||||||
|     } catch (PhutilSyntaxHighlighterException $ex) { |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     $rows = array(); |  | ||||||
|     foreach ($results as $result) { |  | ||||||
|       list($path, $line, $string) = $result; |  | ||||||
|  |  | ||||||
|       $href = $drequest->generateURI(array( |  | ||||||
|         'action' => 'browse', |  | ||||||
|         'path' => $path, |  | ||||||
|         'line' => $line, |  | ||||||
|       )); |  | ||||||
|  |  | ||||||
|       try { |  | ||||||
|         $string = $futures["{$path}:{$line}"]->resolve(); |  | ||||||
|       } catch (PhutilSyntaxHighlighterException $ex) { |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       $string = phutil_tag( |  | ||||||
|         'pre', |  | ||||||
|         array('class' => 'PhabricatorMonospaced'), |  | ||||||
|         $string); |  | ||||||
|  |  | ||||||
|       $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($no_data); |  | ||||||
|  |  | ||||||
|     return id(new AphrontPanelView()) |  | ||||||
|       ->setNoBackground(true) |  | ||||||
|       ->appendChild($table) |  | ||||||
|       ->appendChild($pager); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   private 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); | ||||||
| @@ -267,7 +56,7 @@ final class DiffusionBrowseController extends DiffusionController { | |||||||
|     return $text; |     return $text; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private function buildHeaderView(DiffusionRequest $drequest) { |   protected function buildHeaderView(DiffusionRequest $drequest) { | ||||||
|     $viewer = $this->getRequest()->getUser(); |     $viewer = $this->getRequest()->getUser(); | ||||||
|  |  | ||||||
|     $header = id(new PHUIHeaderView()) |     $header = id(new PHUIHeaderView()) | ||||||
| @@ -278,7 +67,56 @@ final class DiffusionBrowseController extends DiffusionController { | |||||||
|     return $header; |     return $header; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private function buildPropertyView(DiffusionRequest $drequest) { |   protected function buildActionView(DiffusionRequest $drequest) { | ||||||
|  |     $viewer = $this->getRequest()->getUser(); | ||||||
|  |  | ||||||
|  |     $view = id(new PhabricatorActionListView()) | ||||||
|  |       ->setUser($viewer); | ||||||
|  |  | ||||||
|  |     $history_uri = $drequest->generateURI( | ||||||
|  |       array( | ||||||
|  |         'action' => 'history', | ||||||
|  |       )); | ||||||
|  |  | ||||||
|  |     $view->addAction( | ||||||
|  |       id(new PhabricatorActionView()) | ||||||
|  |         ->setName(pht('View History')) | ||||||
|  |         ->setHref($history_uri) | ||||||
|  |         ->setIcon('perflab')); | ||||||
|  |  | ||||||
|  |     $behind_head = $drequest->getRawCommit(); | ||||||
|  |     $head_uri = $drequest->generateURI( | ||||||
|  |       array( | ||||||
|  |         'commit' => '', | ||||||
|  |         'action' => 'browse', | ||||||
|  |       )); | ||||||
|  |     $view->addAction( | ||||||
|  |       id(new PhabricatorActionView()) | ||||||
|  |         ->setName(pht('Jump to HEAD')) | ||||||
|  |         ->setHref($head_uri) | ||||||
|  |         ->setIcon('home') | ||||||
|  |         ->setDisabled(!$behind_head)); | ||||||
|  |  | ||||||
|  |     // TODO: Ideally, this should live in Owners and be event-triggered, but | ||||||
|  |     // there's no reasonable object for it to react to right now. | ||||||
|  |  | ||||||
|  |     $owners_uri = id(new PhutilURI('/owners/view/search/')) | ||||||
|  |       ->setQueryParams( | ||||||
|  |         array( | ||||||
|  |           'repository' => $drequest->getCallsign(), | ||||||
|  |           'path' => '/'.$drequest->getPath(), | ||||||
|  |         )); | ||||||
|  |  | ||||||
|  |     $view->addAction( | ||||||
|  |       id(new PhabricatorActionView()) | ||||||
|  |         ->setName(pht('Find Owners')) | ||||||
|  |         ->setHref((string)$owners_uri) | ||||||
|  |         ->setIcon('preview')); | ||||||
|  |  | ||||||
|  |     return $view; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   protected function buildPropertyView(DiffusionRequest $drequest) { | ||||||
|     $viewer = $this->getRequest()->getUser(); |     $viewer = $this->getRequest()->getUser(); | ||||||
|  |  | ||||||
|     $view = id(new PhabricatorPropertyListView()) |     $view = id(new PhabricatorPropertyListView()) | ||||||
| @@ -312,4 +150,49 @@ final class DiffusionBrowseController extends DiffusionController { | |||||||
|     return $view; |     return $view; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   protected function buildOpenRevisions() { | ||||||
|  |     $user = $this->getRequest()->getUser(); | ||||||
|  |  | ||||||
|  |     $drequest = $this->getDiffusionRequest(); | ||||||
|  |     $repository = $drequest->getRepository(); | ||||||
|  |     $path = $drequest->getPath(); | ||||||
|  |  | ||||||
|  |     $path_map = id(new DiffusionPathIDQuery(array($path)))->loadPathIDs(); | ||||||
|  |     $path_id = idx($path_map, $path); | ||||||
|  |     if (!$path_id) { | ||||||
|  |       return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     $revisions = id(new DifferentialRevisionQuery()) | ||||||
|  |       ->setViewer($user) | ||||||
|  |       ->withPath($repository->getID(), $path_id) | ||||||
|  |       ->withStatus(DifferentialRevisionQuery::STATUS_OPEN) | ||||||
|  |       ->setOrder(DifferentialRevisionQuery::ORDER_PATH_MODIFIED) | ||||||
|  |       ->setLimit(10) | ||||||
|  |       ->needRelationships(true) | ||||||
|  |       ->execute(); | ||||||
|  |  | ||||||
|  |     if (!$revisions) { | ||||||
|  |       return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     $view = id(new DifferentialRevisionListView()) | ||||||
|  |       ->setRevisions($revisions) | ||||||
|  |       ->setFields(DifferentialRevisionListView::getDefaultFields($user)) | ||||||
|  |       ->setUser($user) | ||||||
|  |       ->loadAssets(); | ||||||
|  |  | ||||||
|  |     $phids = $view->getRequiredHandlePHIDs(); | ||||||
|  |     $handles = $this->loadViewerHandles($phids); | ||||||
|  |     $view->setHandles($handles); | ||||||
|  |  | ||||||
|  |     $header = id(new PHUIHeaderView()) | ||||||
|  |       ->setHeader(pht('Pending Differential Revisions')); | ||||||
|  |  | ||||||
|  |     return array( | ||||||
|  |       $header, | ||||||
|  |       $view, | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,108 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | final class DiffusionBrowseDirectoryController | ||||||
|  |   extends DiffusionBrowseController { | ||||||
|  |  | ||||||
|  |   private $browseQueryResults; | ||||||
|  |  | ||||||
|  |   public function setBrowseQueryResults(DiffusionBrowseResultSet $results) { | ||||||
|  |     $this->browseQueryResults = $results; | ||||||
|  |     return $this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function getBrowseQueryResults() { | ||||||
|  |     return $this->browseQueryResults; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function processRequest() { | ||||||
|  |     $drequest = $this->diffusionRequest; | ||||||
|  |  | ||||||
|  |     $results = $this->getBrowseQueryResults(); | ||||||
|  |     $reason = $results->getReasonForEmptyResultSet(); | ||||||
|  |  | ||||||
|  |     $content = array(); | ||||||
|  |  | ||||||
|  |     $content[] = $this->buildHeaderView($drequest); | ||||||
|  |     $content[] = $this->buildActionView($drequest); | ||||||
|  |     $content[] = $this->buildPropertyView($drequest); | ||||||
|  |  | ||||||
|  |     $content[] = $this->renderSearchForm($collapsed = true); | ||||||
|  |  | ||||||
|  |     if (!$results->isValidResults()) { | ||||||
|  |       $empty_result = new DiffusionEmptyResultView(); | ||||||
|  |       $empty_result->setDiffusionRequest($drequest); | ||||||
|  |       $empty_result->setDiffusionBrowseResultSet($results); | ||||||
|  |       $empty_result->setView($this->getRequest()->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($this->getRequest()->getUser()); | ||||||
|  |  | ||||||
|  |       $browse_panel = new AphrontPanelView(); | ||||||
|  |       $browse_panel->appendChild($browse_table); | ||||||
|  |       $browse_panel->setNoBackground(); | ||||||
|  |  | ||||||
|  |       $content[] = $browse_panel; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     $content[] = $this->buildOpenRevisions(); | ||||||
|  |  | ||||||
|  |     $readme = $this->callConduitWithDiffusionRequest( | ||||||
|  |       'diffusion.readmequery', | ||||||
|  |       array( | ||||||
|  |         'paths' => $results->getPathDicts(), | ||||||
|  |       )); | ||||||
|  |     if ($readme) { | ||||||
|  |       $box = new PHUIBoxView(); | ||||||
|  |       $box->setShadow(true); | ||||||
|  |       $box->appendChild($readme); | ||||||
|  |       $box->addPadding(PHUI::PADDING_LARGE); | ||||||
|  |       $box->addMargin(PHUI::MARGIN_LARGE); | ||||||
|  |  | ||||||
|  |       $header = id(new PHUIHeaderView()) | ||||||
|  |         ->setHeader(pht('README')); | ||||||
|  |  | ||||||
|  |       $content[] = array( | ||||||
|  |         $header, | ||||||
|  |         $box, | ||||||
|  |       ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     $crumbs = $this->buildCrumbs( | ||||||
|  |       array( | ||||||
|  |         'branch' => true, | ||||||
|  |         'path'   => true, | ||||||
|  |         'view'   => 'browse', | ||||||
|  |       )); | ||||||
|  |  | ||||||
|  |     return $this->buildApplicationPage( | ||||||
|  |       array( | ||||||
|  |         $crumbs, | ||||||
|  |         $content, | ||||||
|  |       ), | ||||||
|  |       array( | ||||||
|  |         'device' => true, | ||||||
|  |         'title' => array( | ||||||
|  |           nonempty(basename($drequest->getPath()), '/'), | ||||||
|  |           $drequest->getRepository()->getCallsign().' Repository', | ||||||
|  |         ), | ||||||
|  |       )); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -1,6 +1,6 @@ | |||||||
| <?php | <?php | ||||||
|  |  | ||||||
| final class DiffusionBrowseFileController extends DiffusionController { | final class DiffusionBrowseFileController extends DiffusionBrowseController { | ||||||
|  |  | ||||||
|   private $corpusType = 'text'; |   private $corpusType = 'text'; | ||||||
|  |  | ||||||
| @@ -8,7 +8,6 @@ final class DiffusionBrowseFileController extends DiffusionController { | |||||||
|   private $lintMessages; |   private $lintMessages; | ||||||
|  |  | ||||||
|   public function processRequest() { |   public function processRequest() { | ||||||
|  |  | ||||||
|     $request = $this->getRequest(); |     $request = $this->getRequest(); | ||||||
|     $drequest = $this->getDiffusionRequest(); |     $drequest = $this->getDiffusionRequest(); | ||||||
|  |  | ||||||
| @@ -75,7 +74,7 @@ final class DiffusionBrowseFileController extends DiffusionController { | |||||||
|     $content = array(); |     $content = array(); | ||||||
|  |  | ||||||
|     $content[] = $this->buildHeaderView($drequest); |     $content[] = $this->buildHeaderView($drequest); | ||||||
|     $view = $this->buildBrowseActionView($drequest); |     $view = $this->buildActionView($drequest); | ||||||
|     $content[] = $this->enrichActionView($view, $drequest, $selected); |     $content[] = $this->enrichActionView($view, $drequest, $selected); | ||||||
|     $content[] = $this->buildPropertyView($drequest); |     $content[] = $this->buildPropertyView($drequest); | ||||||
|  |  | ||||||
| @@ -968,40 +967,4 @@ final class DiffusionBrowseFileController extends DiffusionController { | |||||||
|     return head($parents); |     return head($parents); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private function buildHeaderView(DiffusionRequest $drequest) { |  | ||||||
|     $viewer = $this->getRequest()->getUser(); |  | ||||||
|  |  | ||||||
|     $header = id(new PHUIHeaderView()) |  | ||||||
|       ->setUser($viewer) |  | ||||||
|       ->setHeader($this->renderPathLinks($drequest)) |  | ||||||
|       ->setPolicyObject($drequest->getRepository()); |  | ||||||
|  |  | ||||||
|     return $header; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   private function buildPropertyView(DiffusionRequest $drequest) { |  | ||||||
|     $viewer = $this->getRequest()->getUser(); |  | ||||||
|  |  | ||||||
|     $view = id(new PhabricatorPropertyListView()) |  | ||||||
|       ->setUser($viewer); |  | ||||||
|  |  | ||||||
|     $stable_commit = $drequest->getStableCommitName(); |  | ||||||
|     $callsign = $drequest->getRepository()->getCallsign(); |  | ||||||
|  |  | ||||||
|     $view->addProperty( |  | ||||||
|       pht('Commit'), |  | ||||||
|       phutil_tag( |  | ||||||
|         'a', |  | ||||||
|         array( |  | ||||||
|           'href' => $drequest->generateURI( |  | ||||||
|             array( |  | ||||||
|               'action' => 'commit', |  | ||||||
|               'commit' => $stable_commit, |  | ||||||
|             )), |  | ||||||
|         ), |  | ||||||
|         $drequest->getRepository()->formatCommitName($stable_commit))); |  | ||||||
|  |  | ||||||
|     return $view; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,39 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | final class DiffusionBrowseMainController extends DiffusionBrowseController { | ||||||
|  |  | ||||||
|  |   public function processRequest() { | ||||||
|  |     $drequest = $this->diffusionRequest; | ||||||
|  |     $request = $this->getRequest(); | ||||||
|  |  | ||||||
|  |     // Figure out if we're browsing a directory, a file, or a search result | ||||||
|  |     // list. Then delegate to the appropriate controller. | ||||||
|  |  | ||||||
|  |     $search = $request->getStr('grep'); | ||||||
|  |     if (strlen($search)) { | ||||||
|  |       $controller = new DiffusionBrowseSearchController($request); | ||||||
|  |     } else { | ||||||
|  |       $results = DiffusionBrowseResultSet::newFromConduit( | ||||||
|  |         $this->callConduitWithDiffusionRequest( | ||||||
|  |           'diffusion.browsequery', | ||||||
|  |           array( | ||||||
|  |             'path' => $drequest->getPath(), | ||||||
|  |             'commit' => $drequest->getCommit(), | ||||||
|  |           ))); | ||||||
|  |       $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); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,132 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | final class DiffusionBrowseSearchController extends DiffusionBrowseController { | ||||||
|  |  | ||||||
|  |   public function processRequest() { | ||||||
|  |     $drequest = $this->diffusionRequest; | ||||||
|  |  | ||||||
|  |     $content = array(); | ||||||
|  |  | ||||||
|  |     $content[] = $this->buildHeaderView($drequest); | ||||||
|  |     $content[] = $this->buildActionView($drequest); | ||||||
|  |     $content[] = $this->buildPropertyView($drequest); | ||||||
|  |     $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( | ||||||
|  |         'device' => true, | ||||||
|  |         'title' => array( | ||||||
|  |           nonempty(basename($drequest->getPath()), '/'), | ||||||
|  |           $drequest->getRepository()->getCallsign().' Repository', | ||||||
|  |         ), | ||||||
|  |       )); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   private function renderSearchResults() { | ||||||
|  |     $drequest = $this->getDiffusionRequest(); | ||||||
|  |     $repository = $drequest->getRepository(); | ||||||
|  |     $results = array(); | ||||||
|  |     $no_data = pht('No results found.'); | ||||||
|  |  | ||||||
|  |     $limit = 100; | ||||||
|  |     $page = $this->getRequest()->getInt('page', 0); | ||||||
|  |     $pager = new AphrontPagerView(); | ||||||
|  |     $pager->setPageSize($limit); | ||||||
|  |     $pager->setOffset($page); | ||||||
|  |     $pager->setURI($this->getRequest()->getRequestURI(), 'page'); | ||||||
|  |  | ||||||
|  |     try { | ||||||
|  |  | ||||||
|  |       $results = $this->callConduitWithDiffusionRequest( | ||||||
|  |         'diffusion.searchquery', | ||||||
|  |         array( | ||||||
|  |           'grep' => $this->getRequest()->getStr('grep'), | ||||||
|  |           'stableCommitName' => $drequest->getStableCommitName(), | ||||||
|  |           'path' => $drequest->getPath(), | ||||||
|  |           'limit' => $limit + 1, | ||||||
|  |           'offset' => $page)); | ||||||
|  |  | ||||||
|  |     } catch (ConduitException $ex) { | ||||||
|  |       $err = $ex->getErrorDescription(); | ||||||
|  |       if ($err != '') { | ||||||
|  |         return id(new AphrontErrorView()) | ||||||
|  |           ->setTitle(pht('Search Error')) | ||||||
|  |           ->appendChild($err); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     $results = $pager->sliceResults($results); | ||||||
|  |  | ||||||
|  |     require_celerity_resource('syntax-highlighting-css'); | ||||||
|  |  | ||||||
|  |     // NOTE: This can be wrong because we may find the string inside the | ||||||
|  |     // comment. But it's correct in most cases and highlighting the whole file | ||||||
|  |     // would be too expensive. | ||||||
|  |     $futures = array(); | ||||||
|  |     $engine = PhabricatorSyntaxHighlighter::newEngine(); | ||||||
|  |     foreach ($results as $result) { | ||||||
|  |       list($path, $line, $string) = $result; | ||||||
|  |       $futures["{$path}:{$line}"] = $engine->getHighlightFuture( | ||||||
|  |         $engine->getLanguageFromFilename($path), | ||||||
|  |         ltrim($string)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     try { | ||||||
|  |       Futures($futures)->limit(8)->resolveAll(); | ||||||
|  |     } catch (PhutilSyntaxHighlighterException $ex) { | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     $rows = array(); | ||||||
|  |     foreach ($results as $result) { | ||||||
|  |       list($path, $line, $string) = $result; | ||||||
|  |  | ||||||
|  |       $href = $drequest->generateURI(array( | ||||||
|  |         'action' => 'browse', | ||||||
|  |         'path' => $path, | ||||||
|  |         'line' => $line, | ||||||
|  |       )); | ||||||
|  |  | ||||||
|  |       try { | ||||||
|  |         $string = $futures["{$path}:{$line}"]->resolve(); | ||||||
|  |       } catch (PhutilSyntaxHighlighterException $ex) { | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       $string = phutil_tag( | ||||||
|  |         'pre', | ||||||
|  |         array('class' => 'PhabricatorMonospaced'), | ||||||
|  |         $string); | ||||||
|  |  | ||||||
|  |       $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($no_data); | ||||||
|  |  | ||||||
|  |     return id(new AphrontPanelView()) | ||||||
|  |       ->setNoBackground(true) | ||||||
|  |       ->appendChild($table) | ||||||
|  |       ->appendChild($pager); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -97,51 +97,6 @@ abstract class DiffusionController extends PhabricatorController { | |||||||
|     return $crumbs; |     return $crumbs; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   protected function buildOpenRevisions() { |  | ||||||
|     $user = $this->getRequest()->getUser(); |  | ||||||
|  |  | ||||||
|     $drequest = $this->getDiffusionRequest(); |  | ||||||
|     $repository = $drequest->getRepository(); |  | ||||||
|     $path = $drequest->getPath(); |  | ||||||
|  |  | ||||||
|     $path_map = id(new DiffusionPathIDQuery(array($path)))->loadPathIDs(); |  | ||||||
|     $path_id = idx($path_map, $path); |  | ||||||
|     if (!$path_id) { |  | ||||||
|       return null; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     $revisions = id(new DifferentialRevisionQuery()) |  | ||||||
|       ->setViewer($user) |  | ||||||
|       ->withPath($repository->getID(), $path_id) |  | ||||||
|       ->withStatus(DifferentialRevisionQuery::STATUS_OPEN) |  | ||||||
|       ->setOrder(DifferentialRevisionQuery::ORDER_PATH_MODIFIED) |  | ||||||
|       ->setLimit(10) |  | ||||||
|       ->needRelationships(true) |  | ||||||
|       ->execute(); |  | ||||||
|  |  | ||||||
|     if (!$revisions) { |  | ||||||
|       return null; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     $view = id(new DifferentialRevisionListView()) |  | ||||||
|       ->setRevisions($revisions) |  | ||||||
|       ->setFields(DifferentialRevisionListView::getDefaultFields($user)) |  | ||||||
|       ->setUser($user) |  | ||||||
|       ->loadAssets(); |  | ||||||
|  |  | ||||||
|     $phids = $view->getRequiredHandlePHIDs(); |  | ||||||
|     $handles = $this->loadViewerHandles($phids); |  | ||||||
|     $view->setHandles($handles); |  | ||||||
|  |  | ||||||
|     $header = id(new PHUIHeaderView()) |  | ||||||
|       ->setHeader(pht('Pending Differential Revisions')); |  | ||||||
|  |  | ||||||
|     return array( |  | ||||||
|       $header, |  | ||||||
|       $view, |  | ||||||
|     ); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   private function buildCrumbList(array $spec = array()) { |   private function buildCrumbList(array $spec = array()) { | ||||||
|  |  | ||||||
|     $spec = $spec + array( |     $spec = $spec + array( | ||||||
| @@ -344,56 +299,6 @@ abstract class DiffusionController extends PhabricatorController { | |||||||
|     return $this->getApplicationURI($repository->getCallsign().'/'.$path); |     return $this->getApplicationURI($repository->getCallsign().'/'.$path); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   protected function buildBrowseActionView(DiffusionRequest $drequest) { |  | ||||||
|     $viewer = $this->getRequest()->getUser(); |  | ||||||
|  |  | ||||||
|     $view = id(new PhabricatorActionListView()) |  | ||||||
|       ->setUser($viewer); |  | ||||||
|  |  | ||||||
|     $history_uri = $drequest->generateURI( |  | ||||||
|       array( |  | ||||||
|         'action' => 'history', |  | ||||||
|       )); |  | ||||||
|  |  | ||||||
|     $view->addAction( |  | ||||||
|       id(new PhabricatorActionView()) |  | ||||||
|         ->setName(pht('View History')) |  | ||||||
|         ->setHref($history_uri) |  | ||||||
|         ->setIcon('perflab')); |  | ||||||
|  |  | ||||||
|     $behind_head = $drequest->getRawCommit(); |  | ||||||
|     $head_uri = $drequest->generateURI( |  | ||||||
|       array( |  | ||||||
|         'commit' => '', |  | ||||||
|         'action' => 'browse', |  | ||||||
|       )); |  | ||||||
|     $view->addAction( |  | ||||||
|       id(new PhabricatorActionView()) |  | ||||||
|         ->setName(pht('Jump to HEAD')) |  | ||||||
|         ->setHref($head_uri) |  | ||||||
|         ->setIcon('home') |  | ||||||
|         ->setDisabled(!$behind_head)); |  | ||||||
|  |  | ||||||
|     // TODO: Ideally, this should live in Owners and be event-triggered, but |  | ||||||
|     // there's no reasonable object for it to react to right now. |  | ||||||
|  |  | ||||||
|     $owners_uri = id(new PhutilURI('/owners/view/search/')) |  | ||||||
|       ->setQueryParams( |  | ||||||
|         array( |  | ||||||
|           'repository' => $drequest->getCallsign(), |  | ||||||
|           'path' => '/'.$drequest->getPath(), |  | ||||||
|         )); |  | ||||||
|  |  | ||||||
|     $view->addAction( |  | ||||||
|       id(new PhabricatorActionView()) |  | ||||||
|         ->setName(pht('Find Owners')) |  | ||||||
|         ->setHref((string)$owners_uri) |  | ||||||
|         ->setIcon('preview')); |  | ||||||
|  |  | ||||||
|     return $view; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   protected function renderPathLinks(DiffusionRequest $drequest) { |   protected function renderPathLinks(DiffusionRequest $drequest) { | ||||||
|     $path = $drequest->getPath(); |     $path = $drequest->getPath(); | ||||||
|     $path_parts = array_filter(explode('/', trim($path, '/'))); |     $path_parts = array_filter(explode('/', trim($path, '/'))); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 epriestley
					epriestley