@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
1<?php
2
3final class PhabricatorPasteSearchEngine
4 extends PhabricatorApplicationSearchEngine {
5
6 public function getResultTypeDescription() {
7 return pht('Pastes');
8 }
9
10 public function getApplicationClassName() {
11 return PhabricatorPasteApplication::class;
12 }
13
14 public function newQuery() {
15 return id(new PhabricatorPasteQuery())
16 ->needSnippets(true);
17 }
18
19 protected function buildQueryFromParameters(array $map) {
20 $query = $this->newQuery();
21
22 if ($map['authorPHIDs']) {
23 $query->withAuthorPHIDs($map['authorPHIDs']);
24 }
25
26 if ($map['languages']) {
27 $query->withLanguages($map['languages']);
28 }
29
30 if ($map['createdStart']) {
31 $query->withDateCreatedAfter($map['createdStart']);
32 }
33
34 if ($map['createdEnd']) {
35 $query->withDateCreatedBefore($map['createdEnd']);
36 }
37
38 if ($map['statuses']) {
39 $query->withStatuses($map['statuses']);
40 }
41
42 return $query;
43 }
44
45 protected function buildCustomSearchFields() {
46 return array(
47 id(new PhabricatorUsersSearchField())
48 ->setAliases(array('authors'))
49 ->setKey('authorPHIDs')
50 ->setConduitKey('authors')
51 ->setLabel(pht('Authors'))
52 ->setDescription(
53 pht('Search for pastes with specific authors.')),
54 id(new PhabricatorSearchStringListField())
55 ->setKey('languages')
56 ->setLabel(pht('Languages'))
57 ->setDescription(
58 pht('Search for pastes highlighted in specific languages.')),
59 id(new PhabricatorSearchDateField())
60 ->setKey('createdStart')
61 ->setLabel(pht('Created After'))
62 ->setDescription(
63 pht('Search for pastes created after a given time.')),
64 id(new PhabricatorSearchDateField())
65 ->setKey('createdEnd')
66 ->setLabel(pht('Created Before'))
67 ->setDescription(
68 pht('Search for pastes created before a given time.')),
69 id(new PhabricatorSearchCheckboxesField())
70 ->setKey('statuses')
71 ->setLabel(pht('Status'))
72 ->setDescription(
73 pht('Search for archived or active pastes.'))
74 ->setOptions(
75 id(new PhabricatorPaste())
76 ->getStatusNameMap()),
77 );
78 }
79
80 protected function getDefaultFieldOrder() {
81 return array(
82 '...',
83 'createdStart',
84 'createdEnd',
85 );
86 }
87
88 protected function getURI($path) {
89 return '/paste/'.$path;
90 }
91
92 protected function getBuiltinQueryNames() {
93 $names = array(
94 'active' => pht('Active Pastes'),
95 'all' => pht('All Pastes'),
96 );
97
98 if ($this->requireViewer()->isLoggedIn()) {
99 $names['authored'] = pht('Authored');
100 }
101
102 return $names;
103 }
104
105 public function buildSavedQueryFromBuiltin($query_key) {
106
107 $query = $this->newSavedQuery();
108 $query->setQueryKey($query_key);
109
110 switch ($query_key) {
111 case 'active':
112 return $query->setParameter(
113 'statuses',
114 array(
115 PhabricatorPaste::STATUS_ACTIVE,
116 ));
117 case 'all':
118 return $query;
119 case 'authored':
120 return $query->setParameter(
121 'authorPHIDs',
122 array($this->requireViewer()->getPHID()));
123 }
124
125 return parent::buildSavedQueryFromBuiltin($query_key);
126 }
127
128 protected function getRequiredHandlePHIDsForResultList(
129 array $pastes,
130 PhabricatorSavedQuery $query) {
131 return mpull($pastes, 'getAuthorPHID');
132 }
133
134 /**
135 * @param array<PhabricatorPaste> $pastes
136 * @param PhabricatorSavedQuery $query
137 * @param array<PhabricatorObjectHandle> $handles
138 */
139 protected function renderResultList(
140 array $pastes,
141 PhabricatorSavedQuery $query,
142 array $handles) {
143 assert_instances_of($pastes, PhabricatorPaste::class);
144
145 $viewer = $this->requireViewer();
146
147 $lang_map = PhabricatorEnv::getEnvConfig('pygments.dropdown-choices');
148
149 $list = new PHUIObjectItemListView();
150 $list->setUser($viewer);
151 foreach ($pastes as $paste) {
152 $created = phabricator_date($paste->getDateCreated(), $viewer);
153 $author = $handles[$paste->getAuthorPHID()]->renderLink();
154
155 $snippet_type = $paste->getSnippet()->getType();
156 $lines = phutil_split_lines($paste->getSnippet()->getContent());
157
158 $preview = id(new PhabricatorSourceCodeView())
159 ->setLines($lines)
160 ->setTruncatedFirstBytes(
161 $snippet_type == PhabricatorPasteSnippet::FIRST_BYTES)
162 ->setTruncatedFirstLines(
163 $snippet_type == PhabricatorPasteSnippet::FIRST_LINES)
164 ->setURI(new PhutilURI($paste->getURI()));
165
166 $source_code = phutil_tag(
167 'div',
168 array(
169 'class' => 'phabricator-source-code-summary',
170 ),
171 $preview);
172
173 $created = phabricator_datetime($paste->getDateCreated(), $viewer);
174 $line_count = $paste->getSnippet()->getContentLineCount();
175 $line_count = pht(
176 '%s Line(s)',
177 new PhutilNumber($line_count));
178
179 $title = nonempty($paste->getTitle(), pht('(An Untitled Masterwork)'));
180
181 $item = id(new PHUIObjectItemView())
182 ->setObjectName('P'.$paste->getID())
183 ->setHeader($title)
184 ->setHref('/P'.$paste->getID())
185 ->setObject($paste)
186 ->addByline(pht('Author: %s', $author))
187 ->addIcon('none', $created)
188 ->addIcon('none', $line_count)
189 ->appendChild($source_code);
190
191 if ($paste->isArchived()) {
192 $item->setDisabled(true);
193 }
194
195 $lang_name = $paste->getLanguage();
196 if ($lang_name) {
197 $lang_name = idx($lang_map, $lang_name, $lang_name);
198 $item->addIcon('none', $lang_name);
199 }
200
201 $list->addItem($item);
202 }
203
204 $result = new PhabricatorApplicationSearchResultView();
205 $result->setObjectList($list);
206 $result->setNoDataString(pht('No pastes found.'));
207
208 return $result;
209 }
210
211 protected function getNewUserBody() {
212 $viewer = $this->requireViewer();
213
214 $create_button = id(new PhabricatorPasteEditEngine())
215 ->setViewer($viewer)
216 ->newNUXButton(pht('Create a Paste'));
217
218 $icon = $this->getApplication()->getIcon();
219 $app_name = $this->getApplication()->getName();
220 $view = id(new PHUIBigInfoView())
221 ->setIcon($icon)
222 ->setTitle(pht('Welcome to %s', $app_name))
223 ->setDescription(
224 pht('Store, share, and embed snippets of code.'))
225 ->addAction($create_button);
226
227 return $view;
228 }
229}