Skip to content

Commit d82e135

Browse files
author
epriestley
committed
Implement generalized application search in Macros
Summary: Ref T2625. Works out the last kinks of generalization and gives Macros the more powerful new query engine. Overall, this feels pretty good to me. Test Plan: Executed, saved and edited a bunch of Macro queries. Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T2625 Differential Revision: https://secure.phabricator.com/D6078
1 parent 5d94a8a commit d82e135

File tree

9 files changed

+227
-152
lines changed

9 files changed

+227
-152
lines changed

src/__phutil_library_map__.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1088,6 +1088,7 @@
10881088
'PhabricatorMacroMemeDialogController' => 'applications/macro/controller/PhabricatorMacroMemeDialogController.php',
10891089
'PhabricatorMacroQuery' => 'applications/macro/query/PhabricatorMacroQuery.php',
10901090
'PhabricatorMacroReplyHandler' => 'applications/macro/mail/PhabricatorMacroReplyHandler.php',
1091+
'PhabricatorMacroSearchEngine' => 'applications/macro/query/PhabricatorMacroSearchEngine.php',
10911092
'PhabricatorMacroTransaction' => 'applications/macro/storage/PhabricatorMacroTransaction.php',
10921093
'PhabricatorMacroTransactionComment' => 'applications/macro/storage/PhabricatorMacroTransactionComment.php',
10931094
'PhabricatorMacroTransactionQuery' => 'applications/macro/query/PhabricatorMacroTransactionQuery.php',
@@ -2874,12 +2875,17 @@
28742875
'PhabricatorMacroDisableController' => 'PhabricatorMacroController',
28752876
'PhabricatorMacroEditController' => 'PhabricatorMacroController',
28762877
'PhabricatorMacroEditor' => 'PhabricatorApplicationTransactionEditor',
2877-
'PhabricatorMacroListController' => 'PhabricatorMacroController',
2878+
'PhabricatorMacroListController' =>
2879+
array(
2880+
0 => 'PhabricatorMacroController',
2881+
1 => 'PhabricatorApplicationSearchResultsControllerInterface',
2882+
),
28782883
'PhabricatorMacroMailReceiver' => 'PhabricatorObjectMailReceiver',
28792884
'PhabricatorMacroMemeController' => 'PhabricatorMacroController',
28802885
'PhabricatorMacroMemeDialogController' => 'PhabricatorMacroController',
28812886
'PhabricatorMacroQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
28822887
'PhabricatorMacroReplyHandler' => 'PhabricatorMailReplyHandler',
2888+
'PhabricatorMacroSearchEngine' => 'PhabricatorApplicationSearchEngine',
28832889
'PhabricatorMacroTransaction' => 'PhabricatorApplicationTransaction',
28842890
'PhabricatorMacroTransactionComment' => 'PhabricatorApplicationTransactionComment',
28852891
'PhabricatorMacroTransactionQuery' => 'PhabricatorApplicationTransactionQuery',

