@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 PhabricatorCalendarImportViewController
4 extends PhabricatorCalendarController {
5
6 public function handleRequest(AphrontRequest $request) {
7 $viewer = $request->getViewer();
8
9 $import = id(new PhabricatorCalendarImportQuery())
10 ->setViewer($viewer)
11 ->withIDs(array($request->getURIData('id')))
12 ->executeOne();
13 if (!$import) {
14 return new Aphront404Response();
15 }
16
17 $crumbs = $this->buildApplicationCrumbs();
18 $crumbs->addTextCrumb(
19 pht('Imports'),
20 '/calendar/import/');
21 $crumbs->addTextCrumb(pht('Import %d', $import->getID()));
22 $crumbs->setBorder(true);
23
24 $timeline = $this->buildTransactionTimeline(
25 $import,
26 new PhabricatorCalendarImportTransactionQuery());
27 $timeline->setShouldTerminate(true);
28
29 $header = $this->buildHeaderView($import);
30 $curtain = $this->buildCurtain($import);
31 $details = $this->buildPropertySection($import);
32
33 $log_messages = $this->buildLogMessages($import);
34 $imported_events = $this->buildImportedEvents($import);
35
36 $view = id(new PHUITwoColumnView())
37 ->setHeader($header)
38 ->setMainColumn(
39 array(
40 $log_messages,
41 $imported_events,
42 $timeline,
43 ))
44 ->setCurtain($curtain)
45 ->addPropertySection(pht('Details'), $details);
46
47 $page_title = pht(
48 'Import %d %s',
49 $import->getID(),
50 $import->getDisplayName());
51
52 return $this->newPage()
53 ->setTitle($page_title)
54 ->setCrumbs($crumbs)
55 ->setPageObjectPHIDs(array($import->getPHID()))
56 ->appendChild($view);
57 }
58
59 private function buildHeaderView(
60 PhabricatorCalendarImport $import) {
61 $viewer = $this->getViewer();
62 $id = $import->getID();
63
64 if ($import->getIsDisabled()) {
65 $icon = 'fa-ban';
66 $color = 'red';
67 $status = pht('Disabled');
68 } else {
69 $icon = 'fa-check';
70 $color = 'bluegrey';
71 $status = pht('Active');
72 }
73
74 $header = id(new PHUIHeaderView())
75 ->setViewer($viewer)
76 ->setHeader($import->getDisplayName())
77 ->setStatus($icon, $color, $status)
78 ->setPolicyObject($import);
79
80 return $header;
81 }
82
83 private function buildCurtain(PhabricatorCalendarImport $import) {
84 $viewer = $this->getViewer();
85 $id = $import->getID();
86
87 $curtain = $this->newCurtainView($import);
88 $engine = $import->getEngine();
89
90 $can_edit = PhabricatorPolicyFilter::hasCapability(
91 $viewer,
92 $import,
93 PhabricatorPolicyCapability::CAN_EDIT);
94
95 $edit_uri = "import/edit/{$id}/";
96 $edit_uri = $this->getApplicationURI($edit_uri);
97
98 $can_disable = ($can_edit && $engine->canDisable($viewer, $import));
99
100 $curtain->addAction(
101 id(new PhabricatorActionView())
102 ->setName(pht('Edit Import'))
103 ->setIcon('fa-pencil')
104 ->setDisabled(!$can_edit)
105 ->setWorkflow(!$can_edit)
106 ->setHref($edit_uri));
107
108 $reload_uri = "import/reload/{$id}/";
109 $reload_uri = $this->getApplicationURI($reload_uri);
110
111 $curtain->addAction(
112 id(new PhabricatorActionView())
113 ->setName(pht('Reload Import'))
114 ->setIcon('fa-refresh')
115 ->setDisabled(!$can_edit)
116 ->setWorkflow(true)
117 ->setHref($reload_uri));
118
119 $disable_uri = "import/disable/{$id}/";
120 $disable_uri = $this->getApplicationURI($disable_uri);
121 if ($import->getIsDisabled()) {
122 $disable_name = pht('Enable Import');
123 $disable_icon = 'fa-check';
124 } else {
125 $disable_name = pht('Disable Import');
126 $disable_icon = 'fa-ban';
127 }
128
129 $curtain->addAction(
130 id(new PhabricatorActionView())
131 ->setName($disable_name)
132 ->setIcon($disable_icon)
133 ->setDisabled(!$can_disable)
134 ->setWorkflow(true)
135 ->setHref($disable_uri));
136
137 if ($can_edit) {
138 $can_delete = $engine->canDeleteAnyEvents($viewer, $import);
139 } else {
140 $can_delete = false;
141 }
142
143 $delete_uri = "import/delete/{$id}/";
144 $delete_uri = $this->getApplicationURI($delete_uri);
145
146 $curtain->addAction(
147 id(new PhabricatorActionView())
148 ->setName(pht('Delete Imported Events'))
149 ->setIcon('fa-times')
150 ->setDisabled(!$can_delete)
151 ->setWorkflow(true)
152 ->setHref($delete_uri));
153
154 return $curtain;
155 }
156
157 private function buildPropertySection(
158 PhabricatorCalendarImport $import) {
159 $viewer = $this->getViewer();
160
161 $properties = id(new PHUIPropertyListView())
162 ->setViewer($viewer);
163
164 $engine = $import->getEngine();
165
166 $properties->addProperty(
167 pht('Source Type'),
168 $engine->getImportEngineTypeName());
169
170 if ($import->getIsDisabled()) {
171 $auto_updates = phutil_tag('em', array(), pht('Import Disabled'));
172 $has_trigger = false;
173 } else {
174 $frequency = $import->getTriggerFrequency();
175 $frequency_map = PhabricatorCalendarImport::getTriggerFrequencyMap();
176 $frequency_names = ipull($frequency_map, 'name');
177 $auto_updates = idx($frequency_names, $frequency, $frequency);
178
179 if ($frequency == PhabricatorCalendarImport::FREQUENCY_ONCE) {
180 $has_trigger = false;
181 $auto_updates = phutil_tag('em', array(), $auto_updates);
182 } else {
183 $has_trigger = true;
184 }
185 }
186
187 $properties->addProperty(
188 pht('Automatic Updates'),
189 $auto_updates);
190
191 if ($has_trigger) {
192 $trigger = id(new PhabricatorWorkerTriggerQuery())
193 ->setViewer($viewer)
194 ->withPHIDs(array($import->getTriggerPHID()))
195 ->needEvents(true)
196 ->executeOne();
197
198 if (!$trigger) {
199 $next_trigger = phutil_tag('em', array(), pht('Invalid Trigger'));
200 } else {
201 $now = PhabricatorTime::getNow();
202 $next_epoch = $trigger->getNextEventPrediction();
203 $next_trigger = pht(
204 '%s (%s)',
205 phabricator_datetime($next_epoch, $viewer),
206 phutil_format_relative_time($next_epoch - $now));
207 }
208
209 $properties->addProperty(
210 pht('Next Update'),
211 $next_trigger);
212 }
213
214 $engine->appendImportProperties(
215 $viewer,
216 $import,
217 $properties);
218
219 return $properties;
220 }
221
222 private function buildLogMessages(PhabricatorCalendarImport $import) {
223 $viewer = $this->getViewer();
224
225 $logs = id(new PhabricatorCalendarImportLogQuery())
226 ->setViewer($viewer)
227 ->withImportPHIDs(array($import->getPHID()))
228 ->setLimit(25)
229 ->execute();
230
231 $logs_view = id(new PhabricatorCalendarImportLogView())
232 ->setViewer($viewer)
233 ->setLogs($logs);
234
235 $all_uri = $this->getApplicationURI('import/log/');
236 $all_uri = (string)id(new PhutilURI($all_uri))
237 ->replaceQueryParam('importSourcePHID', $import->getPHID());
238
239 $all_button = id(new PHUIButtonView())
240 ->setTag('a')
241 ->setText(pht('View All'))
242 ->setIcon('fa-search')
243 ->setHref($all_uri);
244
245 $header = id(new PHUIHeaderView())
246 ->setHeader(pht('Log Messages'))
247 ->addActionLink($all_button);
248
249 return id(new PHUIObjectBoxView())
250 ->setHeader($header)
251 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
252 ->setTable($logs_view);
253 }
254
255 private function buildImportedEvents(PhabricatorCalendarImport $import) {
256 $viewer = $this->getViewer();
257
258 $engine = id(new PhabricatorCalendarEventSearchEngine())
259 ->setViewer($viewer);
260
261 $saved = $engine->newSavedQuery()
262 ->setParameter('importSourcePHIDs', array($import->getPHID()));
263
264 $pager = $engine->newPagerForSavedQuery($saved);
265 $pager->setPageSize(25);
266
267 $query = $engine->buildQueryFromSavedQuery($saved);
268
269 $results = $engine->executeQuery($query, $pager);
270 $view = $engine->renderResults($results, $saved);
271 $list = $view->getObjectList();
272 $list->setNoDataString(pht('No imported events.'));
273
274 $all_uri = $this->getApplicationURI();
275 $all_uri = (string)id(new PhutilURI($all_uri))
276 ->replaceQueryParam('importSourcePHID', $import->getPHID())
277 ->replaceQueryParam('display', 'list');
278
279 $all_button = id(new PHUIButtonView())
280 ->setTag('a')
281 ->setText(pht('View All'))
282 ->setIcon('fa-search')
283 ->setHref($all_uri);
284
285 $header = id(new PHUIHeaderView())
286 ->setHeader(pht('Imported Events'))
287 ->addActionLink($all_button);
288
289 return id(new PHUIObjectBoxView())
290 ->setHeader($header)
291 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
292 ->setObjectList($list);
293 }
294
295}