@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
at recaptime-dev/main 200 lines 5.2 kB view raw
1<?php 2 3final class DiffusionSymbolController extends DiffusionController { 4 5 public function handleRequest(AphrontRequest $request) { 6 $viewer = $this->getViewer(); 7 8 // See T13638 for discussion of escaping. 9 $name = $request->getURIData('name'); 10 $name = phutil_unescape_uri_path_component($name); 11 12 $query = id(new DiffusionSymbolQuery()) 13 ->setViewer($viewer) 14 ->setName($name); 15 16 if ($request->getStr('context')) { 17 $query->setContext($request->getStr('context')); 18 } 19 20 if ($request->getStr('type')) { 21 $query->setType($request->getStr('type')); 22 } 23 24 if ($request->getStr('lang')) { 25 $query->setLanguage($request->getStr('lang')); 26 } 27 28 $repos = array(); 29 if ($request->getStr('repositories')) { 30 $phids = $request->getStr('repositories'); 31 $phids = explode(',', $phids); 32 $phids = array_filter($phids); 33 34 if ($phids) { 35 $repos = id(new PhabricatorRepositoryQuery()) 36 ->setViewer($request->getUser()) 37 ->withPHIDs($phids) 38 ->execute(); 39 40 $repo_phids = mpull($repos, 'getPHID'); 41 if ($repo_phids) { 42 $query->withRepositoryPHIDs($repo_phids); 43 } 44 } 45 } 46 47 $query->needPaths(true); 48 $query->needRepositories(true); 49 50 $symbols = $query->execute(); 51 52 $external_query = id(new DiffusionExternalSymbolQuery()) 53 ->withNames(array($name)); 54 55 if ($request->getStr('context')) { 56 $external_query->withContexts(array($request->getStr('context'))); 57 } 58 59 if ($request->getStr('type')) { 60 $external_query->withTypes(array($request->getStr('type'))); 61 } 62 63 if ($request->getStr('lang')) { 64 $external_query->withLanguages(array($request->getStr('lang'))); 65 } 66 67 if ($request->getStr('path')) { 68 $external_query->withPaths(array($request->getStr('path'))); 69 } 70 71 if ($request->getInt('line')) { 72 $external_query->withLines(array($request->getInt('line'))); 73 } 74 75 if ($request->getInt('char')) { 76 $external_query->withCharacterPositions( 77 array( 78 $request->getInt('char'), 79 )); 80 } 81 82 if ($repos) { 83 $external_query->withRepositories($repos); 84 } 85 86 $external_sources = id(new PhutilClassMapQuery()) 87 ->setAncestorClass(DiffusionExternalSymbolsSource::class) 88 ->execute(); 89 90 $results = array($symbols); 91 foreach ($external_sources as $source) { 92 $source_results = $source->executeQuery($external_query); 93 94 if (!is_array($source_results)) { 95 throw new Exception( 96 pht( 97 'Expected a list of results from external symbol source "%s".', 98 get_class($source))); 99 } 100 101 try { 102 assert_instances_of( 103 $source_results, 104 PhabricatorRepositorySymbol::class); 105 } catch (InvalidArgumentException $ex) { 106 throw new Exception( 107 pht( 108 'Expected a list of PhabricatorRepositorySymbol objects '. 109 'from external symbol source "%s".', 110 get_class($source))); 111 } 112 113 $results[] = $source_results; 114 } 115 $symbols = array_mergev($results); 116 117 if ($request->getBool('jump') && count($symbols) == 1) { 118 // If this is a clickthrough from Differential, just jump them 119 // straight to the target if we got a single hit. 120 $symbol = head($symbols); 121 return id(new AphrontRedirectResponse()) 122 ->setIsExternal($symbol->isExternal()) 123 ->setURI($symbol->getURI()); 124 } 125 126 $rows = array(); 127 foreach ($symbols as $symbol) { 128 $href = $symbol->getURI(); 129 130 if ($symbol->isExternal()) { 131 $source = $symbol->getSource(); 132 $location = $symbol->getLocation(); 133 } else { 134 $repo = $symbol->getRepository(); 135 $file = $symbol->getPath(); 136 $line = $symbol->getLineNumber(); 137 138 $source = $repo->getMonogram(); 139 $location = $file.':'.$line; 140 } 141 $location = phutil_tag( 142 'a', 143 array( 144 'href' => $href, 145 ), 146 $location); 147 148 $rows[] = array( 149 $symbol->getSymbolType(), 150 $symbol->getSymbolContext(), 151 $symbol->getSymbolName(), 152 $symbol->getSymbolLanguage(), 153 $source, 154 $location, 155 ); 156 } 157 158 $table = new AphrontTableView($rows); 159 $table->setHeaders( 160 array( 161 pht('Type'), 162 pht('Context'), 163 pht('Name'), 164 pht('Language'), 165 pht('Source'), 166 pht('Location'), 167 )); 168 $table->setColumnClasses( 169 array( 170 '', 171 '', 172 'pri', 173 '', 174 '', 175 '', 176 )); 177 $table->setNoDataString( 178 pht('No matching symbol could be found in any indexed repository.')); 179 180 $header = id(new PHUIHeaderView()) 181 ->setHeader(pht('Similar Symbols')) 182 ->setHeaderIcon('fa-bullseye'); 183 184 $crumbs = $this->buildApplicationCrumbs(); 185 $crumbs->addTextCrumb(pht('Find Symbol')); 186 $crumbs->setBorder(true); 187 188 $view = id(new PHUITwoColumnView()) 189 ->setHeader($header) 190 ->setFooter(array( 191 $table, 192 )); 193 194 return $this->newPage() 195 ->setTitle(pht('Find Symbol')) 196 ->setCrumbs($crumbs) 197 ->appendChild($view); 198 } 199 200}