@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator

Add ability to name saved queries.

Summary: Can name saved queries.

Test Plan: Try naming some saved queries using the form.

Reviewers: epriestley

CC: aran, Korvin, AnhNhan

Maniphest Tasks: T2625

Differential Revision: https://secure.phabricator.com/D5878

Conflicts:

src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php

authored by

Bryan Cuccioli and committed by
epriestley
3c1f402d c36f44a0

+182 -2
+12
resources/sql/patches/20130508.search_namedquery.sql
··· 1 + CREATE TABLE {$NAMESPACE}_search.search_namedquery ( 2 + id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, 3 + userPHID VARCHAR(64) NOT NULL COLLATE utf8_bin, 4 + engineClassName VARCHAR(128) NOT NULL COLLATE utf8_bin, 5 + queryName VARCHAR(255) NOT NULL COLLATE utf8_bin, 6 + queryKey VARCHAR(12) NOT NULL COLLATE utf8_bin, 7 + dateCreated INT(10) UNSIGNED NOT NULL, 8 + dateModified INT(10) UNSIGNED NOT NULL, 9 + UNIQUE KEY `key_userquery` (userPHID, engineClassName, queryKey), 10 + PRIMARY KEY(id) 11 + ) 12 + ENGINE=InnoDB, COLLATE utf8_general_ci
+7
src/__phutil_library_map__.php
··· 1115 1115 'PhabricatorMustVerifyEmailController' => 'applications/auth/controller/PhabricatorMustVerifyEmailController.php', 1116 1116 'PhabricatorMySQLConfigOptions' => 'applications/config/option/PhabricatorMySQLConfigOptions.php', 1117 1117 'PhabricatorMySQLFileStorageEngine' => 'applications/files/engine/PhabricatorMySQLFileStorageEngine.php', 1118 + 'PhabricatorNamedQuery' => 'applications/search/storage/PhabricatorNamedQuery.php', 1118 1119 'PhabricatorNoteExample' => 'applications/uiexample/examples/PhabricatorNoteExample.php', 1119 1120 'PhabricatorNotificationBuilder' => 'applications/notification/builder/PhabricatorNotificationBuilder.php', 1120 1121 'PhabricatorNotificationClearController' => 'applications/notification/controller/PhabricatorNotificationClearController.php', ··· 1198 1199 'PhabricatorPasteDAO' => 'applications/paste/storage/PhabricatorPasteDAO.php', 1199 1200 'PhabricatorPasteEditController' => 'applications/paste/controller/PhabricatorPasteEditController.php', 1200 1201 'PhabricatorPasteListController' => 'applications/paste/controller/PhabricatorPasteListController.php', 1202 + 'PhabricatorPasteQueriesController' => 'applications/paste/controller/PhabricatorPasteQueriesController.php', 1201 1203 'PhabricatorPasteQuery' => 'applications/paste/query/PhabricatorPasteQuery.php', 1202 1204 'PhabricatorPasteRemarkupRule' => 'applications/paste/remarkup/PhabricatorPasteRemarkupRule.php', 1203 1205 'PhabricatorPasteSearchEngine' => 'applications/paste/query/PhabricatorPasteSearchEngine.php', ··· 1331 1333 'PhabricatorSearchIndexer' => 'applications/search/index/PhabricatorSearchIndexer.php', 1332 1334 'PhabricatorSearchManagementIndexWorkflow' => 'applications/search/management/PhabricatorSearchManagementIndexWorkflow.php', 1333 1335 'PhabricatorSearchManagementWorkflow' => 'applications/search/management/PhabricatorSearchManagementWorkflow.php', 1336 + 'PhabricatorSearchNameController' => 'applications/search/controller/PhabricatorSearchNameController.php', 1334 1337 'PhabricatorSearchQuery' => 'applications/search/storage/PhabricatorSearchQuery.php', 1335 1338 'PhabricatorSearchRelationship' => 'applications/search/constants/PhabricatorSearchRelationship.php', 1336 1339 'PhabricatorSearchResultView' => 'applications/search/view/PhabricatorSearchResultView.php', ··· 2828 2831 'PhabricatorMustVerifyEmailController' => 'PhabricatorAuthController', 2829 2832 'PhabricatorMySQLConfigOptions' => 'PhabricatorApplicationConfigOptions', 2830 2833 'PhabricatorMySQLFileStorageEngine' => 'PhabricatorFileStorageEngine', 2834 + 'PhabricatorNamedQuery' => 'PhabricatorSearchDAO', 2831 2835 'PhabricatorNoteExample' => 'PhabricatorUIExample', 2832 2836 'PhabricatorNotificationClearController' => 'PhabricatorNotificationController', 2833 2837 'PhabricatorNotificationConfigOptions' => 'PhabricatorApplicationConfigOptions', ··· 2908 2912 'PhabricatorPasteDAO' => 'PhabricatorLiskDAO', 2909 2913 'PhabricatorPasteEditController' => 'PhabricatorPasteController', 2910 2914 'PhabricatorPasteListController' => 'PhabricatorPasteController', 2915 + 'PhabricatorPasteQueriesController' => 'PhabricatorPasteController', 2911 2916 'PhabricatorPasteQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 2912 2917 'PhabricatorPasteRemarkupRule' => 'PhabricatorRemarkupRuleObject', 2913 2918 'PhabricatorPasteSearchEngine' => 'PhabricatorApplicationSearchEngine', ··· 3038 3043 'PhabricatorSearchHovercardController' => 'PhabricatorSearchBaseController', 3039 3044 'PhabricatorSearchManagementIndexWorkflow' => 'PhabricatorSearchManagementWorkflow', 3040 3045 'PhabricatorSearchManagementWorkflow' => 'PhutilArgumentWorkflow', 3046 + 'PhabricatorSearchNameController' => 'PhabricatorSearchBaseController', 3041 3047 'PhabricatorSearchQuery' => 'PhabricatorSearchDAO', 3042 3048 'PhabricatorSearchResultView' => 'AphrontView', 3043 3049 'PhabricatorSearchSelectController' => 'PhabricatorSearchBaseController', ··· 3452 3458 'ReleephBranchEditor' => 'PhabricatorEditor', 3453 3459 'ReleephBranchNamePreviewController' => 'PhabricatorController', 3454 3460 'ReleephBranchPreviewView' => 'AphrontFormControl', 3461 + 'ReleephBranchTemplate' => 'PhabricatorMarkupInterface', 3455 3462 'ReleephBranchViewController' => 'ReleephController', 3456 3463 'ReleephCommitFinderException' => 'Exception', 3457 3464 'ReleephCommitMessageFieldSpecification' => 'ReleephFieldSpecification',
+1
src/applications/paste/application/PhabricatorApplicationPaste.php
··· 37 37 'edit/(?P<id>[1-9]\d*)/' => 'PhabricatorPasteEditController', 38 38 'filter/(?P<filter>\w+)/' => 'PhabricatorPasteListController', 39 39 'query/(?P<queryKey>\w+)/'=> 'PhabricatorPasteListController', 40 + 'savedqueries/' => 'PhabricatorPasteQueriesController', 40 41 ), 41 42 ); 42 43 }
+4
src/applications/paste/controller/PhabricatorPasteController.php
··· 18 18 if ($user->isLoggedIn()) { 19 19 $nav->addFilter('my', pht('My Pastes')); 20 20 } 21 + 22 + $nav->addLabel(pht('Search')); 21 23 $nav->addFilter('advanced', pht('Advanced Search')); 24 + $nav->addFilter('', pht('Saved Queries'), 25 + $this->getApplicationURI('/savedqueries/')); 22 26 23 27 $nav->selectFilter($filter, 'all'); 24 28
+64
src/applications/paste/controller/PhabricatorPasteQueriesController.php
··· 1 + <?php 2 + 3 + final class PhabricatorPasteQueriesController 4 + extends PhabricatorPasteController { 5 + 6 + public function processRequest() { 7 + $request = $this->getRequest(); 8 + $user = $request->getUser(); 9 + 10 + $nav = $this->buildSideNavView(""); 11 + $filter = $nav->getSelectedFilter(); 12 + 13 + $table = new PhabricatorNamedQuery(); 14 + $conn = $table->establishConnection('r'); 15 + $data = queryfx_all( 16 + $conn, 17 + 'SELECT * FROM %T WHERE userPHID=%s AND engineClassName=%s', 18 + $table->getTableName(), 19 + $user->getPHID(), 20 + 'PhabricatorPasteSearchEngine'); 21 + 22 + $list = new PhabricatorObjectItemListView(); 23 + $list->setUser($user); 24 + 25 + foreach ($data as $key => $saved_query) { 26 + $date_created = phabricator_datetime($saved_query["dateCreated"], $user); 27 + $item = id(new PhabricatorObjectItemView()) 28 + ->setHeader($saved_query["queryName"]) 29 + ->setHref('/paste/query/'.$saved_query["queryKey"].'/') 30 + ->addByline(pht('Date Created: ').$date_created); 31 + $list->addItem($item); 32 + } 33 + 34 + $pager = new AphrontCursorPagerView(); 35 + $pager->readFromRequest($request); 36 + 37 + $list->setPager($pager); 38 + 39 + $list->setNoDataString(pht("No results found for this query.")); 40 + 41 + $nav->appendChild( 42 + array( 43 + $list, 44 + )); 45 + 46 + $crumbs = $this 47 + ->buildApplicationCrumbs($nav) 48 + ->addCrumb( 49 + id(new PhabricatorCrumbView()) 50 + ->setName(pht("Saved Queries")) 51 + ->setHref($this->getApplicationURI('/savedqueries/'))); 52 + 53 + $nav->setCrumbs($crumbs); 54 + 55 + return $this->buildApplicationPage( 56 + $nav, 57 + array( 58 + 'title' => pht("Saved Queries"), 59 + 'device' => true, 60 + 'dust' => true, 61 + )); 62 + } 63 + 64 + }
+4 -1
src/applications/paste/query/PhabricatorPasteSearchEngine.php
··· 83 83 84 84 $form->appendChild( 85 85 id(new AphrontFormSubmitControl()) 86 - ->setValue(pht('Filter Pastes'))); 86 + ->setValue(pht('Filter Pastes')) 87 + ->addCancelButton( 88 + '/search/name/'.$saved_query->getQueryKey().'/', 89 + pht('Save Custom Query...'))); 87 90 88 91 return $form; 89 92 }
+2 -1
src/applications/search/application/PhabricatorApplicationSearch.php
··· 34 34 'index/(?P<phid>[^/]+)/' => 'PhabricatorSearchIndexController', 35 35 'hovercard/(?P<mode>retrieve|test)/' => 36 36 'PhabricatorSearchHovercardController', 37 - ), 37 + 'name/(?P<queryKey>\w+)/' => 'PhabricatorSearchNameController', 38 + ), 38 39 ); 39 40 } 40 41
+71
src/applications/search/controller/PhabricatorSearchNameController.php
··· 1 + <?php 2 + 3 + /** 4 + * @group search 5 + */ 6 + final class PhabricatorSearchNameController 7 + extends PhabricatorSearchBaseController { 8 + 9 + private $queryKey; 10 + 11 + public function willProcessRequest(array $data) { 12 + $this->queryKey = idx($data, 'queryKey'); 13 + } 14 + 15 + public function processRequest() { 16 + $request = $this->getRequest(); 17 + $user = $request->getUser(); 18 + 19 + if ($this->queryKey) { 20 + $saved_query = id(new PhabricatorSavedQuery())->loadOneWhere( 21 + 'queryKey = %s', 22 + $this->queryKey); 23 + if (!$saved_query) { 24 + return new Aphront404Response(); 25 + } 26 + } else { 27 + return new Aphront404Response(); 28 + } 29 + 30 + if ($request->isFormPost()) { 31 + $request_data = $request->getRequestData(); 32 + 33 + $named_query = id(new PhabricatorNamedQuery()) 34 + ->setUserPHID($user->getPHID()) 35 + ->setQueryKey($saved_query->getQueryKey()) 36 + ->setQueryName($request_data["set_name"]) 37 + ->setEngineClassName($saved_query->getEngineClassName()); 38 + 39 + try { 40 + $named_query->save(); 41 + } catch (AphrontQueryDuplicateKeyException $ex) { 42 + // Ignore, the user is naming an identical query. 43 + } 44 + 45 + return id(new AphrontRedirectResponse()) 46 + ->setURI('/search/'); 47 + } 48 + 49 + $form = id(new AphrontFormView()) 50 + ->setUser($user); 51 + 52 + $form->appendChild( 53 + id(new AphrontFormTextControl()) 54 + ->setName('set_name') 55 + ->setLabel(pht('Query Name'))); 56 + 57 + $form->appendChild( 58 + id(new AphrontFormSubmitControl()) 59 + ->setValue(pht('Save'))); 60 + 61 + return $this->buildStandardPageResponse( 62 + array( 63 + $form, 64 + ), 65 + array( 66 + 'title' => 'Name Query', 67 + )); 68 + } 69 + 70 + 71 + }
+13
src/applications/search/storage/PhabricatorNamedQuery.php
··· 1 + <?php 2 + 3 + /** 4 + * @group search 5 + */ 6 + final class PhabricatorNamedQuery extends PhabricatorSearchDAO { 7 + 8 + protected $queryKey = ""; 9 + protected $queryName = ""; 10 + protected $userPHID = ""; 11 + protected $engineClassName = ""; 12 + 13 + }
+4
src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
··· 1282 1282 'type' => 'php', 1283 1283 'name' => $this->getPatchPath('20130507.releephrqmailkeypop.php'), 1284 1284 ), 1285 + '20130508.search_namedquery.sql' => array( 1286 + 'type' => 'sql', 1287 + 'name' => $this->getPatchPath('20130508.search_namedquery.sql'), 1288 + ), 1285 1289 ); 1286 1290 } 1287 1291 }