@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.

Introduce search result buckets

Summary:
Ref T10939. Currently, Differential hard-codes some behaviors for the "active" filter. This introduces "buckets" to make this grouping behavior more general/flexible.

The buckets don't actually do any grouping yet, this just gets rid of the `$query === 'active'` stuff so far.

These buckets change the page size to a large value, becuase pagination won't currently work with bucketing.

The problem is that we normally paginate by selecting one more result than we need: so if we're building a page of size 10, we'll select 11 results. This is fast, and if we get 11 back, we know there's a next page with at least one result on it.

With buckets, we can't do this, since our 11 results might come back in these buckets:

- A, B, C, A, C, C, A, A, B, B, (B)

So we know there are more results, and we know that bucket B has more results, but we have no clue if bucket A and bucket C have more results or not (or if there's anything in bucket D, etc).

We might need to select a thousand more results to get the first (D) or the next (A).

So we could render something like "Some buckets have more results, click here to go to the next page", but users would normally expect to be able to see "This specific bucket, A, has more results.", and we can't do that without a lot more work.

It doesn't really matter for revisions, because almost no one has 1K of them, but this may need to be resolved eventually.

(I have some OK-ish ideas for resolving it but nothing I'm particularly happy with.)

Test Plan: {F1376542}

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10939

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

+111 -17
+6
src/__phutil_library_map__.php
··· 533 533 'DifferentialRevisionQuery' => 'applications/differential/query/DifferentialRevisionQuery.php', 534 534 'DifferentialRevisionRepositoryHeraldField' => 'applications/differential/herald/DifferentialRevisionRepositoryHeraldField.php', 535 535 'DifferentialRevisionRepositoryProjectsHeraldField' => 'applications/differential/herald/DifferentialRevisionRepositoryProjectsHeraldField.php', 536 + 'DifferentialRevisionRequiredActionResultBucket' => 'applications/differential/query/DifferentialRevisionRequiredActionResultBucket.php', 537 + 'DifferentialRevisionResultBucket' => 'applications/differential/query/DifferentialRevisionResultBucket.php', 536 538 'DifferentialRevisionReviewersHeraldField' => 'applications/differential/herald/DifferentialRevisionReviewersHeraldField.php', 537 539 'DifferentialRevisionSearchEngine' => 'applications/differential/query/DifferentialRevisionSearchEngine.php', 538 540 'DifferentialRevisionStatus' => 'applications/differential/constants/DifferentialRevisionStatus.php', ··· 3317 3319 'PhabricatorSearchOrderField' => 'applications/search/field/PhabricatorSearchOrderField.php', 3318 3320 'PhabricatorSearchPreferencesSettingsPanel' => 'applications/settings/panel/PhabricatorSearchPreferencesSettingsPanel.php', 3319 3321 'PhabricatorSearchRelationship' => 'applications/search/constants/PhabricatorSearchRelationship.php', 3322 + 'PhabricatorSearchResultBucket' => 'applications/search/buckets/PhabricatorSearchResultBucket.php', 3320 3323 'PhabricatorSearchResultView' => 'applications/search/view/PhabricatorSearchResultView.php', 3321 3324 'PhabricatorSearchSchemaSpec' => 'applications/search/storage/PhabricatorSearchSchemaSpec.php', 3322 3325 'PhabricatorSearchSelectController' => 'applications/search/controller/PhabricatorSearchSelectController.php', ··· 4758 4761 'DifferentialRevisionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 4759 4762 'DifferentialRevisionRepositoryHeraldField' => 'DifferentialRevisionHeraldField', 4760 4763 'DifferentialRevisionRepositoryProjectsHeraldField' => 'DifferentialRevisionHeraldField', 4764 + 'DifferentialRevisionRequiredActionResultBucket' => 'DifferentialRevisionResultBucket', 4765 + 'DifferentialRevisionResultBucket' => 'PhabricatorSearchResultBucket', 4761 4766 'DifferentialRevisionReviewersHeraldField' => 'DifferentialRevisionHeraldField', 4762 4767 'DifferentialRevisionSearchEngine' => 'PhabricatorApplicationSearchEngine', 4763 4768 'DifferentialRevisionStatus' => 'Phobject', ··· 8009 8014 'PhabricatorSearchOrderField' => 'PhabricatorSearchField', 8010 8015 'PhabricatorSearchPreferencesSettingsPanel' => 'PhabricatorSettingsPanel', 8011 8016 'PhabricatorSearchRelationship' => 'Phobject', 8017 + 'PhabricatorSearchResultBucket' => 'Phobject', 8012 8018 'PhabricatorSearchResultView' => 'AphrontView', 8013 8019 'PhabricatorSearchSchemaSpec' => 'PhabricatorConfigSchemaSpec', 8014 8020 'PhabricatorSearchSelectController' => 'PhabricatorSearchBaseController',
+12
src/applications/differential/query/DifferentialRevisionRequiredActionResultBucket.php
··· 1 + <?php 2 + 3 + final class DifferentialRevisionRequiredActionResultBucket 4 + extends DifferentialRevisionResultBucket { 5 + 6 + const BUCKETKEY = 'action'; 7 + 8 + public function getResultBucketName() { 9 + return pht('Bucket by Required Action'); 10 + } 11 + 12 + }
+13
src/applications/differential/query/DifferentialRevisionResultBucket.php
··· 1 + <?php 2 + 3 + abstract class DifferentialRevisionResultBucket 4 + extends PhabricatorSearchResultBucket { 5 + 6 + public static function getAllResultBuckets() { 7 + return id(new PhutilClassMapQuery()) 8 + ->setAncestorClass(__CLASS__) 9 + ->setUniqueMethod('getResultBucketKey') 10 + ->execute(); 11 + } 12 + 13 + }
+11 -17
src/applications/differential/query/DifferentialRevisionSearchEngine.php
··· 11 11 return 'PhabricatorDifferentialApplication'; 12 12 } 13 13 14 + protected function newResultBuckets() { 15 + return DifferentialRevisionResultBucket::getAllResultBuckets(); 16 + } 17 + 14 18 public function newQuery() { 15 19 return id(new DifferentialRevisionQuery()) 16 20 ->needFlags(true) 17 21 ->needDrafts(true) 18 22 ->needRelationships(true); 19 23 } 20 - 21 - public function getPageSize(PhabricatorSavedQuery $saved) { 22 - if ($saved->getQueryKey() == 'active') { 23 - return 0xFFFF; 24 - } 25 - return parent::getPageSize($saved); 26 - } 27 - 28 24 29 25 protected function buildQueryFromParameters(array $map) { 30 26 $query = $this->newQuery(); ··· 114 110 115 111 switch ($query_key) { 116 112 case 'active': 113 + $bucket_key = DifferentialRevisionRequiredActionResultBucket::BUCKETKEY; 114 + 117 115 return $query 118 116 ->setParameter('responsiblePHIDs', array($viewer->getPHID())) 119 - ->setParameter('status', DifferentialRevisionQuery::STATUS_OPEN); 117 + ->setParameter('status', DifferentialRevisionQuery::STATUS_OPEN) 118 + ->setParameter('bucket', $bucket_key); 120 119 case 'authored': 121 120 return $query 122 121 ->setParameter('authorPHIDs', array($viewer->getPHID())); ··· 139 138 ); 140 139 } 141 140 142 - private function getOrderOptions() { 143 - return array( 144 - DifferentialRevisionQuery::ORDER_CREATED => pht('Created'), 145 - DifferentialRevisionQuery::ORDER_MODIFIED => pht('Updated'), 146 - ); 147 - } 148 - 149 141 protected function renderResultList( 150 142 array $revisions, 151 143 PhabricatorSavedQuery $query, ··· 157 149 ->setUser($viewer) 158 150 ->setNoBox($this->isPanelContext()); 159 151 152 + $bucket = $this->getResultBucket($query); 153 + 160 154 $views = array(); 161 - if ($query->getQueryKey() == 'active') { 155 + if ($bucket) { 162 156 $split = DifferentialRevisionQuery::splitResponsible( 163 157 $revisions, 164 158 $query->getParameter('responsiblePHIDs'));
+31
src/applications/search/buckets/PhabricatorSearchResultBucket.php
··· 1 + <?php 2 + 3 + abstract class PhabricatorSearchResultBucket 4 + extends Phobject { 5 + 6 + private $pageSize; 7 + 8 + final public function setPageSize($page_size) { 9 + $this->pageSize = $page_size; 10 + return $this; 11 + } 12 + 13 + final public function getPageSize() { 14 + if ($this->pageSize === null) { 15 + return $this->getDefaultPageSize(); 16 + } 17 + 18 + return $this->pageSize; 19 + } 20 + 21 + protected function getDefaultPageSize() { 22 + return 1000; 23 + } 24 + 25 + abstract public function getResultBucketName(); 26 + 27 + final public function getResultBucketKey() { 28 + return $this->getPhobjectClassConstant('BUCKETKEY'); 29 + } 30 + 31 + }
+38
src/applications/search/engine/PhabricatorApplicationSearchEngine.php
··· 28 28 const CONTEXT_LIST = 'list'; 29 29 const CONTEXT_PANEL = 'panel'; 30 30 31 + const BUCKET_NONE = 'none'; 32 + 31 33 public function setController(PhabricatorController $controller) { 32 34 $this->controller = $controller; 33 35 return $this; ··· 264 266 ->setKey('order') 265 267 ->setOrderAliases($query->getBuiltinOrderAliasMap()) 266 268 ->setOptions($orders); 269 + } 270 + 271 + $buckets = $this->newResultBuckets(); 272 + if ($query && $buckets) { 273 + $bucket_options = array( 274 + self::BUCKET_NONE => pht('No Bucketing'), 275 + ) + mpull($buckets, 'getResultBucketName'); 276 + 277 + $fields[] = id(new PhabricatorSearchSelectField()) 278 + ->setLabel(pht('Bucket')) 279 + ->setKey('bucket') 280 + ->setOptions($bucket_options); 267 281 } 268 282 269 283 $field_map = array(); ··· 944 958 /* -( Paging and Executing Queries )--------------------------------------- */ 945 959 946 960 961 + protected function newResultBuckets() { 962 + return array(); 963 + } 964 + 965 + protected function getResultBucket(PhabricatorSavedQuery $saved) { 966 + $key = $saved->getParameter('bucket'); 967 + if ($key == self::BUCKET_NONE) { 968 + return null; 969 + } 970 + 971 + $buckets = $this->newResultBuckets(); 972 + return idx($buckets, $key); 973 + } 974 + 975 + 947 976 public function getPageSize(PhabricatorSavedQuery $saved) { 977 + $bucket = $this->getResultBucket($saved); 978 + 948 979 $limit = (int)$saved->getParameter('limit'); 949 980 950 981 if ($limit > 0) { 982 + if ($bucket) { 983 + $bucket->setPageSize($limit); 984 + } 951 985 return $limit; 986 + } 987 + 988 + if ($bucket) { 989 + return $bucket->getPageSize(); 952 990 } 953 991 954 992 return 100;