diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 7d2641f5a0..c7626bcc20 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1362,6 +1362,7 @@ phutil_register_library_map(array( 'PhabricatorSearchConfigOptions' => 'applications/search/config/PhabricatorSearchConfigOptions.php', 'PhabricatorSearchController' => 'applications/search/controller/PhabricatorSearchController.php', 'PhabricatorSearchDAO' => 'applications/search/storage/PhabricatorSearchDAO.php', + 'PhabricatorSearchDeleteController' => 'applications/search/controller/PhabricatorSearchDeleteController.php', 'PhabricatorSearchDocument' => 'applications/search/storage/document/PhabricatorSearchDocument.php', 'PhabricatorSearchDocumentField' => 'applications/search/storage/document/PhabricatorSearchDocumentField.php', 'PhabricatorSearchDocumentIndexer' => 'applications/search/index/PhabricatorSearchDocumentIndexer.php', @@ -3147,6 +3148,7 @@ phutil_register_library_map(array( 'PhabricatorSearchConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorSearchController' => 'PhabricatorSearchBaseController', 'PhabricatorSearchDAO' => 'PhabricatorLiskDAO', + 'PhabricatorSearchDeleteController' => 'PhabricatorSearchBaseController', 'PhabricatorSearchDocument' => 'PhabricatorSearchDAO', 'PhabricatorSearchDocumentField' => 'PhabricatorSearchDAO', 'PhabricatorSearchDocumentRelationship' => 'PhabricatorSearchDAO', diff --git a/src/applications/paste/controller/PhabricatorPasteQueriesController.php b/src/applications/paste/controller/PhabricatorPasteQueriesController.php index 6f59ffcfa7..11a71a0340 100644 --- a/src/applications/paste/controller/PhabricatorPasteQueriesController.php +++ b/src/applications/paste/controller/PhabricatorPasteQueriesController.php @@ -38,6 +38,11 @@ final class PhabricatorPasteQueriesController $item->setBarColor('grey'); } else { $item->addIcon('none', $date_created); + $item->addAction( + id(new PhabricatorMenuItemView()) + ->setIcon('delete') + ->setHref('/search/delete/'.$named_query->getQueryKey().'/') + ->setWorkflow(true)); $item->addAction( id(new PhabricatorMenuItemView()) ->setIcon('edit') diff --git a/src/applications/paste/controller/PhabricatorPasteViewController.php b/src/applications/paste/controller/PhabricatorPasteViewController.php index 2462f452cc..4d218e9250 100644 --- a/src/applications/paste/controller/PhabricatorPasteViewController.php +++ b/src/applications/paste/controller/PhabricatorPasteViewController.php @@ -2,13 +2,12 @@ final class PhabricatorPasteViewController extends PhabricatorPasteController { + private $id; + public function shouldAllowPublic() { return true; } - private $id; - private $handles; - public function willProcessRequest(array $data) { $this->id = $data['id']; } diff --git a/src/applications/paste/query/PhabricatorPasteSearchEngine.php b/src/applications/paste/query/PhabricatorPasteSearchEngine.php index c96fed44ac..305a15968d 100644 --- a/src/applications/paste/query/PhabricatorPasteSearchEngine.php +++ b/src/applications/paste/query/PhabricatorPasteSearchEngine.php @@ -84,6 +84,10 @@ final class PhabricatorPasteSearchEngine return '/paste/query/'.$query->getQueryKey().'/'; } + public function getQueryManagementURI() { + return '/paste/savedqueries/'; + } + public function getBuiltinQueryNames() { $names = array( 'all' => pht('All Pastes'), @@ -99,6 +103,7 @@ final class PhabricatorPasteSearchEngine public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); + $query->setQueryKey($query_key); switch ($query_key) { case 'all': diff --git a/src/applications/search/application/PhabricatorApplicationSearch.php b/src/applications/search/application/PhabricatorApplicationSearch.php index 26e20148f4..7e6d027ebe 100644 --- a/src/applications/search/application/PhabricatorApplicationSearch.php +++ b/src/applications/search/application/PhabricatorApplicationSearch.php @@ -35,6 +35,7 @@ final class PhabricatorApplicationSearch extends PhabricatorApplication { 'hovercard/(?Pretrieve|test)/' => 'PhabricatorSearchHovercardController', 'edit/(?P[^/]+)/' => 'PhabricatorSearchEditController', + 'delete/(?P[^/]+)/' => 'PhabricatorSearchDeleteController', ), ); } diff --git a/src/applications/search/controller/PhabricatorSearchDeleteController.php b/src/applications/search/controller/PhabricatorSearchDeleteController.php new file mode 100644 index 0000000000..3745d06d75 --- /dev/null +++ b/src/applications/search/controller/PhabricatorSearchDeleteController.php @@ -0,0 +1,60 @@ +queryKey = idx($data, 'queryKey'); + } + + public function processRequest() { + $request = $this->getRequest(); + $user = $request->getUser(); + + $saved_query = id(new PhabricatorSavedQueryQuery()) + ->setViewer($user) + ->withQueryKeys(array($this->queryKey)) + ->executeOne(); + + if (!$saved_query) { + return new Aphront404Response(); + } + + $engine = $saved_query->newEngine(); + + $named_query = id(new PhabricatorNamedQueryQuery()) + ->setViewer($user) + ->withQueryKeys(array($saved_query->getQueryKey())) + ->withUserPHIDs(array($user->getPHID())) + ->executeOne(); + if (!$named_query) { + return new Aphront404Response(); + } + + $return_uri = $engine->getQueryManagementURI(); + + if ($request->isDialogFormPost()) { + $named_query->delete(); + return id(new AphrontRedirectResponse())->setURI($return_uri); + } + + $dialog = id(new AphrontDialogView()) + ->setUser($user) + ->setTitle(pht("Really Delete Query?")) + ->appendChild( + pht( + 'Really delete the query "%s"? You can not undo this. Remember '. + 'all the great times you had filtering results together?', + $named_query->getQueryName())) + ->addCancelButton($return_uri) + ->addSubmitButton(pht('Delete Query')); + + return id(new AphrontDialogResponse())->setDialog($dialog); + } + +} diff --git a/src/applications/search/controller/PhabricatorSearchEditController.php b/src/applications/search/controller/PhabricatorSearchEditController.php index a2cbfcc33b..b4b448cbd1 100644 --- a/src/applications/search/controller/PhabricatorSearchEditController.php +++ b/src/applications/search/controller/PhabricatorSearchEditController.php @@ -25,7 +25,10 @@ final class PhabricatorSearchEditController return new Aphront404Response(); } - $engine = $saved_query->newEngine(); + $engine = $saved_query->newEngine()->setViewer($user); + + $complete_uri = $engine->getQueryManagementURI(); + $cancel_uri = $complete_uri; $named_query = id(new PhabricatorNamedQueryQuery()) ->setViewer($user) @@ -37,6 +40,11 @@ final class PhabricatorSearchEditController ->setUserPHID($user->getPHID()) ->setQueryKey($saved_query->getQueryKey()) ->setEngineClassName($saved_query->getEngineClassName()); + + // If we haven't saved the query yet, this is a "Save..." operation, so + // take the user back to the query if they cancel instead of back to the + // management interface. + $cancel_uri = $engine->getQueryResultsPageURI($saved_query); } $e_name = true; @@ -53,9 +61,7 @@ final class PhabricatorSearchEditController if (!$errors) { $named_query->save(); - - $results_uri = $engine->getQueryResultsPageURI($saved_query); - return id(new AphrontRedirectResponse())->setURI($results_uri); + return id(new AphrontRedirectResponse())->setURI($complete_uri); } } @@ -76,7 +82,8 @@ final class PhabricatorSearchEditController $form->appendChild( id(new AphrontFormSubmitControl()) - ->setValue(pht('Save Query'))); + ->setValue(pht('Save Query')) + ->addCancelButton($cancel_uri)); if ($named_query->getID()) { $title = pht('Edit Saved Query'); diff --git a/src/applications/search/engine/PhabricatorApplicationSearchEngine.php b/src/applications/search/engine/PhabricatorApplicationSearchEngine.php index ae72c5545a..07a3676009 100644 --- a/src/applications/search/engine/PhabricatorApplicationSearchEngine.php +++ b/src/applications/search/engine/PhabricatorApplicationSearchEngine.php @@ -5,6 +5,7 @@ * creating and storing saved queries. * * @task builtin Builtin Queries + * @task uri Query URIs * * @group search */ @@ -57,10 +58,21 @@ abstract class PhabricatorApplicationSearchEngine { * * @param PhabricatorSavedQuery The query to build a URI for. * @return string URI where the query can be executed. + * @task uri */ abstract public function getQueryResultsPageURI(PhabricatorSavedQuery $query); + /** + * Return an application URI for query management. This is used when, e.g., + * a query deletion operation is cancelled. + * + * @return string URI where queries can be managed. + * @task uri + */ + abstract public function getQueryManagementURI(); + + public function newSavedQuery() { return id(new PhabricatorSavedQuery()) ->setEngineClassName(get_class($this));