mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-13 09:06:14 +01:00
16a8ed72bd
Summary: Remove the `PhabricatorDefaultSearchEngineSelector` class. This is quite similar to D12053. Test Plan: Went to `/view/PhabricatorSearchApplication/` and saw the storage engine configuration. Set `search.elastic.host` and saw the highlighted storage engine change. Reviewers: #blessed_reviewers, epriestley Reviewed By: #blessed_reviewers, epriestley Subscribers: Korvin, epriestley Differential Revision: https://secure.phabricator.com/D12670
195 lines
5.6 KiB
PHP
195 lines
5.6 KiB
PHP
<?php
|
|
|
|
abstract class PhabricatorSearchDocumentIndexer extends Phobject {
|
|
|
|
private $context;
|
|
|
|
protected function setContext($context) {
|
|
$this->context = $context;
|
|
return $this;
|
|
}
|
|
|
|
protected function getContext() {
|
|
return $this->context;
|
|
}
|
|
|
|
abstract public function getIndexableObject();
|
|
abstract protected function buildAbstractDocumentByPHID($phid);
|
|
|
|
protected function getViewer() {
|
|
return PhabricatorUser::getOmnipotentUser();
|
|
}
|
|
|
|
public function shouldIndexDocumentByPHID($phid) {
|
|
$object = $this->getIndexableObject();
|
|
return (phid_get_type($phid) == phid_get_type($object->generatePHID()));
|
|
}
|
|
|
|
public function getIndexIterator() {
|
|
$object = $this->getIndexableObject();
|
|
return new LiskMigrationIterator($object);
|
|
}
|
|
|
|
protected function loadDocumentByPHID($phid) {
|
|
$object = id(new PhabricatorObjectQuery())
|
|
->setViewer($this->getViewer())
|
|
->withPHIDs(array($phid))
|
|
->executeOne();
|
|
if (!$object) {
|
|
throw new Exception("Unable to load object by phid '{$phid}'!");
|
|
}
|
|
return $object;
|
|
}
|
|
|
|
public function indexDocumentByPHID($phid, $context) {
|
|
try {
|
|
$this->setContext($context);
|
|
|
|
$document = $this->buildAbstractDocumentByPHID($phid);
|
|
if ($document === null) {
|
|
// This indexer doesn't build a document index, so we're done.
|
|
return $this;
|
|
}
|
|
|
|
$object = $this->loadDocumentByPHID($phid);
|
|
|
|
// Automatically rebuild CustomField indexes if the object uses custom
|
|
// fields.
|
|
if ($object instanceof PhabricatorCustomFieldInterface) {
|
|
$this->indexCustomFields($document, $object);
|
|
}
|
|
|
|
// Automatically rebuild subscriber indexes if the object is subscribable.
|
|
if ($object instanceof PhabricatorSubscribableInterface) {
|
|
$this->indexSubscribers($document);
|
|
}
|
|
|
|
// Automatically build project relationships
|
|
if ($object instanceof PhabricatorProjectInterface) {
|
|
$this->indexProjects($document, $object);
|
|
}
|
|
|
|
$engine = PhabricatorSearchEngine::loadEngine();
|
|
try {
|
|
$engine->reindexAbstractDocument($document);
|
|
} catch (Exception $ex) {
|
|
$phid = $document->getPHID();
|
|
$class = get_class($engine);
|
|
|
|
phlog("Unable to index document {$phid} with engine {$class}.");
|
|
phlog($ex);
|
|
}
|
|
|
|
$this->dispatchDidUpdateIndexEvent($phid, $document);
|
|
} catch (Exception $ex) {
|
|
$class = get_class($this);
|
|
phlog("Unable to build document {$phid} with indexer {$class}.");
|
|
phlog($ex);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
protected function newDocument($phid) {
|
|
return id(new PhabricatorSearchAbstractDocument())
|
|
->setPHID($phid)
|
|
->setDocumentType(phid_get_type($phid));
|
|
}
|
|
|
|
protected function indexSubscribers(
|
|
PhabricatorSearchAbstractDocument $doc) {
|
|
|
|
$subscribers = PhabricatorSubscribersQuery::loadSubscribersForPHID(
|
|
$doc->getPHID());
|
|
$handles = id(new PhabricatorHandleQuery())
|
|
->setViewer($this->getViewer())
|
|
->withPHIDs($subscribers)
|
|
->execute();
|
|
|
|
foreach ($handles as $phid => $handle) {
|
|
$doc->addRelationship(
|
|
PhabricatorSearchRelationship::RELATIONSHIP_SUBSCRIBER,
|
|
$phid,
|
|
$handle->getType(),
|
|
$doc->getDocumentModified()); // Bogus timestamp.
|
|
}
|
|
}
|
|
|
|
protected function indexProjects(
|
|
PhabricatorSearchAbstractDocument $doc,
|
|
PhabricatorProjectInterface $object) {
|
|
|
|
$project_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
|
|
$object->getPHID(),
|
|
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
|
|
if ($project_phids) {
|
|
foreach ($project_phids as $project_phid) {
|
|
$doc->addRelationship(
|
|
PhabricatorSearchRelationship::RELATIONSHIP_PROJECT,
|
|
$project_phid,
|
|
PhabricatorProjectProjectPHIDType::TYPECONST,
|
|
$doc->getDocumentModified()); // Bogus timestamp.
|
|
}
|
|
}
|
|
}
|
|
|
|
protected function indexTransactions(
|
|
PhabricatorSearchAbstractDocument $doc,
|
|
PhabricatorApplicationTransactionQuery $query,
|
|
array $phids) {
|
|
|
|
$xactions = id(clone $query)
|
|
->setViewer($this->getViewer())
|
|
->withObjectPHIDs($phids)
|
|
->execute();
|
|
|
|
foreach ($xactions as $xaction) {
|
|
if (!$xaction->hasComment()) {
|
|
continue;
|
|
}
|
|
|
|
$comment = $xaction->getComment();
|
|
$doc->addField(
|
|
PhabricatorSearchField::FIELD_COMMENT,
|
|
$comment->getContent());
|
|
}
|
|
}
|
|
|
|
protected function indexCustomFields(
|
|
PhabricatorSearchAbstractDocument $document,
|
|
PhabricatorCustomFieldInterface $object) {
|
|
|
|
// Rebuild the ApplicationSearch indexes. These are internal and not part of
|
|
// the fulltext search, but putting them in this workflow allows users to
|
|
// use the same tools to rebuild the indexes, which is easy to understand.
|
|
|
|
$field_list = PhabricatorCustomField::getObjectFields(
|
|
$object,
|
|
PhabricatorCustomField::ROLE_DEFAULT);
|
|
|
|
$field_list->setViewer($this->getViewer());
|
|
$field_list->readFieldsFromStorage($object);
|
|
|
|
// Rebuild ApplicationSearch indexes.
|
|
$field_list->rebuildIndexes($object);
|
|
|
|
// Rebuild global search indexes.
|
|
$field_list->updateAbstractDocument($document);
|
|
}
|
|
|
|
private function dispatchDidUpdateIndexEvent(
|
|
$phid,
|
|
PhabricatorSearchAbstractDocument $document) {
|
|
|
|
$event = new PhabricatorEvent(
|
|
PhabricatorEventType::TYPE_SEARCH_DIDUPDATEINDEX,
|
|
array(
|
|
'phid' => $phid,
|
|
'object' => $this->loadDocumentByPHID($phid),
|
|
'document' => $document,
|
|
));
|
|
$event->setUser($this->getViewer());
|
|
PhutilEventEngine::dispatchEvent($event);
|
|
}
|
|
|
|
}
|