src/applications/macro/application/PhabricatorApplicationMacro.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public function getApplicationGroup() {
2525
public function getRoutes() {
2626
return array(
2727
'/macro/' => array(
28-
'((?P<filter>all|active|my)/)?' => 'PhabricatorMacroListController',
28+
'(query/(?P<key>[^/]+)/)?' => 'PhabricatorMacroListController',
2929
'create/' => 'PhabricatorMacroEditController',
3030
'view/(?P<id>[1-9]\d*)/' => 'PhabricatorMacroViewController',
3131
'comment/(?P<id>[1-9]\d*)/' => 'PhabricatorMacroCommentController',

src/applications/macro/controller/PhabricatorMacroController.php

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
abstract class PhabricatorMacroController
44
extends PhabricatorController {
55

6-
protected function buildSideNavView($for_app = false, $has_search = false) {
6+
protected function buildSideNavView($for_app = false) {
77
$nav = new AphrontSideNavFilterView();
88
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
99

@@ -14,16 +14,9 @@ protected function buildSideNavView($for_app = false, $has_search = false) {
1414
$this->getApplicationURI('/create/'));
1515
}
1616

17-
$nav->addLabel(pht('Macros'));
18-
$nav->addFilter('active', pht('Active Macros'));
19-
$nav->addFilter('all', pht('All Macros'));
20-
$nav->addFilter('my', pht('My Macros'));
21-
if ($has_search) {
22-
$nav->addFilter('search',
23-
pht('Search'),
24-
$this->getRequest()->getRequestURI());
25-
}
26-
17+
id(new PhabricatorMacroSearchEngine())
18+
->setViewer($this->getRequest()->getUser())
19+
->addNavigationItems($nav);
2720

2821
return $nav;
2922
}
Lines changed: 37 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,39 @@
11
<?php
22

3-
final class PhabricatorMacroListController
4-
extends PhabricatorMacroController {
3+
final class PhabricatorMacroListController extends PhabricatorMacroController
4+
implements PhabricatorApplicationSearchResultsControllerInterface {
55

6-
private $filter;
6+
private $key;
7+
8+
public function shouldAllowPublic() {
9+
return true;
10+
}
711

812
public function willProcessRequest(array $data) {
9-
$this->filter = idx($data, 'filter', 'active');
13+
$this->key = idx($data, 'key', 'active');
1014
}
1115

1216
public function processRequest() {
13-
1417
$request = $this->getRequest();
15-
$viewer = $request->getUser();
16-
17-
$pager = id(new AphrontCursorPagerView())
18-
->readFromRequest($request);
19-
20-
$query = new PhabricatorMacroQuery();
21-
$query->setViewer($viewer);
22-
23-
$filter = $request->getStr('name');
24-
if (strlen($filter)) {
25-
$query->withNameLike($filter);
26-
}
27-
28-
$authors = $request->getArr('authors');
29-
30-
if ($authors) {
31-
$query->withAuthorPHIDs($authors);
32-
}
33-
34-
$has_search = $filter || $authors;
35-
36-
if ($this->filter == 'my') {
37-
$query->withAuthorPHIDs(array($viewer->getPHID()));
38-
// For pre-filling the tokenizer
39-
$authors = array($viewer->getPHID());
40-
}
41-
42-
if ($this->filter == 'active') {
43-
$query->withStatus(PhabricatorMacroQuery::STATUS_ACTIVE);
44-
}
45-
46-
$macros = $query->executeWithCursorPager($pager);
47-
if ($has_search) {
48-
$nodata = pht('There are no macros matching the filter.');
49-
} else {
50-
$nodata = pht('There are no image macros yet.');
51-
}
18+
$controller = id(new PhabricatorApplicationSearchController($request))
19+
->setQueryKey($this->key)
20+
->setSearchEngine(new PhabricatorMacroSearchEngine())
21+
->setNavigation($this->buildSideNavView());
5222

53-
if ($authors) {
54-
$author_phids = array_fuse($authors);
55-
} else {
56-
$author_phids = array();
57-
}
23+
return $this->delegateToController($controller);
24+
}
5825

59-
$author_phids += mpull($macros, 'getAuthorPHID', 'getAuthorPHID');
26+
public function renderResultsList(array $macros) {
27+
assert_instances_of($macros, 'PhabricatorFileImageMacro');
28+
$viewer = $this->getRequest()->getUser();
6029

30+
$author_phids = mpull($macros, 'getAuthorPHID', 'getAuthorPHID');
6131
$this->loadHandles($author_phids);
62-
$author_handles = array_select_keys($this->getLoadedHandles(), $authors);
63-
64-
$filter_form = id(new AphrontFormView())
65-
->setMethod('GET')
66-
->setUser($request->getUser())
67-
->setNoShading(true)
68-
->appendChild(
69-
id(new AphrontFormTextControl())
70-
->setName('name')
71-
->setLabel(pht('Name'))
72-
->setValue($filter))
73-
->appendChild(
74-
id(new AphrontFormTokenizerControl())
75-
->setName('authors')
76-
->setLabel(pht('Authors'))
77-
->setDatasource('/typeahead/common/users/')
78-
->setValue(mpull($author_handles, 'getFullName')))
79-
->appendChild(
80-
id(new AphrontFormSubmitControl())
81-
->setValue(pht('Filter Image Macros')));
82-
83-
$filter_view = new AphrontListFilterView();
84-
$filter_view->appendChild($filter_form);
85-
86-
$nav = $this->buildSideNavView(
87-
$for_app = false,
88-
$has_search);
89-
$nav->selectFilter($has_search ? 'search' : $this->filter);
90-
91-
$nav->appendChild($filter_view);
32+
$author_handles = array_select_keys(
33+
$this->getLoadedHandles(),
34+
$author_phids);
9235

9336
$pinboard = new PhabricatorPinboardView();
94-
$pinboard->setNoDataString($nodata);
9537
foreach ($macros as $macro) {
9638
$file = $macro->getFile();
9739

@@ -108,6 +50,14 @@ public function processRequest() {
10850
'div',
10951
array(),
11052
pht('Created on %s', $datetime)));
53+
} else {
54+
// Very old macros don't have a creation date. Rendering something
55+
// keeps all the pins at the same height and avoids flow issues.
56+
$item->appendChild(
57+
phutil_tag(
58+
'div',
59+
array(),
60+
pht('Created in ages long past')));
11161
}
11262

11363
if ($macro->getAuthorPHID()) {
@@ -117,45 +67,17 @@ public function processRequest() {
11767
}
11868

11969
$item->setURI($this->getApplicationURI('/view/'.$macro->getID().'/'));
120-
$item->setHeader($macro->getName());
12170

122-
$pinboard->addItem($item);
123-
}
124-
$nav->appendChild($pinboard);
125-
126-
if (!$has_search) {
127-
$nav->appendChild($pager);
128-
switch ($this->filter) {
129-
case 'all':
130-
$name = pht('All Macros');
131-
break;
132-
case 'my':
133-
$name = pht('My Macros');
134-
break;
135-
case 'active':
136-
$name = pht('Active Macros');
137-
break;
138-
default:
139-
throw new Exception("Unknown filter $this->filter");
140-
break;
71+
$name = $macro->getName();
72+
if ($macro->getIsDisabled()) {
73+
$name = pht('%s (Disabled)', $name);
14174
}
142-
} else {
143-
$name = pht('Search');
75+
$item->setHeader($name);
76+
77+
$pinboard->addItem($item);
14478
}
14579

146-
$crumbs = $this->buildApplicationCrumbs();
147-
$crumbs->addCrumb(
148-
id(new PhabricatorCrumbView())
149-
->setName($name)
150-
->setHref($request->getRequestURI()));
151-
$nav->setCrumbs($crumbs);
152-
153-
return $this->buildApplicationPage(
154-
$nav,
155-
array(
156-
'device' => true,
157-
'title' => pht('Image Macros'),
158-
'dust' => true,
159-
));
80+
return $pinboard;
81+
16082
}
16183
}

src/applications/macro/query/PhabricatorMacroQuery.php

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@ final class PhabricatorMacroQuery
1515
private $status = 'status-any';
1616
const STATUS_ANY = 'status-any';
1717
const STATUS_ACTIVE = 'status-active';
18+
const STATUS_DISABLED = 'status-disabled';
19+
20+
public static function getStatusOptions() {
21+
return array(
22+
self::STATUS_ACTIVE => pht('Active Macros'),
23+
self::STATUS_DISABLED => pht('Disabled Macros'),
24+
self::STATUS_ANY => pht('Active and Disabled Macros'),
25+
);
26+
}
1827

1928
public function withIDs(array $ids) {
2029
$this->ids = $ids;
@@ -99,10 +108,21 @@ protected function buildWhereClause(AphrontDatabaseConnection $conn) {
99108
$this->names);
100109
}
101110

102-
if ($this->status == self::STATUS_ACTIVE) {
103-
$where[] = qsprintf(
104-
$conn,
105-
'm.isDisabled = 0');
111+
switch ($this->status) {
112+
case self::STATUS_ACTIVE:
113+
$where[] = qsprintf(
114+
$conn,
115+
'm.isDisabled = 0');
116+
break;
117+
case self::STATUS_DISABLED:
118+
$where[] = qsprintf(
119+
$conn,
120+
'm.isDisabled = 1');
121+
break;
122+
case self::STATUS_ANY:
123+
break;
124+
default:
125+
throw new Exception("Unknown status '{$this->status}'!");
106126
}
107127

108128
$where[] = $this->buildPagingClause($conn);

0 commit comments

Comments
 (0)