diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -536,6 +536,7 @@ 'DifferentialRevisionPackageHeraldField' => 'applications/differential/herald/DifferentialRevisionPackageHeraldField.php', 'DifferentialRevisionPackageOwnerHeraldField' => 'applications/differential/herald/DifferentialRevisionPackageOwnerHeraldField.php', 'DifferentialRevisionQuery' => 'applications/differential/query/DifferentialRevisionQuery.php', + 'DifferentialRevisionRelationshipSource' => 'applications/search/relationship/DifferentialRevisionRelationshipSource.php', 'DifferentialRevisionRepositoryHeraldField' => 'applications/differential/herald/DifferentialRevisionRepositoryHeraldField.php', 'DifferentialRevisionRepositoryProjectsHeraldField' => 'applications/differential/herald/DifferentialRevisionRepositoryProjectsHeraldField.php', 'DifferentialRevisionRequiredActionResultBucket' => 'applications/differential/query/DifferentialRevisionRequiredActionResultBucket.php', @@ -614,6 +615,7 @@ 'DiffusionCommitParentsQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionCommitParentsQueryConduitAPIMethod.php', 'DiffusionCommitQuery' => 'applications/diffusion/query/DiffusionCommitQuery.php', 'DiffusionCommitRef' => 'applications/diffusion/data/DiffusionCommitRef.php', + 'DiffusionCommitRelationshipSource' => 'applications/search/relationship/DiffusionCommitRelationshipSource.php', 'DiffusionCommitRemarkupRule' => 'applications/diffusion/remarkup/DiffusionCommitRemarkupRule.php', 'DiffusionCommitRemarkupRuleTestCase' => 'applications/diffusion/remarkup/__tests__/DiffusionCommitRemarkupRuleTestCase.php', 'DiffusionCommitRepositoryHeraldField' => 'applications/diffusion/herald/DiffusionCommitRepositoryHeraldField.php', @@ -1442,6 +1444,7 @@ 'ManiphestTaskPriorityHeraldField' => 'applications/maniphest/herald/ManiphestTaskPriorityHeraldField.php', 'ManiphestTaskQuery' => 'applications/maniphest/query/ManiphestTaskQuery.php', 'ManiphestTaskRelationship' => 'applications/maniphest/relationship/ManiphestTaskRelationship.php', + 'ManiphestTaskRelationshipSource' => 'applications/search/relationship/ManiphestTaskRelationshipSource.php', 'ManiphestTaskResultListView' => 'applications/maniphest/view/ManiphestTaskResultListView.php', 'ManiphestTaskSearchEngine' => 'applications/maniphest/query/ManiphestTaskSearchEngine.php', 'ManiphestTaskStatus' => 'applications/maniphest/constants/ManiphestTaskStatus.php', @@ -2867,6 +2870,7 @@ 'PhabricatorObjectQuery' => 'applications/phid/query/PhabricatorObjectQuery.php', 'PhabricatorObjectRelationship' => 'applications/search/relationship/PhabricatorObjectRelationship.php', 'PhabricatorObjectRelationshipList' => 'applications/search/relationship/PhabricatorObjectRelationshipList.php', + 'PhabricatorObjectRelationshipSource' => 'applications/search/relationship/PhabricatorObjectRelationshipSource.php', 'PhabricatorObjectRemarkupRule' => 'infrastructure/markup/rule/PhabricatorObjectRemarkupRule.php', 'PhabricatorObjectSelectorDialog' => 'view/control/PhabricatorObjectSelectorDialog.php', 'PhabricatorOffsetPagedQuery' => 'infrastructure/query/PhabricatorOffsetPagedQuery.php', @@ -3397,6 +3401,7 @@ 'PhabricatorSearchOrderField' => 'applications/search/field/PhabricatorSearchOrderField.php', 'PhabricatorSearchRelationship' => 'applications/search/constants/PhabricatorSearchRelationship.php', 'PhabricatorSearchRelationshipController' => 'applications/search/controller/PhabricatorSearchRelationshipController.php', + 'PhabricatorSearchRelationshipSourceController' => 'applications/search/controller/PhabricatorSearchRelationshipSourceController.php', 'PhabricatorSearchResultBucket' => 'applications/search/buckets/PhabricatorSearchResultBucket.php', 'PhabricatorSearchResultBucketGroup' => 'applications/search/buckets/PhabricatorSearchResultBucketGroup.php', 'PhabricatorSearchResultView' => 'applications/search/view/PhabricatorSearchResultView.php', @@ -3870,6 +3875,7 @@ 'PholioMockNameHeraldField' => 'applications/pholio/herald/PholioMockNameHeraldField.php', 'PholioMockPHIDType' => 'applications/pholio/phid/PholioMockPHIDType.php', 'PholioMockQuery' => 'applications/pholio/query/PholioMockQuery.php', + 'PholioMockRelationshipSource' => 'applications/search/relationship/PholioMockRelationshipSource.php', 'PholioMockSearchEngine' => 'applications/pholio/query/PholioMockSearchEngine.php', 'PholioMockThumbGridView' => 'applications/pholio/view/PholioMockThumbGridView.php', 'PholioMockViewController' => 'applications/pholio/controller/PholioMockViewController.php', @@ -4887,6 +4893,7 @@ 'DifferentialRevisionPackageHeraldField' => 'DifferentialRevisionHeraldField', 'DifferentialRevisionPackageOwnerHeraldField' => 'DifferentialRevisionHeraldField', 'DifferentialRevisionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', + 'DifferentialRevisionRelationshipSource' => 'PhabricatorObjectRelationshipSource', 'DifferentialRevisionRepositoryHeraldField' => 'DifferentialRevisionHeraldField', 'DifferentialRevisionRepositoryProjectsHeraldField' => 'DifferentialRevisionHeraldField', 'DifferentialRevisionRequiredActionResultBucket' => 'DifferentialRevisionResultBucket', @@ -4965,6 +4972,7 @@ 'DiffusionCommitParentsQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod', 'DiffusionCommitQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'DiffusionCommitRef' => 'Phobject', + 'DiffusionCommitRelationshipSource' => 'PhabricatorObjectRelationshipSource', 'DiffusionCommitRemarkupRule' => 'PhabricatorObjectRemarkupRule', 'DiffusionCommitRemarkupRuleTestCase' => 'PhabricatorTestCase', 'DiffusionCommitRepositoryHeraldField' => 'DiffusionCommitHeraldField', @@ -5935,6 +5943,7 @@ 'ManiphestTaskPriorityHeraldField' => 'ManiphestTaskHeraldField', 'ManiphestTaskQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'ManiphestTaskRelationship' => 'PhabricatorObjectRelationship', + 'ManiphestTaskRelationshipSource' => 'PhabricatorObjectRelationshipSource', 'ManiphestTaskResultListView' => 'ManiphestView', 'ManiphestTaskSearchEngine' => 'PhabricatorApplicationSearchEngine', 'ManiphestTaskStatus' => 'ManiphestConstants', @@ -7561,6 +7570,7 @@ 'PhabricatorObjectQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorObjectRelationship' => 'Phobject', 'PhabricatorObjectRelationshipList' => 'Phobject', + 'PhabricatorObjectRelationshipSource' => 'Phobject', 'PhabricatorObjectRemarkupRule' => 'PhutilRemarkupRule', 'PhabricatorObjectSelectorDialog' => 'Phobject', 'PhabricatorOffsetPagedQuery' => 'PhabricatorQuery', @@ -8219,6 +8229,7 @@ 'PhabricatorSearchOrderField' => 'PhabricatorSearchField', 'PhabricatorSearchRelationship' => 'Phobject', 'PhabricatorSearchRelationshipController' => 'PhabricatorSearchBaseController', + 'PhabricatorSearchRelationshipSourceController' => 'PhabricatorSearchBaseController', 'PhabricatorSearchResultBucket' => 'Phobject', 'PhabricatorSearchResultBucketGroup' => 'Phobject', 'PhabricatorSearchResultView' => 'AphrontView', @@ -8790,6 +8801,7 @@ 'PholioMockNameHeraldField' => 'PholioMockHeraldField', 'PholioMockPHIDType' => 'PhabricatorPHIDType', 'PholioMockQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', + 'PholioMockRelationshipSource' => 'PhabricatorObjectRelationshipSource', 'PholioMockSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PholioMockThumbGridView' => 'AphrontView', 'PholioMockViewController' => 'PholioController', diff --git a/src/applications/maniphest/relationship/ManiphestTaskHasCommitRelationship.php b/src/applications/maniphest/relationship/ManiphestTaskHasCommitRelationship.php --- a/src/applications/maniphest/relationship/ManiphestTaskHasCommitRelationship.php +++ b/src/applications/maniphest/relationship/ManiphestTaskHasCommitRelationship.php @@ -17,13 +17,6 @@ return 'fa-code'; } - public function shouldAppearInActionMenu() { - // TODO: For now, the default search for commits is not very good, so - // it is hard to find objects to link to. Until that works better, just - // hide this item. - return false; - } - public function canRelateObjects($src, $dst) { return ($dst instanceof PhabricatorRepositoryCommit); } @@ -40,4 +33,8 @@ return pht('Save Related Commits'); } + protected function newRelationshipSource() { + return new DiffusionCommitRelationshipSource(); + } + } diff --git a/src/applications/maniphest/relationship/ManiphestTaskHasMockRelationship.php b/src/applications/maniphest/relationship/ManiphestTaskHasMockRelationship.php --- a/src/applications/maniphest/relationship/ManiphestTaskHasMockRelationship.php +++ b/src/applications/maniphest/relationship/ManiphestTaskHasMockRelationship.php @@ -33,4 +33,8 @@ return pht('Save Related Mocks'); } + protected function newRelationshipSource() { + return new PholioMockRelationshipSource(); + } + } diff --git a/src/applications/maniphest/relationship/ManiphestTaskHasParentRelationship.php b/src/applications/maniphest/relationship/ManiphestTaskHasParentRelationship.php --- a/src/applications/maniphest/relationship/ManiphestTaskHasParentRelationship.php +++ b/src/applications/maniphest/relationship/ManiphestTaskHasParentRelationship.php @@ -37,4 +37,8 @@ return pht('Save Parent Tasks'); } + protected function newRelationshipSource() { + return new ManiphestTaskRelationshipSource(); + } + } diff --git a/src/applications/maniphest/relationship/ManiphestTaskHasRevisionRelationship.php b/src/applications/maniphest/relationship/ManiphestTaskHasRevisionRelationship.php --- a/src/applications/maniphest/relationship/ManiphestTaskHasRevisionRelationship.php +++ b/src/applications/maniphest/relationship/ManiphestTaskHasRevisionRelationship.php @@ -33,4 +33,8 @@ return pht('Save Related Revisions'); } + protected function newRelationshipSource() { + return new DifferentialRevisionRelationshipSource(); + } + } diff --git a/src/applications/maniphest/relationship/ManiphestTaskHasSubtaskRelationship.php b/src/applications/maniphest/relationship/ManiphestTaskHasSubtaskRelationship.php --- a/src/applications/maniphest/relationship/ManiphestTaskHasSubtaskRelationship.php +++ b/src/applications/maniphest/relationship/ManiphestTaskHasSubtaskRelationship.php @@ -37,4 +37,8 @@ return pht('Save Subtasks'); } + protected function newRelationshipSource() { + return new ManiphestTaskRelationshipSource(); + } + } diff --git a/src/applications/phame/search/PhamePostFulltextEngine.php b/src/applications/phame/search/PhamePostFulltextEngine.php --- a/src/applications/phame/search/PhamePostFulltextEngine.php +++ b/src/applications/phame/search/PhamePostFulltextEngine.php @@ -28,7 +28,6 @@ $post->getPHID(), PhabricatorPhamePostPHIDType::TYPECONST, PhabricatorTime::getNow()); - } } diff --git a/src/applications/pholio/search/PholioMockFulltextEngine.php b/src/applications/pholio/search/PholioMockFulltextEngine.php --- a/src/applications/pholio/search/PholioMockFulltextEngine.php +++ b/src/applications/pholio/search/PholioMockFulltextEngine.php @@ -20,6 +20,14 @@ $mock->getAuthorPHID(), PhabricatorPeopleUserPHIDType::TYPECONST, $mock->getDateCreated()); + + $document->addRelationship( + $mock->isClosed() + ? PhabricatorSearchRelationship::RELATIONSHIP_CLOSED + : PhabricatorSearchRelationship::RELATIONSHIP_OPEN, + $mock->getPHID(), + PholioMockPHIDType::TYPECONST, + PhabricatorTime::getNow()); } } diff --git a/src/applications/repository/search/DiffusionCommitFulltextEngine.php b/src/applications/repository/search/DiffusionCommitFulltextEngine.php --- a/src/applications/repository/search/DiffusionCommitFulltextEngine.php +++ b/src/applications/repository/search/DiffusionCommitFulltextEngine.php @@ -47,5 +47,13 @@ $repository->getPHID(), PhabricatorRepositoryRepositoryPHIDType::TYPECONST, $date_created); + + $document->addRelationship( + $commit->isUnreachable() + ? PhabricatorSearchRelationship::RELATIONSHIP_CLOSED + : PhabricatorSearchRelationship::RELATIONSHIP_OPEN, + $commit->getPHID(), + PhabricatorRepositoryCommitPHIDType::TYPECONST, + PhabricatorTime::getNow()); } } diff --git a/src/applications/search/application/PhabricatorSearchApplication.php b/src/applications/search/application/PhabricatorSearchApplication.php --- a/src/applications/search/application/PhabricatorSearchApplication.php +++ b/src/applications/search/application/PhabricatorSearchApplication.php @@ -43,6 +43,8 @@ 'order/(?P[^/]+)/' => 'PhabricatorSearchOrderController', 'rel/(?P[^/]+)/(?P[^/]+)/' => 'PhabricatorSearchRelationshipController', + 'source/(?P[^/]+)/(?P[^/]+)/' + => 'PhabricatorSearchRelationshipSourceController', ), ); } diff --git a/src/applications/search/controller/PhabricatorSearchBaseController.php b/src/applications/search/controller/PhabricatorSearchBaseController.php --- a/src/applications/search/controller/PhabricatorSearchBaseController.php +++ b/src/applications/search/controller/PhabricatorSearchBaseController.php @@ -2,10 +2,41 @@ abstract class PhabricatorSearchBaseController extends PhabricatorController { + const ACTION_ATTACH = 'attach'; const ACTION_MERGE = 'merge'; const ACTION_DEPENDENCIES = 'dependencies'; const ACTION_BLOCKS = 'blocks'; const ACTION_EDGE = 'edge'; + protected function loadRelationshipObject() { + $request = $this->getRequest(); + $viewer = $this->getViewer(); + + $phid = $request->getURIData('sourcePHID'); + + return id(new PhabricatorObjectQuery()) + ->setViewer($viewer) + ->withPHIDs(array($phid)) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->executeOne(); + } + + protected function loadRelationship($object) { + $request = $this->getRequest(); + $viewer = $this->getViewer(); + + $relationship_key = $request->getURIData('relationshipKey'); + + $list = PhabricatorObjectRelationshipList::newForObject( + $viewer, + $object); + + return $list->getRelationship($relationship_key); + } + } diff --git a/src/applications/search/controller/PhabricatorSearchRelationshipController.php b/src/applications/search/controller/PhabricatorSearchRelationshipController.php --- a/src/applications/search/controller/PhabricatorSearchRelationshipController.php +++ b/src/applications/search/controller/PhabricatorSearchRelationshipController.php @@ -6,26 +6,12 @@ public function handleRequest(AphrontRequest $request) { $viewer = $this->getViewer(); - $phid = $request->getURIData('sourcePHID'); - $object = id(new PhabricatorObjectQuery()) - ->setViewer($viewer) - ->withPHIDs(array($phid)) - ->requireCapabilities( - array( - PhabricatorPolicyCapability::CAN_VIEW, - PhabricatorPolicyCapability::CAN_EDIT, - )) - ->executeOne(); + $object = $this->loadRelationshipObject(); if (!$object) { return new Aphront404Response(); } - $list = PhabricatorObjectRelationshipList::newForObject( - $viewer, - $object); - - $relationship_key = $request->getURIData('relationshipKey'); - $relationship = $list->getRelationship($relationship_key); + $relationship = $this->loadRelationship($object); if (!$relationship) { return new Aphront404Response(); } @@ -135,21 +121,7 @@ $dialog_button = $relationship->getDialogButtonText(); $dialog_instructions = $relationship->getDialogInstructionsText(); - // TODO: Remove this, this is just legacy support. - $legacy_kinds = array( - ManiphestTaskHasCommitEdgeType::EDGECONST => 'CMIT', - ManiphestTaskHasMockEdgeType::EDGECONST => 'MOCK', - ManiphestTaskHasRevisionEdgeType::EDGECONST => 'DREV', - ManiphestTaskDependsOnTaskEdgeType::EDGECONST => 'TASK', - ManiphestTaskDependedOnByTaskEdgeType::EDGECONST => 'TASK', - ); - - $edge_type = $relationship->getEdgeConstant(); - $legacy_kind = idx($legacy_kinds, $edge_type); - if (!$legacy_kind) { - throw new Exception( - pht('Only specific legacy relationships are supported!')); - } + $source_uri = $relationship->getSourceURI($object); return id(new PhabricatorObjectSelectorDialog()) ->setUser($viewer) @@ -157,9 +129,9 @@ ->setHandles($handles) ->setFilters($filters) ->setSelectedFilter('created') - ->setExcluded($phid) + ->setExcluded($src_phid) ->setCancelURI($done_uri) - ->setSearchURI("/search/select/{$legacy_kind}/edge/") + ->setSearchURI($source_uri) ->setTitle($dialog_title) ->setHeader($dialog_header) ->setButtonText($dialog_button) diff --git a/src/applications/search/controller/PhabricatorSearchRelationshipSourceController.php b/src/applications/search/controller/PhabricatorSearchRelationshipSourceController.php new file mode 100644 --- /dev/null +++ b/src/applications/search/controller/PhabricatorSearchRelationshipSourceController.php @@ -0,0 +1,89 @@ +getViewer(); + + $object = $this->loadRelationshipObject(); + if (!$object) { + return new Aphront404Response(); + } + + $relationship = $this->loadRelationship($object); + if (!$relationship) { + return new Aphront404Response(); + } + + $source = $relationship->newSource(); + $query = new PhabricatorSavedQuery(); + + $action = $request->getURIData('action'); + $query_str = $request->getStr('query'); + $filter = $request->getStr('filter'); + + $query->setEngineClassName('PhabricatorSearchApplicationSearchEngine'); + $query->setParameter('query', $query_str); + + $types = $source->getResultPHIDTypes(); + $query->setParameter('types', $types); + + $status_open = PhabricatorSearchRelationship::RELATIONSHIP_OPEN; + + switch ($filter) { + case 'assigned': + $query->setParameter('ownerPHIDs', array($viewer->getPHID())); + $query->setParameter('statuses', array($status_open)); + break; + case 'created'; + $query->setParameter('authorPHIDs', array($viewer->getPHID())); + $query->setParameter('statuses', array($status_open)); + break; + case 'open': + $query->setParameter('statuses', array($status_open)); + break; + } + + $query->setParameter('excludePHIDs', array($request->getStr('exclude'))); + + $capabilities = $relationship->getRequiredRelationshipCapabilities(); + + $results = id(new PhabricatorSearchDocumentQuery()) + ->setViewer($viewer) + ->requireObjectCapabilities($capabilities) + ->withSavedQuery($query) + ->setOffset(0) + ->setLimit(100) + ->execute(); + + $phids = array_fill_keys(mpull($results, 'getPHID'), true); + $phids += $this->queryObjectNames($query_str, $capabilities); + + $phids = array_keys($phids); + $handles = $viewer->loadHandles($phids); + + $data = array(); + foreach ($handles as $handle) { + $view = new PhabricatorHandleObjectSelectorDataView($handle); + $data[] = $view->renderData(); + } + + return id(new AphrontAjaxResponse())->setContent($data); + } + + private function queryObjectNames($query, $capabilities) { + $request = $this->getRequest(); + $viewer = $request->getUser(); + + $objects = id(new PhabricatorObjectQuery()) + ->setViewer($viewer) + ->requireCapabilities($capabilities) + ->withTypes(array($request->getURIData('type'))) + ->withNames(array($query)) + ->execute(); + + return mpull($objects, 'getPHID'); + } + +} diff --git a/src/applications/search/relationship/DifferentialRevisionRelationshipSource.php b/src/applications/search/relationship/DifferentialRevisionRelationshipSource.php new file mode 100644 --- /dev/null +++ b/src/applications/search/relationship/DifferentialRevisionRelationshipSource.php @@ -0,0 +1,12 @@ +newRelationshipSource(); + } + + abstract protected function newRelationshipSource(); + + final public function getSourceURI($object) { + $relationship_key = $this->getRelationshipConstant(); + $object_phid = $object->getPHID(); + + return "/search/source/{$relationship_key}/{$object_phid}/"; + } + final public function newAction($object) { $is_enabled = $this->isActionEnabled($object); $action_uri = $this->getActionURI($object); diff --git a/src/applications/search/relationship/PhabricatorObjectRelationshipSource.php b/src/applications/search/relationship/PhabricatorObjectRelationshipSource.php new file mode 100644 --- /dev/null +++ b/src/applications/search/relationship/PhabricatorObjectRelationshipSource.php @@ -0,0 +1,7 @@ +