@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
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Make owners typeahead mostly reasonable

Summary: Ref T8320. Fixes T8427. This is still a little funky because Owners has weird name rules, but should fix the bugs (unselectable packages) in T8427.

Test Plan: Browsed Owners typaheads, used various search functions.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T8320, T8427

Differential Revision: https://secure.phabricator.com/D13349

+107 -89
+80 -29
src/applications/owners/query/PhabricatorOwnersPackageQuery.php
··· 7 7 private $phids; 8 8 private $ownerPHIDs; 9 9 private $repositoryPHIDs; 10 + private $namePrefix; 10 11 11 12 /** 12 13 * Owners are direct owners, and members of owning projects. ··· 31 32 return $this; 32 33 } 33 34 34 - protected function loadPage() { 35 - $table = new PhabricatorOwnersPackage(); 36 - $conn_r = $table->establishConnection('r'); 35 + public function withNamePrefix($prefix) { 36 + $this->namePrefix = $prefix; 37 + return $this; 38 + } 37 39 38 - $data = queryfx_all( 39 - $conn_r, 40 - 'SELECT p.* FROM %T p %Q %Q %Q %Q', 41 - $table->getTableName(), 42 - $this->buildJoinClause($conn_r), 43 - $this->buildWhereClause($conn_r), 44 - $this->buildOrderClause($conn_r), 45 - $this->buildLimitClause($conn_r)); 40 + public function newResultObject() { 41 + return new PhabricatorOwnersPackage(); 42 + } 46 43 47 - return $table->loadAllFromArray($data); 44 + protected function loadPage() { 45 + return $this->loadStandardPage(new PhabricatorOwnersPackage()); 48 46 } 49 47 50 - protected function buildJoinClause(AphrontDatabaseConnection $conn_r) { 51 - $joins = array(); 48 + protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) { 49 + $joins = parent::buildJoinClauseParts($conn); 52 50 53 51 if ($this->ownerPHIDs !== null) { 54 52 $joins[] = qsprintf( 55 - $conn_r, 53 + $conn, 56 54 'JOIN %T o ON o.packageID = p.id', 57 55 id(new PhabricatorOwnersOwner())->getTableName()); 58 56 } 59 57 60 58 if ($this->repositoryPHIDs !== null) { 61 59 $joins[] = qsprintf( 62 - $conn_r, 60 + $conn, 63 61 'JOIN %T rpath ON rpath.packageID = p.id', 64 62 id(new PhabricatorOwnersPath())->getTableName()); 65 63 } 66 64 67 - return implode(' ', $joins); 65 + return $joins; 68 66 } 69 67 70 - protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { 71 - $where = array(); 68 + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { 69 + $where = parent::buildWhereClauseParts($conn); 72 70 73 71 if ($this->phids !== null) { 74 72 $where[] = qsprintf( 75 - $conn_r, 73 + $conn, 76 74 'p.phid IN (%Ls)', 77 75 $this->phids); 78 76 } 79 77 80 78 if ($this->ids !== null) { 81 79 $where[] = qsprintf( 82 - $conn_r, 80 + $conn, 83 81 'p.id IN (%Ld)', 84 82 $this->ids); 85 83 } 86 84 87 85 if ($this->repositoryPHIDs !== null) { 88 86 $where[] = qsprintf( 89 - $conn_r, 87 + $conn, 90 88 'rpath.repositoryPHID IN (%Ls)', 91 89 $this->repositoryPHIDs); 92 90 } ··· 94 92 if ($this->ownerPHIDs !== null) { 95 93 $base_phids = $this->ownerPHIDs; 96 94 97 - $query = new PhabricatorProjectQuery(); 98 - $query->setViewer($this->getViewer()); 99 - $query->withMemberPHIDs($base_phids); 100 - $projects = $query->execute(); 95 + $projects = id(new PhabricatorProjectQuery()) 96 + ->setViewer($this->getViewer()) 97 + ->withMemberPHIDs($base_phids) 98 + ->execute(); 101 99 $project_phids = mpull($projects, 'getPHID'); 102 100 103 101 $all_phids = array_merge($base_phids, $project_phids); 104 102 105 103 $where[] = qsprintf( 106 - $conn_r, 104 + $conn, 107 105 'o.userPHID IN (%Ls)', 108 106 $all_phids); 109 107 } 110 108 111 - $where[] = $this->buildPagingClause($conn_r); 112 - return $this->formatWhereClause($where); 109 + if (strlen($this->namePrefix)) { 110 + // NOTE: This is a hacky mess, but this column is currently case 111 + // sensitive and unique. 112 + $where[] = qsprintf( 113 + $conn, 114 + 'LOWER(p.name) LIKE %>', 115 + phutil_utf8_strtolower($this->namePrefix)); 116 + } 117 + 118 + return $where; 119 + } 120 + 121 + protected function shouldGroupQueryResultRows() { 122 + if ($this->repositoryPHIDs) { 123 + return true; 124 + } 125 + 126 + if ($this->ownerPHIDs) { 127 + return true; 128 + } 129 + 130 + return parent::shouldGroupQueryResultRows(); 131 + } 132 + 133 + public function getBuiltinOrders() { 134 + return array( 135 + 'name' => array( 136 + 'vector' => array('name'), 137 + 'name' => pht('Name'), 138 + ), 139 + ) + parent::getBuiltinOrders(); 140 + } 141 + 142 + public function getOrderableColumns() { 143 + return parent::getOrderableColumns() + array( 144 + 'name' => array( 145 + 'table' => $this->getPrimaryTableAlias(), 146 + 'column' => 'name', 147 + 'type' => 'string', 148 + 'unique' => true, 149 + 'reverse' => true, 150 + ), 151 + ); 152 + } 153 + 154 + protected function getPagingValueMap($cursor, array $keys) { 155 + $package = $this->loadCursorObject($cursor); 156 + return array( 157 + 'id' => $package->getID(), 158 + 'name' => $package->getName(), 159 + ); 113 160 } 114 161 115 162 public function getQueryApplicationClass() { 116 163 return 'PhabricatorOwnersApplication'; 164 + } 165 + 166 + protected function getPrimaryTableAlias() { 167 + return 'p'; 117 168 } 118 169 119 170 }
+22 -51
src/applications/owners/query/PhabricatorOwnersPackageSearchEngine.php
··· 11 11 return 'PhabricatorOwnersApplication'; 12 12 } 13 13 14 - public function buildSavedQueryFromRequest(AphrontRequest $request) { 15 - $saved = new PhabricatorSavedQuery(); 14 + public function newQuery() { 15 + return new PhabricatorOwnersPackageQuery(); 16 + } 16 17 17 - $saved->setParameter( 18 - 'ownerPHIDs', 19 - $this->readUsersFromRequest( 20 - $request, 21 - 'owners', 22 - array( 23 - PhabricatorProjectProjectPHIDType::TYPECONST, 24 - ))); 25 - 26 - $saved->setParameter( 27 - 'repositoryPHIDs', 28 - $this->readPHIDsFromRequest( 29 - $request, 30 - 'repositories', 31 - array( 32 - PhabricatorRepositoryRepositoryPHIDType::TYPECONST, 33 - ))); 34 - 35 - return $saved; 18 + protected function buildCustomSearchFields() { 19 + return array( 20 + id(new PhabricatorSearchDatasourceField()) 21 + ->setLabel(pht('Owners')) 22 + ->setKey('ownerPHIDs') 23 + ->setAliases(array('owner', 'owners')) 24 + ->setDatasource(new PhabricatorProjectOrUserDatasource()), 25 + id(new PhabricatorSearchDatasourceField()) 26 + ->setLabel(pht('Repositories')) 27 + ->setKey('repositoryPHIDs') 28 + ->setAliases(array('repository', 'repositories')) 29 + ->setDatasource(new DiffusionRepositoryDatasource()), 30 + ); 36 31 } 37 32 38 - public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { 39 - $query = id(new PhabricatorOwnersPackageQuery()); 33 + protected function buildQueryFromParameters(array $map) { 34 + $query = $this->newQuery(); 40 35 41 - $owner_phids = $saved->getParameter('ownerPHIDs', array()); 42 - if ($owner_phids) { 43 - $query->withOwnerPHIDs($owner_phids); 36 + if ($map['ownerPHIDs']) { 37 + $query->withOwnerPHIDs($map['ownerPHIDs']); 44 38 } 45 39 46 - $repository_phids = $saved->getParameter('repositoryPHIDs', array()); 47 - if ($repository_phids) { 48 - $query->withRepositoryPHIDs($repository_phids); 40 + if ($map['repositoryPHIDs']) { 41 + $query->withRepositoryPHIDs($map['repositoryPHIDs']); 49 42 } 50 43 51 44 return $query; 52 - } 53 - 54 - public function buildSearchForm( 55 - AphrontFormView $form, 56 - PhabricatorSavedQuery $saved) { 57 - 58 - $owner_phids = $saved->getParameter('ownerPHIDs', array()); 59 - $repository_phids = $saved->getParameter('repositoryPHIDs', array()); 60 - 61 - $form 62 - ->appendControl( 63 - id(new AphrontFormTokenizerControl()) 64 - ->setDatasource(new PhabricatorProjectOrUserDatasource()) 65 - ->setName('owners') 66 - ->setLabel(pht('Owners')) 67 - ->setValue($owner_phids)) 68 - ->appendControl( 69 - id(new AphrontFormTokenizerControl()) 70 - ->setDatasource(new DiffusionRepositoryDatasource()) 71 - ->setName('repositories') 72 - ->setLabel(pht('Repositories')) 73 - ->setValue($repository_phids)); 74 45 } 75 46 76 47 protected function getURI($path) {
+5 -9
src/applications/owners/typeahead/PhabricatorOwnersPackageDatasource.php
··· 3 3 final class PhabricatorOwnersPackageDatasource 4 4 extends PhabricatorTypeaheadDatasource { 5 5 6 - public function isBrowsable() { 7 - // TODO: Make this browsable. 8 - return false; 9 - } 10 - 11 6 public function getBrowseTitle() { 12 7 return pht('Browse Packages'); 13 8 } ··· 26 21 27 22 $results = array(); 28 23 29 - $packages = id(new PhabricatorOwnersPackageQuery()) 30 - ->setViewer($viewer) 31 - ->execute(); 24 + $query = id(new PhabricatorOwnersPackageQuery()) 25 + ->withNamePrefix($raw_query) 26 + ->setOrder('name'); 32 27 28 + $packages = $this->executeQuery($query); 33 29 foreach ($packages as $package) { 34 30 $results[] = id(new PhabricatorTypeaheadResult()) 35 31 ->setName($package->getName()) ··· 37 33 ->setPHID($package->getPHID()); 38 34 } 39 35 40 - return $results; 36 + return $this->filterResultsAgainstTokens($results); 41 37 } 42 38 43 39 }