@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

Add Room typeahead for Conpherence Search

Summary: Ref T3165. Builds an ngram table for Conpherence Room titles, allowing a tokenizer for searching a subset of rooms.

Test Plan: Say `Gabbert` in two different rooms, search all, see two rooms returned. Search specific room, see specific result.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

Maniphest Tasks: T3165

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

+114 -3
+11
resources/sql/autopatches/20161011.conpherence.ngrams.php
··· 1 + <?php 2 + 3 + $table = new ConpherenceThread(); 4 + 5 + foreach (new LiskMigrationIterator($table) as $thread) { 6 + PhabricatorSearchWorker::queueDocumentForIndexing( 7 + $thread->getPHID(), 8 + array( 9 + 'force' => true, 10 + )); 11 + }
+7
resources/sql/autopatches/20161011.conpherence.ngrams.sql
··· 1 + CREATE TABLE {$NAMESPACE}_conpherence.conpherence_threadtitle_ngrams ( 2 + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 3 + objectID INT UNSIGNED NOT NULL, 4 + ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT}, 5 + KEY `key_object` (objectID), 6 + KEY `key_ngram` (ngram, objectID) 7 + ) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
+5
src/__phutil_library_map__.php
··· 313 313 'ConpherenceSchemaSpec' => 'applications/conpherence/storage/ConpherenceSchemaSpec.php', 314 314 'ConpherenceTestCase' => 'applications/conpherence/__tests__/ConpherenceTestCase.php', 315 315 'ConpherenceThread' => 'applications/conpherence/storage/ConpherenceThread.php', 316 + 'ConpherenceThreadDatasource' => 'applications/conpherence/typeahead/ConpherenceThreadDatasource.php', 316 317 'ConpherenceThreadIndexEngineExtension' => 'applications/conpherence/engineextension/ConpherenceThreadIndexEngineExtension.php', 317 318 'ConpherenceThreadListView' => 'applications/conpherence/view/ConpherenceThreadListView.php', 318 319 'ConpherenceThreadMailReceiver' => 'applications/conpherence/mail/ConpherenceThreadMailReceiver.php', ··· 320 321 'ConpherenceThreadQuery' => 'applications/conpherence/query/ConpherenceThreadQuery.php', 321 322 'ConpherenceThreadRemarkupRule' => 'applications/conpherence/remarkup/ConpherenceThreadRemarkupRule.php', 322 323 'ConpherenceThreadSearchEngine' => 'applications/conpherence/query/ConpherenceThreadSearchEngine.php', 324 + 'ConpherenceThreadTitleNgrams' => 'applications/conpherence/storage/ConpherenceThreadTitleNgrams.php', 323 325 'ConpherenceTransaction' => 'applications/conpherence/storage/ConpherenceTransaction.php', 324 326 'ConpherenceTransactionComment' => 'applications/conpherence/storage/ConpherenceTransactionComment.php', 325 327 'ConpherenceTransactionQuery' => 'applications/conpherence/query/ConpherenceTransactionQuery.php', ··· 4814 4816 'PhabricatorApplicationTransactionInterface', 4815 4817 'PhabricatorMentionableInterface', 4816 4818 'PhabricatorDestructibleInterface', 4819 + 'PhabricatorNgramsInterface', 4817 4820 ), 4821 + 'ConpherenceThreadDatasource' => 'PhabricatorTypeaheadDatasource', 4818 4822 'ConpherenceThreadIndexEngineExtension' => 'PhabricatorIndexEngineExtension', 4819 4823 'ConpherenceThreadListView' => 'AphrontView', 4820 4824 'ConpherenceThreadMailReceiver' => 'PhabricatorObjectMailReceiver', ··· 4822 4826 'ConpherenceThreadQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 4823 4827 'ConpherenceThreadRemarkupRule' => 'PhabricatorObjectRemarkupRule', 4824 4828 'ConpherenceThreadSearchEngine' => 'PhabricatorApplicationSearchEngine', 4829 + 'ConpherenceThreadTitleNgrams' => 'PhabricatorSearchNgrams', 4825 4830 'ConpherenceTransaction' => 'PhabricatorApplicationTransaction', 4826 4831 'ConpherenceTransactionComment' => 'PhabricatorApplicationTransactionComment', 4827 4832 'ConpherenceTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
+6
src/applications/conpherence/query/ConpherenceThreadQuery.php
··· 76 76 return $this; 77 77 } 78 78 79 + public function withTitleNgrams($ngrams) { 80 + return $this->withNgramsConstraint( 81 + id(new ConpherenceThreadTitleNgrams()), 82 + $ngrams); 83 + } 84 + 79 85 protected function loadPage() { 80 86 $table = new ConpherenceThread(); 81 87 $conn_r = $table->establishConnection('r');
+9 -2
src/applications/conpherence/query/ConpherenceThreadSearchEngine.php
··· 22 22 ->setLabel(pht('Participants')) 23 23 ->setKey('participants') 24 24 ->setAliases(array('participant')), 25 + id(new PhabricatorSearchDatasourceField()) 26 + ->setLabel(pht('Rooms')) 27 + ->setKey('phids') 28 + ->setDescription(pht('Search by room titles.')) 29 + ->setDatasource(id(new ConpherenceThreadDatasource())), 25 30 id(new PhabricatorSearchTextField()) 26 - ->setLabel(pht('Contains Words')) 31 + ->setLabel(pht('Room Contains Words')) 27 32 ->setKey('fulltext'), 28 33 ); 29 34 } ··· 47 52 if ($map['fulltext']) { 48 53 $query->withFulltext($map['fulltext']); 49 54 } 50 - 55 + if ($map['phids']) { 56 + $query->withPHIDs($map['phids']); 57 + } 51 58 return $query; 52 59 } 53 60
+12 -1
src/applications/conpherence/storage/ConpherenceThread.php
··· 5 5 PhabricatorPolicyInterface, 6 6 PhabricatorApplicationTransactionInterface, 7 7 PhabricatorMentionableInterface, 8 - PhabricatorDestructibleInterface { 8 + PhabricatorDestructibleInterface, 9 + PhabricatorNgramsInterface { 9 10 10 11 protected $title; 11 12 protected $topic; ··· 425 426 PhabricatorApplicationTransactionView $timeline, 426 427 AphrontRequest $request) { 427 428 return $timeline; 429 + } 430 + 431 + /* -( PhabricatorNgramInterface )------------------------------------------ */ 432 + 433 + 434 + public function newNgrams() { 435 + return array( 436 + id(new ConpherenceThreadTitleNgrams()) 437 + ->setValue($this->getTitle()), 438 + ); 428 439 } 429 440 430 441
+17
src/applications/conpherence/storage/ConpherenceThreadTitleNgrams.php
··· 1 + <?php 2 + 3 + final class ConpherenceThreadTitleNgrams 4 + extends PhabricatorSearchNgrams { 5 + 6 + public function getNgramKey() { 7 + return 'threadtitle'; 8 + } 9 + 10 + public function getColumnName() { 11 + return 'title'; 12 + } 13 + 14 + public function getApplicationName() { 15 + return 'conpherence'; 16 + } 17 + }
+47
src/applications/conpherence/typeahead/ConpherenceThreadDatasource.php
··· 1 + <?php 2 + 3 + final class ConpherenceThreadDatasource 4 + extends PhabricatorTypeaheadDatasource { 5 + 6 + public function getBrowseTitle() { 7 + return pht('Browse Room'); 8 + } 9 + 10 + public function getPlaceholderText() { 11 + return pht('Type a room title...'); 12 + } 13 + 14 + public function getDatasourceApplicationClass() { 15 + return 'PhabricatorConpherenceApplication'; 16 + } 17 + 18 + public function loadResults() { 19 + $viewer = $this->getViewer(); 20 + $raw_query = $this->getRawQuery(); 21 + 22 + $rooms = id(new ConpherenceThreadQuery()) 23 + ->setViewer($viewer) 24 + ->withTitleNgrams($raw_query) 25 + ->needParticipants(true) 26 + ->execute(); 27 + 28 + $results = array(); 29 + foreach ($rooms as $room) { 30 + if (strlen($room->getTopic())) { 31 + $topic = $room->getTopic(); 32 + } else { 33 + $topic = phutil_tag('em', array(), pht('No topic set')); 34 + } 35 + 36 + $token = id(new PhabricatorTypeaheadResult()) 37 + ->setName($room->getTitle()) 38 + ->setPHID($room->getPHID()) 39 + ->addAttribute($topic); 40 + 41 + $results[] = $token; 42 + } 43 + 44 + return $results; 45 + } 46 + 47 + }