@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 upstream/main 118 lines 3.3 kB view raw
1<?php 2 3final class PhabricatorSearchDocumentQuery 4 extends PhabricatorPolicyAwareQuery { 5 6 private $savedQuery; 7 private $objectCapabilities; 8 private $unfilteredOffset; 9 private $fulltextResultSet; 10 11 public function withSavedQuery(PhabricatorSavedQuery $query) { 12 $this->savedQuery = $query; 13 return $this; 14 } 15 16 public function requireObjectCapabilities(array $capabilities) { 17 $this->objectCapabilities = $capabilities; 18 return $this; 19 } 20 21 protected function getRequiredObjectCapabilities() { 22 if ($this->objectCapabilities) { 23 return $this->objectCapabilities; 24 } 25 26 return $this->getRequiredCapabilities(); 27 } 28 29 /** 30 * @return PhabricatorFulltextResultSet 31 */ 32 public function getFulltextResultSet() { 33 if (!$this->fulltextResultSet) { 34 throw new PhutilInvalidStateException('execute'); 35 } 36 37 return $this->fulltextResultSet; 38 } 39 40 protected function willExecute() { 41 $this->unfilteredOffset = 0; 42 $this->fulltextResultSet = null; 43 } 44 45 /** 46 * Load a raw page of results. 47 * 48 * @return list PHIDs of the search result objects as array keys. 49 */ 50 protected function loadPage() { 51 // NOTE: The offset and limit information in the inherited properties of 52 // this object represent a policy-filtered offset and limit, but the 53 // underlying query engine needs an unfiltered offset and limit. We keep 54 // track of an unfiltered result offset internally. 55 56 $query = id(clone($this->savedQuery)) 57 ->setParameter('offset', $this->unfilteredOffset) 58 ->setParameter('limit', $this->getRawResultLimit()); 59 60 $result_set = PhabricatorSearchService::newResultSet($query); 61 $phids = $result_set->getPHIDs(); 62 63 $this->fulltextResultSet = $result_set; 64 $this->unfilteredOffset += count($phids); 65 66 $handles = id(new PhabricatorHandleQuery()) 67 ->setViewer($this->getViewer()) 68 ->requireObjectCapabilities($this->getRequiredObjectCapabilities()) 69 ->withPHIDs($phids) 70 ->execute(); 71 72 // Retain engine order. 73 $handles = array_select_keys($handles, $phids); 74 75 return $handles; 76 } 77 78 protected function willFilterPage(array $handles) { 79 // NOTE: This is used by the object selector dialog to exclude the object 80 // you're looking at, so that, e.g., a task can't be set as a dependency 81 // of itself in the UI. 82 83 // TODO: Remove this after object selection moves to ApplicationSearch. 84 85 $exclude = array(); 86 if ($this->savedQuery) { 87 $exclude_phids = $this->savedQuery->getParameter('excludePHIDs', array()); 88 $exclude = array_fuse($exclude_phids); 89 } 90 91 foreach ($handles as $key => $handle) { 92 if (!$handle->isComplete()) { 93 unset($handles[$key]); 94 continue; 95 } 96 if ($handle->getPolicyFiltered()) { 97 unset($handles[$key]); 98 continue; 99 } 100 if (isset($exclude[$handle->getPHID()])) { 101 unset($handles[$key]); 102 continue; 103 } 104 } 105 106 return $handles; 107 } 108 109 public function getQueryApplicationClass() { 110 return PhabricatorSearchApplication::class; 111 } 112 113 protected function nextPage(array $page) { 114 // We already updated the internal offset in `loadPage()` after loading 115 // results, so we do not need to make any additional state updates here. 116 } 117 118}