1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-18 21:02:41 +01:00

Inch toward using ApplicationSearch to power related objects

Summary:
Ref T4788. Fixes T9232. This moves the "search for stuff to attach to this object" flow away from hard-coding and legacy constants and toward something more modular and flexible.

It also adds an "Edit Commits..." action to Maniphest, resolving T9232. The behavior of the search for commits isn't great right now, but it will improve once these use real ApplicationSearch.

Test Plan: Edited a tasks' related commits, mocks, tasks, etc.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T4788, T9232

Differential Revision: https://secure.phabricator.com/D16189
This commit is contained in:
epriestley 2016-06-28 16:05:05 -07:00
parent 9827cc1622
commit 25cc90d632
19 changed files with 249 additions and 41 deletions

View file

@ -536,6 +536,7 @@ phutil_register_library_map(array(
'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 @@ phutil_register_library_map(array(
'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 @@ phutil_register_library_map(array(
'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 @@ phutil_register_library_map(array(
'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 @@ phutil_register_library_map(array(
'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 @@ phutil_register_library_map(array(
'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 @@ phutil_register_library_map(array(
'DifferentialRevisionPackageHeraldField' => 'DifferentialRevisionHeraldField',
'DifferentialRevisionPackageOwnerHeraldField' => 'DifferentialRevisionHeraldField',
'DifferentialRevisionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'DifferentialRevisionRelationshipSource' => 'PhabricatorObjectRelationshipSource',
'DifferentialRevisionRepositoryHeraldField' => 'DifferentialRevisionHeraldField',
'DifferentialRevisionRepositoryProjectsHeraldField' => 'DifferentialRevisionHeraldField',
'DifferentialRevisionRequiredActionResultBucket' => 'DifferentialRevisionResultBucket',
@ -4965,6 +4972,7 @@ phutil_register_library_map(array(
'DiffusionCommitParentsQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
'DiffusionCommitQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'DiffusionCommitRef' => 'Phobject',
'DiffusionCommitRelationshipSource' => 'PhabricatorObjectRelationshipSource',
'DiffusionCommitRemarkupRule' => 'PhabricatorObjectRemarkupRule',
'DiffusionCommitRemarkupRuleTestCase' => 'PhabricatorTestCase',
'DiffusionCommitRepositoryHeraldField' => 'DiffusionCommitHeraldField',
@ -5935,6 +5943,7 @@ phutil_register_library_map(array(
'ManiphestTaskPriorityHeraldField' => 'ManiphestTaskHeraldField',
'ManiphestTaskQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'ManiphestTaskRelationship' => 'PhabricatorObjectRelationship',
'ManiphestTaskRelationshipSource' => 'PhabricatorObjectRelationshipSource',
'ManiphestTaskResultListView' => 'ManiphestView',
'ManiphestTaskSearchEngine' => 'PhabricatorApplicationSearchEngine',
'ManiphestTaskStatus' => 'ManiphestConstants',
@ -7561,6 +7570,7 @@ phutil_register_library_map(array(
'PhabricatorObjectQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorObjectRelationship' => 'Phobject',
'PhabricatorObjectRelationshipList' => 'Phobject',
'PhabricatorObjectRelationshipSource' => 'Phobject',
'PhabricatorObjectRemarkupRule' => 'PhutilRemarkupRule',
'PhabricatorObjectSelectorDialog' => 'Phobject',
'PhabricatorOffsetPagedQuery' => 'PhabricatorQuery',
@ -8219,6 +8229,7 @@ phutil_register_library_map(array(
'PhabricatorSearchOrderField' => 'PhabricatorSearchField',
'PhabricatorSearchRelationship' => 'Phobject',
'PhabricatorSearchRelationshipController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchRelationshipSourceController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchResultBucket' => 'Phobject',
'PhabricatorSearchResultBucketGroup' => 'Phobject',
'PhabricatorSearchResultView' => 'AphrontView',
@ -8790,6 +8801,7 @@ phutil_register_library_map(array(
'PholioMockNameHeraldField' => 'PholioMockHeraldField',
'PholioMockPHIDType' => 'PhabricatorPHIDType',
'PholioMockQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PholioMockRelationshipSource' => 'PhabricatorObjectRelationshipSource',
'PholioMockSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PholioMockThumbGridView' => 'AphrontView',
'PholioMockViewController' => 'PholioController',

View file

@ -17,13 +17,6 @@ final class ManiphestTaskHasCommitRelationship
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 @@ final class ManiphestTaskHasCommitRelationship
return pht('Save Related Commits');
}
protected function newRelationshipSource() {
return new DiffusionCommitRelationshipSource();
}
}

View file

@ -33,4 +33,8 @@ final class ManiphestTaskHasMockRelationship
return pht('Save Related Mocks');
}
protected function newRelationshipSource() {
return new PholioMockRelationshipSource();
}
}

View file

@ -37,4 +37,8 @@ final class ManiphestTaskHasParentRelationship
return pht('Save Parent Tasks');
}
protected function newRelationshipSource() {
return new ManiphestTaskRelationshipSource();
}
}

View file

@ -33,4 +33,8 @@ final class ManiphestTaskHasRevisionRelationship
return pht('Save Related Revisions');
}
protected function newRelationshipSource() {
return new DifferentialRevisionRelationshipSource();
}
}

View file

@ -37,4 +37,8 @@ final class ManiphestTaskHasSubtaskRelationship
return pht('Save Subtasks');
}
protected function newRelationshipSource() {
return new ManiphestTaskRelationshipSource();
}
}

View file

@ -28,7 +28,6 @@ final class PhamePostFulltextEngine
$post->getPHID(),
PhabricatorPhamePostPHIDType::TYPECONST,
PhabricatorTime::getNow());
}
}

