Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2896192
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Advanced/Developer...
View Handle
View Hovercard
Size
36 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/applications/maniphest/controller/taskselectorsearch/ManiphestTaskSelectorSearchController.php b/src/applications/maniphest/controller/taskselectorsearch/ManiphestTaskSelectorSearchController.php
index 4d6010804f..14a591969a 100644
--- a/src/applications/maniphest/controller/taskselectorsearch/ManiphestTaskSelectorSearchController.php
+++ b/src/applications/maniphest/controller/taskselectorsearch/ManiphestTaskSelectorSearchController.php
@@ -1,44 +1,58 @@
<?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 ManiphestTaskSelectorSearchController extends ManiphestController {
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$query = new PhabricatorSearchQuery();
$query->setQuery($request->getStr('query'));
$query->setParameter('type', 'TASK');
+ switch ($request->getStr('filter')) {
+ case 'assigned':
+ $query->setParameter('owner', array($user->getPHID()));
+ $query->setParameter('open', 1);
+ break;
+ case 'created';
+ $query->setParameter('author', array($user->getPHID()));
+ $query->setParameter('open', 1);
+ break;
+ case 'open':
+ $query->setParameter('open', 1);
+ break;
+ }
+
$exec = new PhabricatorSearchMySQLExecutor();
$results = $exec->executeSearch($query);
$results = ipull($results, 'phid');
$handles = id(new PhabricatorObjectHandleData($results))
->loadHandles();
$data = array();
foreach ($handles as $handle) {
$view = new PhabricatorHandleObjectSelectorDataView($handle);
$data[] = $view->renderData();
}
return id(new AphrontAjaxResponse())->setContent($data);
}
}
diff --git a/src/applications/phid/handle/view/selector/PhabricatorHandleObjectSelectorDataView.php b/src/applications/phid/handle/view/selector/PhabricatorHandleObjectSelectorDataView.php
index 954346464f..cc69990f63 100644
--- a/src/applications/phid/handle/view/selector/PhabricatorHandleObjectSelectorDataView.php
+++ b/src/applications/phid/handle/view/selector/PhabricatorHandleObjectSelectorDataView.php
@@ -1,35 +1,35 @@
<?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 PhabricatorHandleObjectSelectorDataView {
private $handle;
public function __construct($handle) {
$this->handle = $handle;
}
public function renderData() {
$handle = $this->handle;
return array(
'phid' => $handle->getPHID(),
'name' => $handle->getFullName(),
- 'href' => $handle->getURI(),
+ 'uri' => $handle->getURI(),
);
}
}
diff --git a/src/applications/search/constants/field/PhabricatorSearchField.php b/src/applications/search/constants/field/PhabricatorSearchField.php
index 25609d9247..28fefba104 100644
--- a/src/applications/search/constants/field/PhabricatorSearchField.php
+++ b/src/applications/search/constants/field/PhabricatorSearchField.php
@@ -1,25 +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 PhabricatorSearchField {
const FIELD_TITLE = 'titl';
const FIELD_BODY = 'body';
const FIELD_TEST_PLAN = 'tpln';
+ const FIELD_COMMENT = 'cmnt';
}
diff --git a/src/applications/search/constants/relationship/PhabricatorSearchRelationship.php b/src/applications/search/constants/relationship/PhabricatorSearchRelationship.php
index e9398917ec..488acfa445 100644
--- a/src/applications/search/constants/relationship/PhabricatorSearchRelationship.php
+++ b/src/applications/search/constants/relationship/PhabricatorSearchRelationship.php
@@ -1,26 +1,30 @@
<?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';
+ const RELATIONSHIP_OWNER = 'ownr';
+
+ const RELATIONSHIP_OPEN = 'open';
+ const RELATIONSHIP_TOUCH = 'poke';
}
diff --git a/src/applications/search/controller/search/PhabricatorSearchController.php b/src/applications/search/controller/search/PhabricatorSearchController.php
index 63b03b6543..738420cdde 100644
--- a/src/applications/search/controller/search/PhabricatorSearchController.php
+++ b/src/applications/search/controller/search/PhabricatorSearchController.php
@@ -1,95 +1,148 @@
<?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'));
+
+ if (strlen($request->getStr('type'))) {
+ $query->setParameter('type', $request->getStr('type'));
+ }
+
+ if ($request->getArr('author')) {
+ $query->setParameter('author', $request->getArr('author'));
+ }
+
+ if ($request->getInt('open')) {
+ $query->setParameter('open', $request->getInt('open'));
+ }
+
$query->save();
return id(new AphrontRedirectResponse())
->setURI('/search/'.$query->getID().'/');
}
}
+ $options = array(
+ '' => 'All Documents',
+ 'DREV' => 'Differential Revisions',
+ 'TASK' => 'Maniphest Tasks',
+ );
+
+ $status_options = array(
+ 0 => 'Open and Closed Documents',
+ 1 => 'Open Documents',
+ );
+
+ $phids = array_merge(
+ $query->getParameter('author', array())
+ );
+
+ $handles = id(new PhabricatorObjectHandleData($phids))
+ ->loadHandles();
+
+ $author_value = array_select_keys(
+ $handles,
+ $query->getParameter('author', array()));
+ $author_value = mpull($author_value, 'getFullName', 'getPHID');
$search_form = new AphrontFormView();
$search_form
->setUser($user)
->setAction('/search/')
->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 AphrontFormTokenizerControl())
+ ->setName('author')
+ ->setLabel('Author')
+ ->setDatasource('/typeahead/common/users/')
+ ->setValue($author_value))
+ ->appendChild(
+ id(new AphrontFormSelectControl())
+ ->setLabel('Document Status')
+ ->setName('open')
+ ->setOptions($status_options)
+ ->setValue($query->getParameter('open')))
->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',
));
}
}
diff --git a/src/applications/search/execute/mysql/PhabricatorSearchMySQLExecutor.php b/src/applications/search/execute/mysql/PhabricatorSearchMySQLExecutor.php
index 455572ccc6..d967c35b1f 100644
--- a/src/applications/search/execute/mysql/PhabricatorSearchMySQLExecutor.php
+++ b/src/applications/search/execute/mysql/PhabricatorSearchMySQLExecutor.php
@@ -1,138 +1,169 @@
<?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')) {
+ 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',
- AdjutantRelationship::RELATIONSHIP_AUTHOR);
+ PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR);
+
+ $join[] = $this->joinRelationship(
+ $conn_r,
+ $query,
+ 'open',
+ PhabricatorSearchRelationship::RELATIONSHIP_OPEN);
+
+/*
$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.documentTitle,
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) {
+ $phids = $query->getParameter($field, array());
+ if (!$phids) {
return null;
}
- return qsprintf(
+
+ $is_existence = false;
+ switch ($type) {
+ case PhabricatorSearchRelationship::RELATIONSHIP_OPEN:
+ $is_existence = true;
+ break;
+ }
+
+ $sql = qsprintf(
$conn,
- 'relationship AS %C ON %C.fbid = data.fbid AND %C.relation = %s
- AND %C.relatedFBID in (%Ld)',
- $field,
+ '%T AS %C ON %C.phid = document.phid AND %C.relation = %s',
+ id(new PhabricatorSearchDocumentRelationship())->getTableName(),
$field,
$field,
- $type,
$field,
- $fbids);
+ $type);
+
+ if (!$is_existence) {
+ $sql .= qsprintf(
+ $conn,
+ ' AND %C.relatedPHID in (%Ls)',
+ $field,
+ $phids);
+ }
+
+ return $sql;
}
}
diff --git a/src/applications/search/execute/mysql/__init__.php b/src/applications/search/execute/mysql/__init__.php
index a356035a92..b78985af0c 100644
--- a/src/applications/search/execute/mysql/__init__.php
+++ b/src/applications/search/execute/mysql/__init__.php
@@ -1,16 +1,20 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
+phutil_require_module('phabricator', 'applications/search/constants/relationship');
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', 'applications/search/storage/document/relationship');
phutil_require_module('phabricator', 'storage/qsprintf');
phutil_require_module('phabricator', 'storage/queryfx');
+phutil_require_module('phutil', 'utils');
+
phutil_require_source('PhabricatorSearchMySQLExecutor.php');
diff --git a/src/applications/search/index/abstractdocument/PhabricatorSearchAbstractDocument.php b/src/applications/search/index/abstractdocument/PhabricatorSearchAbstractDocument.php
index 73b3df4409..b66464a9de 100644
--- a/src/applications/search/index/abstractdocument/PhabricatorSearchAbstractDocument.php
+++ b/src/applications/search/index/abstractdocument/PhabricatorSearchAbstractDocument.php
@@ -1,92 +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);
+ 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/indexer/differential/PhabricatorSearchDifferentialIndexer.php b/src/applications/search/index/indexer/differential/PhabricatorSearchDifferentialIndexer.php
index cf56c42429..5ad13064a1 100644
--- a/src/applications/search/index/indexer/differential/PhabricatorSearchDifferentialIndexer.php
+++ b/src/applications/search/index/indexer/differential/PhabricatorSearchDifferentialIndexer.php
@@ -1,43 +1,45 @@
<?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());
+ $rev->getAuthorPHID(),
+ 'USER',
+ $rev->getDateCreated());
PhabricatorSearchDocument::reindexAbstractDocument($doc);
}
}
diff --git a/src/applications/search/index/indexer/maniphest/PhabricatorSearchManiphestIndexer.php b/src/applications/search/index/indexer/maniphest/PhabricatorSearchManiphestIndexer.php
index ce66caa5eb..7fe489e5af 100644
--- a/src/applications/search/index/indexer/maniphest/PhabricatorSearchManiphestIndexer.php
+++ b/src/applications/search/index/indexer/maniphest/PhabricatorSearchManiphestIndexer.php
@@ -1,40 +1,120 @@
<?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());
+ $task->getAuthorPHID(),
+ 'USER',
+ $task->getDateCreated());
+
+ if ($task->getStatus() == ManiphestTaskStatus::STATUS_OPEN) {
+ $doc->addRelationship(
+ PhabricatorSearchRelationship::RELATIONSHIP_OPEN,
+ $task->getPHID(),
+ 'TASK',
+ time());
+ }
+
+ $transactions = id(new ManiphestTransaction())->loadAllWhere(
+ 'taskID = %d',
+ $task->getID());
+
+ $current_ccs = $task->getCCPHIDs();
+ $touches = array();
+ $owner = null;
+ $ccs = array();
+ foreach ($transactions as $transaction) {
+ if ($transaction->hasComments()) {
+ $doc->addField(
+ PhabricatorSearchField::FIELD_COMMENT,
+ $transaction->getComments());
+ }
+
+ $author = $transaction->getAuthorPHID();
+
+ // Record the most recent time they touched this object.
+ $touches[$author] = $transaction->getDateCreated();
+
+ switch ($transaction->getTransactionType()) {
+ case ManiphestTransactionType::TYPE_OWNER:
+ $owner = $transaction;
+ break;
+ case ManiphestTransactionType::TYPE_CCS:
+ // For users who are still CC'd, record the first time they were
+ // added to CC.
+ foreach ($transaction->getNewValue() as $added_cc) {
+ if (in_array($added_cc, $current_ccs)) {
+ if (empty($ccs[$added_cc])) {
+ $ccs[$added_cc] = $transaction->getDateCreated();
+
+ // CCs count as touches, even if you didn't technically
+ // interact with the object directly.
+ $touches[$added_cc] = $transaction->getDateCreated();
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ if ($owner && $owner->getNewValue()) {
+ $doc->addRelationship(
+ PhabricatorSearchRelationship::RELATIONSHIP_OWNER,
+ $owner->getNewValue(),
+ 'USER',
+ $owner->getDateCreated());
+ }
+
+ foreach ($touches as $touch => $time) {
+ $doc->addRelationship(
+ PhabricatorSearchRelationship::RELATIONSHIP_TOUCH,
+ $touch,
+ 'USER',
+ $time);
+ }
+
+ // We need to load handles here since non-users may subscribe (mailing
+ // lists, e.g.)
+ $handles = id(new PhabricatorObjectHandleData(array_keys($ccs)))
+ ->loadHandles();
+ foreach ($ccs as $cc => $time) {
+ $doc->addRelationship(
+ PhabricatorSearchRelationship::RELATIONSHIP_SUBSCRIBER,
+ $handles[$cc]->getPHID(),
+ $handles[$cc]->getType(),
+ $time);
+ }
PhabricatorSearchDocument::reindexAbstractDocument($doc);
}
}
diff --git a/src/applications/search/index/indexer/maniphest/__init__.php b/src/applications/search/index/indexer/maniphest/__init__.php
index 6bc0288b98..62fe069f4e 100644
--- a/src/applications/search/index/indexer/maniphest/__init__.php
+++ b/src/applications/search/index/indexer/maniphest/__init__.php
@@ -1,16 +1,22 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
+phutil_require_module('phabricator', 'applications/maniphest/constants/status');
+phutil_require_module('phabricator', 'applications/maniphest/constants/transactiontype');
+phutil_require_module('phabricator', 'applications/maniphest/storage/transaction');
+phutil_require_module('phabricator', 'applications/phid/handle/data');
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_module('phutil', 'utils');
+
phutil_require_source('PhabricatorSearchManiphestIndexer.php');
diff --git a/src/applications/search/storage/document/document/PhabricatorSearchDocument.php b/src/applications/search/storage/document/document/PhabricatorSearchDocument.php
index 1693efad85..920cb332ef 100644
--- a/src/applications/search/storage/document/document/PhabricatorSearchDocument.php
+++ b/src/applications/search/storage/document/document/PhabricatorSearchDocument.php
@@ -1,104 +1,108 @@
<?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)',
+ '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, $toPHID) = $relationship;
+ list($rtype, $to_phid, $to_type, $time) = $relationship;
$sql[] = qsprintf(
$conn_w,
- '(%s, %s, %s)',
+ '(%s, %s, %s, %s, %d)',
$phid,
- $toPHID,
- $rtype);
+ $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) '.
+ 'INSERT INTO %T'.
+ ' (phid, relatedPHID, relation, relatedType, relatedTime) '.
' VALUES %Q',
$rship_dao->getTableName(),
implode(', ', $sql));
}
}
}
diff --git a/src/applications/search/storage/document/relationship/PhabricatorSearchDocumentRelationship.php b/src/applications/search/storage/document/relationship/PhabricatorSearchDocumentRelationship.php
index a5257e5b36..21c8158603 100644
--- a/src/applications/search/storage/document/relationship/PhabricatorSearchDocumentRelationship.php
+++ b/src/applications/search/storage/document/relationship/PhabricatorSearchDocumentRelationship.php
@@ -1,32 +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.
*/
class PhabricatorSearchDocumentRelationship extends PhabricatorSearchDAO {
protected $phid;
protected $relatedPHID;
protected $relation;
+ protected $relatedType;
+ protected $relatedTime;
public function getConfiguration() {
return array(
self::CONFIG_TIMESTAMPS => false,
self::CONFIG_IDS => self::IDS_MANUAL,
) + parent::getConfiguration();
}
}
diff --git a/webroot/rsrc/js/application/core/behavior-object-selector.js b/webroot/rsrc/js/application/core/behavior-object-selector.js
index 58d43002bc..72be21dd7a 100644
--- a/webroot/rsrc/js/application/core/behavior-object-selector.js
+++ b/webroot/rsrc/js/application/core/behavior-object-selector.js
@@ -1,159 +1,168 @@
/**
* @provides javelin-behavior-phabricator-object-selector
* @requires javelin-lib-dev
*/
JX.behavior('phabricator-object-selector', function(config) {
var n = 0;
var phids = {};
var handles = config.handles;
for (var k in handles) {
phids[k] = true;
}
var attach_list = {};
var phid_input = JX.DOM.find(
JX.$(config.form),
'input',
'aphront-dialog-application-input');
function onreceive(seq, r) {
if (seq != n) {
return;
}
var display = [];
attach_list = {};
for (var k in r) {
handles[r[k].phid] = r[k];
display.push(renderHandle(r[k], true));
}
if (!display.length) {
display = renderNote('No results.');
}
JX.DOM.setContent(JX.$(config.results), display);
}
function redrawAttached() {
var display = [];
for (var k in phids) {
display.push(renderHandle(handles[k], false));
}
if (!display.length) {
display = renderNote('Nothing attached.');
}
JX.DOM.setContent(JX.$(config.current), display);
phid_input.value = JX.keys(phids).join(';');
}
function renderHandle(h, attach) {
var link = JX.$N(
'a',
{href : h.uri, target : '_blank'},
h.name);
var td = JX.$N('td');
var table = JX.$N(
'table',
{className: 'phabricator-object-selector-handle'},
JX.$N(
'tbody',
{},
[JX.$N('th', {}, link), td]));
var btn = JX.$N(
'a',
{className: 'button small grey'},
attach ? 'Attach' : 'Remove');
JX.Stratcom.addSigil(btn, 'object-attach-button');
JX.Stratcom.addData(btn, {handle : h, table : table});
if (attach) {
attach_list[h.phid] = btn;
if (h.phid in phids) {
JX.DOM.alterClass(btn, 'disabled', true);
btn.disabled = true;
}
}
JX.DOM.setContent(td, btn);
return table;
}
function renderNote(note) {
return JX.$N('div', {className : 'object-selector-nothing'}, note);
}
function sendQuery() {
JX.DOM.setContent(JX.$(config.results), renderNote('Loading...'))
new JX.Request(config.uri, JX.bind(null, onreceive, ++n))
.setData({
filter: JX.$(config.filter).value,
query: JX.$(config.query).value
})
.send();
}
JX.DOM.listen(
JX.$(config.search),
'submit',
null,
function(e) {
e.kill();
sendQuery();
});
+ JX.DOM.listen(
+ JX.$(config.search),
+ 'click',
+ 'tag:button',
+ function(e) {
+ e.kill();
+ sendQuery();
+ });
+
JX.DOM.listen(
JX.$(config.results),
'click',
'object-attach-button',
function(e) {
e.kill();
var button = e.getNode('object-attach-button');
if (button.disabled) {
return;
}
var data = e.getNodeData('object-attach-button');
phids[data.handle.phid] = true;
JX.DOM.alterClass(button, 'disabled', true);
button.disabled = true;
redrawAttached();
});
JX.DOM.listen(
JX.$(config.current),
'click',
'object-attach-button',
function(e) {
e.kill();
var button = e.getNode('object-attach-button');
if (button.disabled) {
return;
}
var data = e.getNodeData('object-attach-button');
delete phids[data.handle.phid];
if (attach_list[data.handle.phid]) {
JX.DOM.alterClass(attach_list[data.handle.phid], 'disabled', false);
attach_list[data.handle.phid].disabled = false;
}
redrawAttached();
});
sendQuery();
redrawAttached();
});
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Jan 19 2025, 22:42 (6 w, 3 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1129508
Default Alt Text
(36 KB)
Attached To
Mode
rP Phorge
Attached
Detach File
Event Timeline
Log In to Comment