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

Fix pagination of fulltext search results

Summary:
Fixes T8285. Fulltext search relies on an underlying engine which can not realistically use cursor paging. This is unusual and creates some oddness.

Tweak a few numbers -- and how offsets are handled -- to separate the filtered offset and unfiltered offset.

Test Plan:
- Set page size to 2.
- Ran a query.
- Paged forward and backward through results sensibly, seeing the full result set.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T8285

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

+23 -18
+1 -1
src/__phutil_library_map__.php
··· 9148 9148 'PhabricatorSearchDocument' => 'PhabricatorSearchDAO', 9149 9149 'PhabricatorSearchDocumentField' => 'PhabricatorSearchDAO', 9150 9150 'PhabricatorSearchDocumentFieldType' => 'Phobject', 9151 - 'PhabricatorSearchDocumentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 9151 + 'PhabricatorSearchDocumentQuery' => 'PhabricatorPolicyAwareQuery', 9152 9152 'PhabricatorSearchDocumentRelationship' => 'PhabricatorSearchDAO', 9153 9153 'PhabricatorSearchDocumentTypeDatasource' => 'PhabricatorTypeaheadDatasource', 9154 9154 'PhabricatorSearchEditController' => 'PhabricatorSearchBaseController',
+21 -16
src/applications/search/query/PhabricatorSearchDocumentQuery.php
··· 1 1 <?php 2 2 3 3 final class PhabricatorSearchDocumentQuery 4 - extends PhabricatorCursorPagedPolicyAwareQuery { 4 + extends PhabricatorPolicyAwareQuery { 5 5 6 6 private $savedQuery; 7 7 private $objectCapabilities; 8 + private $unfilteredOffset; 8 9 9 10 public function withSavedQuery(PhabricatorSavedQuery $query) { 10 11 $this->savedQuery = $query; ··· 20 21 if ($this->objectCapabilities) { 21 22 return $this->objectCapabilities; 22 23 } 24 + 23 25 return $this->getRequiredCapabilities(); 24 26 } 25 27 28 + protected function willExecute() { 29 + $this->unfilteredOffset = 0; 30 + } 31 + 26 32 protected function loadPage() { 27 - $phids = $this->loadDocumentPHIDsWithoutPolicyChecks(); 33 + // NOTE: The offset and limit information in the inherited properties of 34 + // this object represent a policy-filtered offset and limit, but the 35 + // underlying query engine needs an unfiltered offset and limit. We keep 36 + // track of an unfiltered result offset internally. 37 + 38 + $query = id(clone($this->savedQuery)) 39 + ->setParameter('offset', $this->unfilteredOffset) 40 + ->setParameter('limit', $this->getRawResultLimit()); 41 + 42 + $phids = PhabricatorSearchService::executeSearch($query); 43 + 44 + $this->unfilteredOffset += count($phids); 28 45 29 46 $handles = id(new PhabricatorHandleQuery()) 30 47 ->setViewer($this->getViewer()) ··· 69 86 return $handles; 70 87 } 71 88 72 - public function loadDocumentPHIDsWithoutPolicyChecks() { 73 - $query = id(clone($this->savedQuery)) 74 - ->setParameter('offset', $this->getOffset()) 75 - ->setParameter('limit', $this->getRawResultLimit()); 76 - return PhabricatorSearchService::executeSearch($query); 77 - } 78 - 79 89 public function getQueryApplicationClass() { 80 90 return 'PhabricatorSearchApplication'; 81 91 } 82 92 83 - protected function getResultCursor($result) { 84 - throw new Exception( 85 - pht( 86 - 'This query does not support cursor paging; it must be offset paged.')); 87 - } 88 - 89 93 protected function nextPage(array $page) { 90 - $this->setOffset($this->getOffset() + count($page)); 94 + // We already updated the internal offset in `loadPage()` after loading 95 + // results, so we do not need to make any additional state updates here. 91 96 return $this; 92 97 } 93 98
+1 -1
src/view/phui/PHUIPagerView.php
··· 55 55 } 56 56 57 57 public function willShowPagingControls() { 58 - return $this->hasMorePages; 58 + return $this->hasMorePages || $this->getOffset(); 59 59 } 60 60 61 61 public function getHasMorePages() {