View file

@ -20,6 +20,14 @@ final class PholioMockFulltextEngine
$mock->getAuthorPHID(),
PhabricatorPeopleUserPHIDType::TYPECONST,
$mock->getDateCreated());
$document->addRelationship(
$mock->isClosed()
? PhabricatorSearchRelationship::RELATIONSHIP_CLOSED
: PhabricatorSearchRelationship::RELATIONSHIP_OPEN,
$mock->getPHID(),
PholioMockPHIDType::TYPECONST,
PhabricatorTime::getNow());
}
}

View file

@ -47,5 +47,13 @@ final class DiffusionCommitFulltextEngine
$repository->getPHID(),
PhabricatorRepositoryRepositoryPHIDType::TYPECONST,
$date_created);
$document->addRelationship(
$commit->isUnreachable()
? PhabricatorSearchRelationship::RELATIONSHIP_CLOSED
: PhabricatorSearchRelationship::RELATIONSHIP_OPEN,
$commit->getPHID(),
PhabricatorRepositoryCommitPHIDType::TYPECONST,
PhabricatorTime::getNow());
}
}

View file

@ -43,6 +43,8 @@ final class PhabricatorSearchApplication extends PhabricatorApplication {
'order/(?P<engine>[^/]+)/' => 'PhabricatorSearchOrderController',
'rel/(?P<relationshipKey>[^/]+)/(?P<sourcePHID>[^/]+)/'
=> 'PhabricatorSearchRelationshipController',
'source/(?P<relationshipKey>[^/]+)/(?P<sourcePHID>[^/]+)/'
=> 'PhabricatorSearchRelationshipSourceController',
),
);
}

View file

@ -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);
}
}

View file

@ -6,26 +6,12 @@ final class PhabricatorSearchRelationshipController
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 @@ final class PhabricatorSearchRelationshipController
$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 @@ final class PhabricatorSearchRelationshipController
->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)

View file

@ -0,0 +1,89 @@
<?php
final class PhabricatorSearchRelationshipSourceController
extends PhabricatorSearchBaseController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->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');
}
}

View file

@ -0,0 +1,12 @@
<?php
final class DifferentialRevisionRelationshipSource
extends PhabricatorObjectRelationshipSource {
public function getResultPHIDTypes() {
return array(
DifferentialRevisionPHIDType::TYPECONST,
);
}
}

View file

@ -0,0 +1,12 @@
<?php
final class DiffusionCommitRelationshipSource
extends PhabricatorObjectRelationshipSource {
public function getResultPHIDTypes() {
return array(
PhabricatorRepositoryCommitPHIDType::TYPECONST,
);
}
}

View file

@ -0,0 +1,12 @@
<?php
final class ManiphestTaskRelationshipSource
extends PhabricatorObjectRelationshipSource {
public function getResultPHIDTypes() {
return array(
ManiphestTaskPHIDType::TYPECONST,
);
}
}

View file

@ -47,6 +47,25 @@ abstract class PhabricatorObjectRelationship extends Phobject {
PhabricatorPolicyCapability::CAN_EDIT);
}
public function getRequiredRelationshipCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
);
}
final public function newSource() {
return $this->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);

View file

@ -0,0 +1,7 @@
<?php
abstract class PhabricatorObjectRelationshipSource extends Phobject {
abstract public function getResultPHIDTypes();
}

View file

@ -0,0 +1,12 @@
<?php
final class PholioMockRelationshipSource
extends PhabricatorObjectRelationshipSource {
public function getResultPHIDTypes() {
return array(
PholioMockPHIDType::TYPECONST,
);
}
}