Changeset View
Changeset View
Standalone View
Standalone View
src/applications/search/query/PhabricatorSearchDocumentQuery.php
| <?php | <?php | ||||
| final class PhabricatorSearchDocumentQuery | final class PhabricatorSearchDocumentQuery | ||||
| extends PhabricatorCursorPagedPolicyAwareQuery { | extends PhabricatorPolicyAwareQuery { | ||||
| private $savedQuery; | private $savedQuery; | ||||
| private $objectCapabilities; | private $objectCapabilities; | ||||
| private $unfilteredOffset; | |||||
| public function withSavedQuery(PhabricatorSavedQuery $query) { | public function withSavedQuery(PhabricatorSavedQuery $query) { | ||||
| $this->savedQuery = $query; | $this->savedQuery = $query; | ||||
| return $this; | return $this; | ||||
| } | } | ||||
| public function requireObjectCapabilities(array $capabilities) { | public function requireObjectCapabilities(array $capabilities) { | ||||
| $this->objectCapabilities = $capabilities; | $this->objectCapabilities = $capabilities; | ||||
| return $this; | return $this; | ||||
| } | } | ||||
| protected function getRequiredObjectCapabilities() { | protected function getRequiredObjectCapabilities() { | ||||
| if ($this->objectCapabilities) { | if ($this->objectCapabilities) { | ||||
| return $this->objectCapabilities; | return $this->objectCapabilities; | ||||
| } | } | ||||
| return $this->getRequiredCapabilities(); | return $this->getRequiredCapabilities(); | ||||
| } | } | ||||
| protected function willExecute() { | |||||
| $this->unfilteredOffset = 0; | |||||
| } | |||||
| protected function loadPage() { | protected function loadPage() { | ||||
| $phids = $this->loadDocumentPHIDsWithoutPolicyChecks(); | // NOTE: The offset and limit information in the inherited properties of | ||||
| // this object represent a policy-filtered offset and limit, but the | |||||
| // underlying query engine needs an unfiltered offset and limit. We keep | |||||
| // track of an unfiltered result offset internally. | |||||
| $query = id(clone($this->savedQuery)) | |||||
| ->setParameter('offset', $this->unfilteredOffset) | |||||
| ->setParameter('limit', $this->getRawResultLimit()); | |||||
| $phids = PhabricatorSearchService::executeSearch($query); | |||||
| $this->unfilteredOffset += count($phids); | |||||
| $handles = id(new PhabricatorHandleQuery()) | $handles = id(new PhabricatorHandleQuery()) | ||||
| ->setViewer($this->getViewer()) | ->setViewer($this->getViewer()) | ||||
| ->requireObjectCapabilities($this->getRequiredObjectCapabilities()) | ->requireObjectCapabilities($this->getRequiredObjectCapabilities()) | ||||
| ->withPHIDs($phids) | ->withPHIDs($phids) | ||||
| ->execute(); | ->execute(); | ||||
| // Retain engine order. | // Retain engine order. | ||||
| Show All 28 Lines | foreach ($handles as $key => $handle) { | ||||
| unset($handles[$key]); | unset($handles[$key]); | ||||
| continue; | continue; | ||||
| } | } | ||||
| } | } | ||||
| return $handles; | return $handles; | ||||
| } | } | ||||
| public function loadDocumentPHIDsWithoutPolicyChecks() { | |||||
| $query = id(clone($this->savedQuery)) | |||||
| ->setParameter('offset', $this->getOffset()) | |||||
| ->setParameter('limit', $this->getRawResultLimit()); | |||||
| return PhabricatorSearchService::executeSearch($query); | |||||
| } | |||||
| public function getQueryApplicationClass() { | public function getQueryApplicationClass() { | ||||
| return 'PhabricatorSearchApplication'; | return 'PhabricatorSearchApplication'; | ||||
| } | } | ||||
| protected function getResultCursor($result) { | |||||
| throw new Exception( | |||||
| pht( | |||||
| 'This query does not support cursor paging; it must be offset paged.')); | |||||
| } | |||||
| protected function nextPage(array $page) { | protected function nextPage(array $page) { | ||||
| $this->setOffset($this->getOffset() + count($page)); | // We already updated the internal offset in `loadPage()` after loading | ||||
| // results, so we do not need to make any additional state updates here. | |||||
| return $this; | return $this; | ||||
| } | } | ||||
| } | } | ||||