[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/search/index/ -> PhabricatorSearchDocumentIndexer.php (source)

   1  <?php
   2  
   3  abstract class PhabricatorSearchDocumentIndexer {
   4  
   5    abstract public function getIndexableObject();
   6    abstract protected function buildAbstractDocumentByPHID($phid);
   7  
   8    protected function getViewer() {
   9      return PhabricatorUser::getOmnipotentUser();
  10    }
  11  
  12    public function shouldIndexDocumentByPHID($phid) {
  13      $object = $this->getIndexableObject();
  14      return (phid_get_type($phid) == phid_get_type($object->generatePHID()));
  15    }
  16  
  17    public function getIndexIterator() {
  18      $object = $this->getIndexableObject();
  19      return new LiskMigrationIterator($object);
  20    }
  21  
  22    protected function loadDocumentByPHID($phid) {
  23      $object = id(new PhabricatorObjectQuery())
  24        ->setViewer($this->getViewer())
  25        ->withPHIDs(array($phid))
  26        ->executeOne();
  27      if (!$object) {
  28        throw new Exception("Unable to load object by phid '{$phid}'!");
  29      }
  30      return $object;
  31    }
  32  
  33    public function indexDocumentByPHID($phid) {
  34      try {
  35        $document = $this->buildAbstractDocumentByPHID($phid);
  36  
  37        $object = $this->loadDocumentByPHID($phid);
  38  
  39        // Automatically rebuild CustomField indexes if the object uses custom
  40        // fields.
  41        if ($object instanceof PhabricatorCustomFieldInterface) {
  42          $this->indexCustomFields($document, $object);
  43        }
  44  
  45        // Automatically rebuild subscriber indexes if the object is subscribable.
  46        if ($object instanceof PhabricatorSubscribableInterface) {
  47          $this->indexSubscribers($document);
  48        }
  49  
  50        // Automatically build project relationships
  51        if ($object instanceof PhabricatorProjectInterface) {
  52          $this->indexProjects($document, $object);
  53        }
  54  
  55        $engine = PhabricatorSearchEngineSelector::newSelector()->newEngine();
  56        try {
  57          $engine->reindexAbstractDocument($document);
  58        } catch (Exception $ex) {
  59          $phid = $document->getPHID();
  60          $class = get_class($engine);
  61  
  62          phlog("Unable to index document {$phid} with engine {$class}.");
  63          phlog($ex);
  64        }
  65  
  66        $this->dispatchDidUpdateIndexEvent($phid, $document);
  67      } catch (Exception $ex) {
  68        $class = get_class($this);
  69        phlog("Unable to build document {$phid} with indexer {$class}.");
  70        phlog($ex);
  71      }
  72  
  73      return $this;
  74    }
  75  
  76    protected function newDocument($phid) {
  77      return id(new PhabricatorSearchAbstractDocument())
  78        ->setPHID($phid)
  79        ->setDocumentType(phid_get_type($phid));
  80    }
  81  
  82    protected function indexSubscribers(
  83      PhabricatorSearchAbstractDocument $doc) {
  84  
  85      $subscribers = PhabricatorSubscribersQuery::loadSubscribersForPHID(
  86        $doc->getPHID());
  87      $handles = id(new PhabricatorHandleQuery())
  88        ->setViewer($this->getViewer())
  89        ->withPHIDs($subscribers)
  90        ->execute();
  91  
  92      foreach ($handles as $phid => $handle) {
  93        $doc->addRelationship(
  94          PhabricatorSearchRelationship::RELATIONSHIP_SUBSCRIBER,
  95          $phid,
  96          $handle->getType(),
  97          $doc->getDocumentModified()); // Bogus timestamp.
  98      }
  99    }
 100  
 101    protected function indexProjects(
 102      PhabricatorSearchAbstractDocument $doc,
 103      PhabricatorProjectInterface $object) {
 104  
 105      $project_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
 106        $object->getPHID(),
 107        PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
 108      if ($project_phids) {
 109        foreach ($project_phids as $project_phid) {
 110          $doc->addRelationship(
 111            PhabricatorSearchRelationship::RELATIONSHIP_PROJECT,
 112            $project_phid,
 113            PhabricatorProjectProjectPHIDType::TYPECONST,
 114            $doc->getDocumentModified()); // Bogus timestamp.
 115        }
 116      }
 117    }
 118  
 119    protected function indexTransactions(
 120      PhabricatorSearchAbstractDocument $doc,
 121      PhabricatorApplicationTransactionQuery $query,
 122      array $phids) {
 123  
 124      $xactions = id(clone $query)
 125        ->setViewer($this->getViewer())
 126        ->withObjectPHIDs($phids)
 127        ->execute();
 128  
 129      foreach ($xactions as $xaction) {
 130        if (!$xaction->hasComment()) {
 131          continue;
 132        }
 133  
 134        $comment = $xaction->getComment();
 135        $doc->addField(
 136          PhabricatorSearchField::FIELD_COMMENT,
 137          $comment->getContent());
 138      }
 139    }
 140  
 141    protected function indexCustomFields(
 142      PhabricatorSearchAbstractDocument $document,
 143      PhabricatorCustomFieldInterface $object) {
 144  
 145      // Rebuild the ApplicationSearch indexes. These are internal and not part of
 146      // the fulltext search, but putting them in this workflow allows users to
 147      // use the same tools to rebuild the indexes, which is easy to understand.
 148  
 149      $field_list = PhabricatorCustomField::getObjectFields(
 150        $object,
 151        PhabricatorCustomField::ROLE_DEFAULT);
 152  
 153      $field_list->setViewer($this->getViewer());
 154      $field_list->readFieldsFromStorage($object);
 155  
 156      // Rebuild ApplicationSearch indexes.
 157      $field_list->rebuildIndexes($object);
 158  
 159      // Rebuild global search indexes.
 160      $field_list->updateAbstractDocument($document);
 161    }
 162  
 163    private function dispatchDidUpdateIndexEvent(
 164      $phid,
 165      PhabricatorSearchAbstractDocument $document) {
 166  
 167      $event = new PhabricatorEvent(
 168        PhabricatorEventType::TYPE_SEARCH_DIDUPDATEINDEX,
 169        array(
 170          'phid'      => $phid,
 171          'object'    => $this->loadDocumentByPHID($phid),
 172          'document'  => $document,
 173        ));
 174      $event->setUser($this->getViewer());
 175      PhutilEventEngine::dispatchEvent($event);
 176    }
 177  
 178  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1