@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 304 lines 8.6 kB view raw
1<?php 2 3final class PhabricatorRepositorySearchEngine 4 extends PhabricatorApplicationSearchEngine { 5 6 public function getResultTypeDescription() { 7 return pht('Repositories'); 8 } 9 10 public function getApplicationClassName() { 11 return PhabricatorDiffusionApplication::class; 12 } 13 14 public function newQuery() { 15 return id(new PhabricatorRepositoryQuery()) 16 ->needProjectPHIDs(true) 17 ->needCommitCounts(true) 18 ->needMostRecentCommits(true) 19 ->needProfileImage(true); 20 } 21 22 protected function buildCustomSearchFields() { 23 return array( 24 id(new PhabricatorSearchStringListField()) 25 ->setLabel(pht('Callsigns')) 26 ->setKey('callsigns') 27 ->setDescription( 28 pht('Search for repositories with specific callsigns.')), 29 id(new PhabricatorSearchStringListField()) 30 ->setLabel(pht('Short Names')) 31 ->setKey('shortNames') 32 ->setDescription( 33 pht('Search for repositories with specific short names.')), 34 id(new PhabricatorSearchSelectField()) 35 ->setLabel(pht('Status')) 36 ->setKey('status') 37 ->setDescription( 38 pht('Search for repositories with a specific status.')) 39 ->setOptions($this->getStatusOptions()), 40 id(new PhabricatorSearchSelectField()) 41 ->setLabel(pht('Hosted')) 42 ->setKey('hosted') 43 ->setDescription( 44 pht('Search for repositories which are hosted or remote.')) 45 ->setOptions($this->getHostedOptions()), 46 id(new PhabricatorSearchCheckboxesField()) 47 ->setLabel(pht('Types')) 48 ->setKey('types') 49 ->setDescription( 50 pht('Search for repositories of a specific VCS type.')) 51 ->setOptions(PhabricatorRepositoryType::getAllRepositoryTypes()), 52 id(new PhabricatorSearchStringListField()) 53 ->setLabel(pht('URIs')) 54 ->setKey('uris') 55 ->setDescription( 56 pht('Search for repositories by clone/checkout URI.')), 57 id(new PhabricatorPHIDsSearchField()) 58 ->setLabel(pht('Services')) 59 ->setKey('almanacServicePHIDs') 60 ->setDescription( 61 pht('Search for repositories with a specific Almanac Service.')) 62 ->setAliases( 63 array( 64 'almanacServicePHID', 65 'almanacService', 66 'almanacServices', 67 )), 68 ); 69 } 70 71 protected function buildQueryFromParameters(array $map) { 72 $query = $this->newQuery(); 73 74 if ($map['callsigns']) { 75 $query->withCallsigns($map['callsigns']); 76 } 77 78 if ($map['shortNames']) { 79 $query->withSlugs($map['shortNames']); 80 } 81 82 if ($map['status']) { 83 $status = idx($this->getStatusValues(), $map['status']); 84 if ($status) { 85 $query->withStatus($status); 86 } 87 } 88 89 if ($map['hosted']) { 90 $hosted = idx($this->getHostedValues(), $map['hosted']); 91 if ($hosted) { 92 $query->withHosted($hosted); 93 } 94 } 95 96 if ($map['types']) { 97 $query->withTypes($map['types']); 98 } 99 100 if ($map['uris']) { 101 $query->withURIs($map['uris']); 102 } 103 104 if ($map['almanacServicePHIDs']) { 105 $query->withAlmanacServicePHIDs($map['almanacServicePHIDs']); 106 } 107 108 return $query; 109 } 110 111 protected function getURI($path) { 112 return '/diffusion/'.$path; 113 } 114 115 protected function getBuiltinQueryNames() { 116 $names = array( 117 'active' => pht('Active Repositories'), 118 'all' => pht('All Repositories'), 119 ); 120 121 return $names; 122 } 123 124 public function buildSavedQueryFromBuiltin($query_key) { 125 126 $query = $this->newSavedQuery(); 127 $query->setQueryKey($query_key); 128 129 switch ($query_key) { 130 case 'active': 131 return $query->setParameter('status', 'open'); 132 case 'all': 133 return $query; 134 } 135 136 return parent::buildSavedQueryFromBuiltin($query_key); 137 } 138 139 private function getStatusOptions() { 140 return array( 141 '' => pht('Active and Inactive Repositories'), 142 'open' => pht('Active Repositories'), 143 'closed' => pht('Inactive Repositories'), 144 ); 145 } 146 147 private function getStatusValues() { 148 return array( 149 '' => PhabricatorRepositoryQuery::STATUS_ALL, 150 'open' => PhabricatorRepositoryQuery::STATUS_OPEN, 151 'closed' => PhabricatorRepositoryQuery::STATUS_CLOSED, 152 ); 153 } 154 155 private function getHostedOptions() { 156 return array( 157 '' => pht('Hosted and Remote Repositories'), 158 'phabricator' => pht('Hosted Repositories'), 159 'remote' => pht('Remote Repositories'), 160 ); 161 } 162 163 private function getHostedValues() { 164 return array( 165 '' => PhabricatorRepositoryQuery::HOSTED_ALL, 166 'phabricator' => PhabricatorRepositoryQuery::HOSTED_PHABRICATOR, 167 'remote' => PhabricatorRepositoryQuery::HOSTED_REMOTE, 168 ); 169 } 170 171 protected function getRequiredHandlePHIDsForResultList( 172 array $repositories, 173 PhabricatorSavedQuery $query) { 174 return array_mergev(mpull($repositories, 'getProjectPHIDs')); 175 } 176 177 /** 178 * @param array<PhabricatorRepository> $repositories 179 * @param PhabricatorSavedQuery $query 180 * @param array<PhabricatorObjectHandle> $handles 181 */ 182 protected function renderResultList( 183 array $repositories, 184 PhabricatorSavedQuery $query, 185 array $handles) { 186 assert_instances_of($repositories, PhabricatorRepository::class); 187 188 $viewer = $this->requireViewer(); 189 190 $list = new PHUIObjectItemListView(); 191 foreach ($repositories as $repository) { 192 $id = $repository->getID(); 193 194 $item = id(new PHUIObjectItemView()) 195 ->setViewer($viewer) 196 ->setObject($repository) 197 ->setHeader($repository->getName()) 198 ->setObjectName($repository->getMonogram()) 199 ->setHref($repository->getURI()) 200 ->setImageURI($repository->getProfileImageURI()); 201 202 $commit = $repository->getMostRecentCommit(); 203 if ($commit) { 204 $commit_link = phutil_tag( 205 'a', 206 array( 207 'href' => $commit->getURI(), 208 ), 209 pht( 210 '%s: %s', 211 $commit->getLocalName(), 212 $commit->getSummary())); 213 214 $item->setSubhead($commit_link); 215 $item->setEpoch($commit->getEpoch()); 216 } 217 218 $item->addIcon( 219 'none', 220 PhabricatorRepositoryType::getNameForRepositoryType( 221 $repository->getVersionControlSystem())); 222 223 $size = $repository->getCommitCount(); 224 if ($size) { 225 $history_uri = $repository->generateURI( 226 array( 227 'action' => 'history', 228 )); 229 230 $item->addAttribute( 231 phutil_tag( 232 'a', 233 array( 234 'href' => $history_uri, 235 ), 236 pht('%s Commit(s)', new PhutilNumber($size)))); 237 } else { 238 $item->addAttribute(pht('No Commits')); 239 } 240 241 $project_handles = array_select_keys( 242 $handles, 243 $repository->getProjectPHIDs()); 244 if ($project_handles) { 245 $item->addAttribute( 246 id(new PHUIHandleTagListView()) 247 ->setSlim(true) 248 ->setHandles($project_handles)); 249 } 250 251 if (!$repository->isTracked()) { 252 $item->setDisabled(true); 253 $item->addIcon('disable-grey', pht('Inactive')); 254 } else if ($repository->isImporting()) { 255 $item->addIcon('fa-clock-o indigo', pht('Importing...')); 256 } 257 258 $list->addItem($item); 259 } 260 261 $result = new PhabricatorApplicationSearchResultView(); 262 $result->setObjectList($list); 263 $result->setNoDataString(pht('No repositories found for this query.')); 264 265 return $result; 266 } 267 268 protected function willUseSavedQuery(PhabricatorSavedQuery $saved) { 269 $project_phids = $saved->getParameter('projectPHIDs', array()); 270 271 $old = $saved->getParameter('projects', array()); 272 foreach ($old as $phid) { 273 $project_phids[] = $phid; 274 } 275 276 $any = $saved->getParameter('anyProjectPHIDs', array()); 277 foreach ($any as $project) { 278 $project_phids[] = 'any('.$project.')'; 279 } 280 281 $saved->setParameter('projectPHIDs', $project_phids); 282 } 283 284 protected function getNewUserBody() { 285 286 $new_button = id(new PHUIButtonView()) 287 ->setTag('a') 288 ->setText(pht('New Repository')) 289 ->setHref('/diffusion/edit/') 290 ->setColor(PHUIButtonView::GREEN); 291 292 $icon = $this->getApplication()->getIcon(); 293 $app_name = $this->getApplication()->getName(); 294 $view = id(new PHUIBigInfoView()) 295 ->setIcon($icon) 296 ->setTitle(pht('Welcome to %s', $app_name)) 297 ->setDescription( 298 pht('Import, create, or just browse repositories in Diffusion.')) 299 ->addAction($new_button); 300 301 return $view; 302 } 303 304}