Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/search/controller/search/PhabricatorSearchController.php b/src/applications/search/controller/search/PhabricatorSearchController.php
index e9afaa83cb..93dc03e84b 100644
--- a/src/applications/search/controller/search/PhabricatorSearchController.php
+++ b/src/applications/search/controller/search/PhabricatorSearchController.php
@@ -1,307 +1,300 @@
<?php
/*
* Copyright 2012 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.
*/
/**
* @group search
*/
final class PhabricatorSearchController
extends PhabricatorSearchBaseController {
private $key;
public function willProcessRequest(array $data) {
$this->key = idx($data, 'key');
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
if ($this->key) {
$query = id(new PhabricatorSearchQuery())->loadOneWhere(
'queryKey = %s',
$this->key);
if (!$query) {
return new Aphront404Response();
}
} else {
$query = new PhabricatorSearchQuery();
if ($request->isFormPost()) {
$query_str = $request->getStr('query');
$pref_jump = PhabricatorUserPreferences::PREFERENCE_SEARCHBAR_JUMP;
if ($request->getStr('jump') != 'no' &&
$user && $user->loadPreferences()->getPreference($pref_jump, 1)) {
$response = PhabricatorJumpNavHandler::jumpPostResponse($query_str);
} else {
$response = null;
}
if ($response) {
return $response;
} else {
$query->setQuery($query_str);
if ($request->getStr('scope')) {
switch ($request->getStr('scope')) {
case PhabricatorSearchScope::SCOPE_OPEN_REVISIONS:
$query->setParameter('open', 1);
$query->setParameter(
'type',
PhabricatorPHIDConstants::PHID_TYPE_DREV);
break;
case PhabricatorSearchScope::SCOPE_OPEN_TASKS:
$query->setParameter('open', 1);
$query->setParameter(
'type',
PhabricatorPHIDConstants::PHID_TYPE_TASK);
break;
case PhabricatorSearchScope::SCOPE_WIKI:
$query->setParameter(
'type',
PhabricatorPHIDConstants::PHID_TYPE_WIKI);
break;
case PhabricatorSearchScope::SCOPE_COMMITS:
$query->setParameter(
'type',
PhabricatorPHIDConstants::PHID_TYPE_CMIT);
break;
default:
break;
}
} else {
if (strlen($request->getStr('type'))) {
$query->setParameter('type', $request->getStr('type'));
}
if ($request->getArr('author')) {
$query->setParameter('author', $request->getArr('author'));
}
if ($request->getArr('owner')) {
$query->setParameter('owner', $request->getArr('owner'));
}
if ($request->getInt('open')) {
$query->setParameter('open', $request->getInt('open'));
}
if ($request->getArr('project')) {
$query->setParameter('project', $request->getArr('project'));
}
}
$query->save();
return id(new AphrontRedirectResponse())
->setURI('/search/'.$query->getQueryKey().'/');
}
}
}
- $more = PhabricatorEnv::getEnvConfig('search.more-document-types', array());
-
$options = array(
'' => 'All Documents',
- PhabricatorPHIDConstants::PHID_TYPE_DREV => 'Differential Revisions',
- PhabricatorPHIDConstants::PHID_TYPE_CMIT => 'Repository Commits',
- PhabricatorPHIDConstants::PHID_TYPE_TASK => 'Maniphest Tasks',
- PhabricatorPHIDConstants::PHID_TYPE_WIKI => 'Phriction Documents',
- PhabricatorPHIDConstants::PHID_TYPE_USER => 'Phabricator Users',
- ) + $more;
+ ) + PhabricatorSearchAbstractDocument::getSupportedTypes();
$status_options = array(
0 => 'Open and Closed Documents',
1 => 'Open Documents',
);
$phids = array_merge(
$query->getParameter('author', array()),
$query->getParameter('owner', array()),
$query->getParameter('project', array())
);
$handles = id(new PhabricatorObjectHandleData($phids))
->loadHandles();
$author_value = array_select_keys(
$handles,
$query->getParameter('author', array()));
$author_value = mpull($author_value, 'getFullName', 'getPHID');
$owner_value = array_select_keys(
$handles,
$query->getParameter('owner', array()));
$owner_value = mpull($owner_value, 'getFullName', 'getPHID');
$project_value = array_select_keys(
$handles,
$query->getParameter('project', array()));
$project_value = mpull($project_value, 'getFullName', 'getPHID');
$search_form = new AphrontFormView();
$search_form
->setUser($user)
->setAction('/search/')
->appendChild(
phutil_render_tag(
'input',
array(
'type' => 'hidden',
'name' => 'jump',
'value' => 'no',
)))
->appendChild(
id(new AphrontFormTextControl())
->setLabel('Search')
->setName('query')
->setValue($query->getQuery()))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel('Document Type')
->setName('type')
->setOptions($options)
->setValue($query->getParameter('type')))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel('Document Status')
->setName('open')
->setOptions($status_options)
->setValue($query->getParameter('open')))
->appendChild(
id(new AphrontFormTokenizerControl())
->setName('author')
->setLabel('Author')
->setDatasource('/typeahead/common/users/')
->setValue($author_value))
->appendChild(
id(new AphrontFormTokenizerControl())
->setName('owner')
->setLabel('Owner')
->setDatasource('/typeahead/common/searchowner/')
->setValue($owner_value)
->setCaption(
'Tip: search for "Up For Grabs" to find unowned documents.'))
->appendChild(
id(new AphrontFormTokenizerControl())
->setName('project')
->setLabel('Project')
->setDatasource('/typeahead/common/projects/')
->setValue($project_value))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue('Search'));
$search_panel = new AphrontPanelView();
$search_panel->setHeader('Search Phabricator');
$search_panel->appendChild($search_form);
require_celerity_resource('phabricator-search-results-css');
if ($query->getID()) {
$limit = 20;
$pager = new AphrontPagerView();
$pager->setURI($request->getRequestURI(), 'page');
$pager->setPageSize($limit);
$pager->setOffset($request->getInt('page'));
$query->setParameter('limit', $limit + 1);
$query->setParameter('offset', $pager->getOffset());
$engine = PhabricatorSearchEngineSelector::newSelector()->newEngine();
$results = $engine->executeSearch($query);
$results = $pager->sliceResults($results);
if (!$request->getInt('page')) {
$jump = null;
$query_str = $query->getQuery();
$match = null;
if (preg_match('/^r([A-Z]+)(\S*)$/', $query_str, $match)) {
$repository = id(new PhabricatorRepository())
->loadOneWhere('callsign = %s', $match[1]);
if ($match[2] == '') {
$jump = $repository;
} else if ($repository) {
$jump = id(new PhabricatorRepositoryCommit())->loadOneWhere(
'repositoryID = %d AND commitIdentifier = %s',
$repository->getID(),
$match[2]);
if (!$jump) {
try {
$jump = id(new PhabricatorRepositoryCommit())->loadOneWhere(
'repositoryID = %d AND commitIdentifier LIKE %>',
$repository->getID(),
$match[2]);
} catch (AphrontQueryCountException $ex) {
// Ambiguous, no jump.
}
}
}
} else if (preg_match('/^d(\d+)$/i', $query_str, $match)) {
$jump = id(new DifferentialRevision())->load($match[1]);
} else if (preg_match('/^t(\d+)$/i', $query_str, $match)) {
$jump = id(new ManiphestTask())->load($match[1]);
}
if ($jump) {
array_unshift($results, $jump->getPHID());
}
}
if ($results) {
$loader = new PhabricatorObjectHandleData($results);
$handles = $loader->loadHandles();
$objects = $loader->loadObjects();
$results = array();
foreach ($handles as $phid => $handle) {
$view = new PhabricatorSearchResultView();
$view->setHandle($handle);
$view->setQuery($query);
$view->setObject(idx($objects, $phid));
$results[] = $view->render();
}
$results =
'<div class="phabricator-search-result-list">'.
implode("\n", $results).
'<div class="search-results-pager">'.
$pager->render().
'</div>'.
'</div>';
} else {
$results =
'<div class="phabricator-search-result-list">'.
'<p class="phabricator-search-no-results">No search results.</p>'.
'</div>';
}
} else {
$results = null;
}
return $this->buildStandardPageResponse(
array(
$search_panel,
$results,
),
array(
'title' => 'Search Results',
));
}
}
diff --git a/src/applications/search/controller/search/__init__.php b/src/applications/search/controller/search/__init__.php
index 5e3ac55056..1a46a0412d 100644
--- a/src/applications/search/controller/search/__init__.php
+++ b/src/applications/search/controller/search/__init__.php
@@ -1,38 +1,38 @@
<?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/differential/storage/revision');
phutil_require_module('phabricator', 'applications/maniphest/storage/task');
phutil_require_module('phabricator', 'applications/people/storage/preferences');
phutil_require_module('phabricator', 'applications/phid/constants');
phutil_require_module('phabricator', 'applications/phid/handle/data');
phutil_require_module('phabricator', 'applications/repository/storage/commit');
phutil_require_module('phabricator', 'applications/repository/storage/repository');
phutil_require_module('phabricator', 'applications/search/constants/scope');
phutil_require_module('phabricator', 'applications/search/controller/base');
phutil_require_module('phabricator', 'applications/search/engine/jumpnav');
+phutil_require_module('phabricator', 'applications/search/index/abstractdocument');
phutil_require_module('phabricator', 'applications/search/selector/base');
phutil_require_module('phabricator', 'applications/search/storage/query');
phutil_require_module('phabricator', 'applications/search/view/searchresult');
phutil_require_module('phabricator', 'infrastructure/celerity/api');
-phutil_require_module('phabricator', 'infrastructure/env');
phutil_require_module('phabricator', 'view/control/pager');
phutil_require_module('phabricator', 'view/form/base');
phutil_require_module('phabricator', 'view/form/control/select');
phutil_require_module('phabricator', 'view/form/control/submit');
phutil_require_module('phabricator', 'view/form/control/text');
phutil_require_module('phabricator', 'view/form/control/tokenizer');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorSearchController.php');
diff --git a/src/applications/search/engine/elastic/PhabricatorSearchEngineElastic.php b/src/applications/search/engine/elastic/PhabricatorSearchEngineElastic.php
index f31ca9f4ec..1bb2488a6b 100644
--- a/src/applications/search/engine/elastic/PhabricatorSearchEngineElastic.php
+++ b/src/applications/search/engine/elastic/PhabricatorSearchEngineElastic.php
@@ -1,173 +1,216 @@
<?php
/*
- * Copyright 2011 Facebook, Inc.
+ * Copyright 2012 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 PhabricatorSearchEngineElastic extends PhabricatorSearchEngine {
public function reindexAbstractDocument(
PhabricatorSearchAbstractDocument $doc) {
$type = $doc->getDocumentType();
$phid = $doc->getPHID();
+ $handle = PhabricatorObjectHandleData::loadOneHandle($phid);
$spec = array(
- 'phid' => $phid,
- 'type' => $type,
'title' => $doc->getDocumentTitle(),
- 'dateCreated' => date('c', $doc->getDocumentCreated()),
- 'dateModified' => date('c', $doc->getDocumentModified()),
+ 'url' => PhabricatorEnv::getProductionURI($handle->getURI()),
+ 'dateCreated' => $doc->getDocumentCreated(),
+ '_timestamp' => $doc->getDocumentModified(),
'field' => array(),
'relationship' => array(),
);
foreach ($doc->getFieldData() as $field) {
- list($ftype, $corpus, $aux_phid) = $field;
- $spec['field'][$ftype][] = array(
- 'corpus' => $corpus,
- 'aux' => $aux_phid,
- );
+ $spec['field'][] = array_combine(array('type', 'corpus', 'aux'), $field);
}
foreach ($doc->getRelationshipData() as $relationship) {
list($rtype, $to_phid, $to_type, $time) = $relationship;
$spec['relationship'][$rtype][] = array(
'phid' => $to_phid,
'phidType' => $to_type,
- 'when' => date('c', $time),
+ 'when' => $time,
);
}
$this->executeRequest(
"/phabricator/{$type}/{$phid}/",
$spec,
$is_write = true);
}
public function reconstructDocument($phid) {
+ $type = phid_get_type($phid);
- $response = $this->executeRequest(
- '/phabricator/_search',
- array(
- 'query' => array(
- 'ids' => array(
- 'values' => array(
- $phid,
- ),
- ),
- ),
- ),
- $is_write = false);
+ $response = $this->executeRequest("/phabricator/{$type}/{$phid}", array());
- $hit = $response['hits']['hits'][0]['_source'];
- if (!$hit) {
+ if (empty($response['exists'])) {
return null;
}
+ $hit = $response['_source'];
+
$doc = new PhabricatorSearchAbstractDocument();
- $doc->setPHID($hit['phid']);
- $doc->setDocumentType($hit['type']);
+ $doc->setPHID($phid);
+ $doc->setDocumentType($response['_type']);
$doc->setDocumentTitle($hit['title']);
- $doc->setDocumentCreated(strtotime($hit['dateCreated']));
- $doc->setDocumentModified(strtotime($hit['dateModified']));
-
- foreach ($hit['field'] as $ftype => $fdefs) {
- foreach ($fdefs as $fdef) {
- $doc->addField(
- $ftype,
- $fdef['corpus'],
- $fdef['aux']);
- }
+ $doc->setDocumentCreated($hit['dateCreated']);
+ $doc->setDocumentModified($hit['_timestamp']);
+
+ foreach ($hit['field'] as $fdef) {
+ $doc->addField($fdef['type'], $fdef['corpus'], $fdef['aux']);
}
foreach ($hit['relationship'] as $rtype => $rships) {
foreach ($rships as $rship) {
$doc->addRelationship(
$rtype,
$rship['phid'],
$rship['phidType'],
- strtotime($rship['when']));
+ $rship['when']);
}
}
return $doc;
}
public function executeSearch(PhabricatorSearchQuery $query) {
- $spec = array(
- 'text' => array(
- '_all' => $query->getQuery(),
- ),
- );
+ $spec = array();
+ $filter = array();
+
+ if ($query->getQuery()) {
+ $spec[] = array(
+ 'field' => array(
+ 'field.corpus' => $query->getQuery(),
+ ),
+ );
+ }
+
+ $exclude = $query->getParameter('exclude');
+ if ($exclude) {
+ $filter[] = array(
+ 'not' => array(
+ 'ids' => array(
+ 'values' => array($exclude),
+ ),
+ ),
+ );
+ }
$type = $query->getParameter('type');
if ($type) {
$uri = "/phabricator/{$type}/_search";
} else {
- $uri = "/phabricator/_search";
+ // Don't use '/phabricator/_search' for the case that there is something
+ // else in the index (for example if 'phabricator' is only an alias to
+ // some bigger index).
+ $types = PhabricatorSearchAbstractDocument::getSupportedTypes();
+ $uri = '/phabricator/' . implode(',', array_keys($types)) . '/_search';
}
- $response = $this->executeRequest(
- $uri,
- array(
- 'query' => $spec,
- ),
- $is_write = false);
+ $rel_mapping = array(
+ 'author' => PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR,
+ 'open' => PhabricatorSearchRelationship::RELATIONSHIP_OPEN,
+ 'owner' => PhabricatorSearchRelationship::RELATIONSHIP_OWNER,
+ 'project' => PhabricatorSearchRelationship::RELATIONSHIP_PROJECT,
+ 'repository' => PhabricatorSearchRelationship::RELATIONSHIP_REPOSITORY,
+ );
+ foreach ($rel_mapping as $name => $field) {
+ $param = $query->getParameter($name);
+ if (is_array($param)) {
+ $should = array();
+ foreach ($param as $val) {
+ $should[] = array(
+ 'text' => array(
+ "relationship.{$field}.phid" => array(
+ 'query' => $val,
+ 'type' => 'phrase',
+ ),
+ ),
+ );
+ }
+ $spec[] = array('bool' => array('should' => $should));
+ } else if ($param) {
+ $filter[] = array(
+ 'exists' => array(
+ 'field' => "relationship.{$field}.phid",
+ ),
+ );
+ }
+ }
- $phids = array();
- foreach ($response['hits']['hits'] as $hit) {
- $phids[] = $hit['_id'];
+ if ($spec) {
+ $spec = array('query' => array('bool' => array('must' => $spec)));
}
+ if ($filter) {
+ $filter = array('filter' => array('and' => $filter));
+ if ($spec) {
+ $spec = array(
+ 'query' => array(
+ 'filtered' => $spec + $filter,
+ ),
+ );
+ } else {
+ $spec = $filter;
+ }
+ }
+
+ $spec['from'] = (int)$query->getParameter('offset', 0);
+ $spec['size'] = (int)$query->getParameter('limit', 0);
+ $response = $this->executeRequest($uri, $spec);
+
+ $phids = ipull($response['hits']['hits'], '_id');
return $phids;
}
- private function executeRequest($path, array $data, $is_write) {
+ private function executeRequest($path, array $data, $is_write = false) {
$uri = PhabricatorEnv::getEnvConfig('search.elastic.host');
$uri = new PhutilURI($uri);
$data = json_encode($data);
$uri->setPath($path);
$protocol = $uri->getProtocol();
if ($protocol == 'https') {
$future = new HTTPSFuture($uri, $data);
} else {
$future = new HTTPFuture($uri, $data);
}
if ($is_write) {
$future->setMethod('PUT');
} else {
$future->setMethod('GET');
}
list($body) = $future->resolvex();
if ($is_write) {
return null;
}
$body = json_decode($body, true);
if (!is_array($body)) {
throw new Exception("elasticsearch server returned invalid JSON!");
}
return $body;
}
}
diff --git a/src/applications/search/engine/elastic/__init__.php b/src/applications/search/engine/elastic/__init__.php
index 8bf12fdd73..1acaecabd5 100644
--- a/src/applications/search/engine/elastic/__init__.php
+++ b/src/applications/search/engine/elastic/__init__.php
@@ -1,18 +1,22 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
+phutil_require_module('phabricator', 'applications/phid/handle/data');
+phutil_require_module('phabricator', 'applications/phid/utils');
+phutil_require_module('phabricator', 'applications/search/constants/relationship');
phutil_require_module('phabricator', 'applications/search/engine/base');
phutil_require_module('phabricator', 'applications/search/index/abstractdocument');
phutil_require_module('phabricator', 'infrastructure/env');
phutil_require_module('phutil', 'future/http/http');
phutil_require_module('phutil', 'future/http/https');
phutil_require_module('phutil', 'parser/uri');
+phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorSearchEngineElastic.php');
diff --git a/src/applications/search/engine/mysql/PhabricatorSearchEngineMySQL.php b/src/applications/search/engine/mysql/PhabricatorSearchEngineMySQL.php
index 00d3a8c0d3..7b3d1c9e6f 100644
--- a/src/applications/search/engine/mysql/PhabricatorSearchEngineMySQL.php
+++ b/src/applications/search/engine/mysql/PhabricatorSearchEngineMySQL.php
@@ -1,342 +1,347 @@
<?php
/*
* Copyright 2012 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.
*/
/**
* @group search
*/
final class PhabricatorSearchEngineMySQL extends PhabricatorSearchEngine {
public 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, phidType, field, auxPHID, corpus) '.
' VALUES (%s, %s, %s, %ns, %s)',
$field_dao->getTableName(),
$phid,
$doc->getDocumentType(),
$ftype,
$aux_phid,
$corpus);
}
$sql = array();
foreach ($doc->getRelationshipData() as $relationship) {
list($rtype, $to_phid, $to_type, $time) = $relationship;
$sql[] = qsprintf(
$conn_w,
'(%s, %s, %s, %s, %d)',
$phid,
$to_phid,
$rtype,
$to_type,
$time);
}
$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, relatedType, relatedTime) '.
' VALUES %Q',
$rship_dao->getTableName(),
implode(', ', $sql));
}
}
/**
* Rebuild the PhabricatorSearchAbstractDocument that was used to index
* an object out of the index itself. This is primarily useful for debugging,
* as it allows you to inspect the search index representation of a
* document.
*
* @param phid PHID of a document which exists in the search index.
* @return null|PhabricatorSearchAbstractDocument Abstract document object
* which corresponds to the original abstract document used to
* build the document index.
*/
public function reconstructDocument($phid) {
$dao_doc = new PhabricatorSearchDocument();
$dao_field = new PhabricatorSearchDocumentField();
$dao_relationship = new PhabricatorSearchDocumentRelationship();
$t_doc = $dao_doc->getTableName();
$t_field = $dao_field->getTableName();
$t_relationship = $dao_relationship->getTableName();
$doc = queryfx_one(
$dao_doc->establishConnection('r'),
'SELECT * FROM %T WHERE phid = %s',
$t_doc,
$phid);
if (!$doc) {
return null;
}
$fields = queryfx_all(
$dao_field->establishConnection('r'),
'SELECT * FROM %T WHERE phid = %s',
$t_field,
$phid);
$relationships = queryfx_all(
$dao_relationship->establishConnection('r'),
'SELECT * FROM %T WHERE phid = %s',
$t_relationship,
$phid);
$adoc = id(new PhabricatorSearchAbstractDocument())
->setPHID($phid)
->setDocumentType($doc['documentType'])
->setDocumentTitle($doc['documentTitle'])
->setDocumentCreated($doc['documentCreated'])
->setDocumentModified($doc['documentModified']);
foreach ($fields as $field) {
$adoc->addField(
$field['field'],
$field['corpus'],
$field['auxPHID']);
}
foreach ($relationships as $relationship) {
$adoc->addRelationship(
$relationship['relation'],
$relationship['relatedPHID'],
$relationship['relatedType'],
$relationship['relatedTime']);
}
return $adoc;
}
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 IN BOOLEAN MODE)',
$q);
// When searching for a string, promote user listings above other
// listings.
$order = qsprintf(
$conn_r,
'ORDER BY
IF(documentType = %s, 0, 1) ASC,
MAX(MATCH(corpus) AGAINST (%s)) DESC',
'USER',
$q);
$field = $query->getParameter('field');
if ($field/* && $field != AdjutantQuery::FIELD_ALL*/) {
$where[] = qsprintf(
$conn_r,
'field.field = %s',
$field);
}
}
$exclude = $query->getParameter('exclude');
if ($exclude) {
$where[] = qsprintf($conn_r, 'document.phid != %s', $exclude);
}
if ($query->getParameter('type')) {
if (strlen($q)) {
// TODO: verify that this column actually does something useful in query
// plans once we have nontrivial amounts of data.
$where[] = qsprintf(
$conn_r,
'field.phidType = %s',
$query->getParameter('type'));
}
$where[] = qsprintf(
$conn_r,
'document.documentType = %s',
$query->getParameter('type'));
}
$join[] = $this->joinRelationship(
$conn_r,
$query,
'author',
PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR);
$join[] = $this->joinRelationship(
$conn_r,
$query,
'open',
PhabricatorSearchRelationship::RELATIONSHIP_OPEN);
$join[] = $this->joinRelationship(
$conn_r,
$query,
'owner',
PhabricatorSearchRelationship::RELATIONSHIP_OWNER);
$join[] = $this->joinRelationship(
$conn_r,
$query,
'project',
PhabricatorSearchRelationship::RELATIONSHIP_PROJECT);
$join[] = $this->joinRelationship(
$conn_r,
$query,
'repository',
PhabricatorSearchRelationship::RELATIONSHIP_REPOSITORY);
/*
$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 = '';
}
$offset = (int)$query->getParameter('offset', 0);
$limit = (int)$query->getParameter('limit', 25);
$hits = queryfx_all(
$conn_r,
'SELECT
document.phid
FROM %T document
%Q
%Q
GROUP BY document.phid
%Q
LIMIT %d, %d',
$t_doc,
$join,
$where,
$order,
$offset,
$limit);
return ipull($hits, 'phid');
}
- protected function joinRelationship($conn, $query, $field, $type) {
+ protected function joinRelationship(
+ AphrontDatabaseConnection $conn,
+ PhabricatorSearchQuery $query,
+ $field,
+ $type) {
+
$phids = $query->getParameter($field, array());
if (!$phids) {
return null;
}
$is_existence = false;
switch ($type) {
case PhabricatorSearchRelationship::RELATIONSHIP_OPEN:
$is_existence = true;
break;
}
$sql = qsprintf(
$conn,
'%T AS %C ON %C.phid = document.phid AND %C.relation = %s',
id(new PhabricatorSearchDocumentRelationship())->getTableName(),
$field,
$field,
$field,
$type);
if (!$is_existence) {
$sql .= qsprintf(
$conn,
' AND %C.relatedPHID in (%Ls)',
$field,
$phids);
}
return $sql;
}
}
diff --git a/src/applications/search/index/abstractdocument/PhabricatorSearchAbstractDocument.php b/src/applications/search/index/abstractdocument/PhabricatorSearchAbstractDocument.php
index 97cad5007f..9bea89dda6 100644
--- a/src/applications/search/index/abstractdocument/PhabricatorSearchAbstractDocument.php
+++ b/src/applications/search/index/abstractdocument/PhabricatorSearchAbstractDocument.php
@@ -1,95 +1,106 @@
<?php
/*
- * Copyright 2011 Facebook, Inc.
+ * Copyright 2012 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.
*/
/**
* @group search
*/
final class PhabricatorSearchAbstractDocument {
private $phid;
private $documentType;
private $documentTitle;
private $documentCreated;
private $documentModified;
private $fields = array();
private $relationships = array();
+ public static function getSupportedTypes() {
+ $more = PhabricatorEnv::getEnvConfig('search.more-document-types', array());
+ return array(
+ PhabricatorPHIDConstants::PHID_TYPE_DREV => 'Differential Revisions',
+ PhabricatorPHIDConstants::PHID_TYPE_CMIT => 'Repository Commits',
+ PhabricatorPHIDConstants::PHID_TYPE_TASK => 'Maniphest Tasks',
+ PhabricatorPHIDConstants::PHID_TYPE_WIKI => 'Phriction Documents',
+ PhabricatorPHIDConstants::PHID_TYPE_USER => 'Phabricator Users',
+ ) + $more;
+ }
+
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, $rtype, $time) {
$this->relationships[] = array($type, $related_phid, $rtype, $time);
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;
}
}
diff --git a/src/applications/search/index/abstractdocument/__init__.php b/src/applications/search/index/abstractdocument/__init__.php
index 355519d478..f1af4dec62 100644
--- a/src/applications/search/index/abstractdocument/__init__.php
+++ b/src/applications/search/index/abstractdocument/__init__.php
@@ -1,12 +1,14 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
+phutil_require_module('phabricator', 'applications/phid/constants');
phutil_require_module('phabricator', 'applications/search/constants/field');
+phutil_require_module('phabricator', 'infrastructure/env');
phutil_require_source('PhabricatorSearchAbstractDocument.php');
diff --git a/src/applications/search/index/indexer/user/PhabricatorSearchUserIndexer.php b/src/applications/search/index/indexer/user/PhabricatorSearchUserIndexer.php
index e321eff38e..7cacf31492 100644
--- a/src/applications/search/index/indexer/user/PhabricatorSearchUserIndexer.php
+++ b/src/applications/search/index/indexer/user/PhabricatorSearchUserIndexer.php
@@ -1,38 +1,38 @@
<?php
/*
* Copyright 2012 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.
*/
/**
* @group search
*/
final class PhabricatorSearchUserIndexer
extends PhabricatorSearchDocumentIndexer {
public static function indexUser(PhabricatorUser $user) {
$doc = new PhabricatorSearchAbstractDocument();
$doc->setPHID($user->getPHID());
$doc->setDocumentType(PhabricatorPHIDConstants::PHID_TYPE_USER);
- $doc->setDocumentTitle($user->getUserName().'('.$user->getRealName().')');
+ $doc->setDocumentTitle($user->getUserName().' ('.$user->getRealName().')');
$doc->setDocumentCreated($user->getDateCreated());
$doc->setDocumentModified($user->getDateModified());
// TODO: Index the blurbs from their profile or something? Probably not
// actually useful...
self::reindexAbstractDocument($doc);
}
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Feb 24, 11:47 PM (8 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
851659
Default Alt Text
(37 KB)

Event Timeline