diff --git a/src/applications/pholio/search/PholioSearchIndexer.php b/src/applications/pholio/search/PholioSearchIndexer.php index 2ca69100b1..f05465818d 100644 --- a/src/applications/pholio/search/PholioSearchIndexer.php +++ b/src/applications/pholio/search/PholioSearchIndexer.php @@ -1,34 +1,37 @@ loadDocumentByPHID($phid); - $doc = new PhabricatorSearchAbstractDocument(); - $doc->setPHID($mock->getPHID()); - $doc->setDocumentType(phid_get_type($mock->getPHID())); - $doc->setDocumentTitle($mock->getName()); - $doc->setDocumentCreated($mock->getDateCreated()); - $doc->setDocumentModified($mock->getDateModified()); + $doc = $this->newDocument($phid) + ->setDocumentTitle($mock->getName()) + ->setDocumentCreated($mock->getDateCreated()) + ->setDocumentModified($mock->getDateModified()); $doc->addField( PhabricatorSearchField::FIELD_BODY, $mock->getDescription()); $doc->addRelationship( PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR, $mock->getAuthorPHID(), PhabricatorPeoplePHIDTypeUser::TYPECONST, $mock->getDateCreated()); + $this->indexTransactions( + $doc, + new PholioTransactionQuery(), + array($phid)); + return $doc; } } diff --git a/src/applications/ponder/editor/PonderQuestionEditor.php b/src/applications/ponder/editor/PonderQuestionEditor.php index b72dafba32..32caa7da81 100644 --- a/src/applications/ponder/editor/PonderQuestionEditor.php +++ b/src/applications/ponder/editor/PonderQuestionEditor.php @@ -1,158 +1,174 @@ getTransactionType()) { case PonderQuestionTransaction::TYPE_ANSWERS: return true; } } return false; } protected function applyInitialEffects( PhabricatorLiskDAO $object, array $xactions) { foreach ($xactions as $xaction) { switch ($xaction->getTransactionType()) { case PonderQuestionTransaction::TYPE_ANSWERS: $new_value = $xaction->getNewValue(); $new = idx($new_value, '+', array()); foreach ($new as $new_answer) { $answer = idx($new_answer, 'answer'); if (!$answer) { continue; } $answer->save(); } break; } } } public function getTransactionTypes() { $types = parent::getTransactionTypes(); $types[] = PhabricatorTransactions::TYPE_COMMENT; $types[] = PonderQuestionTransaction::TYPE_TITLE; $types[] = PonderQuestionTransaction::TYPE_CONTENT; $types[] = PonderQuestionTransaction::TYPE_ANSWERS; $types[] = PonderQuestionTransaction::TYPE_STATUS; return $types; } protected function getCustomTransactionOldValue( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PonderQuestionTransaction::TYPE_TITLE: return $object->getTitle(); case PonderQuestionTransaction::TYPE_CONTENT: return $object->getContent(); case PonderQuestionTransaction::TYPE_ANSWERS: return mpull($object->getAnswers(), 'getPHID'); case PonderQuestionTransaction::TYPE_STATUS: return $object->getStatus(); } } protected function getCustomTransactionNewValue( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PonderQuestionTransaction::TYPE_TITLE: case PonderQuestionTransaction::TYPE_CONTENT: case PonderQuestionTransaction::TYPE_STATUS: return $xaction->getNewValue(); case PonderQuestionTransaction::TYPE_ANSWERS: $raw_new_value = $xaction->getNewValue(); $new_value = array(); foreach ($raw_new_value as $key => $answers) { $phids = array(); foreach ($answers as $answer) { $obj = idx($answer, 'answer'); if (!$answer) { continue; } $phids[] = $obj->getPHID(); } $new_value[$key] = $phids; } $xaction->setNewValue($new_value); return $this->getPHIDTransactionNewValue($xaction); } } protected function applyCustomInternalTransaction( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PonderQuestionTransaction::TYPE_TITLE: $object->setTitle($xaction->getNewValue()); break; case PonderQuestionTransaction::TYPE_CONTENT: $object->setContent($xaction->getNewValue()); break; case PonderQuestionTransaction::TYPE_STATUS: $object->setStatus($xaction->getNewValue()); break; case PonderQuestionTransaction::TYPE_ANSWERS: $old = $xaction->getOldValue(); $new = $xaction->getNewValue(); $add = array_diff_key($new, $old); $rem = array_diff_key($old, $new); $count = $object->getAnswerCount(); $count += count($add); $count -= count($rem); $object->setAnswerCount($count); break; } } protected function applyCustomExternalTransaction( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { return; } protected function mergeTransactions( PhabricatorApplicationTransaction $u, PhabricatorApplicationTransaction $v) { $type = $u->getTransactionType(); switch ($type) { case PonderQuestionTransaction::TYPE_TITLE: case PonderQuestionTransaction::TYPE_CONTENT: case PonderQuestionTransaction::TYPE_STATUS: return $v; } return parent::mergeTransactions($u, $v); } protected function supportsFeed() { return true; } protected function getMailTo(PhabricatorLiskDAO $object) { return array($object->getAuthorPHID()); } + protected function supportsSearch() { + return true; + } + + protected function shouldImplyCC( + PhabricatorLiskDAO $object, + PhabricatorApplicationTransaction $xaction) { + + switch ($xaction->getTransactionType()) { + case PonderQuestionTransaction::TYPE_ANSWERS: + return true; + } + + return parent::shouldImplyCC($object, $xaction); + } + // TODO: Mail support } diff --git a/src/applications/ponder/search/PonderSearchIndexer.php b/src/applications/ponder/search/PonderSearchIndexer.php index 49f69d662f..854d4fd9d7 100644 --- a/src/applications/ponder/search/PonderSearchIndexer.php +++ b/src/applications/ponder/search/PonderSearchIndexer.php @@ -1,71 +1,53 @@ loadDocumentByPHID($phid); - $question->attachRelated(); - - $doc = new PhabricatorSearchAbstractDocument(); - $doc->setPHID($question->getPHID()); - $doc->setDocumentType(PonderPHIDTypeQuestion::TYPECONST); - $doc->setDocumentTitle($question->getTitle()); - $doc->setDocumentCreated($question->getDateCreated()); - $doc->setDocumentModified($question->getDateModified()); + $doc = $this->newDocument($phid) + ->setDocumentTitle($question->getTitle()) + ->setDocumentCreated($question->getDateCreated()) + ->setDocumentModified($question->getDateModified()); $doc->addField( PhabricatorSearchField::FIELD_BODY, $question->getContent()); $doc->addRelationship( PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR, $question->getAuthorPHID(), PhabricatorPeoplePHIDTypeUser::TYPECONST, $question->getDateCreated()); - $comments = $question->getComments(); - foreach ($comments as $curcomment) { - $doc->addField( - PhabricatorSearchField::FIELD_COMMENT, - $curcomment->getContent()); - } - - $answers = $question->getAnswers(); - foreach ($answers as $curanswer) { - if (strlen($curanswer->getContent())) { - $doc->addField( - PhabricatorSearchField::FIELD_COMMENT, - $curanswer->getContent()); - } - - $answer_comments = $curanswer->getComments(); - foreach ($answer_comments as $curcomment) { + $answers = id(new PonderAnswerQuery()) + ->setViewer($this->getViewer()) + ->withQuestionIDs(array($question->getID())) + ->execute(); + foreach ($answers as $answer) { + if (strlen($answer->getContent())) { $doc->addField( PhabricatorSearchField::FIELD_COMMENT, - $curcomment->getContent()); + $answer->getContent()); } } - $subscribers = PhabricatorSubscribersQuery::loadSubscribersForPHID( - $question->getPHID()); - $handles = id(new PhabricatorObjectHandleData($subscribers)) - ->setViewer(PhabricatorUser::getOmnipotentUser()) - ->loadHandles(); + $this->indexTransactions( + $doc, + new PonderQuestionTransactionQuery(), + array($phid)); + $this->indexTransactions( + $doc, + new PonderAnswerTransactionQuery(), + mpull($answers, 'getPHID')); - foreach ($handles as $phid => $handle) { - $doc->addRelationship( - PhabricatorSearchRelationship::RELATIONSHIP_SUBSCRIBER, - $phid, - $handle->getType(), - $question->getDateModified()); // Bogus timestamp. - } + $this->indexSubscribers($doc); return $doc; } } diff --git a/src/applications/search/index/PhabricatorSearchDocumentIndexer.php b/src/applications/search/index/PhabricatorSearchDocumentIndexer.php index e0fa8afe6d..b7fddf568c 100644 --- a/src/applications/search/index/PhabricatorSearchDocumentIndexer.php +++ b/src/applications/search/index/PhabricatorSearchDocumentIndexer.php @@ -1,54 +1,108 @@ 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 = $this->getIndexableObject(); - $document = $object->loadOneWhere('phid = %s', $phid); - if (!$document) { - throw new Exception("Unable to load document by phid '{$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 $document; + return $object; } public function indexDocumentByPHID($phid) { try { $document = $this->buildAbstractDocumentByPHID($phid); $engine = PhabricatorSearchEngineSelector::newSelector()->newEngine(); try { $engine->reindexAbstractDocument($document); } catch (Exception $ex) { $phid = $document->getPHID(); $class = get_class($engine); phlog("Unable to index document {$phid} by engine {$class}."); phlog($ex); } } catch (Exception $ex) { $class = get_class($this); phlog("Unable to build document {$phid} by 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 indexTransactions( + PhabricatorSearchAbstractDocument $doc, + PhabricatorApplicationTransactionQuery $query, + array $phids) { + + $xactions = id(clone $query) + ->setViewer($this->getViewer()) + ->withObjectPHIDs($phids) + ->withTransactionTypes(array(PhabricatorTransactions::TYPE_COMMENT)) + ->execute(); + + foreach ($xactions as $xaction) { + if (!$xaction->hasComment()) { + continue; + } + + $comment = $xaction->getComment(); + $doc->addField( + PhabricatorSearchField::FIELD_COMMENT, + $comment->getContent()); + } + } + }