mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-09 16:32:39 +01:00
Add a rough Quick Search datasource for Phriction documents
Summary: Depends on D19106. Fixes T5941. Ref T13077. Allows you to find Phriction documents as suggestions from global quick search. Also supports `w` to jump to Phriction and `w query` to query Phriction. The actual query logic for the datasource may need some tweaking after it collides with reality, but seems to produce fairly reasonable results in local testing against synthetic data. Test Plan: Searched for "Porcupine Facts", "Travel Companions", and other useful local pages. Searched for `w`. Searched for `w zebra facts`. Maniphest Tasks: T13077, T5941 Differential Revision: https://secure.phabricator.com/D19107
This commit is contained in:
parent
b8bb4d3ad5
commit
f82206a4d1
6 changed files with 167 additions and 14 deletions
|
@ -10,7 +10,7 @@ return array(
|
|||
'conpherence.pkg.css' => 'e68cf1fa',
|
||||
'conpherence.pkg.js' => '15191c65',
|
||||
'core.pkg.css' => 'e4f098a5',
|
||||
'core.pkg.js' => '3ac6e174',
|
||||
'core.pkg.js' => 'bd19de1c',
|
||||
'darkconsole.pkg.js' => '1f9a31bc',
|
||||
'differential.pkg.css' => '113e692c',
|
||||
'differential.pkg.js' => 'f6d809c0',
|
||||
|
@ -506,7 +506,7 @@ return array(
|
|||
'rsrc/js/core/behavior-reorder-applications.js' => '76b9fc3e',
|
||||
'rsrc/js/core/behavior-reveal-content.js' => '60821bc7',
|
||||
'rsrc/js/core/behavior-scrollbar.js' => '834a1173',
|
||||
'rsrc/js/core/behavior-search-typeahead.js' => 'd0a99ab4',
|
||||
'rsrc/js/core/behavior-search-typeahead.js' => 'c3e917d9',
|
||||
'rsrc/js/core/behavior-select-content.js' => 'bf5374ef',
|
||||
'rsrc/js/core/behavior-select-on-click.js' => '4e3e79a6',
|
||||
'rsrc/js/core/behavior-setup-check-https.js' => '491416b3',
|
||||
|
@ -663,7 +663,7 @@ return array(
|
|||
'javelin-behavior-phabricator-oncopy' => '2926fff2',
|
||||
'javelin-behavior-phabricator-remarkup-assist' => 'acd29eee',
|
||||
'javelin-behavior-phabricator-reveal-content' => '60821bc7',
|
||||
'javelin-behavior-phabricator-search-typeahead' => 'd0a99ab4',
|
||||
'javelin-behavior-phabricator-search-typeahead' => 'c3e917d9',
|
||||
'javelin-behavior-phabricator-show-older-transactions' => '8f29b364',
|
||||
'javelin-behavior-phabricator-tooltips' => 'c420b0b9',
|
||||
'javelin-behavior-phabricator-transaction-comment-form' => 'b23b49e6',
|
||||
|
@ -1918,6 +1918,17 @@ return array(
|
|||
'javelin-dom',
|
||||
'javelin-vector',
|
||||
),
|
||||
'c3e917d9' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-typeahead-ondemand-source',
|
||||
'javelin-typeahead',
|
||||
'javelin-dom',
|
||||
'javelin-uri',
|
||||
'javelin-util',
|
||||
'javelin-stratcom',
|
||||
'phabricator-prefab',
|
||||
'phuix-icon-view',
|
||||
),
|
||||
'c420b0b9' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-behavior-device',
|
||||
|
@ -1969,17 +1980,6 @@ return array(
|
|||
'phabricator-notification',
|
||||
'conpherence-thread-manager',
|
||||
),
|
||||
'd0a99ab4' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-typeahead-ondemand-source',
|
||||
'javelin-typeahead',
|
||||
'javelin-dom',
|
||||
'javelin-uri',
|
||||
'javelin-util',
|
||||
'javelin-stratcom',
|
||||
'phabricator-prefab',
|
||||
'phuix-icon-view',
|
||||
),
|
||||
'd0c516d5' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
|
|
|
@ -4855,6 +4855,7 @@ phutil_register_library_map(array(
|
|||
'PhrictionController' => 'applications/phriction/controller/PhrictionController.php',
|
||||
'PhrictionCreateConduitAPIMethod' => 'applications/phriction/conduit/PhrictionCreateConduitAPIMethod.php',
|
||||
'PhrictionDAO' => 'applications/phriction/storage/PhrictionDAO.php',
|
||||
'PhrictionDatasourceEngineExtension' => 'applications/phriction/engineextension/PhrictionDatasourceEngineExtension.php',
|
||||
'PhrictionDeleteController' => 'applications/phriction/controller/PhrictionDeleteController.php',
|
||||
'PhrictionDiffController' => 'applications/phriction/controller/PhrictionDiffController.php',
|
||||
'PhrictionDocument' => 'applications/phriction/storage/PhrictionDocument.php',
|
||||
|
@ -4862,6 +4863,7 @@ phutil_register_library_map(array(
|
|||
'PhrictionDocumentContentHeraldField' => 'applications/phriction/herald/PhrictionDocumentContentHeraldField.php',
|
||||
'PhrictionDocumentContentTransaction' => 'applications/phriction/xaction/PhrictionDocumentContentTransaction.php',
|
||||
'PhrictionDocumentController' => 'applications/phriction/controller/PhrictionDocumentController.php',
|
||||
'PhrictionDocumentDatasource' => 'applications/phriction/typeahead/PhrictionDocumentDatasource.php',
|
||||
'PhrictionDocumentDeleteTransaction' => 'applications/phriction/xaction/PhrictionDocumentDeleteTransaction.php',
|
||||
'PhrictionDocumentFerretEngine' => 'applications/phriction/search/PhrictionDocumentFerretEngine.php',
|
||||
'PhrictionDocumentFulltextEngine' => 'applications/phriction/search/PhrictionDocumentFulltextEngine.php',
|
||||
|
@ -10777,6 +10779,7 @@ phutil_register_library_map(array(
|
|||
'PhrictionController' => 'PhabricatorController',
|
||||
'PhrictionCreateConduitAPIMethod' => 'PhrictionConduitAPIMethod',
|
||||
'PhrictionDAO' => 'PhabricatorLiskDAO',
|
||||
'PhrictionDatasourceEngineExtension' => 'PhabricatorDatasourceEngineExtension',
|
||||
'PhrictionDeleteController' => 'PhrictionController',
|
||||
'PhrictionDiffController' => 'PhrictionController',
|
||||
'PhrictionDocument' => array(
|
||||
|
@ -10796,6 +10799,7 @@ phutil_register_library_map(array(
|
|||
'PhrictionDocumentContentHeraldField' => 'PhrictionDocumentHeraldField',
|
||||
'PhrictionDocumentContentTransaction' => 'PhrictionDocumentTransactionType',
|
||||
'PhrictionDocumentController' => 'PhrictionController',
|
||||
'PhrictionDocumentDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||
'PhrictionDocumentDeleteTransaction' => 'PhrictionDocumentTransactionType',
|
||||
'PhrictionDocumentFerretEngine' => 'PhabricatorFerretEngine',
|
||||
'PhrictionDocumentFulltextEngine' => 'PhabricatorFulltextEngine',
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
final class PhrictionDatasourceEngineExtension
|
||||
extends PhabricatorDatasourceEngineExtension {
|
||||
|
||||
public function newQuickSearchDatasources() {
|
||||
return array(
|
||||
new PhrictionDocumentDatasource(),
|
||||
);
|
||||
}
|
||||
|
||||
public function newJumpURI($query) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
// Send "w" to Phriction.
|
||||
if (preg_match('/^w\z/i', $query)) {
|
||||
return '/w/';
|
||||
}
|
||||
|
||||
// Send "w <string>" to a search for similar wiki documents.
|
||||
$matches = null;
|
||||
if (preg_match('/^w\s+(.+)\z/i', $query, $matches)) {
|
||||
$raw_query = $matches[1];
|
||||
|
||||
$engine = id(new PhrictionDocument())
|
||||
->newFerretEngine();
|
||||
|
||||
$compiler = id(new PhutilSearchQueryCompiler())
|
||||
->setEnableFunctions(true);
|
||||
|
||||
$raw_tokens = $compiler->newTokens($raw_query);
|
||||
|
||||
$fulltext_tokens = array();
|
||||
foreach ($raw_tokens as $raw_token) {
|
||||
$fulltext_token = id(new PhabricatorFulltextToken())
|
||||
->setToken($raw_token);
|
||||
$fulltext_tokens[] = $fulltext_token;
|
||||
}
|
||||
|
||||
$documents = id(new PhrictionDocumentQuery())
|
||||
->setViewer($viewer)
|
||||
->withFerretConstraint($engine, $fulltext_tokens)
|
||||
->execute();
|
||||
if (count($documents) == 1) {
|
||||
return head($documents)->getURI();
|
||||
} else {
|
||||
// More than one match, jump to search.
|
||||
return urisprintf(
|
||||
'/phriction/?order=relevance&query=%s#R',
|
||||
$raw_query);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -149,6 +149,10 @@ final class PhrictionDocument extends PhrictionDAO
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
return self::getSlugURI($this->getSlug());
|
||||
}
|
||||
|
||||
/* -( Status )------------------------------------------------------------- */
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
|
||||
final class PhrictionDocumentDatasource
|
||||
extends PhabricatorTypeaheadDatasource {
|
||||
|
||||
public function getBrowseTitle() {
|
||||
return pht('Browse Documents');
|
||||
}
|
||||
|
||||
public function getPlaceholderText() {
|
||||
return pht('Type a document name...');
|
||||
}
|
||||
|
||||
public function getDatasourceApplicationClass() {
|
||||
return 'PhabricatorPhrictionApplication';
|
||||
}
|
||||
|
||||
public function loadResults() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$raw_query = $this->getRawQuery();
|
||||
|
||||
$engine = id(new PhrictionDocument())
|
||||
->newFerretEngine();
|
||||
|
||||
$compiler = id(new PhutilSearchQueryCompiler())
|
||||
->setEnableFunctions(true);
|
||||
|
||||
$raw_tokens = $compiler->newTokens($raw_query);
|
||||
|
||||
$fulltext_tokens = array();
|
||||
foreach ($raw_tokens as $raw_token) {
|
||||
|
||||
// This is a little hacky and could maybe be cleaner. We're treating
|
||||
// every search term as though the user had entered "title:dog" insead
|
||||
// of "dog".
|
||||
|
||||
$alternate_token = PhutilSearchQueryToken::newFromDictionary(
|
||||
array(
|
||||
'quoted' => $raw_token->isQuoted(),
|
||||
'value' => $raw_token->getValue(),
|
||||
'operator' => PhutilSearchQueryCompiler::OPERATOR_SUBSTRING,
|
||||
'function' => 'title',
|
||||
));
|
||||
|
||||
$fulltext_token = id(new PhabricatorFulltextToken())
|
||||
->setToken($alternate_token);
|
||||
$fulltext_tokens[] = $fulltext_token;
|
||||
}
|
||||
|
||||
$documents = id(new PhrictionDocumentQuery())
|
||||
->setViewer($viewer)
|
||||
->withFerretConstraint($engine, $fulltext_tokens)
|
||||
->needContent(true)
|
||||
->execute();
|
||||
|
||||
$results = array();
|
||||
foreach ($documents as $document) {
|
||||
$content = $document->getContent();
|
||||
|
||||
if (!$document->isActive()) {
|
||||
$closed = $document->getStatusDisplayName();
|
||||
} else {
|
||||
$closed = null;
|
||||
}
|
||||
|
||||
$slug = $document->getSlug();
|
||||
$title = $content->getTitle();
|
||||
|
||||
$sprite = 'phabricator-search-icon phui-font-fa phui-icon-view fa-book';
|
||||
|
||||
$result = id(new PhabricatorTypeaheadResult())
|
||||
->setName($title)
|
||||
->setDisplayName($title)
|
||||
->setURI($document->getURI())
|
||||
->setPHID($document->getPHID())
|
||||
->setDisplayType($slug)
|
||||
->setPriorityType('wiki')
|
||||
->setImageSprite($sprite)
|
||||
->setClosed($closed);
|
||||
|
||||
$results[] = $result;
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
}
|
|
@ -70,6 +70,7 @@ JX.behavior('phabricator-search-typeahead', function(config) {
|
|||
'proj',
|
||||
'user',
|
||||
'repo',
|
||||
'wiki',
|
||||
'symb',
|
||||
'misc'
|
||||
];
|
||||
|
|
Loading…
Reference in a new issue