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

Use ApplicationSearch in Diviner

Summary: Ref T988. Ref T2625. Rough cut of ApplicationSearch in Diviner, for detailed Atom queries. This isn't useful yet, and isn't linked in the UI.

Test Plan: {F44836}

Reviewers: btrahan, chad

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T988, T2625

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

+316 -8
+21 -3
src/__phutil_library_map__.php
··· 503 503 'DivinerArticleAtomizer' => 'applications/diviner/atomizer/DivinerArticleAtomizer.php', 504 504 'DivinerAtom' => 'applications/diviner/atom/DivinerAtom.php', 505 505 'DivinerAtomCache' => 'applications/diviner/cache/DivinerAtomCache.php', 506 + 'DivinerAtomListController' => 'applications/diviner/controller/DivinerAtomListController.php', 507 + 'DivinerAtomQuery' => 'applications/diviner/query/DivinerAtomQuery.php', 506 508 'DivinerAtomRef' => 'applications/diviner/atom/DivinerAtomRef.php', 509 + 'DivinerAtomSearchEngine' => 'applications/diviner/query/DivinerAtomSearchEngine.php', 507 510 'DivinerAtomizeWorkflow' => 'applications/diviner/workflow/DivinerAtomizeWorkflow.php', 508 511 'DivinerAtomizer' => 'applications/diviner/atomizer/DivinerAtomizer.php', 512 + 'DivinerBookQuery' => 'applications/diviner/query/DivinerBookQuery.php', 513 + 'DivinerController' => 'applications/diviner/controller/DivinerController.php', 509 514 'DivinerDAO' => 'applications/diviner/storage/DivinerDAO.php', 510 515 'DivinerDefaultRenderer' => 'applications/diviner/renderer/DivinerDefaultRenderer.php', 511 516 'DivinerDiskCache' => 'applications/diviner/cache/DivinerDiskCache.php', 512 517 'DivinerFileAtomizer' => 'applications/diviner/atomizer/DivinerFileAtomizer.php', 513 518 'DivinerGenerateWorkflow' => 'applications/diviner/workflow/DivinerGenerateWorkflow.php', 514 - 'DivinerListController' => 'applications/diviner/controller/DivinerListController.php', 519 + 'DivinerLegacyController' => 'applications/diviner/controller/DivinerLegacyController.php', 515 520 'DivinerLiveAtom' => 'applications/diviner/storage/DivinerLiveAtom.php', 516 521 'DivinerLiveBook' => 'applications/diviner/storage/DivinerLiveBook.php', 517 522 'DivinerLivePublisher' => 'applications/diviner/publisher/DivinerLivePublisher.php', ··· 2316 2321 'DiffusionView' => 'AphrontView', 2317 2322 'DivinerArticleAtomizer' => 'DivinerAtomizer', 2318 2323 'DivinerAtomCache' => 'DivinerDiskCache', 2324 + 'DivinerAtomListController' => 2325 + array( 2326 + 0 => 'DivinerController', 2327 + 1 => 'PhabricatorApplicationSearchResultsControllerInterface', 2328 + ), 2329 + 'DivinerAtomQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 2330 + 'DivinerAtomSearchEngine' => 'PhabricatorApplicationSearchEngine', 2319 2331 'DivinerAtomizeWorkflow' => 'DivinerWorkflow', 2332 + 'DivinerBookQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 2333 + 'DivinerController' => 'PhabricatorController', 2320 2334 'DivinerDAO' => 'PhabricatorLiskDAO', 2321 2335 'DivinerDefaultRenderer' => 'DivinerRenderer', 2322 2336 'DivinerFileAtomizer' => 'DivinerAtomizer', 2323 2337 'DivinerGenerateWorkflow' => 'DivinerWorkflow', 2324 - 'DivinerListController' => 'PhabricatorController', 2338 + 'DivinerLegacyController' => 'DivinerController', 2325 2339 'DivinerLiveAtom' => 'DivinerDAO', 2326 2340 'DivinerLiveBook' => 2327 2341 array( ··· 2329 2343 1 => 'PhabricatorPolicyInterface', 2330 2344 ), 2331 2345 'DivinerLivePublisher' => 'DivinerPublisher', 2332 - 'DivinerLiveSymbol' => 'DivinerDAO', 2346 + 'DivinerLiveSymbol' => 2347 + array( 2348 + 0 => 'DivinerDAO', 2349 + 1 => 'PhabricatorPolicyInterface', 2350 + ), 2333 2351 'DivinerPublishCache' => 'DivinerDiskCache', 2334 2352 'DivinerRemarkupRuleSymbol' => 'PhutilRemarkupRule', 2335 2353 'DivinerStaticPublisher' => 'DivinerPublisher',
+4 -1
src/applications/diviner/application/PhabricatorApplicationDiviner.php
··· 20 20 21 21 public function getRoutes() { 22 22 return array( 23 - '/diviner/' => 'DivinerListController', 23 + '/diviner/' => array( 24 + '' => 'DivinerLegacyController', 25 + 'query/((?<key>[^/]+)/)?' => 'DivinerAtomListController', 26 + ), 24 27 ); 25 28 } 26 29
+46
src/applications/diviner/controller/DivinerAtomListController.php
··· 1 + <?php 2 + 3 + final class DivinerAtomListController extends DivinerController 4 + implements PhabricatorApplicationSearchResultsControllerInterface { 5 + 6 + private $key; 7 + 8 + public function shouldAllowPublic() { 9 + return true; 10 + } 11 + 12 + public function willProcessRequest(array $data) { 13 + $this->key = idx($data, 'key', 'all'); 14 + } 15 + 16 + public function processRequest() { 17 + $request = $this->getRequest(); 18 + $controller = id(new PhabricatorApplicationSearchController($request)) 19 + ->setQueryKey($this->key) 20 + ->setSearchEngine(new DivinerAtomSearchEngine()) 21 + ->setNavigation($this->buildSideNavView()); 22 + 23 + return $this->delegateToController($controller); 24 + } 25 + 26 + public function renderResultsList(array $symbols) { 27 + assert_instances_of($symbols, 'DivinerLiveSymbol'); 28 + 29 + $request = $this->getRequest(); 30 + $user = $request->getUser(); 31 + 32 + $list = id(new PhabricatorObjectItemListView()) 33 + ->setUser($user); 34 + 35 + foreach ($symbols as $symbol) { 36 + $item = id(new PhabricatorObjectItemView()) 37 + ->setHeader($symbol->getName()) 38 + ->addIcon('none', $symbol->getType()); 39 + 40 + $list->addItem($item); 41 + } 42 + 43 + return $list; 44 + } 45 + 46 + }
+24
src/applications/diviner/controller/DivinerController.php
··· 1 + <?php 2 + 3 + abstract class DivinerController extends PhabricatorController { 4 + 5 + protected function buildSideNavView() { 6 + $menu = $this->buildMenu(); 7 + return AphrontSideNavFilterView::newFromMenu($menu); 8 + } 9 + 10 + protected function buildApplicationMenu() { 11 + return $this->buildMenu(); 12 + } 13 + 14 + private function buildMenu() { 15 + $menu = new PhabricatorMenuView(); 16 + 17 + id(new DivinerAtomSearchEngine()) 18 + ->setViewer($this->getRequest()->getUser()) 19 + ->addNavigationItems($menu); 20 + 21 + return $menu; 22 + } 23 + 24 + }
+1 -1
src/applications/diviner/controller/DivinerListController.php src/applications/diviner/controller/DivinerLegacyController.php
··· 1 1 <?php 2 2 3 - final class DivinerListController extends PhabricatorController { 3 + final class DivinerLegacyController extends DivinerController { 4 4 5 5 public function processRequest() { 6 6
+2 -2
src/applications/diviner/publisher/DivinerLivePublisher.php
··· 104 104 if ($this->shouldGenerateDocumentForAtom($atom)) { 105 105 $content = $this->getRenderer()->renderAtom($atom); 106 106 107 - $this->loadAtomStorageForSymbol($symbol) 107 + $storage = $this->loadAtomStorageForSymbol($symbol) 108 108 ->setAtomData($atom->toDictionary()) 109 - ->setContent(phutil_safe_html($content)) 109 + ->setContent((string)phutil_safe_html($content)) 110 110 ->save(); 111 111 } 112 112 }
+81
src/applications/diviner/query/DivinerAtomQuery.php
··· 1 + <?php 2 + 3 + final class DivinerAtomQuery 4 + extends PhabricatorCursorPagedPolicyAwareQuery { 5 + 6 + private $ids; 7 + private $phids; 8 + 9 + public function withIDs(array $ids) { 10 + $this->ids = $ids; 11 + return $this; 12 + } 13 + 14 + public function withPHIDs(array $phids) { 15 + $this->phids = $phids; 16 + return $this; 17 + } 18 + 19 + protected function loadPage() { 20 + $table = new DivinerLiveSymbol(); 21 + $conn_r = $table->establishConnection('r'); 22 + 23 + $data = queryfx_all( 24 + $conn_r, 25 + 'SELECT * FROM %T %Q %Q %Q', 26 + $table->getTableName(), 27 + $this->buildWhereClause($conn_r), 28 + $this->buildOrderClause($conn_r), 29 + $this->buildLimitClause($conn_r)); 30 + 31 + return $table->loadAllFromArray($data); 32 + } 33 + 34 + protected function willFilterPage(array $atoms) { 35 + if (!$atoms) { 36 + return $atoms; 37 + } 38 + 39 + $books = array_unique(mpull($atoms, 'getBookPHID')); 40 + 41 + $books = id(new DivinerBookQuery()) 42 + ->setViewer($this->getViewer()) 43 + ->withPHIDs($books) 44 + ->execute(); 45 + $books = mpull($books, null, 'getPHID'); 46 + 47 + foreach ($atoms as $key => $atom) { 48 + $book = idx($books, $atom->getBookPHID()); 49 + if (!$book) { 50 + unset($atoms[$key]); 51 + continue; 52 + } 53 + $atom->attachBook($book); 54 + } 55 + 56 + return $atoms; 57 + } 58 + 59 + private function buildWhereClause(AphrontDatabaseConnection $conn_r) { 60 + $where = array(); 61 + 62 + if ($this->ids) { 63 + $where[] = qsprintf( 64 + $conn_r, 65 + 'id IN (%Ld)', 66 + $this->ids); 67 + } 68 + 69 + if ($this->phids) { 70 + $where[] = qsprintf( 71 + $conn_r, 72 + 'phid IN (%Ls)', 73 + $this->phids); 74 + } 75 + 76 + $where[] = $this->buildPagingClause($conn_r); 77 + 78 + return $this->formatWhereClause($where); 79 + } 80 + 81 + }
+49
src/applications/diviner/query/DivinerAtomSearchEngine.php
··· 1 + <?php 2 + 3 + final class DivinerAtomSearchEngine 4 + extends PhabricatorApplicationSearchEngine { 5 + 6 + public function buildSavedQueryFromRequest(AphrontRequest $request) { 7 + $saved = new PhabricatorSavedQuery(); 8 + 9 + return $saved; 10 + } 11 + 12 + public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { 13 + $query = id(new DivinerAtomQuery()); 14 + 15 + return $query; 16 + } 17 + 18 + public function buildSearchForm( 19 + AphrontFormView $form, 20 + PhabricatorSavedQuery $saved_query) { 21 + 22 + } 23 + 24 + protected function getURI($path) { 25 + return '/diviner/'.$path; 26 + } 27 + 28 + public function getBuiltinQueryNames() { 29 + $names = array( 30 + 'all' => pht('All'), 31 + ); 32 + 33 + return $names; 34 + } 35 + 36 + public function buildSavedQueryFromBuiltin($query_key) { 37 + 38 + $query = $this->newSavedQuery(); 39 + $query->setQueryKey($query_key); 40 + 41 + switch ($query_key) { 42 + case 'all': 43 + return $query; 44 + } 45 + 46 + return parent::buildSavedQueryFromBuiltin($query_key); 47 + } 48 + 49 + }
+56
src/applications/diviner/query/DivinerBookQuery.php
··· 1 + <?php 2 + 3 + final class DivinerBookQuery 4 + extends PhabricatorCursorPagedPolicyAwareQuery { 5 + 6 + private $ids; 7 + private $phids; 8 + 9 + public function withIDs(array $ids) { 10 + $this->ids = $ids; 11 + return $this; 12 + } 13 + 14 + public function withPHIDs(array $phids) { 15 + $this->phids = $phids; 16 + return $this; 17 + } 18 + 19 + protected function loadPage() { 20 + $table = new DivinerLiveBook(); 21 + $conn_r = $table->establishConnection('r'); 22 + 23 + $data = queryfx_all( 24 + $conn_r, 25 + 'SELECT * FROM %T %Q %Q %Q', 26 + $table->getTableName(), 27 + $this->buildWhereClause($conn_r), 28 + $this->buildOrderClause($conn_r), 29 + $this->buildLimitClause($conn_r)); 30 + 31 + return $table->loadAllFromArray($data); 32 + } 33 + 34 + private function buildWhereClause(AphrontDatabaseConnection $conn_r) { 35 + $where = array(); 36 + 37 + if ($this->ids) { 38 + $where[] = qsprintf( 39 + $conn_r, 40 + 'id IN (%Ld)', 41 + $this->ids); 42 + } 43 + 44 + if ($this->phids) { 45 + $where[] = qsprintf( 46 + $conn_r, 47 + 'phid IN (%Ls)', 48 + $this->phids); 49 + } 50 + 51 + $where[] = $this->buildPagingClause($conn_r); 52 + 53 + return $this->formatWhereClause($where); 54 + } 55 + 56 + }
+32 -1
src/applications/diviner/storage/DivinerLiveSymbol.php
··· 1 1 <?php 2 2 3 - final class DivinerLiveSymbol extends DivinerDAO { 3 + final class DivinerLiveSymbol extends DivinerDAO 4 + implements PhabricatorPolicyInterface { 4 5 5 6 protected $phid; 6 7 protected $bookPHID; ··· 10 11 protected $atomIndex; 11 12 protected $graphHash; 12 13 protected $identityHash; 14 + 15 + private $book; 13 16 14 17 public function getConfiguration() { 15 18 return array( ··· 21 24 public function generatePHID() { 22 25 return PhabricatorPHID::generateNewPHID( 23 26 PhabricatorPHIDConstants::PHID_TYPE_ATOM); 27 + } 28 + 29 + public function getBook() { 30 + if ($this->book === null) { 31 + throw new Exception("Call attachBook() before getBook()!"); 32 + } 33 + return $this->book; 34 + } 35 + 36 + public function attachBook(DivinerLiveBook $book) { 37 + $this->book = $book; 38 + return $this; 24 39 } 25 40 26 41 public function save() { ··· 44 59 return parent::save(); 45 60 } 46 61 62 + 63 + /* -( PhabricatorPolicyInterface )----------------------------------------- */ 64 + 65 + public function getCapabilities() { 66 + return $this->getBook()->getCapabilities(); 67 + } 68 + 69 + 70 + public function getPolicy($capability) { 71 + return $this->getBook()->getPolicy($capability); 72 + } 73 + 74 + 75 + public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { 76 + return $this->getBook()->hasAutomaticCapability($capability, $viewer); 77 + } 47 78 48 79 }