Page MenuHomePhorge

No OneTemporary

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

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)

Event Timeline