mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-26 00:32:42 +01:00
Rought cut of search.
Summary: Botched this pretty badly in git so we'll see how much I broke. :/ Test Plan: Reviewers: CC:
This commit is contained in:
parent
fcc467fe5e
commit
147d2e2e3d
43 changed files with 1183 additions and 30 deletions
31
scripts/__init_env__.php
Normal file
31
scripts/__init_env__.php
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once dirname(dirname(__FILE__)).'/conf/__init_conf__.php';
|
||||||
|
|
||||||
|
$env = getenv('PHABRICATOR_ENV');
|
||||||
|
if (!$env) {
|
||||||
|
echo "Define PHABRICATOR_ENV before running this script.\n";
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
$conf = phabricator_read_config_file($env);
|
||||||
|
$conf['phabricator.env'] = $env;
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'infrastructure/env');
|
||||||
|
PhabricatorEnv::setEnvConfig($conf);
|
|
@ -30,5 +30,3 @@ if (!ini_get('date.timezone')) {
|
||||||
}
|
}
|
||||||
|
|
||||||
phutil_load_library(dirname(__FILE__).'/../src/');
|
phutil_load_library(dirname(__FILE__).'/../src/');
|
||||||
|
|
||||||
require_once dirname(dirname(__FILE__)).'/conf/__init_conf__.php';
|
|
||||||
|
|
|
@ -19,18 +19,8 @@
|
||||||
|
|
||||||
$root = dirname(dirname(dirname(__FILE__)));
|
$root = dirname(dirname(dirname(__FILE__)));
|
||||||
require_once $root.'/scripts/__init_script__.php';
|
require_once $root.'/scripts/__init_script__.php';
|
||||||
|
require_once $root.'/scripts/__init_env__.php';
|
||||||
|
|
||||||
$env = getenv('PHABRICATOR_ENV');
|
|
||||||
if (!$env) {
|
|
||||||
echo "Define PHABRICATOR_ENV before running scripts.\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
$conf = phabricator_read_config_file($env);
|
|
||||||
$conf['phabricator.env'] = $env;
|
|
||||||
|
|
||||||
phutil_require_module('phabricator', 'infrastructure/env');
|
|
||||||
PhabricatorEnv::setEnvConfig($conf);
|
|
||||||
phutil_require_module('phutil', 'symbols');
|
phutil_require_module('phutil', 'symbols');
|
||||||
|
|
||||||
PhutilSymbolLoader::loadClass('PhabricatorMetaMTADaemon');
|
PhutilSymbolLoader::loadClass('PhabricatorMetaMTADaemon');
|
||||||
|
|
53
scripts/search/reindex_everything.php
Executable file
53
scripts/search/reindex_everything.php
Executable file
|
@ -0,0 +1,53 @@
|
||||||
|
#!/usr/bin/env php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
$root = dirname(dirname(dirname(__FILE__)));
|
||||||
|
require_once $root.'/scripts/__init_script__.php';
|
||||||
|
require_once $root.'/scripts/__init_env__.php';
|
||||||
|
|
||||||
|
// TODO: Get rid of this script eventually, once this stuff is better-formalized
|
||||||
|
// in Timeline consumers.
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'symbols');
|
||||||
|
PhutilSymbolLoader::loadClass('DifferentialRevision');
|
||||||
|
PhutilSymbolLoader::loadClass('PhabricatorSearchDifferentialIndexer');
|
||||||
|
PhutilSymbolLoader::loadClass('ManiphestTask');
|
||||||
|
PhutilSymbolLoader::loadClass('PhabricatorSearchManiphestIndexer');
|
||||||
|
|
||||||
|
echo "Loading revisions...\n";
|
||||||
|
$revs = id(new DifferentialRevision())->loadAll();
|
||||||
|
$count = count($revs);
|
||||||
|
echo "Reindexing {$count} revisions";
|
||||||
|
foreach ($revs as $rev) {
|
||||||
|
PhabricatorSearchDifferentialIndexer::indexRevision($rev);
|
||||||
|
echo '.';
|
||||||
|
}
|
||||||
|
echo "\n";
|
||||||
|
|
||||||
|
echo "Loading tasks...\n";
|
||||||
|
$tasks = id(new ManiphestTask())->loadAll();
|
||||||
|
$count = count($tasks);
|
||||||
|
echo "Reindexing {$count} tasks";
|
||||||
|
foreach ($tasks as $task) {
|
||||||
|
PhabricatorSearchManiphestIndexer::indexTask($task);
|
||||||
|
echo '.';
|
||||||
|
}
|
||||||
|
echo "\n";
|
||||||
|
echo "Done.\n";
|
||||||
|
|
|
@ -230,6 +230,21 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorRepositoryGitHubNotification' => 'applications/repository/storage/githubnotification',
|
'PhabricatorRepositoryGitHubNotification' => 'applications/repository/storage/githubnotification',
|
||||||
'PhabricatorRepositoryGitHubPostReceiveController' => 'applications/repository/controller/github-post-receive',
|
'PhabricatorRepositoryGitHubPostReceiveController' => 'applications/repository/controller/github-post-receive',
|
||||||
'PhabricatorRepositoryListController' => 'applications/repository/controller/list',
|
'PhabricatorRepositoryListController' => 'applications/repository/controller/list',
|
||||||
|
'PhabricatorSearchAbstractDocument' => 'applications/search/index/abstractdocument',
|
||||||
|
'PhabricatorSearchBaseController' => 'applications/search/controller/base',
|
||||||
|
'PhabricatorSearchController' => 'applications/search/controller/search',
|
||||||
|
'PhabricatorSearchDAO' => 'applications/search/storage/base',
|
||||||
|
'PhabricatorSearchDifferentialIndexer' => 'applications/search/index/indexer/differential',
|
||||||
|
'PhabricatorSearchDocument' => 'applications/search/storage/document/document',
|
||||||
|
'PhabricatorSearchDocumentField' => 'applications/search/storage/document/field',
|
||||||
|
'PhabricatorSearchDocumentIndexer' => 'applications/search/index/indexer/base',
|
||||||
|
'PhabricatorSearchDocumentRelationship' => 'applications/search/storage/document/relationship',
|
||||||
|
'PhabricatorSearchExecutor' => 'applications/search/execute/base',
|
||||||
|
'PhabricatorSearchField' => 'applications/search/constants/field',
|
||||||
|
'PhabricatorSearchManiphestIndexer' => 'applications/search/index/indexer/maniphest',
|
||||||
|
'PhabricatorSearchMySQLExecutor' => 'applications/search/execute/mysql',
|
||||||
|
'PhabricatorSearchQuery' => 'applications/search/storage/query',
|
||||||
|
'PhabricatorSearchRelationship' => 'applications/search/constants/relationship',
|
||||||
'PhabricatorStandardPageView' => 'view/page/standard',
|
'PhabricatorStandardPageView' => 'view/page/standard',
|
||||||
'PhabricatorTypeaheadCommonDatasourceController' => 'applications/typeahead/controller/common',
|
'PhabricatorTypeaheadCommonDatasourceController' => 'applications/typeahead/controller/common',
|
||||||
'PhabricatorTypeaheadDatasourceController' => 'applications/typeahead/controller/base',
|
'PhabricatorTypeaheadDatasourceController' => 'applications/typeahead/controller/base',
|
||||||
|
@ -251,6 +266,7 @@ phutil_register_library_map(array(
|
||||||
'phabricator_format_relative_time' => 'view/utils',
|
'phabricator_format_relative_time' => 'view/utils',
|
||||||
'phabricator_format_timestamp' => 'view/utils',
|
'phabricator_format_timestamp' => 'view/utils',
|
||||||
'phabricator_format_units_generic' => 'view/utils',
|
'phabricator_format_units_generic' => 'view/utils',
|
||||||
|
'phabricator_render_form' => 'infrastructure/javelin/markup',
|
||||||
'qsprintf' => 'storage/qsprintf',
|
'qsprintf' => 'storage/qsprintf',
|
||||||
'queryfx' => 'storage/queryfx',
|
'queryfx' => 'storage/queryfx',
|
||||||
'queryfx_all' => 'storage/queryfx',
|
'queryfx_all' => 'storage/queryfx',
|
||||||
|
@ -437,6 +453,16 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorRepositoryGitHubNotification' => 'PhabricatorRepositoryDAO',
|
'PhabricatorRepositoryGitHubNotification' => 'PhabricatorRepositoryDAO',
|
||||||
'PhabricatorRepositoryGitHubPostReceiveController' => 'PhabricatorRepositoryController',
|
'PhabricatorRepositoryGitHubPostReceiveController' => 'PhabricatorRepositoryController',
|
||||||
'PhabricatorRepositoryListController' => 'PhabricatorController',
|
'PhabricatorRepositoryListController' => 'PhabricatorController',
|
||||||
|
'PhabricatorSearchBaseController' => 'PhabricatorController',
|
||||||
|
'PhabricatorSearchController' => 'PhabricatorSearchBaseController',
|
||||||
|
'PhabricatorSearchDAO' => 'PhabricatorLiskDAO',
|
||||||
|
'PhabricatorSearchDifferentialIndexer' => 'PhabricatorSearchDocumentIndexer',
|
||||||
|
'PhabricatorSearchDocument' => 'PhabricatorSearchDAO',
|
||||||
|
'PhabricatorSearchDocumentField' => 'PhabricatorSearchDAO',
|
||||||
|
'PhabricatorSearchDocumentRelationship' => 'PhabricatorSearchDAO',
|
||||||
|
'PhabricatorSearchManiphestIndexer' => 'PhabricatorSearchDocumentIndexer',
|
||||||
|
'PhabricatorSearchMySQLExecutor' => 'PhabricatorSearchExecutor',
|
||||||
|
'PhabricatorSearchQuery' => 'PhabricatorSearchDAO',
|
||||||
'PhabricatorStandardPageView' => 'AphrontPageView',
|
'PhabricatorStandardPageView' => 'AphrontPageView',
|
||||||
'PhabricatorTypeaheadCommonDatasourceController' => 'PhabricatorTypeaheadDatasourceController',
|
'PhabricatorTypeaheadCommonDatasourceController' => 'PhabricatorTypeaheadDatasourceController',
|
||||||
'PhabricatorTypeaheadDatasourceController' => 'PhabricatorController',
|
'PhabricatorTypeaheadDatasourceController' => 'PhabricatorController',
|
||||||
|
|
|
@ -155,6 +155,11 @@ class AphrontDefaultApplicationConfiguration
|
||||||
'edit/(?P<id>\d+)/$' => 'PhabricatorRepositoryEditController',
|
'edit/(?P<id>\d+)/$' => 'PhabricatorRepositoryEditController',
|
||||||
'delete/(?P<id>\d+)/$' => 'PhabricatorRepositoryDeleteController',
|
'delete/(?P<id>\d+)/$' => 'PhabricatorRepositoryDeleteController',
|
||||||
),
|
),
|
||||||
|
|
||||||
|
'/search/' => array(
|
||||||
|
'$' => 'PhabricatorSearchController',
|
||||||
|
'(?P<id>\d+)/$' => 'PhabricatorSearchController',
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -415,6 +415,8 @@ class DifferentialRevisionEditor {
|
||||||
'actor' => $this->getActorPHID(),
|
'actor' => $this->getActorPHID(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// TODO: When timelines get implemented, move indexing to them.
|
||||||
|
PhabricatorSearchDifferentialIndexer::indexRevision($revision);
|
||||||
// TODO
|
// TODO
|
||||||
// id(new ToolsTimelineEvent('difx', fb_json_encode($event)))->record();
|
// id(new ToolsTimelineEvent('difx', fb_json_encode($event)))->record();
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ phutil_require_module('phabricator', 'applications/differential/mail/newdiff');
|
||||||
phutil_require_module('phabricator', 'applications/differential/storage/comment');
|
phutil_require_module('phabricator', 'applications/differential/storage/comment');
|
||||||
phutil_require_module('phabricator', 'applications/differential/storage/revision');
|
phutil_require_module('phabricator', 'applications/differential/storage/revision');
|
||||||
phutil_require_module('phabricator', 'applications/phid/handle/data');
|
phutil_require_module('phabricator', 'applications/phid/handle/data');
|
||||||
|
phutil_require_module('phabricator', 'applications/search/index/indexer/differential');
|
||||||
phutil_require_module('phabricator', 'storage/qsprintf');
|
phutil_require_module('phabricator', 'storage/qsprintf');
|
||||||
phutil_require_module('phabricator', 'storage/queryfx');
|
phutil_require_module('phabricator', 'storage/queryfx');
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,9 @@ class ManiphestTransactionEditor {
|
||||||
$email_cc,
|
$email_cc,
|
||||||
$task->getCCPHIDs());
|
$task->getCCPHIDs());
|
||||||
|
|
||||||
|
// TODO: Do this offline via timeline
|
||||||
|
PhabricatorSearchManiphestIndexer::indexTask($task);
|
||||||
|
|
||||||
$this->sendEmail($task, $transactions, $email_to, $email_cc);
|
$this->sendEmail($task, $transactions, $email_to, $email_cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ phutil_require_module('phabricator', 'applications/maniphest/constants/transacti
|
||||||
phutil_require_module('phabricator', 'applications/maniphest/view/transactiondetail');
|
phutil_require_module('phabricator', 'applications/maniphest/view/transactiondetail');
|
||||||
phutil_require_module('phabricator', 'applications/metamta/storage/mail');
|
phutil_require_module('phabricator', 'applications/metamta/storage/mail');
|
||||||
phutil_require_module('phabricator', 'applications/phid/handle/data');
|
phutil_require_module('phabricator', 'applications/phid/handle/data');
|
||||||
|
phutil_require_module('phabricator', 'applications/search/index/indexer/maniphest');
|
||||||
phutil_require_module('phabricator', 'infrastructure/env');
|
phutil_require_module('phabricator', 'infrastructure/env');
|
||||||
|
|
||||||
phutil_require_module('phutil', 'utils');
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
|
@ -96,6 +96,52 @@ class PhabricatorObjectHandleData {
|
||||||
$handles[$phid] = $handle;
|
$handles[$phid] = $handle;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'DREV':
|
||||||
|
$class = 'DifferentialRevision';
|
||||||
|
PhutilSymbolLoader::loadClass($class);
|
||||||
|
$object = newv($class, array());
|
||||||
|
|
||||||
|
$revs = $object->loadAllWhere('phid in (%Ls)', $phids);
|
||||||
|
$revs = mpull($revs, null, 'getPHID');
|
||||||
|
|
||||||
|
foreach ($phids as $phid) {
|
||||||
|
$handle = new PhabricatorObjectHandle();
|
||||||
|
$handle->setPHID($phid);
|
||||||
|
if (empty($revs[$phid])) {
|
||||||
|
$handle->setType(self::TYPE_UNKNOWN);
|
||||||
|
$handle->setName('Unknown Revision');
|
||||||
|
} else {
|
||||||
|
$rev = $revs[$phid];
|
||||||
|
$handle->setType($type);
|
||||||
|
$handle->setName($rev->getTitle());
|
||||||
|
$handle->setURI('/D'.$rev->getID());
|
||||||
|
}
|
||||||
|
$handles[$phid] = $handle;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'TASK':
|
||||||
|
$class = 'ManiphestTask';
|
||||||
|
PhutilSymbolLoader::loadClass($class);
|
||||||
|
$object = newv($class, array());
|
||||||
|
|
||||||
|
$tasks = $object->loadAllWhere('phid in (%Ls)', $phids);
|
||||||
|
$tasks = mpull($tasks, null, 'getPHID');
|
||||||
|
|
||||||
|
foreach ($phids as $phid) {
|
||||||
|
$handle = new PhabricatorObjectHandle();
|
||||||
|
$handle->setPHID($phid);
|
||||||
|
if (empty($tasks[$phid])) {
|
||||||
|
$handle->setType(self::TYPE_UNKNOWN);
|
||||||
|
$handle->setName('Unknown Revision');
|
||||||
|
} else {
|
||||||
|
$task = $tasks[$phid];
|
||||||
|
$handle->setType($type);
|
||||||
|
$handle->setName($task->getTitle());
|
||||||
|
$handle->setURI('/T'.$task->getID());
|
||||||
|
}
|
||||||
|
$handles[$phid] = $handle;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'FILE':
|
case 'FILE':
|
||||||
$class = 'PhabricatorFile';
|
$class = 'PhabricatorFile';
|
||||||
PhutilSymbolLoader::loadClass($class);
|
PhutilSymbolLoader::loadClass($class);
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
final class PhabricatorSearchField {
|
||||||
|
|
||||||
|
const FIELD_TITLE = 'titl';
|
||||||
|
const FIELD_BODY = 'body';
|
||||||
|
const FIELD_TEST_PLAN = 'tpln';
|
||||||
|
|
||||||
|
}
|
10
src/applications/search/constants/field/__init__.php
Normal file
10
src/applications/search/constants/field/__init__.php
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorSearchField.php');
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
final class PhabricatorSearchRelationship {
|
||||||
|
|
||||||
|
const RELATIONSHIP_AUTHOR = 'auth';
|
||||||
|
const RELATIONSHIP_REVIEWER = 'revw';
|
||||||
|
const RELATIONSHIP_SUBSCRIBER = 'subs';
|
||||||
|
const RELATIONSHIP_COMMENTER = 'comm';
|
||||||
|
|
||||||
|
}
|
10
src/applications/search/constants/relationship/__init__.php
Normal file
10
src/applications/search/constants/relationship/__init__.php
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorSearchRelationship.php');
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
abstract class PhabricatorSearchBaseController extends PhabricatorController {
|
||||||
|
|
||||||
|
public function buildStandardPageResponse($view, array $data) {
|
||||||
|
$page = $this->buildStandardPageView();
|
||||||
|
|
||||||
|
$page->setApplicationName('Search');
|
||||||
|
$page->setBaseURI('/search/');
|
||||||
|
$page->setTitle(idx($data, 'title'));
|
||||||
|
$page->setGlyph("(?)");
|
||||||
|
$page->appendChild($view);
|
||||||
|
|
||||||
|
$response = new AphrontWebpageResponse();
|
||||||
|
return $response->setContent($page->render());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
src/applications/search/controller/base/__init__.php
Normal file
15
src/applications/search/controller/base/__init__.php
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'aphront/response/webpage');
|
||||||
|
phutil_require_module('phabricator', 'applications/base/controller/base');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorSearchBaseController.php');
|
|
@ -0,0 +1,95 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PhabricatorSearchController extends PhabricatorSearchBaseController {
|
||||||
|
|
||||||
|
private $id;
|
||||||
|
|
||||||
|
public function willProcessRequest(array $data) {
|
||||||
|
$this->id = idx($data, 'id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$user = $request->getUser();
|
||||||
|
|
||||||
|
if ($this->id) {
|
||||||
|
$query = id(new PhabricatorSearchQuery())->load($this->id);
|
||||||
|
if (!$query) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$query = new PhabricatorSearchQuery();
|
||||||
|
|
||||||
|
if ($request->isFormPost()) {
|
||||||
|
$query->setQuery($request->getStr('query'));
|
||||||
|
$query->save();
|
||||||
|
return id(new AphrontRedirectResponse())
|
||||||
|
->setURI('/search/'.$query->getID().'/');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$search_form = new AphrontFormView();
|
||||||
|
$search_form
|
||||||
|
->setUser($user)
|
||||||
|
->setAction('/search/')
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormTextControl())
|
||||||
|
->setLabel('Search')
|
||||||
|
->setName('query')
|
||||||
|
->setValue($query->getQuery()))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormSubmitControl())
|
||||||
|
->setValue('Search'));
|
||||||
|
|
||||||
|
$search_panel = new AphrontPanelView();
|
||||||
|
$search_panel->setHeader('Search Phabricator');
|
||||||
|
$search_panel->appendChild($search_form);
|
||||||
|
|
||||||
|
if ($query->getID()) {
|
||||||
|
$executor = new PhabricatorSearchMySQLExecutor();
|
||||||
|
$results = $executor->executeSearch($query);
|
||||||
|
$results = ipull($results, 'phid');
|
||||||
|
$handles = id(new PhabricatorObjectHandleData($results))
|
||||||
|
->loadHandles();
|
||||||
|
$results = array();
|
||||||
|
foreach ($handles as $handle) {
|
||||||
|
$results[] = '<h1>'.$handle->renderLink().'</h1>';
|
||||||
|
}
|
||||||
|
$results =
|
||||||
|
'<div style="padding: 1em 2em 2em;">'.
|
||||||
|
implode("\n", $results).
|
||||||
|
'</div>';
|
||||||
|
} else {
|
||||||
|
$results = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$results = print_r($results, true);
|
||||||
|
|
||||||
|
return $this->buildStandardPageResponse(
|
||||||
|
array(
|
||||||
|
$search_panel,
|
||||||
|
$results,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'title' => 'Results: what',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
22
src/applications/search/controller/search/__init__.php
Normal file
22
src/applications/search/controller/search/__init__.php
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'aphront/response/404');
|
||||||
|
phutil_require_module('phabricator', 'aphront/response/redirect');
|
||||||
|
phutil_require_module('phabricator', 'applications/phid/handle/data');
|
||||||
|
phutil_require_module('phabricator', 'applications/search/controller/base');
|
||||||
|
phutil_require_module('phabricator', 'applications/search/execute/mysql');
|
||||||
|
phutil_require_module('phabricator', 'applications/search/storage/query');
|
||||||
|
phutil_require_module('phabricator', 'view/form/base');
|
||||||
|
phutil_require_module('phabricator', 'view/form/control/submit');
|
||||||
|
phutil_require_module('phabricator', 'view/layout/panel');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorSearchController.php');
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
abstract class PhabricatorSearchExecutor {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
10
src/applications/search/execute/base/__init__.php
Normal file
10
src/applications/search/execute/base/__init__.php
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorSearchExecutor.php');
|
|
@ -0,0 +1,137 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PhabricatorSearchMySQLExecutor extends PhabricatorSearchExecutor {
|
||||||
|
|
||||||
|
public function executeSearch(PhabricatorSearchQuery $query) {
|
||||||
|
|
||||||
|
$where = array();
|
||||||
|
$join = array();
|
||||||
|
$order = 'ORDER BY documentCreated DESC';
|
||||||
|
|
||||||
|
$dao_doc = new PhabricatorSearchDocument();
|
||||||
|
$dao_field = new PhabricatorSearchDocumentField();
|
||||||
|
|
||||||
|
$t_doc = $dao_doc->getTableName();
|
||||||
|
$t_field = $dao_field->getTableName();
|
||||||
|
|
||||||
|
$conn_r = $dao_doc->establishConnection('r');
|
||||||
|
|
||||||
|
$q = $query->getQuery();
|
||||||
|
|
||||||
|
if (strlen($q)) {
|
||||||
|
$join[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
"{$t_field} field ON field.phid = document.phid");
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'MATCH(corpus) AGAINST (%s)',
|
||||||
|
$q);
|
||||||
|
/*
|
||||||
|
if ($query->getParameter('order') == AdjutantQuery::ORDER_RELEVANCE) {
|
||||||
|
$order = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'ORDER BY MATCH(corpus) AGAINST (%s) DESC',
|
||||||
|
$q);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
$field = $query->getParameter('field');
|
||||||
|
if ($field/* && $field != AdjutantQuery::FIELD_ALL*/) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'field.field = %s',
|
||||||
|
$field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($query->getParameter('type')) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'document.documentType = %s',
|
||||||
|
$query->getParameter('type'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
$join[] = $this->joinRelationship(
|
||||||
|
$conn_r,
|
||||||
|
$query,
|
||||||
|
'author',
|
||||||
|
AdjutantRelationship::RELATIONSHIP_AUTHOR);
|
||||||
|
$join[] = $this->joinRelationship(
|
||||||
|
$conn_r,
|
||||||
|
$query,
|
||||||
|
'reviewer',
|
||||||
|
AdjutantRelationship::RELATIONSHIP_REVIEWER);
|
||||||
|
$join[] = $this->joinRelationship(
|
||||||
|
$conn_r,
|
||||||
|
$query,
|
||||||
|
'subscriber',
|
||||||
|
AdjutantRelationship::RELATIONSHIP_SUBSCRIBER);
|
||||||
|
$join[] = $this->joinRelationship(
|
||||||
|
$conn_r,
|
||||||
|
$query,
|
||||||
|
'repository',
|
||||||
|
AdjutantRelationship::RELATIONSHIP_REPOSITORY);
|
||||||
|
*/
|
||||||
|
$join = array_filter($join);
|
||||||
|
|
||||||
|
foreach ($join as $key => $clause) {
|
||||||
|
$join[$key] = ' JOIN '.$clause;
|
||||||
|
}
|
||||||
|
$join = implode(' ', $join);
|
||||||
|
|
||||||
|
if ($where) {
|
||||||
|
$where = 'WHERE '.implode(' AND ', $where);
|
||||||
|
} else {
|
||||||
|
$where = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$hits = queryfx_all(
|
||||||
|
$conn_r,
|
||||||
|
'SELECT DISTINCT
|
||||||
|
document.phid,
|
||||||
|
document.documentType,
|
||||||
|
document.documentCreated FROM %T document %Q %Q %Q
|
||||||
|
LIMIT 50',
|
||||||
|
$t_doc,
|
||||||
|
$join,
|
||||||
|
$where,
|
||||||
|
$order);
|
||||||
|
|
||||||
|
return $hits;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function joinRelationship($conn, $query, $field, $type) {
|
||||||
|
$fbids = $query->getParameter($field, array());
|
||||||
|
if (!$fbids) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return qsprintf(
|
||||||
|
$conn,
|
||||||
|
'relationship AS %C ON %C.fbid = data.fbid AND %C.relation = %s
|
||||||
|
AND %C.relatedFBID in (%Ld)',
|
||||||
|
$field,
|
||||||
|
$field,
|
||||||
|
$field,
|
||||||
|
$type,
|
||||||
|
$field,
|
||||||
|
$fbids);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
16
src/applications/search/execute/mysql/__init__.php
Normal file
16
src/applications/search/execute/mysql/__init__.php
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/search/execute/base');
|
||||||
|
phutil_require_module('phabricator', 'applications/search/storage/document/document');
|
||||||
|
phutil_require_module('phabricator', 'applications/search/storage/document/field');
|
||||||
|
phutil_require_module('phabricator', 'storage/qsprintf');
|
||||||
|
phutil_require_module('phabricator', 'storage/queryfx');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorSearchMySQLExecutor.php');
|
|
@ -0,0 +1,92 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
final class PhabricatorSearchAbstractDocument {
|
||||||
|
|
||||||
|
private $phid;
|
||||||
|
private $documentType;
|
||||||
|
private $documentTitle;
|
||||||
|
private $documentCreated;
|
||||||
|
private $documentModified;
|
||||||
|
private $fields = array();
|
||||||
|
private $relationships = array();
|
||||||
|
|
||||||
|
public function setPHID($phid) {
|
||||||
|
$this->phid = $phid;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDocumentType($document_type) {
|
||||||
|
$this->documentType = $document_type;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDocumentTitle($title) {
|
||||||
|
$this->documentTitle = $title;
|
||||||
|
$this->addField(PhabricatorSearchField::FIELD_TITLE, $title);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addField($field, $corpus, $aux_phid = null) {
|
||||||
|
$this->fields[] = array($field, $corpus, $aux_phid);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addRelationship($type, $related_phid) {
|
||||||
|
$this->relationships[] = array($type, $related_phid);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDocumentCreated($date) {
|
||||||
|
$this->documentCreated = $date;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDocumentModified($date) {
|
||||||
|
$this->documentModified = $date;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPHID() {
|
||||||
|
return $this->phid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDocumentType() {
|
||||||
|
return $this->documentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDocumentTitle() {
|
||||||
|
return $this->documentTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDocumentCreated() {
|
||||||
|
return $this->documentCreated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDocumentModified() {
|
||||||
|
return $this->documentModified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFieldData() {
|
||||||
|
return $this->fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRelationshipData() {
|
||||||
|
return $this->relationships;
|
||||||
|
}
|
||||||
|
}
|
12
src/applications/search/index/abstractdocument/__init__.php
Normal file
12
src/applications/search/index/abstractdocument/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/search/constants/field');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorSearchAbstractDocument.php');
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
abstract class PhabricatorSearchDocumentIndexer { }
|
10
src/applications/search/index/indexer/base/__init__.php
Normal file
10
src/applications/search/index/indexer/base/__init__.php
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorSearchDocumentIndexer.php');
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PhabricatorSearchDifferentialIndexer
|
||||||
|
extends PhabricatorSearchDocumentIndexer {
|
||||||
|
|
||||||
|
public static function indexRevision(DifferentialRevision $rev) {
|
||||||
|
$doc = new PhabricatorSearchAbstractDocument();
|
||||||
|
$doc->setPHID($rev->getPHID());
|
||||||
|
$doc->setDocumentType('DREV');
|
||||||
|
$doc->setDocumentTitle($rev->getTitle());
|
||||||
|
$doc->setDocumentCreated($rev->getDateCreated());
|
||||||
|
$doc->setDocumentModified($rev->getDateModified());
|
||||||
|
|
||||||
|
$doc->addField(
|
||||||
|
PhabricatorSearchField::FIELD_BODY,
|
||||||
|
$rev->getSummary());
|
||||||
|
$doc->addField(
|
||||||
|
PhabricatorSearchField::FIELD_TEST_PLAN,
|
||||||
|
$rev->getTestPlan());
|
||||||
|
|
||||||
|
$doc->addRelationship(
|
||||||
|
PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR,
|
||||||
|
$rev->getAuthorPHID());
|
||||||
|
|
||||||
|
PhabricatorSearchDocument::reindexAbstractDocument($doc);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/search/constants/field');
|
||||||
|
phutil_require_module('phabricator', 'applications/search/constants/relationship');
|
||||||
|
phutil_require_module('phabricator', 'applications/search/index/abstractdocument');
|
||||||
|
phutil_require_module('phabricator', 'applications/search/index/indexer/base');
|
||||||
|
phutil_require_module('phabricator', 'applications/search/storage/document/document');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorSearchDifferentialIndexer.php');
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PhabricatorSearchManiphestIndexer
|
||||||
|
extends PhabricatorSearchDocumentIndexer {
|
||||||
|
|
||||||
|
public static function indexTask(ManiphestTask $task) {
|
||||||
|
$doc = new PhabricatorSearchAbstractDocument();
|
||||||
|
$doc->setPHID($task->getPHID());
|
||||||
|
$doc->setDocumentType('TASK');
|
||||||
|
$doc->setDocumentTitle($task->getTitle());
|
||||||
|
$doc->setDocumentCreated($task->getDateCreated());
|
||||||
|
$doc->setDocumentModified($task->getDateModified());
|
||||||
|
|
||||||
|
$doc->addField(
|
||||||
|
PhabricatorSearchField::FIELD_BODY,
|
||||||
|
$task->getDescription());
|
||||||
|
|
||||||
|
$doc->addRelationship(
|
||||||
|
PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR,
|
||||||
|
$task->getAuthorPHID());
|
||||||
|
|
||||||
|
PhabricatorSearchDocument::reindexAbstractDocument($doc);
|
||||||
|
}
|
||||||
|
}
|
16
src/applications/search/index/indexer/maniphest/__init__.php
Normal file
16
src/applications/search/index/indexer/maniphest/__init__.php
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/search/constants/field');
|
||||||
|
phutil_require_module('phabricator', 'applications/search/constants/relationship');
|
||||||
|
phutil_require_module('phabricator', 'applications/search/index/abstractdocument');
|
||||||
|
phutil_require_module('phabricator', 'applications/search/index/indexer/base');
|
||||||
|
phutil_require_module('phabricator', 'applications/search/storage/document/document');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorSearchManiphestIndexer.php');
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
abstract class PhabricatorSearchDAO extends PhabricatorLiskDAO {
|
||||||
|
|
||||||
|
public function getApplicationName() {
|
||||||
|
return 'search';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
12
src/applications/search/storage/base/__init__.php
Normal file
12
src/applications/search/storage/base/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/base/storage/lisk');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorSearchDAO.php');
|
|
@ -0,0 +1,104 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PhabricatorSearchDocument extends PhabricatorSearchDAO {
|
||||||
|
|
||||||
|
protected $phid;
|
||||||
|
protected $documentType;
|
||||||
|
protected $documentTitle;
|
||||||
|
protected $documentCreated;
|
||||||
|
protected $documentModified;
|
||||||
|
|
||||||
|
public function getConfiguration() {
|
||||||
|
return array(
|
||||||
|
self::CONFIG_TIMESTAMPS => false,
|
||||||
|
self::CONFIG_IDS => self::IDS_MANUAL,
|
||||||
|
) + parent::getConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIDKey() {
|
||||||
|
return 'phid';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function reindexAbstractDocument(
|
||||||
|
PhabricatorSearchAbstractDocument $doc) {
|
||||||
|
|
||||||
|
$phid = $doc->getPHID();
|
||||||
|
if (!$phid) {
|
||||||
|
throw new Exception("Document has no PHID!");
|
||||||
|
}
|
||||||
|
|
||||||
|
$store = new PhabricatorSearchDocument();
|
||||||
|
$store->setPHID($doc->getPHID());
|
||||||
|
$store->setDocumentType($doc->getDocumentType());
|
||||||
|
$store->setDocumentTitle($doc->getDocumentTitle());
|
||||||
|
$store->setDocumentCreated($doc->getDocumentCreated());
|
||||||
|
$store->setDocumentModified($doc->getDocumentModified());
|
||||||
|
$store->replace();
|
||||||
|
|
||||||
|
$conn_w = $store->establishConnection('w');
|
||||||
|
|
||||||
|
$field_dao = new PhabricatorSearchDocumentField();
|
||||||
|
queryfx(
|
||||||
|
$conn_w,
|
||||||
|
'DELETE FROM %T WHERE phid = %s',
|
||||||
|
$field_dao->getTableName(),
|
||||||
|
$phid);
|
||||||
|
foreach ($doc->getFieldData() as $field) {
|
||||||
|
list($ftype, $corpus, $aux_phid) = $field;
|
||||||
|
queryfx(
|
||||||
|
$conn_w,
|
||||||
|
'INSERT INTO %T (phid, field, auxPHId, corpus) '.
|
||||||
|
' VALUES (%s, %s, %ns, %s)',
|
||||||
|
$field_dao->getTableName(),
|
||||||
|
$phid,
|
||||||
|
$ftype,
|
||||||
|
$aux_phid,
|
||||||
|
$corpus);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$sql = array();
|
||||||
|
foreach ($doc->getRelationshipData() as $relationship) {
|
||||||
|
list($rtype, $toPHID) = $relationship;
|
||||||
|
$sql[] = qsprintf(
|
||||||
|
$conn_w,
|
||||||
|
'(%s, %s, %s)',
|
||||||
|
$phid,
|
||||||
|
$toPHID,
|
||||||
|
$rtype);
|
||||||
|
}
|
||||||
|
|
||||||
|
$rship_dao = new PhabricatorSearchDocumentRelationship();
|
||||||
|
queryfx(
|
||||||
|
$conn_w,
|
||||||
|
'DELETE FROM %T WHERE phid = %s',
|
||||||
|
$rship_dao->getTableName(),
|
||||||
|
$phid);
|
||||||
|
if ($sql) {
|
||||||
|
queryfx(
|
||||||
|
$conn_w,
|
||||||
|
'INSERT INTO %T (phid, relatedPHID, relation) '.
|
||||||
|
' VALUES %Q',
|
||||||
|
$rship_dao->getTableName(),
|
||||||
|
implode(', ', $sql));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/search/storage/base');
|
||||||
|
phutil_require_module('phabricator', 'applications/search/storage/document/field');
|
||||||
|
phutil_require_module('phabricator', 'applications/search/storage/document/relationship');
|
||||||
|
phutil_require_module('phabricator', 'storage/qsprintf');
|
||||||
|
phutil_require_module('phabricator', 'storage/queryfx');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorSearchDocument.php');
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PhabricatorSearchDocumentField extends PhabricatorSearchDAO {
|
||||||
|
|
||||||
|
protected $phid;
|
||||||
|
protected $field;
|
||||||
|
protected $auxPHID;
|
||||||
|
protected $corpus;
|
||||||
|
|
||||||
|
public function getConfiguration() {
|
||||||
|
return array(
|
||||||
|
self::CONFIG_TIMESTAMPS => false,
|
||||||
|
self::CONFIG_IDS => self::IDS_MANUAL,
|
||||||
|
) + parent::getConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
12
src/applications/search/storage/document/field/__init__.php
Normal file
12
src/applications/search/storage/document/field/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/search/storage/base');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorSearchDocumentField.php');
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PhabricatorSearchDocumentRelationship extends PhabricatorSearchDAO {
|
||||||
|
|
||||||
|
protected $phid;
|
||||||
|
protected $relatedPHID;
|
||||||
|
protected $relation;
|
||||||
|
|
||||||
|
public function getConfiguration() {
|
||||||
|
return array(
|
||||||
|
self::CONFIG_TIMESTAMPS => false,
|
||||||
|
self::CONFIG_IDS => self::IDS_MANUAL,
|
||||||
|
) + parent::getConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/search/storage/base');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorSearchDocumentRelationship.php');
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PhabricatorSearchQuery extends PhabricatorSearchDAO {
|
||||||
|
|
||||||
|
protected $authorPHID;
|
||||||
|
protected $query;
|
||||||
|
protected $parameters = array();
|
||||||
|
|
||||||
|
public function getConfiguration() {
|
||||||
|
return array(
|
||||||
|
self::CONFIG_SERIALIZATION => array(
|
||||||
|
'parameters' => self::SERIALIZATION_JSON,
|
||||||
|
),
|
||||||
|
) + parent::getConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setParameter($parameter, $value) {
|
||||||
|
$this->parameters[$parameter] = $value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParameter($parameter, $default = null) {
|
||||||
|
return idx($this->parameters, $parameter, $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
14
src/applications/search/storage/query/__init__.php
Normal file
14
src/applications/search/storage/query/__init__.php
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/search/storage/base');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorSearchQuery.php');
|
|
@ -46,3 +46,25 @@ function javelin_render_tag(
|
||||||
|
|
||||||
return phutil_render_tag($tag, $attributes, $content);
|
return phutil_render_tag($tag, $attributes, $content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function phabricator_render_form(PhabricatorUser $user, $attributes, $content) {
|
||||||
|
return javelin_render_tag(
|
||||||
|
'form',
|
||||||
|
$attributes,
|
||||||
|
phutil_render_tag(
|
||||||
|
'input',
|
||||||
|
array(
|
||||||
|
'type' => 'hidden',
|
||||||
|
'name' => '__csrf__',
|
||||||
|
'value' => $user->getCSRFToken(),
|
||||||
|
)).
|
||||||
|
phutil_render_tag(
|
||||||
|
'input',
|
||||||
|
array(
|
||||||
|
'type' => 'hidden',
|
||||||
|
'name' => '__form__',
|
||||||
|
'value' => true,
|
||||||
|
)).$content);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -154,23 +154,15 @@ class PhabricatorStandardPageView extends AphrontPageView {
|
||||||
' · '.
|
' · '.
|
||||||
'<a href="/settings/">Settings</a>'.
|
'<a href="/settings/">Settings</a>'.
|
||||||
' · '.
|
' · '.
|
||||||
'<form action="/logout/" method="post" style="display: inline;">'.
|
phabricator_render_form(
|
||||||
phutil_render_tag(
|
$user,
|
||||||
'input',
|
|
||||||
array(
|
array(
|
||||||
'type' => 'hidden',
|
'action' => '/search/',
|
||||||
'name' => '__csrf__',
|
'method' => 'post',
|
||||||
'value' => $user->getCSRFToken(),
|
'style' => 'display: inline',
|
||||||
)).
|
),
|
||||||
phutil_render_tag(
|
'<input type="text" name="query" />'.
|
||||||
'input',
|
'<button>Search</button>');
|
||||||
array(
|
|
||||||
'type' => 'hidden',
|
|
||||||
'name' => '__form__',
|
|
||||||
'value' => true,
|
|
||||||
)).
|
|
||||||
'<button class="link">Logout</button>'.
|
|
||||||
'</form>';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,6 +192,17 @@ class PhabricatorStandardPageView extends AphrontPageView {
|
||||||
}
|
}
|
||||||
$foot_links[] = $link;
|
$foot_links[] = $link;
|
||||||
}
|
}
|
||||||
|
// This ends up very early in tab order at the top of the page and there's
|
||||||
|
// a bunch of junk up there anyway, just shove it down here.
|
||||||
|
$foot_links[] = phabricator_render_form(
|
||||||
|
$user,
|
||||||
|
array(
|
||||||
|
'action' => '/logout/',
|
||||||
|
'method' => 'post',
|
||||||
|
'style' => 'display: inline',
|
||||||
|
),
|
||||||
|
'<button class="link">Logout</button>');
|
||||||
|
|
||||||
$foot_links = implode(' · ', $foot_links);
|
$foot_links = implode(' · ', $foot_links);
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in a new issue