Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/conpherence/controller/ConpherenceUpdateController.php
12256 views
1
<?php
2
3
final class ConpherenceUpdateController
4
extends ConpherenceController {
5
6
public function handleRequest(AphrontRequest $request) {
7
$user = $request->getUser();
8
$conpherence_id = $request->getURIData('id');
9
if (!$conpherence_id) {
10
return new Aphront404Response();
11
}
12
13
$need_participants = false;
14
$needed_capabilities = array(PhabricatorPolicyCapability::CAN_VIEW);
15
$action = $request->getStr('action');
16
switch ($action) {
17
case ConpherenceUpdateActions::REMOVE_PERSON:
18
$person_phid = $request->getStr('remove_person');
19
if ($person_phid != $user->getPHID()) {
20
$needed_capabilities[] = PhabricatorPolicyCapability::CAN_EDIT;
21
}
22
break;
23
case ConpherenceUpdateActions::ADD_PERSON:
24
$needed_capabilities[] = PhabricatorPolicyCapability::CAN_EDIT;
25
break;
26
case ConpherenceUpdateActions::LOAD:
27
break;
28
}
29
$conpherence = id(new ConpherenceThreadQuery())
30
->setViewer($user)
31
->withIDs(array($conpherence_id))
32
->needParticipants($need_participants)
33
->requireCapabilities($needed_capabilities)
34
->executeOne();
35
36
$latest_transaction_id = null;
37
$response_mode = $request->isAjax() ? 'ajax' : 'redirect';
38
$error_view = null;
39
$e_file = array();
40
$errors = array();
41
$delete_draft = false;
42
$xactions = array();
43
if ($request->isFormPost() || ($action == ConpherenceUpdateActions::LOAD)) {
44
$editor = id(new ConpherenceEditor())
45
->setContinueOnNoEffect($request->isContinueRequest())
46
->setContentSourceFromRequest($request)
47
->setActor($user);
48
49
switch ($action) {
50
case ConpherenceUpdateActions::DRAFT:
51
$draft = PhabricatorDraft::newFromUserAndKey(
52
$user,
53
$conpherence->getPHID());
54
$draft->setDraft($request->getStr('text'));
55
$draft->replaceOrDelete();
56
return new AphrontAjaxResponse();
57
case ConpherenceUpdateActions::JOIN_ROOM:
58
$xactions[] = id(new ConpherenceTransaction())
59
->setTransactionType(
60
ConpherenceThreadParticipantsTransaction::TRANSACTIONTYPE)
61
->setNewValue(array('+' => array($user->getPHID())));
62
$delete_draft = true;
63
$message = $request->getStr('text');
64
if ($message) {
65
$message_xactions = $editor->generateTransactionsFromText(
66
$user,
67
$conpherence,
68
$message);
69
$xactions = array_merge($xactions, $message_xactions);
70
}
71
// for now, just redirect back to the conpherence so everything
72
// will work okay...!
73
$response_mode = 'redirect';
74
break;
75
case ConpherenceUpdateActions::MESSAGE:
76
$message = $request->getStr('text');
77
if (strlen($message)) {
78
$xactions = $editor->generateTransactionsFromText(
79
$user,
80
$conpherence,
81
$message);
82
$delete_draft = true;
83
} else {
84
$action = ConpherenceUpdateActions::LOAD;
85
$updated = false;
86
$response_mode = 'ajax';
87
}
88
break;
89
case ConpherenceUpdateActions::ADD_PERSON:
90
$person_phids = $request->getArr('add_person');
91
if (!empty($person_phids)) {
92
$xactions[] = id(new ConpherenceTransaction())
93
->setTransactionType(
94
ConpherenceThreadParticipantsTransaction::TRANSACTIONTYPE)
95
->setNewValue(array('+' => $person_phids));
96
}
97
break;
98
case ConpherenceUpdateActions::REMOVE_PERSON:
99
if (!$request->isContinueRequest()) {
100
// do nothing; we'll display a confirmation dialog instead
101
break;
102
}
103
$person_phid = $request->getStr('remove_person');
104
if ($person_phid) {
105
$xactions[] = id(new ConpherenceTransaction())
106
->setTransactionType(
107
ConpherenceThreadParticipantsTransaction::TRANSACTIONTYPE)
108
->setNewValue(array('-' => array($person_phid)));
109
$response_mode = 'go-home';
110
}
111
break;
112
case ConpherenceUpdateActions::LOAD:
113
$updated = false;
114
$response_mode = 'ajax';
115
break;
116
default:
117
throw new Exception(pht('Unknown action: %s', $action));
118
break;
119
}
120
121
if ($xactions) {
122
try {
123
$xactions = $editor->applyTransactions($conpherence, $xactions);
124
if ($delete_draft) {
125
$draft = PhabricatorDraft::newFromUserAndKey(
126
$user,
127
$conpherence->getPHID());
128
$draft->delete();
129
}
130
} catch (PhabricatorApplicationTransactionNoEffectException $ex) {
131
return id(new PhabricatorApplicationTransactionNoEffectResponse())
132
->setCancelURI($this->getApplicationURI($conpherence_id.'/'))
133
->setException($ex);
134
}
135
// xactions had no effect...!
136
if (empty($xactions)) {
137
$errors[] = pht(
138
'That was a non-update. Try cancel.');
139
}
140
}
141
142
if ($xactions || ($action == ConpherenceUpdateActions::LOAD)) {
143
switch ($response_mode) {
144
case 'ajax':
145
$latest_transaction_id = $request->getInt('latest_transaction_id');
146
$content = $this->loadAndRenderUpdates(
147
$action,
148
$conpherence_id,
149
$latest_transaction_id);
150
return id(new AphrontAjaxResponse())
151
->setContent($content);
152
break;
153
case 'go-home':
154
$content = array(
155
'href' => $this->getApplicationURI(),
156
);
157
return id(new AphrontAjaxResponse())
158
->setContent($content);
159
break;
160
case 'redirect':
161
default:
162
return id(new AphrontRedirectResponse())
163
->setURI('/'.$conpherence->getMonogram());
164
break;
165
}
166
}
167
}
168
169
if ($errors) {
170
$error_view = id(new PHUIInfoView())
171
->setErrors($errors);
172
}
173
174
switch ($action) {
175
case ConpherenceUpdateActions::ADD_PERSON:
176
$dialog = $this->renderAddPersonDialog($conpherence);
177
break;
178
case ConpherenceUpdateActions::REMOVE_PERSON:
179
$dialog = $this->renderRemovePersonDialog($conpherence);
180
break;
181
}
182
183
return
184
$dialog
185
->setUser($user)
186
->setWidth(AphrontDialogView::WIDTH_FORM)
187
->setSubmitURI($this->getApplicationURI('update/'.$conpherence_id.'/'))
188
->addSubmitButton()
189
->addCancelButton($this->getApplicationURI($conpherence->getID().'/'));
190
191
}
192
193
private function renderAddPersonDialog(
194
ConpherenceThread $conpherence) {
195
196
$request = $this->getRequest();
197
$user = $request->getUser();
198
$add_person = $request->getStr('add_person');
199
200
$form = id(new AphrontFormView())
201
->setUser($user)
202
->setFullWidth(true)
203
->appendControl(
204
id(new AphrontFormTokenizerControl())
205
->setName('add_person')
206
->setUser($user)
207
->setDatasource(new PhabricatorPeopleDatasource()));
208
209
$view = id(new AphrontDialogView())
210
->setTitle(pht('Add Participants'))
211
->addHiddenInput('action', 'add_person')
212
->addHiddenInput(
213
'latest_transaction_id',
214
$request->getInt('latest_transaction_id'))
215
->appendForm($form);
216
217
return $view;
218
}
219
220
private function renderRemovePersonDialog(
221
ConpherenceThread $conpherence) {
222
223
$request = $this->getRequest();
224
$viewer = $request->getUser();
225
$remove_person = $request->getStr('remove_person');
226
$participants = $conpherence->getParticipants();
227
228
$removed_user = id(new PhabricatorPeopleQuery())
229
->setViewer($viewer)
230
->withPHIDs(array($remove_person))
231
->executeOne();
232
if (!$removed_user) {
233
return new Aphront404Response();
234
}
235
236
$is_self = ($viewer->getPHID() == $removed_user->getPHID());
237
$is_last = (count($participants) == 1);
238
239
$test_conpherence = clone $conpherence;
240
$test_conpherence->attachParticipants(array());
241
$still_visible = PhabricatorPolicyFilter::hasCapability(
242
$removed_user,
243
$test_conpherence,
244
PhabricatorPolicyCapability::CAN_VIEW);
245
246
$body = array();
247
248
if ($is_self) {
249
$title = pht('Leave Room');
250
$body[] = pht(
251
'Are you sure you want to leave this room?');
252
} else {
253
$title = pht('Remove Participant');
254
$body[] = pht(
255
'Remove %s from this room?',
256
phutil_tag('strong', array(), $removed_user->getUsername()));
257
}
258
259
if ($still_visible) {
260
if ($is_self) {
261
$body[] = pht(
262
'You will be able to rejoin the room later.');
263
} else {
264
$body[] = pht(
265
'They will be able to rejoin the room later.');
266
}
267
} else {
268
if ($is_self) {
269
if ($is_last) {
270
$body[] = pht(
271
'You are the last member, so you will never be able to rejoin '.
272
'the room.');
273
} else {
274
$body[] = pht(
275
'You will not be able to rejoin the room on your own, but '.
276
'someone else can invite you later.');
277
}
278
} else {
279
$body[] = pht(
280
'They will not be able to rejoin the room unless invited '.
281
'again.');
282
}
283
}
284
285
$dialog = id(new AphrontDialogView())
286
->setTitle($title)
287
->addHiddenInput('action', 'remove_person')
288
->addHiddenInput('remove_person', $remove_person)
289
->addHiddenInput(
290
'latest_transaction_id',
291
$request->getInt('latest_transaction_id'))
292
->addHiddenInput('__continue__', true);
293
294
foreach ($body as $paragraph) {
295
$dialog->appendParagraph($paragraph);
296
}
297
298
return $dialog;
299
}
300
301
private function loadAndRenderUpdates(
302
$action,
303
$conpherence_id,
304
$latest_transaction_id) {
305
306
$need_transactions = false;
307
switch ($action) {
308
case ConpherenceUpdateActions::LOAD:
309
$need_transactions = true;
310
break;
311
case ConpherenceUpdateActions::MESSAGE:
312
case ConpherenceUpdateActions::ADD_PERSON:
313
$need_transactions = true;
314
break;
315
case ConpherenceUpdateActions::REMOVE_PERSON:
316
default:
317
break;
318
319
}
320
$user = $this->getRequest()->getUser();
321
$conpherence = id(new ConpherenceThreadQuery())
322
->setViewer($user)
323
->setAfterTransactionID($latest_transaction_id)
324
->needProfileImage(true)
325
->needParticipants(true)
326
->needTransactions($need_transactions)
327
->withIDs(array($conpherence_id))
328
->executeOne();
329
330
$non_update = false;
331
$participant = $conpherence->getParticipant($user->getPHID());
332
333
if ($need_transactions && $conpherence->getTransactions()) {
334
$data = ConpherenceTransactionRenderer::renderTransactions(
335
$user,
336
$conpherence);
337
$key = PhabricatorConpherenceColumnMinimizeSetting::SETTINGKEY;
338
$minimized = $user->getUserSetting($key);
339
if (!$minimized) {
340
$participant->markUpToDate($conpherence);
341
}
342
} else if ($need_transactions) {
343
$non_update = true;
344
$data = array();
345
} else {
346
$data = array();
347
}
348
$rendered_transactions = idx($data, 'transactions');
349
$new_latest_transaction_id = idx($data, 'latest_transaction_id');
350
351
$update_uri = $this->getApplicationURI('update/'.$conpherence->getID().'/');
352
$nav_item = null;
353
$header = null;
354
$people_widget = null;
355
switch ($action) {
356
case ConpherenceUpdateActions::ADD_PERSON:
357
$people_widget = id(new ConpherenceParticipantView())
358
->setUser($user)
359
->setConpherence($conpherence)
360
->setUpdateURI($update_uri);
361
$people_widget = hsprintf('%s', $people_widget->render());
362
break;
363
case ConpherenceUpdateActions::REMOVE_PERSON:
364
default:
365
break;
366
}
367
$data = $conpherence->getDisplayData($user);
368
$dropdown_query = id(new AphlictDropdownDataQuery())
369
->setViewer($user);
370
$dropdown_query->execute();
371
372
$map = ConpherenceRoomSettings::getSoundMap();
373
$default_receive = ConpherenceRoomSettings::DEFAULT_RECEIVE_SOUND;
374
$receive_sound = $map[$default_receive]['rsrc'];
375
$mention_sound = null;
376
377
// Get the user's defaults if logged in
378
if ($participant) {
379
$sounds = $this->getSoundForParticipant($user, $participant);
380
$receive_sound = $sounds[ConpherenceRoomSettings::SOUND_RECEIVE];
381
$mention_sound = $sounds[ConpherenceRoomSettings::SOUND_MENTION];
382
}
383
384
$content = array(
385
'non_update' => $non_update,
386
'transactions' => hsprintf('%s', $rendered_transactions),
387
'conpherence_title' => (string)$data['title'],
388
'latest_transaction_id' => $new_latest_transaction_id,
389
'nav_item' => $nav_item,
390
'conpherence_phid' => $conpherence->getPHID(),
391
'header' => $header,
392
'people_widget' => $people_widget,
393
'aphlictDropdownData' => array(
394
$dropdown_query->getNotificationData(),
395
$dropdown_query->getConpherenceData(),
396
),
397
'sound' => array(
398
'receive' => $receive_sound,
399
'mention' => $mention_sound,
400
),
401
);
402
403
return $content;
404
}
405
406
protected function getSoundForParticipant(
407
PhabricatorUser $user,
408
ConpherenceParticipant $participant) {
409
410
$sound_key = PhabricatorConpherenceSoundSetting::SETTINGKEY;
411
$sound_default = $user->getUserSetting($sound_key);
412
413
$settings = $participant->getSettings();
414
$sounds = idx($settings, 'sounds', array());
415
$map = PhabricatorConpherenceSoundSetting::getDefaultSound($sound_default);
416
417
$receive = idx($sounds,
418
ConpherenceRoomSettings::SOUND_RECEIVE,
419
$map[ConpherenceRoomSettings::SOUND_RECEIVE]);
420
$mention = idx($sounds,
421
ConpherenceRoomSettings::SOUND_MENTION,
422
$map[ConpherenceRoomSettings::SOUND_MENTION]);
423
424
$sound_map = ConpherenceRoomSettings::getSoundMap();
425
426
return array(
427
ConpherenceRoomSettings::SOUND_RECEIVE => $sound_map[$receive]['rsrc'],
428
ConpherenceRoomSettings::SOUND_MENTION => $sound_map[$mention]['rsrc'],
429
);
430
431
}
432
433
}
434
435