ILIAS  release_8 Revision v8.24
class.ilObjForumGUI.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
23
36{
37 use ilForumRequestTrait;
38
39 private array $viewModeOptions = [
40 ilForumProperties::VIEW_TREE => 'sort_by_posts',
41 ilForumProperties::VIEW_DATE_ASC => 'sort_by_date',
42 ];
43
44 private array $sortationOptions = [
45 ilForumProperties::VIEW_DATE_ASC => 'ascending_order',
46 ilForumProperties::VIEW_DATE_DESC => 'descending_order',
47 ];
48
49 private \ILIAS\GlobalScreen\Services $globalScreen;
50 public string $modal_history = '';
55 private bool $is_moderator;
57 private bool $hideToolbar = false;
58 private $httpRequest;
59 private \ILIAS\HTTP\Services $http;
62 private ?array $forumObjects = null;
63 private string $confirmation_gui_html = '';
66 private string $requestAction;
67 private array $modalActionsContainer = [];
68
70 public \ILIAS\DI\RBACServices $rbac;
72
73 private int $selectedSorting;
75 protected \ILIAS\Style\Content\Object\ObjectFacade $content_style_domain;
76 protected \ILIAS\Style\Content\GUIService $content_style_gui;
77
78 public function __construct($data, int $id = 0, bool $call_by_reference = true, bool $prepare_output = true)
79 {
80 global $DIC;
81 $this->ctrl = $DIC->ctrl();
82 $this->ctrl->saveParameter($this, ['ref_id']);
83
84 $this->httpRequest = $DIC->http()->request();
85 $this->http = $DIC->http();
86
87 $this->uiFactory = $DIC->ui()->factory();
88 $this->uiRenderer = $DIC->ui()->renderer();
89 $this->globalScreen = $DIC->globalScreen();
90
91 $this->ilObjDataCache = $DIC['ilObjDataCache'];
92 $this->ilNavigationHistory = $DIC['ilNavigationHistory'];
93 $this->ilHelp = $DIC['ilHelp'];
94 $this->rbac = $DIC->rbac();
95
96 $this->type = 'frm';
98
99 $this->tpl->addJavaScript('./Services/JavaScript/js/Basic.js');
100
101 $this->lng->loadLanguageModule('forum');
102 $this->lng->loadLanguageModule('content');
103
104 $this->initSessionStorage();
105
106 $ref_id = $this->retrieveRefId();
107 $thr_pk = $this->retrieveThrPk();
108 $pos_pk = $this->retrieveIntOrZeroFrom($this->http->wrapper()->query(), 'pos_pk');
109
110 $this->objProperties = ilForumProperties::getInstance($this->ilObjDataCache->lookupObjId($ref_id));
111 $this->is_moderator = $this->access->checkAccess('moderate_frm', '', $ref_id);
112
113 $this->objCurrentTopic = new ilForumTopic($thr_pk, $this->is_moderator);
114 $this->checkUsersViewMode();
115 if ($this->selectedSorting === ilForumProperties::VIEW_TREE && ($this->selected_post_storage->get($thr_pk) > 0)) {
116 $this->objCurrentPost = new ilForumPost(
117 $this->selected_post_storage->get($thr_pk) ?? 0,
118 $this->is_moderator
119 );
120 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
121 } else {
122 $this->selected_post_storage->set($this->objCurrentTopic->getId(), 0);
123 $this->objCurrentPost = new ilForumPost(
124 $pos_pk,
125 $this->is_moderator
126 );
127 }
128
129 $this->requestAction = (string) ($this->httpRequest->getQueryParams()['action'] ?? '');
130 $cs = $DIC->contentStyle();
131 $this->content_style_gui = $cs->gui();
132 if (is_object($this->object)) {
133 $this->content_style_domain = $cs->domain()->styleForRefId($this->object->getRefId());
134 }
135 }
136
137 protected function initSessionStorage(): void
138 {
139 $forumValues = ilSession::get('frm');
140 if (!is_array($forumValues)) {
141 $forumValues = [];
142 ilSession::set('frm', $forumValues);
143 }
144
145 $threadId = $this->httpRequest->getQueryParams()['thr_pk'] ?? 0;
146 if ((int) $threadId > 0 && !isset($forumValues[(int) $threadId])) {
147 $forumValues[(int) $threadId] = [];
148 ilSession::set('frm', $forumValues);
149 }
150
151 $this->selected_post_storage = new ilForumThreadSettingsSessionStorage('frm_selected_post');
152 }
153
154 private function retrieveRefId(): int
155 {
156 return $this->retrieveIntOrZeroFrom($this->http->wrapper()->query(), 'ref_id');
157 }
158
159 private function retrieveThrPk(): int
160 {
161 return $this->retrieveIntOrZeroFrom($this->http->wrapper()->query(), 'thr_pk');
162 }
163
164 private function retrieveThreadIds(): array
165 {
166 $thread_ids = [];
167 if ($this->http->wrapper()->post()->has('thread_ids')) {
168 $thread_ids = $this->http->wrapper()->post()->retrieve(
169 'thread_ids',
170 $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())
171 );
172 }
173
174 return $thread_ids;
175 }
176
177 private function retrieveDraftId(): int
178 {
179 return $this->retrieveIntOrZeroFrom($this->http->wrapper()->query(), 'draft_id');
180 }
181
182 protected function toggleExplorerNodeStateObject(): void
183 {
184 $exp = new ilForumExplorerGUI(
185 'frm_exp_' . $this->objCurrentTopic->getId(),
186 $this,
187 'viewThread',
188 $this->objCurrentTopic,
189 $this->objCurrentTopic->getPostRootNode($this->is_moderator)
190 );
191 $exp->toggleExplorerNodeState();
192 }
193
195 array $subtree_nodes,
196 array $pagedPostings,
197 int $pageSize,
198 ilForumPost $firstForumPost
199 ): void {
200 if ($firstForumPost->getId() === $this->objCurrentPost->getId()) {
201 return;
202 }
203
204 if (count($subtree_nodes) > 0 && $this->objCurrentPost->getId() > 0) {
205 $isCurrentPostingInPage = array_filter($pagedPostings, function (ilForumPost $posting): bool {
206 return $posting->getId() === $this->objCurrentPost->getId();
207 });
208
209 if (0 === count($isCurrentPostingInPage)) {
210 $pageOfCurrentPosting = 0;
211 $i = 0;
212 foreach ($subtree_nodes as $node) {
213 if ($i > 0 && 0 === $i % $pageSize) {
214 ++$pageOfCurrentPosting;
215 }
216
217 if ($node->getId() === $this->objCurrentPost->getId()) {
218 break;
219 }
220
221 ++$i;
222 }
223
224 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
225 $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
226 $this->ctrl->setParameter($this, 'page', $pageOfCurrentPosting);
227 $this->ctrl->setParameter(
228 $this,
229 'orderby',
230 $this->getOrderByParam()
231 );
232 $this->ctrl->redirect($this, 'viewThread', (string) $this->objCurrentPost->getId());
233 }
234 }
235 }
236
237 public function ensureThreadBelongsToForum(int $objId, ilForumTopic $thread): void
238 {
240 if ($thread->getForumId() !== $forumId) {
241 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
242 }
243 }
244
245 private function decorateWithAutosave(ilPropertyFormGUI $form): void
246 {
247 $draft_id = $this->retrieveDraftId();
248
251
252 $this->tpl->addJavaScript('./Modules/Forum/js/autosave.js');
253 $autosave_cmd = 'autosaveDraftAsync';
254 if ($this->objCurrentPost->getId() === 0 && $this->objCurrentPost->getThreadId() === 0) {
255 $autosave_cmd = 'autosaveThreadDraftAsync';
256 }
257 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
258 $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
259 $draft_id = max($draft_id, 0);
260 $this->ctrl->setParameter($this, 'draft_id', $draft_id);
261 $this->ctrl->setParameter($this, 'action', ilUtil::stripSlashes($this->requestAction));
262 $this->tpl->addOnLoadCode(
263 "il.Language.setLangVar('saving', " . json_encode($this->lng->txt('saving'), JSON_THROW_ON_ERROR) . ");"
264 );
265
266 $this->tpl->addOnLoadCode('il.ForumDraftsAutosave.init(' . json_encode([
267 'loading_img_src' => ilUtil::getImagePath('loader.svg'),
268 'draft_id' => $draft_id,
269 'interval' => $interval * 1000,
270 'url' => $this->ctrl->getFormAction($this, $autosave_cmd, '', true),
271 'selectors' => [
272 'form' => '#form_' . $form->getId()
273 ]
274 ], JSON_THROW_ON_ERROR) . ');');
275 }
276 }
277
278 private function isTopLevelReplyCommand(): bool
279 {
280 return in_array(
281 strtolower($this->ctrl->getCmd()),
282 array_map('strtolower', ['createTopLevelPost', 'saveTopLevelPost', 'saveTopLevelDraft']),
283 true
284 );
285 }
286
287 public function getUnsafeGetCommands(): array
288 {
289 return [
290 'enableForumNotification',
291 'disableForumNotification',
292 'toggleThreadNotification'
293 ];
294 }
295
296 public function getSafePostCommands(): array
297 {
298 return [];
299 }
300
301 public function executeCommand(): void
302 {
303 $next_class = $this->ctrl->getNextClass($this);
304 $cmd = $this->ctrl->getCmd();
305
306 $exclude_cmds = [
307 'viewThread',
308 'markPostUnread',
309 'markPostRead',
310 'showThreadNotification',
311 'performPostActivation',
312 'askForPostActivation',
313 'askForPostDeactivation',
314 'toggleThreadNotification',
315 'toggleThreadNotificationTab',
316 'toggleStickiness',
317 'cancelPost',
318 'savePost',
319 'saveTopLevelPost',
320 'createTopLevelPost',
321 'saveTopLevelDraft',
322 'quotePost',
323 'getQuotationHTMLAsynch',
324 'autosaveDraftAsync',
325 'autosaveThreadDraftAsync',
326 'saveAsDraft',
327 'editDraft',
328 'updateDraft',
329 'deliverDraftZipFile',
330 'deliverZipFile',
331 'cancelDraft',
332 'deleteThreadDrafts',
333 'deletePosting',
334 'deletePostingDraft',
335 'revokeCensorship',
336 'addCensorship',
337 ];
338
339 if (!in_array($cmd, $exclude_cmds, true)) {
340 $this->prepareOutput();
341 }
342
343 $ref_id = $this->retrieveRefId();
344
345 if (!$this->getCreationMode() && !$this->ctrl->isAsynch() && $this->access->checkAccess(
346 'read',
347 '',
348 $ref_id
349 )) {
351 $ref_id,
353 'frm'
354 );
355 }
356
357 switch (strtolower($next_class)) {
358 case strtolower(ilForumPageGUI::class):
359 if (in_array(strtolower($cmd), array_map('strtolower', [
360 self::UI_CMD_COPAGE_DOWNLOAD_FILE,
361 self::UI_CMD_COPAGE_DISPLAY_FULLSCREEN,
362 self::UI_CMD_COPAGE_DOWNLOAD_PARAGRAPH,
363 ]), true)
364 ) {
365 if (!$this->checkPermissionBool('read')) {
366 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
367 }
368 } elseif (!$this->checkPermissionBool('write') || $this->user->isAnonymous()) {
369 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
370 }
371
372 $this->content_style_gui->addCss($this->tpl, $this->ref_id);
373 $this->tpl->setCurrentBlock('SyntaxStyle');
374 $this->tpl->setVariable('LOCATION_SYNTAX_STYLESHEET', ilObjStyleSheet::getSyntaxStylePath());
375 $this->tpl->parseCurrentBlock();
376
378 $obj = $this->object;
379
380 $forwarder = new ilForumPageCommandForwarder(
381 $this->http,
382 $this->ctrl,
383 $this->tabs_gui,
384 $this->lng,
385 $obj,
386 $this->user,
387 $this->content_style_domain
388 );
389
390 $pageContent = $forwarder->forward();
391 if ($pageContent !== '') {
392 $this->tpl->setContent($pageContent);
393 }
394 break;
395
396 case strtolower(ilLearningProgressGUI::class):
397 if (!ilLearningProgressAccess::checkAccess($this->object->getRefId())) {
398 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
399 }
400
401 $this->tabs_gui->activateTab('learning_progress');
402
403 $usrId = $this->user->getId();
404 if (
405 isset($this->request->getQueryParams()['user_id']) &&
406 is_numeric($this->request->getQueryParams()['user_id'])
407 ) {
408 $usrId = (int) $this->request->getQueryParams()['user_id'];
409 }
410
411 $this->ctrl->forwardCommand(new ilLearningProgressGUI(
413 $this->object->getRefId(),
414 $usrId
415 ));
416 break;
417
418 case strtolower(ilObjectContentStyleSettingsGUI::class):
419 $forum_settings_gui = new ilForumSettingsGUI($this);
420 $forum_settings_gui->settingsTabs();
421 $settings_gui = $this->content_style_gui
422 ->objectSettingsGUIForRefId(
423 null,
424 $this->ref_id
425 );
426 $this->ctrl->forwardCommand($settings_gui);
427 break;
428
429 case strtolower(ilForumSettingsGUI::class):
430 $forum_settings_gui = new ilForumSettingsGUI($this);
431 $this->ctrl->forwardCommand($forum_settings_gui);
432 break;
433
434 case strtolower(ilRepositoryObjectSearchGUI::class):
435 $this->addHeaderAction();
436 $this->setSideBlocks();
437 $this->tabs_gui->activateTab("forums_threads");
438 $this->ctrl->setReturn($this, 'view');
439 $search_gui = new ilRepositoryObjectSearchGUI(
440 $this->object->getRefId(),
441 $this,
442 'view'
443 );
444 $this->ctrl->forwardCommand($search_gui);
445 break;
446
447 case strtolower(ilPermissionGUI::class):
448 $perm_gui = new ilPermissionGUI($this);
449 $this->ctrl->forwardCommand($perm_gui);
450 break;
451
452 case strtolower(ilForumExportGUI::class):
453 $fex_gui = new ilForumExportGUI();
454 $this->ctrl->forwardCommand($fex_gui);
455 $this->http->close();
456 break;
457
458 case strtolower(ilForumModeratorsGUI::class):
459 $fm_gui = new ilForumModeratorsGUI();
460 $this->ctrl->forwardCommand($fm_gui);
461 break;
462
463 case strtolower(ilInfoScreenGUI::class):
464 $this->infoScreen();
465 break;
466
467 case strtolower(ilColumnGUI::class):
468 $this->showThreadsObject();
469 break;
470
471 case strtolower(ilPublicUserProfileGUI::class):
472 $user = $this->retrieveIntOrZeroFrom($this->http->wrapper()->query(), 'user');
473 $profile_gui = new ilPublicUserProfileGUI($user);
474 $add = $this->getUserProfileAdditional($ref_id, $user);
475 $profile_gui->setAdditional($add);
476 $ret = $this->ctrl->forwardCommand($profile_gui);
477 $this->tpl->setContent($ret);
478 break;
479
480 case strtolower(ilObjectCopyGUI::class):
481 $cp = new ilObjectCopyGUI($this);
482 $cp->setType('frm');
483 $this->ctrl->forwardCommand($cp);
484 break;
485
486 case strtolower(ilExportGUI::class):
487 $this->tabs_gui->activateTab('export');
488 $exp = new ilExportGUI($this);
489 $exp->addFormat('xml');
490 $this->ctrl->forwardCommand($exp);
491 break;
492
493 case strtolower(ilRatingGUI::class):
494 if (!$this->objProperties->isIsThreadRatingEnabled() || $this->user->isAnonymous()) {
495 $this->error->raiseError($this->lng->txt('msg_no_perm_read'), $this->error->MESSAGE);
496 }
497
498 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
499 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
500 }
501
502 $this->ensureThreadBelongsToForum($this->object->getId(), $this->objCurrentTopic);
503
504 $rating_gui = new ilRatingGUI();
505 $rating_gui->setObject(
506 $this->object->getId(),
507 $this->object->getType(),
508 $this->objCurrentTopic->getId(),
509 'thread'
510 );
511
512 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
513 $this->ctrl->forwardCommand($rating_gui);
514
516 $this->object->getId(),
517 $this->object->getType(),
518 $this->objCurrentTopic->getId(),
519 'thread'
520 );
521 $this->objCurrentTopic->setAverageRating($avg['avg']);
522 $this->objCurrentTopic->update();
523
524 $this->ctrl->redirect($this, "showThreads");
525
526 // no break
527 case strtolower(ilCommonActionDispatcherGUI::class):
528 $gui = ilCommonActionDispatcherGUI::getInstanceFromAjaxCall();
529 $this->ctrl->forwardCommand($gui);
530 break;
531
532 case strtolower(ilContainerNewsSettingsGUI::class):
533 $forum_settings_gui = new ilForumSettingsGUI($this);
534 $forum_settings_gui->settingsTabs();
535
536 $this->lng->loadLanguageModule('cont');
537 $news_set_gui = new ilContainerNewsSettingsGUI($this);
538 $news_set_gui->setNewsBlockForced(true);
539 $news_set_gui->setPublicNotification(true);
540 $this->ctrl->forwardCommand($news_set_gui);
541 break;
542
543 default:
544 if (in_array($cmd, $this->getTableCommands(), true)) {
545 $notificationCommands = [
546 'enableAdminForceNoti',
547 'disableAdminForceNoti',
548 'enableHideUserToggleNoti',
549 'disableHideUserToggleNoti'
550 ];
551
552 if (!in_array($cmd, $notificationCommands, true)) {
553 $cmd = 'performThreadsAction';
554 }
555 } elseif (($cmd === null || $cmd === '') && $this->getTableCommands() === []) {
556 $cmd = 'showThreads';
557 }
558
559 $cmd .= 'Object';
560 $this->$cmd();
561
562 break;
563 }
564
565 if (
566 $cmd !== 'viewThreadObject' && $cmd !== 'showUserObject' && !in_array(
567 strtolower($next_class),
568 array_map('strtolower', [ilForumPageGUI::class]),
569 true
570 )
571 ) {
572 $this->addHeaderAction();
573 }
574 }
575
579 private function getTableCommands(): array
580 {
581 $tableCommands = [];
582 if ($this->http->wrapper()->post()->has('selected_cmd')) {
583 $tableCommands[] = $this->http->wrapper()->post()->retrieve(
584 'selected_cmd',
585 $this->refinery->kindlyTo()->string()
586 );
587 }
588 if ($this->http->wrapper()->post()->has('selected_cmd2')) {
589 $tableCommands[] = $this->http->wrapper()->post()->retrieve(
590 'selected_cmd2',
591 $this->refinery->kindlyTo()->string()
592 );
593 }
594
595 return $tableCommands;
596 }
597
598 public function infoScreenObject(): void
599 {
600 $this->ctrl->setCmd('showSummary');
601 $this->ctrl->setCmdClass('ilinfoscreengui');
602 $this->infoScreen();
603 }
604
605 protected function initEditCustomForm(ilPropertyFormGUI $a_form): void
606 {
607 $this->forum_settings_gui = new ilForumSettingsGUI($this);
608 $this->forum_settings_gui->getCustomForm($a_form);
609 }
610
611 protected function getEditFormCustomValues(array &$a_values): void
612 {
613 $this->forum_settings_gui->getCustomValues($a_values);
614 }
615
616 protected function updateCustom(ilPropertyFormGUI $form): void
617 {
618 $this->forum_settings_gui->updateCustomValues($form);
619 }
620
621 private function getThreadEditingForm(int $a_thread_id): ilPropertyFormGUI
622 {
623 $form = new ilPropertyFormGUI();
624 $this->ctrl->setParameter($this, 'thr_pk', $a_thread_id);
625 $form->setFormAction($this->ctrl->getFormAction($this, 'updateThread'));
626
627 $ti_prop = new ilTextInputGUI($this->lng->txt('title'), 'title');
628 $ti_prop->setRequired(true);
629 $ti_prop->setMaxLength(255);
630 $ti_prop->setSize(50);
631 $form->addItem($ti_prop);
632
633 $form->addCommandButton('updateThread', $this->lng->txt('save'));
634 $form->addCommandButton('showThreads', $this->lng->txt('cancel'));
635
636 return $form;
637 }
638
639 public function editThreadObject(int $threadId, ilPropertyFormGUI $form = null): void
640 {
641 if (!$this->is_moderator) {
642 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
643 }
644
645 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
646 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
647 }
648
649 $thread = new ilForumTopic($threadId);
650 $this->ensureThreadBelongsToForum($this->object->getId(), $thread);
651
652 $this->tabs_gui->activateTab('forums_threads');
653
654 if (!($form instanceof ilPropertyFormGUI)) {
655 $form = $this->getThreadEditingForm($threadId);
656 $form->setValuesByArray([
657 'title' => $thread->getSubject()
658 ]);
659 }
660
661 $this->tpl->setContent($form->getHTML());
662 }
663
664 public function updateThreadObject(): void
665 {
666 if (!$this->is_moderator) {
667 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
668 }
669
670 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
671 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
672 }
673
674 if (!$this->objCurrentTopic->getId()) {
675 $this->showThreadsObject();
676 return;
677 }
678
679 $this->ensureThreadBelongsToForum($this->object->getId(), $this->objCurrentTopic);
680
681 $form = $this->getThreadEditingForm($this->objCurrentTopic->getId());
682 if (!$form->checkInput()) {
683 $form->setValuesByPost();
684 $this->editThreadObject($this->objCurrentTopic->getId(), $form);
685 return;
686 }
687
688 $this->objCurrentTopic->setSubject($form->getInput('title'));
689 $this->objCurrentTopic->updateThreadTitle();
690
691 $this->tpl->setOnScreenMessage('success', $this->lng->txt('saved_successfully'));
692 $this->showThreadsObject();
693 }
694
695 public function markAllReadObject(): void
696 {
697 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
698 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
699 }
700
701 $this->object->markAllThreadsRead($this->user->getId());
702 $this->tpl->setOnScreenMessage('info', $this->lng->txt('forums_all_threads_marked_read'));
703 $this->showThreadsObject();
704 }
705
706 public function showThreadsObject(): void
707 {
708 $this->getSubTabs();
709 $this->setSideBlocks();
710 $this->getCenterColumnHTML();
711 }
712
713 public function sortThreadsObject(): void
714 {
715 $this->getSubTabs('sortThreads');
716 $this->setSideBlocks();
717 $this->getCenterColumnHTML();
718 }
719
720 public function getSubTabs($subtab = 'showThreads'): void
721 {
722 if ($this->is_moderator && $this->objProperties->getThreadSorting() === 1) {
723 $this->tabs_gui->addSubTabTarget(
724 'show',
725 $this->ctrl->getLinkTarget($this, 'showThreads'),
726 'showThreads',
727 get_class($this),
728 '',
729 $subtab === 'showThreads'
730 );
731
732 if ($this->object->getNumStickyThreads() > 1) {
733 $this->tabs_gui->addSubTabTarget(
734 'sticky_threads_sorting',
735 $this->ctrl->getLinkTarget($this, 'sortThreads'),
736 'sortThreads',
737 get_class($this),
738 '',
739 $subtab === 'sortThreads'
740 );
741 }
742 }
743 }
744
745 public function getContent(): string
746 {
747 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
748 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
749 }
750
751 $cmd = $this->ctrl->getCmd();
752 $frm = $this->object->Forum;
753 $frm->setForumId($this->object->getId());
754 $frm->setForumRefId($this->object->getRefId());
755 $frm->setMDB2Wherecondition('top_frm_fk = %s ', ['integer'], [$frm->getForumId()]);
756
757 $threadsTemplate = new ilTemplate(
758 'tpl.forums_threads_liste.html',
759 true,
760 true,
761 'Modules/Forum'
762 );
763
764 if ($this->confirmation_gui_html !== '') {
765 $threadsTemplate->setVariable('CONFIRMATION_GUI', $this->confirmation_gui_html);
766 }
767
768 // Create topic button
769 if (!$this->hideToolbar() && $this->access->checkAccess('add_thread', '', $this->object->getRefId())) {
771 $btn->setUrl($this->ctrl->getLinkTarget($this, 'createThread'));
772 $btn->setCaption('forums_new_thread');
773 $this->toolbar->addStickyItem($btn);
774 }
775
776 // Mark all topics as read button
777 if ($this->confirmation_gui_html === '' && !$this->user->isAnonymous()) {
778 $this->toolbar->addButton(
779 $this->lng->txt('forums_mark_read'),
780 $this->ctrl->getLinkTarget($this, 'markAllRead')
781 );
782 $this->ctrl->clearParameters($this);
783 }
784
785 if (!$this->user->isAnonymous() && $this->access->checkAccess('write', '', $this->ref_id)) {
786 $this->lng->loadLanguageModule('cntr');
787 $this->toolbar->addComponent(
788 $this->uiFactory->button()->standard(
789 $this->lng->txt('cntr_text_media_editor'),
790 $this->ctrl->getLinkTargetByClass(ilForumPageGUI::class, 'edit')
791 )
792 );
793 }
794
797 $this->user->getId(),
798 ilObjForum::lookupForumIdByObjId($this->object->getId())
799 );
800 if (count($drafts) > 0) {
801 $draftsTable = new ilForumDraftsTableGUI(
802 $this,
803 $cmd,
804 $this->access->checkAccess('add_thread', '', $this->object->getRefId())
805 );
806 $draftsTable->setData($drafts);
807 $threadsTemplate->setVariable('THREADS_DRAFTS_TABLE', $draftsTable->getHTML());
808 }
809 }
810
811 // Import information: Topic (variable $topicData) means frm object, not thread
812 $topicData = $frm->getOneTopic();
813 if ($topicData->getTopPk() > 0) {
814 $frm->setDbTable('frm_data');
815 $frm->setMDB2WhereCondition('top_pk = %s ', ['integer'], [$topicData->getTopPk()]);
816 $frm->updateVisits($topicData->getTopPk());
817
819 $this->object->getType(),
820 $this->object->getRefId(),
821 $this->object->getId(),
822 $this->user->getId()
823 );
824
825 if (!in_array($cmd, ['showThreads', 'sortThreads'])) {
826 $cmd = 'showThreads';
827 }
828
829 $ref_id = $this->retrieveRefId();
830
831 $tbl = new ilForumTopicTableGUI(
832 $this,
833 $cmd,
834 $ref_id,
835 $topicData,
836 $this->is_moderator,
837 (int) (new ilSetting('frma'))->get('forum_overview', (string) ilForumProperties::FORUM_OVERVIEW_WITH_NEW_POSTS)
838 );
839 $tbl->init();
840 $tbl->setMapper($frm)->fetchData();
841 $threadsTemplate->setVariable('THREADS_TABLE', $tbl->getHTML());
842 }
843
844 $this->tpl->setPermanentLink($this->object->getType(), $this->object->getRefId(), '', '_top');
845
846 $this->initStyleSheets();
847
848 $forwarder = new ilForumPageCommandForwarder(
849 $GLOBALS['DIC']['http'],
850 $this->ctrl,
851 $this->tabs_gui,
852 $this->lng,
853 $this->object,
854 $this->user,
855 $this->content_style_domain
856 );
858
859 $this->tpl->setContent($forwarder->forward() . $threadsTemplate->get());
860
861 return '';
862 }
863
864 protected function initStyleSheets(): void
865 {
866 $this->content_style_gui->addCss($this->tpl, $this->ref_id);
867 $this->tpl->setCurrentBlock('SyntaxStyle');
868 $this->tpl->setVariable('LOCATION_SYNTAX_STYLESHEET', ilObjStyleSheet::getSyntaxStylePath());
869 $this->tpl->parseCurrentBlock();
870 }
871
881 protected function renderDraftContent(
883 string $action,
884 ilForumPost $referencePosting,
885 array $drafts
886 ): void {
887 $frm = $this->object->Forum;
888
889 $ref_id = $this->retrieveRefId();
890 $draft_id = $this->retrieveDraftId();
891
892 foreach ($drafts as $draft) {
893 $tmp_file_obj = new ilFileDataForumDrafts($this->object->getId(), $draft->getDraftId());
894 $filesOfDraft = $tmp_file_obj->getFilesOfPost();
895 ksort($filesOfDraft);
896
897 if ($action !== 'showdraft' && $filesOfDraft !== []) {
898 foreach ($filesOfDraft as $file) {
899 $tpl->setCurrentBlock('attachment_download_row');
900 $this->ctrl->setParameter($this, 'draft_id', $tmp_file_obj->getDraftId());
901 $this->ctrl->setParameter($this, 'file', $file['md5']);
902 $tpl->setVariable('HREF_DOWNLOAD', $this->ctrl->getLinkTarget($this, 'viewThread'));
903 $tpl->setVariable('TXT_FILENAME', $file['name']);
904 $this->ctrl->setParameter($this, 'file', '');
905 $this->ctrl->setParameter($this, 'draft_id', '');
906 $this->ctrl->clearParameters($this);
907 $tpl->parseCurrentBlock();
908 }
909
910 $tpl->setCurrentBlock('attachments');
911 $tpl->setVariable('TXT_ATTACHMENTS_DOWNLOAD', $this->lng->txt('forums_attachments'));
912 $tpl->setVariable(
913 'DOWNLOAD_IMG',
914 ilGlyphGUI::get(ilGlyphGUI::ATTACHMENT, $this->lng->txt('forums_download_attachment'))
915 );
916 if (count($filesOfDraft) > 1) {
917 $download_zip_button = ilLinkButton::getInstance();
918 $download_zip_button->setCaption($this->lng->txt('download'), false);
919 $this->ctrl->setParameter($this, 'draft_id', $draft->getDraftId());
920 $download_zip_button->setUrl($this->ctrl->getLinkTarget($this, 'deliverDraftZipFile'));
921 $this->ctrl->setParameter($this, 'draft_id', '');
922 $tpl->setVariable('DOWNLOAD_ZIP', $download_zip_button->render());
923 }
924 $tpl->parseCurrentBlock();
925 }
926
927 $page = 0;
928 if ($this->http->wrapper()->query()->has('page')) {
929 $page = $this->http->wrapper()->query()->retrieve(
930 'page',
931 $this->refinery->kindlyTo()->int()
932 );
933 }
934 $this->renderSplitButton(
935 $tpl,
936 $action,
937 false,
938 $referencePosting,
939 (int) $page,
940 $draft
941 );
942
943 $rowCol = 'tblrowmarked';
944 $tpl->setVariable('ROWCOL', ' ' . $rowCol);
945 $depth = $referencePosting->getDepth() - 1;
946 if ($this->selectedSorting === ilForumProperties::VIEW_TREE) {
947 ++$depth;
948 }
949 $tpl->setVariable('DEPTH', $depth);
950
951 $this->ctrl->setParameter($this, 'pos_pk', $referencePosting->getId());
952 $this->ctrl->setParameter($this, 'thr_pk', $referencePosting->getThreadId());
953 $this->ctrl->setParameter($this, 'draft_id', $draft->getDraftId());
954
955 $backurl = urlencode($this->ctrl->getLinkTarget($this, 'viewThread', (string) $referencePosting->getId()));
956
957 $this->ctrl->setParameter($this, 'backurl', $backurl);
958 $this->ctrl->setParameter($this, 'thr_pk', $referencePosting->getThreadId());
959 $this->ctrl->setParameter($this, 'user', $draft->getPostDisplayUserId());
960
961 $authorinfo = new ilForumAuthorInformation(
962 $draft->getPostAuthorId(),
963 $draft->getPostDisplayUserId(),
964 $draft->getPostUserAlias(),
965 '',
966 [
967 'href' => $this->ctrl->getLinkTarget($this, 'showUser')
968 ]
969 );
970
971 $this->ctrl->clearParameters($this);
972
973 if ($authorinfo->hasSuffix()) {
974 $tpl->setVariable('AUTHOR', $authorinfo->getSuffix());
975 $tpl->setVariable('USR_NAME', $draft->getPostUserAlias());
976 } else {
977 $tpl->setVariable('AUTHOR', $authorinfo->getLinkedAuthorShortName());
978 if ($authorinfo->getAuthorName(true) && !$this->objProperties->isAnonymized()) {
979 $tpl->setVariable('USR_NAME', $authorinfo->getAuthorName(true));
980 }
981 }
982 $tpl->setVariable('DRAFT_ANCHOR', 'draft_' . $draft->getDraftId());
983
984 $tpl->setVariable('USR_IMAGE', $authorinfo->getProfilePicture());
985 $tpl->setVariable(
986 'USR_ICON_ALT',
987 ilLegacyFormElementsUtil::prepareFormOutput($authorinfo->getAuthorShortName())
988 );
989 if ($authorinfo->getAuthor()->getId() && ilForum::_isModerator(
990 $ref_id,
991 $draft->getPostAuthorId()
992 )) {
993 if ($authorinfo->getAuthor()->getGender() === 'f') {
994 $tpl->setVariable('ROLE', $this->lng->txt('frm_moderator_f'));
995 } elseif ($authorinfo->getAuthor()->getGender() === 'm') {
996 $tpl->setVariable('ROLE', $this->lng->txt('frm_moderator_m'));
997 } elseif ($authorinfo->getAuthor()->getGender() === 'n') {
998 $tpl->setVariable('ROLE', $this->lng->txt('frm_moderator_n'));
999 }
1000 }
1001
1002 if ($draft->getUpdateUserId() > 0) {
1003 $draft->setPostUpdate($draft->getPostUpdate());
1004
1005 $this->ctrl->setParameter($this, 'backurl', $backurl);
1006 $this->ctrl->setParameter($this, 'thr_pk', $referencePosting->getThreadId());
1007 $this->ctrl->setParameter($this, 'user', $referencePosting->getUpdateUserId());
1008 $this->ctrl->setParameter($this, 'draft_id', $draft->getDraftId());
1009
1010 $authorinfo = new ilForumAuthorInformation(
1011 $draft->getPostAuthorId(),
1012 // We assume the editor is the author here
1013 $draft->getPostDisplayUserId(),
1014 $draft->getPostUserAlias(),
1015 '',
1016 ['href' => $this->ctrl->getLinkTarget($this, 'showUser')]
1017 );
1018
1019 $this->ctrl->clearParameters($this);
1020
1021 $tpl->setVariable(
1022 'POST_UPDATE_TXT',
1023 $this->lng->txt('edited_on') . ': ' . $frm->convertDate($draft->getPostUpdate()) . ' - ' . strtolower($this->lng->txt('by'))
1024 );
1025 $tpl->setVariable('UPDATE_AUTHOR', $authorinfo->getLinkedAuthorShortName());
1026 if ($authorinfo->getAuthorName(true) && !$this->objProperties->isAnonymized() && !$authorinfo->hasSuffix()) {
1027 $tpl->setVariable('UPDATE_USR_NAME', $authorinfo->getAuthorName(true));
1028 }
1029 }
1030
1031 $draft->setPostMessage($frm->prepareText($draft->getPostMessage()));
1032
1033 $tpl->setVariable('SUBJECT', $draft->getPostSubject());
1034 $tpl->setVariable('POST_DATE', $frm->convertDate($draft->getPostDate()));
1035
1036 if (!$referencePosting->isCensored() || ($this->objCurrentPost->getId() === $referencePosting->getId() && $action === 'censor')) {
1037 $spanClass = '';
1038 if (ilForum::_isModerator($this->ref_id, $draft->getPostDisplayUserId())) {
1039 $spanClass = 'moderator';
1040 }
1041
1042 if ($draft->getPostMessage() === strip_tags($draft->getPostMessage())) {
1043 // We can be sure, that there are not html tags
1044 $draft->setPostMessage(nl2br($draft->getPostMessage()));
1045 }
1046
1047 if ($spanClass !== "") {
1048 $tpl->setVariable(
1049 'POST',
1050 "<span class=\"" . $spanClass . "\">" . ilRTE::_replaceMediaObjectImageSrc(
1051 $draft->getPostMessage(),
1052 1
1053 ) . "</span>"
1054 );
1055 } else {
1056 $tpl->setVariable('POST', ilRTE::_replaceMediaObjectImageSrc($draft->getPostMessage(), 1));
1057 }
1058 }
1059
1060 if ($action === 'editdraft' && $draft->getDraftId() === $draft_id) {
1061 $oEditReplyForm = $this->getReplyEditForm();
1062
1063 if (!$this->objCurrentTopic->isClosed() && in_array($this->requestAction, ['showdraft', 'editdraft'])) {
1064 $this->renderPostingForm($tpl, $frm, $referencePosting, $this->requestAction);
1065 }
1066
1067 $tpl->setVariable('EDIT_DRAFT_ANCHOR', 'draft_edit_' . $draft->getDraftId());
1068 $tpl->setVariable('DRAFT_FORM', $oEditReplyForm->getHTML() . $this->modal_history);
1069 }
1070
1071 $tpl->parseCurrentBlock();
1072 }
1073 }
1074
1075 protected function renderPostContent(
1077 ilForumPost $node,
1078 string $action,
1079 int $pageIndex,
1080 int $postIndex
1081 ): void {
1082 $forumObj = $this->object;
1083 $frm = $this->object->Forum;
1084
1085 $fileDataOfForum = new ilFileDataForum($forumObj->getId(), $node->getId());
1086
1087 $filesOfPost = $fileDataOfForum->getFilesOfPost();
1088 ksort($filesOfPost);
1089 if (count($filesOfPost) > 0) {
1090 if ($action !== 'showedit' || $node->getId() !== $this->objCurrentPost->getId()) {
1091 foreach ($filesOfPost as $file) {
1092 $tpl->setCurrentBlock('attachment_download_row');
1093 $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
1094 $this->ctrl->setParameter($this, 'file', $file['md5']);
1095 $tpl->setVariable('HREF_DOWNLOAD', $this->ctrl->getLinkTarget($this, 'viewThread'));
1096 $tpl->setVariable('TXT_FILENAME', $file['name']);
1097 $this->ctrl->clearParameters($this);
1098 $tpl->parseCurrentBlock();
1099 }
1100
1101 $tpl->setCurrentBlock('attachments');
1102 $tpl->setVariable('TXT_ATTACHMENTS_DOWNLOAD', $this->lng->txt('forums_attachments'));
1103 $tpl->setVariable(
1104 'DOWNLOAD_IMG',
1105 ilGlyphGUI::get(ilGlyphGUI::ATTACHMENT, $this->lng->txt('forums_download_attachment'))
1106 );
1107 if (count($filesOfPost) > 1) {
1108 $download_zip_button = ilLinkButton::getInstance();
1109 $download_zip_button->setCaption($this->lng->txt('download'), false);
1110 $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
1111 $download_zip_button->setUrl($this->ctrl->getLinkTarget($this, 'deliverZipFile'));
1112
1113 $tpl->setVariable('DOWNLOAD_ZIP', $download_zip_button->render());
1114 }
1115
1116 $tpl->parseCurrentBlock();
1117 }
1118 }
1119 $this->renderSplitButton($tpl, $action, true, $node, $pageIndex);
1120
1121 $tpl->setVariable('POST_ANKER', $node->getId());
1122 $tpl->setVariable('TXT_PERMA_LINK', $this->lng->txt('perma_link'));
1123 $tpl->setVariable('PERMA_TARGET', '_top');
1124
1125 $rowCol = ilUtil::switchColor($postIndex, 'tblrow1', 'tblrow2');
1126 if (($this->is_moderator || $node->isOwner($this->user->getId())) && !$node->isActivated() && !$this->objCurrentTopic->isClosed()) {
1127 $rowCol = 'ilPostingNeedsActivation';
1128 } elseif ($this->objProperties->getMarkModeratorPosts()) {
1129 $isAuthorModerator = ilForum::_isModerator($this->object->getRefId(), $node->getPosAuthorId());
1130 if ($isAuthorModerator && $node->isAuthorModerator() === null) {
1131 $rowCol = 'ilModeratorPosting';
1132 } elseif ($node->isAuthorModerator()) {
1133 $rowCol = 'ilModeratorPosting';
1134 }
1135 }
1136
1137 if (
1138 (!in_array($action, ['delete', 'censor']) && !$this->displayConfirmPostActivation()) ||
1139 $this->objCurrentPost->getId() !== $node->getId()
1140 ) {
1141 $tpl->setVariable('ROWCOL', ' ' . $rowCol);
1142 } else {
1143 $rowCol = 'tblrowmarked';
1144 }
1145
1146 if ($node->isCensored()) {
1147 if ($action !== 'censor') {
1148 $tpl->setVariable('TXT_CENSORSHIP_ADVICE', $this->lng->txt('post_censored_comment_by_moderator'));
1149 }
1150
1151 $rowCol = 'tblrowmarked';
1152 }
1153
1154 $tpl->setVariable('ROWCOL', ' ' . $rowCol);
1155 $tpl->setVariable('DEPTH', $node->getDepth() - 1);
1156 if (!$node->isActivated() && ($node->isOwner($this->user->getId()) || $this->is_moderator)) {
1157 $tpl->setVariable('POST_NOT_ACTIVATED_YET', $this->lng->txt('frm_post_not_activated_yet'));
1158 }
1159
1160 $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
1161 $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
1162 $backurl = urlencode($this->ctrl->getLinkTarget($this, 'viewThread', (string) $node->getId()));
1163 $this->ctrl->clearParameters($this);
1164
1165 $this->ctrl->setParameter($this, 'backurl', $backurl);
1166 $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
1167 $this->ctrl->setParameter($this, 'user', $node->getDisplayUserId());
1168 $authorinfo = new ilForumAuthorInformation(
1169 $node->getPosAuthorId(),
1170 $node->getDisplayUserId(),
1171 (string) $node->getUserAlias(),
1172 (string) $node->getImportName(),
1173 [
1174 'href' => $this->ctrl->getLinkTarget($this, 'showUser')
1175 ]
1176 );
1177 $this->ctrl->clearParameters($this);
1178
1179 if ($authorinfo->hasSuffix()) {
1180 if (!$authorinfo->isDeleted()) {
1181 $tpl->setVariable('USR_NAME', $authorinfo->getAlias());
1182 }
1183 $tpl->setVariable('AUTHOR', $authorinfo->getSuffix());
1184 } else {
1185 if ($authorinfo->getAuthorName(true) && !$this->objProperties->isAnonymized()) {
1186 $tpl->setVariable('USR_NAME', $authorinfo->getAuthorName(true));
1187 }
1188 $tpl->setVariable('AUTHOR', $authorinfo->getLinkedAuthorShortName());
1189 }
1190
1191 $tpl->setVariable('USR_IMAGE', $authorinfo->getProfilePicture());
1192 $tpl->setVariable(
1193 'USR_ICON_ALT',
1194 ilLegacyFormElementsUtil::prepareFormOutput($authorinfo->getAuthorShortName())
1195 );
1196 $isModerator = ilForum::_isModerator($this->ref_id, $node->getPosAuthorId());
1197 if ($isModerator && $authorinfo->getAuthor()->getId()) {
1198 $authorRole = $this->lng->txt('frm_moderator_n');
1199 if (is_string($authorinfo->getAuthor()->getGender()) && $authorinfo->getAuthor()->getGender() !== '') {
1200 $authorRole = $this->lng->txt('frm_moderator_' . $authorinfo->getAuthor()->getGender());
1201 }
1202 $tpl->setVariable('ROLE', $authorRole);
1203 }
1204
1205 if ($node->getUpdateUserId() > 0) {
1206 $node->setChangeDate($node->getChangeDate());
1207
1208 $this->ctrl->setParameter($this, 'backurl', $backurl);
1209 $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
1210 $this->ctrl->setParameter($this, 'user', $node->getUpdateUserId());
1211 $update_user_id = $node->getUpdateUserId();
1212 if ($node->getDisplayUserId() === 0 && $node->getPosAuthorId() === $node->getUpdateUserId()) {
1213 $update_user_id = $node->getDisplayUserId();
1214 }
1215 $authorinfo = new ilForumAuthorInformation(
1216 $node->getPosAuthorId(),
1217 $update_user_id,
1218 (string) $node->getUserAlias(),
1219 (string) $node->getImportName(),
1220 [
1221 'href' => $this->ctrl->getLinkTarget($this, 'showUser')
1222 ]
1223 );
1224 $this->ctrl->clearParameters($this);
1225
1226 $tpl->setVariable(
1227 'POST_UPDATE_TXT',
1228 $this->lng->txt('edited_on') . ': ' . $frm->convertDate($node->getChangeDate()) . ' - ' . strtolower($this->lng->txt('by'))
1229 );
1230 $tpl->setVariable('UPDATE_AUTHOR', $authorinfo->getLinkedAuthorShortName());
1231 if ($authorinfo->getAuthorName(true) && !$this->objProperties->isAnonymized() && !$authorinfo->hasSuffix()) {
1232 $tpl->setVariable('UPDATE_USR_NAME', $authorinfo->getAuthorName(true));
1233 }
1234 }
1235
1236 if ($this->selectedSorting === ilForumProperties::VIEW_TREE
1237 && $node->getId() !== $this->selected_post_storage->get($node->getThreadId())) {
1238 $target = $this->uiFactory->symbol()->icon()->custom(
1239 ilUtil::getImagePath('target.svg'),
1240 $this->lng->txt('target_select')
1241 );
1242
1243 $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
1244 $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
1245
1246 $tpl->setVariable(
1247 'TARGET',
1248 $this->uiRenderer->render(
1249 $this->uiFactory->link()->bulky(
1250 $target,
1251 $this->lng->txt('select'),
1252 new \ILIAS\Data\URI(
1253 ILIAS_HTTP_PATH . '/' . $this->ctrl->getLinkTarget($this, 'selectPost', (string) $node->getId())
1254 )
1255 )
1256 )
1257 );
1258 }
1259
1260 $node->setMessage($frm->prepareText($node->getMessage()));
1261
1262 if ($this->user->isAnonymous() || $node->isPostRead()) {
1263 $tpl->setVariable('SUBJECT', $node->getSubject());
1264 } else {
1265 $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
1266 $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
1267 $this->ctrl->setParameter($this, 'page', $pageIndex);
1268 $this->ctrl->setParameter(
1269 $this,
1270 'orderby',
1271 $this->getOrderByParam()
1272 );
1273 $this->ctrl->setParameter($this, 'viewmode', $this->selectedSorting);
1274 $mark_post_target = $this->ctrl->getLinkTarget($this, 'markPostRead', (string) $node->getId());
1275
1276 $tpl->setVariable(
1277 'SUBJECT',
1278 "<a href=\"" . $mark_post_target . "\"><b>" . $node->getSubject() . "</b></a>"
1279 );
1280 }
1281
1282 $tpl->setVariable('POST_DATE', $frm->convertDate($node->getCreateDate()));
1283
1284 if (!$node->isCensored() || ($this->objCurrentPost->getId() === $node->getId() && $action === 'censor')) {
1285 $spanClass = "";
1286 if (ilForum::_isModerator($this->ref_id, $node->getDisplayUserId())) {
1287 $spanClass = 'moderator';
1288 }
1289
1290 // possible bugfix for mantis #8223
1291 if ($node->getMessage() === strip_tags($node->getMessage())) {
1292 // We can be sure, that there are not html tags
1293 $node->setMessage(nl2br($node->getMessage()));
1294 }
1295
1296 if ($spanClass !== '') {
1297 $tpl->setVariable(
1298 'POST',
1299 "<span class=\"" . $spanClass . "\">" .
1301 "</span>"
1302 );
1303 } else {
1304 $tpl->setVariable('POST', ilRTE::_replaceMediaObjectImageSrc($node->getMessage(), 1));
1305 }
1306 } else {
1307 $tpl->setVariable('POST', "<span class=\"moderator\">" . nl2br((string) $node->getCensorshipComment()) . "</span>");
1308 }
1309
1310 $tpl->parseCurrentBlock();
1311 }
1312
1313 protected function selectPostObject(): void
1314 {
1315 $thr_pk = (int) $this->httpRequest->getQueryParams()['thr_pk'];
1316 $pos_pk = (int) $this->httpRequest->getQueryParams()['pos_pk'];
1317
1318 $this->selected_post_storage->set(
1319 $thr_pk,
1320 $pos_pk
1321 );
1322
1323 $this->viewThreadObject();
1324 }
1325
1329 protected function afterSave(ilObject $new_object): void
1330 {
1331 $this->tpl->setOnScreenMessage('success', $this->lng->txt('frm_added'), true);
1332 $this->ctrl->setParameter($this, 'ref_id', $new_object->getRefId());
1333 $this->ctrl->redirect($this, 'createThread');
1334 }
1335
1336 protected function getTabs(): void
1337 {
1338 $this->ilHelp->setScreenIdComponent("frm");
1339
1340 $this->ctrl->setParameter($this, 'ref_id', $this->ref_id);
1341
1342 $active = [
1343 '',
1344 'showThreads',
1345 'sortThreads',
1346 'view',
1347 'markAllRead',
1348 'enableForumNotification',
1349 'disableForumNotification',
1350 'moveThreads',
1351 'performMoveThreads',
1352 'cancelMoveThreads',
1353 'performThreadsAction',
1354 'createThread',
1355 'addThread',
1356 'showUser',
1357 'confirmDeleteThreads',
1358 'merge',
1359 'mergeThreads',
1360 'performMergeThreads'
1361 ];
1362
1363 $force_active = false;
1364 if (in_array($this->ctrl->getCmd(), $active, true)) {
1365 $force_active = true;
1366 }
1367
1368 if ($this->access->checkAccess(
1369 'read',
1370 '',
1371 $this->ref_id
1372 )) {
1373 $this->tabs_gui->addTarget(
1374 self::UI_TAB_ID_THREADS,
1375 $this->ctrl->getLinkTarget($this, 'showThreads'),
1376 $this->ctrl->getCmd(),
1377 get_class($this),
1378 '',
1379 $force_active
1380 );
1381 }
1382
1383 if ($this->access->checkAccess('visible', '', $this->ref_id) || $this->access->checkAccess(
1384 'read',
1385 '',
1386 $this->ref_id
1387 )) {
1388 $cmdClass = '';
1389 if ($this->http->wrapper()->query()->has('cmdClass')) {
1390 $cmdClass = $this->http->wrapper()->query()->retrieve(
1391 'cmdClass',
1392 $this->refinery->kindlyTo()->string()
1393 );
1394 }
1395
1396 $force_active = $this->ctrl->getNextClass() === 'ilinfoscreengui' || strtolower($cmdClass) === 'ilnotegui';
1397 $this->tabs_gui->addTarget(
1398 self::UI_TAB_ID_INFO,
1399 $this->ctrl->getLinkTargetByClass([__CLASS__, ilInfoScreenGUI::class], 'showSummary'),
1400 ['showSummary', 'infoScreen'],
1401 '',
1402 '',
1403 $force_active
1404 );
1405 }
1406
1407 if ($this->access->checkAccess('write', '', $this->ref_id)) {
1408 $force_active = $this->ctrl->getCmd() === 'edit';
1409 $this->tabs_gui->addTarget(
1410 self::UI_TAB_ID_SETTINGS,
1411 $this->ctrl->getLinkTarget($this, 'edit'),
1412 'edit',
1413 get_class($this),
1414 '',
1415 $force_active
1416 );
1417 }
1418
1419 if ($this->access->checkAccess('write', '', $this->ref_id)) {
1420 $this->tabs_gui->addTarget(
1421 self::UI_TAB_ID_MODERATORS,
1422 $this->ctrl->getLinkTargetByClass(ilForumModeratorsGUI::class, 'showModerators'),
1423 'showModerators',
1424 get_class($this)
1425 );
1426 }
1427
1428 if (ilLearningProgressAccess::checkAccess($this->object->getRefId())) {
1429 $this->tabs_gui->addTab(
1430 'learning_progress',
1431 $this->lng->txt('learning_progress'),
1432 $this->ctrl->getLinkTargetByClass(ilLearningProgressGUI::class)
1433 );
1434 }
1435
1436 if ($this->settings->get('enable_fora_statistics', '0')) {
1437 $hasStatisticsAccess = $this->access->checkAccess('write', '', $this->ref_id);
1438 if (!$hasStatisticsAccess) {
1439 $hasStatisticsAccess = (
1440 $this->objProperties->isStatisticEnabled() &&
1441 $this->access->checkAccess('read', '', $this->ref_id)
1442 );
1443 }
1444
1445 if ($hasStatisticsAccess) {
1446 $force_active = $this->ctrl->getCmd() === 'showStatistics';
1447 $this->tabs_gui->addTarget(
1448 self::UI_TAB_ID_STATS,
1449 $this->ctrl->getLinkTarget($this, 'showStatistics'),
1450 'showStatistics',
1451 get_class($this),
1452 '',
1453 $force_active
1454 );
1455 }
1456 }
1457
1458 if ($this->access->checkAccess('write', '', $this->object->getRefId())) {
1459 $this->tabs_gui->addTarget(
1460 self::UI_TAB_ID_EXPORT,
1461 $this->ctrl->getLinkTargetByClass(ilExportGUI::class, ''),
1462 '',
1463 'ilexportgui'
1464 );
1465 }
1466
1467 if ($this->access->checkAccess('edit_permission', '', $this->ref_id)) {
1468 $this->tabs_gui->addTarget(
1469 self::UI_TAB_ID_PERMISSIONS,
1470 $this->ctrl->getLinkTargetByClass([get_class($this), ilPermissionGUI::class], 'perm'),
1471 ['perm', 'info', 'owner'],
1472 'ilpermissiongui'
1473 );
1474 }
1475 }
1476
1477 public function showStatisticsObject(): void
1478 {
1479 if (!$this->settings->get('enable_fora_statistics', '0')) {
1480 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1481 }
1482
1483 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
1484 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1485 }
1486
1487 if (!$this->objProperties->isStatisticEnabled()) {
1488 if ($this->access->checkAccess('write', '', $this->object->getRefId())) {
1489 $this->tpl->setOnScreenMessage('info', $this->lng->txt('frm_statistics_disabled_for_participants'));
1490 } else {
1491 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1492 }
1493 }
1494
1495 $this->object->Forum->setForumId($this->object->getId());
1496
1497 $tbl = new ilForumStatisticsTableGUI(
1498 $this,
1499 'showStatistics',
1500 $this->object,
1501 $this->user,
1503 $this->access->checkRbacOrPositionPermissionAccess(
1504 'read_learning_progress',
1505 'read_learning_progress',
1506 $this->object->getRefId()
1507 )
1508 );
1509 $tbl->setId('il_frm_statistic_table_' . $this->object->getRefId());
1510 $tbl->setTitle(
1511 $this->lng->txt('statistic'),
1512 'icon_usr.svg',
1513 $this->lng->txt('obj_' . $this->object->getType())
1514 );
1515
1516 $data = $this->object->Forum->getUserStatistics($this->objProperties->isPostActivationEnabled());
1517 $result = [];
1518 $counter = 0;
1519 foreach ($data as $row) {
1520 $result[$counter]['usr_id'] = $row['usr_id'];
1521 $result[$counter]['ranking'] = $row['num_postings'];
1522 $result[$counter]['login'] = $row['login'];
1523 $result[$counter]['lastname'] = $row['lastname'];
1524 $result[$counter]['firstname'] = $row['firstname'];
1525
1526 ++$counter;
1527 }
1528 $tbl->setData($result);
1529
1530 $this->tpl->setContent($tbl->getHTML());
1531 }
1532
1533 public static function _goto($a_target, $a_thread = 0, $a_posting = 0): void
1534 {
1535 global $DIC;
1536 $main_tpl = $DIC->ui()->mainTemplate();
1537
1538 $ilAccess = $DIC->access();
1539 $lng = $DIC->language();
1540 $ilErr = $DIC['ilErr'];
1541
1542 $a_target = is_numeric($a_target) ? (int) $a_target : 0;
1543 $a_thread = is_numeric($a_thread) ? (int) $a_thread : 0;
1544 if ($ilAccess->checkAccess('read', '', $a_target)) {
1545 if ($a_thread !== 0) {
1546 $objTopic = new ilForumTopic($a_thread);
1547 if ($objTopic->getFrmObjId() &&
1548 $objTopic->getFrmObjId() !== ilObject::_lookupObjectId($a_target)) {
1549 $ref_ids = ilObject::_getAllReferences($objTopic->getFrmObjId());
1550 foreach ($ref_ids as $ref_id) {
1551 if ($ilAccess->checkAccess('read', '', $ref_id)) {
1552 $new_ref_id = $ref_id;
1553 break;
1554 }
1555 }
1556
1557 if (isset($new_ref_id) && $new_ref_id !== $a_target) {
1558 $DIC->ctrl()->redirectToURL(
1559 ILIAS_HTTP_PATH . '/goto.php?target=frm_' . $new_ref_id . '_' . $a_thread . '_' . $a_posting
1560 );
1561 }
1562 }
1563
1564 $DIC->ctrl()->setParameterByClass(__CLASS__, 'ref_id', (string) ((int) $a_target));
1565 if (is_numeric($a_thread)) {
1566 $DIC->ctrl()->setParameterByClass(__CLASS__, 'thr_pk', (string) ((int) $a_thread));
1567 }
1568 if (is_numeric($a_posting)) {
1569 $DIC->ctrl()->setParameterByClass(__CLASS__, 'pos_pk', (string) ((int) $a_posting));
1570 }
1571 $DIC->ctrl()->redirectByClass(
1572 [ilRepositoryGUI::class, self::class],
1573 'viewThread',
1574 is_numeric($a_posting) ? (string) ((int) $a_posting) : ''
1575 );
1576 } else {
1577 $DIC->ctrl()->setParameterByClass(self::class, 'ref_id', $a_target);
1578 $DIC->ctrl()->redirectByClass([ilRepositoryGUI::class, self::class,], '');
1579 $DIC->http()->close();
1580 }
1581 } elseif ($ilAccess->checkAccess('visible', '', $a_target)) {
1582 $DIC->ctrl()->setParameterByClass(ilInfoScreenGUI::class, 'ref_id', $a_target);
1583 $DIC->ctrl()->redirectByClass(
1584 [
1585 ilRepositoryGUI::class,
1586 self::class,
1587 ilInfoScreenGUI::class
1588 ],
1589 'showSummary'
1590 );
1591 } elseif ($ilAccess->checkAccess('read', '', ROOT_FOLDER_ID)) {
1592 $main_tpl->setOnScreenMessage('info', sprintf(
1593 $lng->txt('msg_no_perm_read_item'),
1595 ), true);
1596 $DIC->http()->close();
1597 }
1598
1599 $ilErr->raiseError($lng->txt('msg_no_perm_read'), $ilErr->FATAL);
1600 }
1601
1602 public function performDeleteThreadsObject(): void
1603 {
1604 $threadIds = $this->retrieveThreadIds();
1605 if ($threadIds === []) {
1606 $this->tpl->setOnScreenMessage('info', $this->lng->txt('select_at_least_one_thread'), true);
1607 $this->ctrl->redirect($this, 'showThreads');
1608 }
1609
1610 if (!$this->is_moderator) {
1611 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1612 }
1613
1614 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
1615 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1616 }
1617
1618 $forumObj = new ilObjForum($this->object->getRefId());
1619 $this->objProperties->setObjId($forumObj->getId());
1620
1621 $frm = new ilForum();
1622
1623 $success_message = "forums_thread_deleted";
1624 if (count($threadIds) > 1) {
1625 $success_message = "forums_threads_deleted";
1626 }
1627
1628 $threads = [];
1629 array_walk($threadIds, function (int $threadId) use (&$threads) {
1630 $thread = new ilForumTopic($threadId);
1631 $this->ensureThreadBelongsToForum($this->object->getId(), $thread);
1632
1633 $threads[] = $thread;
1634 });
1635
1636 $frm->setForumId($forumObj->getId());
1637 $frm->setForumRefId($forumObj->getRefId());
1638 foreach ($threads as $thread) {
1639 $first_node = $frm->getFirstPostNode($thread->getId());
1640 if (isset($first_node['pos_pk']) && (int) $first_node['pos_pk']) {
1641 $frm->deletePost((int) $first_node['pos_pk']);
1642 $this->tpl->setOnScreenMessage('info', $this->lng->txt($success_message), true);
1643 }
1644 }
1645 $this->ctrl->redirect($this, 'showThreads');
1646 }
1647
1648 public function confirmDeleteThreads(): void
1649 {
1650 $thread_ids = $this->retrieveThreadIds();
1651 if ($thread_ids === []) {
1652 $this->tpl->setOnScreenMessage('info', $this->lng->txt('select_at_least_one_thread'));
1653 $this->ctrl->redirect($this, 'showThreads');
1654 }
1655
1656 if (!$this->is_moderator) {
1657 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1658 }
1659
1660 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
1661 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1662 }
1663
1665 $threads = [];
1666 array_walk($thread_ids, function (int $threadId) use (&$threads): void {
1667 $thread = new ilForumTopic($threadId);
1668 $this->ensureThreadBelongsToForum($this->object->getId(), $thread);
1669
1670 $threads[] = $thread;
1671 });
1672
1673 $c_gui = new ilConfirmationGUI();
1674
1675 $c_gui->setFormAction($this->ctrl->getFormAction($this, 'performDeleteThreads'));
1676 $c_gui->setHeaderText($this->lng->txt('frm_sure_delete_threads'));
1677 $c_gui->setCancel($this->lng->txt('cancel'), 'showThreads');
1678 $c_gui->setConfirm($this->lng->txt('confirm'), 'performDeleteThreads');
1679
1680 foreach ($threads as $thread) {
1681 $c_gui->addItem('thread_ids[]', (string) $thread->getId(), $thread->getSubject());
1682 }
1683
1684 $this->confirmation_gui_html = $c_gui->getHTML();
1685
1686 $this->hideToolbar(true);
1687 $this->tpl->setContent($c_gui->getHTML());
1688 }
1689
1690 protected function confirmDeleteThreadDraftsObject(): void
1691 {
1692 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
1693 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1694 }
1695
1696 $draftIds = array_filter((array) ($this->httpRequest->getParsedBody()['draft_ids'] ?? []));
1697 if ($draftIds === []) {
1698 $this->tpl->setOnScreenMessage('info', $this->lng->txt('select_at_least_one_thread'));
1699 $this->showThreadsObject();
1700 return;
1701 }
1702
1703 $confirmation = new ilConfirmationGUI();
1704 $confirmation->setFormAction($this->ctrl->getFormAction($this, 'deleteThreadDrafts'));
1705 $confirmation->setHeaderText($this->lng->txt('sure_delete_drafts'));
1706 $confirmation->setCancel($this->lng->txt('cancel'), 'showThreads');
1707 $confirmation->setConfirm($this->lng->txt('confirm'), 'deleteThreadDrafts');
1708 $instances = ilForumPostDraft::getDraftInstancesByUserId($this->user->getId());
1709 foreach ($draftIds as $draftId) {
1710 if (array_key_exists($draftId, $instances)) {
1711 $confirmation->addItem('draft_ids[]', (string) $draftId, $instances[$draftId]->getPostSubject());
1712 }
1713 }
1714
1715 $this->tpl->setContent($confirmation->getHTML());
1716 }
1717
1718 public function prepareThreadScreen(ilObjForum $a_forum_obj): void
1719 {
1720 $this->ilHelp->setScreenIdComponent("frm");
1721
1722 $this->tpl->loadStandardTemplate();
1723
1724 $this->tpl->setTitleIcon(ilObject::_getIcon(0, "big", "frm"));
1725
1726 $ref_id = $this->retrieveRefId();
1727 $this->tabs_gui->setBackTarget(
1728 $this->lng->txt('frm_all_threads'),
1729 $this->ctrl->getLinkTarget(
1730 $this,
1731 'showThreads'
1732 )
1733 );
1734
1736 $frm = $a_forum_obj->Forum;
1737 $frm->setForumId($a_forum_obj->getId());
1738 }
1739
1740 public function performPostActivationObject(): void
1741 {
1742 if (!$this->is_moderator) {
1743 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1744 }
1745
1746 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
1747 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1748 }
1749
1750 $this->ensureThreadBelongsToForum($this->object->getId(), $this->objCurrentPost->getThread());
1751
1752 $this->objCurrentPost->activatePost();
1753 $GLOBALS['ilAppEventHandler']->raise(
1754 'Modules/Forum',
1755 'activatedPost',
1756 [
1757 'object' => $this->object,
1758 'ref_id' => $this->object->getRefId(),
1759 'post' => $this->objCurrentPost
1760 ]
1761 );
1762 $this->tpl->setOnScreenMessage('info', $this->lng->txt('forums_post_was_activated'), true);
1763
1764 $this->viewThreadObject();
1765 }
1766
1767 private function deletePostingObject(): void
1768 {
1769 if (
1770 !$this->user->isAnonymous() &&
1771 !$this->objCurrentTopic->isClosed() && (
1772 $this->is_moderator ||
1773 ($this->objCurrentPost->isOwner($this->user->getId()) && !$this->objCurrentPost->hasReplies())
1774 )
1775 ) {
1776 $this->ensureThreadBelongsToForum($this->object->getId(), $this->objCurrentPost->getThread());
1777
1778 $oForumObjects = $this->getForumObjects();
1779 $forumObj = $oForumObjects['forumObj'];
1780
1781 $frm = new ilForum();
1782 $frm->setForumId($forumObj->getId());
1783 $frm->setForumRefId($forumObj->getRefId());
1784 $dead_thr = $frm->deletePost($this->objCurrentPost->getId());
1785
1786 // if complete thread was deleted ...
1787 if ($dead_thr === $this->objCurrentTopic->getId()) {
1788 $frm->setMDB2WhereCondition('top_frm_fk = %s ', ['integer'], [$forumObj->getId()]);
1789 $topicData = $frm->getOneTopic();
1790 $this->tpl->setOnScreenMessage('info', $this->lng->txt('forums_post_deleted'), true);
1791 if ($topicData->getTopNumThreads() > 0) {
1792 $this->ctrl->redirect($this, 'showThreads');
1793 } else {
1794 $this->ctrl->redirect($this, 'createThread');
1795 }
1796 }
1797 $this->tpl->setOnScreenMessage('info', $this->lng->txt('forums_post_deleted'), true);
1798 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
1799 $this->ctrl->redirect($this, 'viewThread');
1800 }
1801
1802 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1803 }
1804
1805 private function deletePostingDraftObject(): void
1806 {
1807 $this->deleteSelectedDraft();
1808 }
1809
1810 private function revokeCensorshipObject(): void
1811 {
1812 $this->handleCensorship(true);
1813 }
1814
1815 private function addCensorshipObject(): void
1816 {
1817 $this->handleCensorship();
1818 }
1819
1820 private function getModalActions(): string
1821 {
1822 $modalString = '';
1823 foreach ($this->modalActionsContainer as $modal) {
1824 $modalString .= $this->uiRenderer->render($modal);
1825 }
1826
1827 return $modalString;
1828 }
1829
1830 private function handleCensorship($wasRevoked = false): void
1831 {
1832 $message = '';
1833 if ($this->is_moderator && !$this->objCurrentTopic->isClosed()) {
1834 if ($this->http->wrapper()->post()->has('formData')) {
1835 $formData = $this->http->wrapper()->post()->retrieve(
1836 'formData',
1837 $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->string())
1838 );
1839 $message = $this->handleFormInput($formData['cens_message']);
1840 }
1841
1842 if ($message === '' && $this->http->wrapper()->post()->has('cens_message')) {
1843 $cens_message = $this->http->wrapper()->post()->retrieve(
1844 'cens_message',
1845 $this->refinery->kindlyTo()->string()
1846 );
1847 $message = $this->handleFormInput($cens_message);
1848 }
1849 $this->ensureThreadBelongsToForum($this->object->getId(), $this->objCurrentPost->getThread());
1850
1851 $oForumObjects = $this->getForumObjects();
1852 $frm = $oForumObjects['frm'];
1853
1854 if ($wasRevoked) {
1855 $frm->postCensorship($this->object, $message, $this->objCurrentPost->getId());
1856 $this->tpl->setOnScreenMessage('success', $this->lng->txt('frm_censorship_revoked'));
1857 } else {
1858 $frm->postCensorship($this->object, $message, $this->objCurrentPost->getId(), 1);
1859 $this->tpl->setOnScreenMessage('success', $this->lng->txt('frm_censorship_applied'));
1860 }
1861
1862 $this->viewThreadObject();
1863 return;
1864 }
1865
1866 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1867 }
1868
1869 public function askForPostActivationObject(): void
1870 {
1871 if (!$this->is_moderator) {
1872 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1873 }
1874
1875 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
1876 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1877 }
1878
1879 $this->setDisplayConfirmPostActivation(true);
1880
1881 $this->viewThreadObject();
1882 }
1883
1884 public function setDisplayConfirmPostActivation(bool $status = false): void
1885 {
1886 $this->display_confirm_post_activation = $status;
1887 }
1888
1889 public function displayConfirmPostActivation(): bool
1890 {
1891 return $this->display_confirm_post_activation;
1892 }
1893
1894 protected function toggleThreadNotificationObject(): void
1895 {
1896 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
1897 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1898 }
1899
1900 $this->ensureThreadBelongsToForum($this->object->getId(), $this->objCurrentTopic);
1901
1902 if ($this->objCurrentTopic->isNotificationEnabled($this->user->getId())) {
1903 $this->objCurrentTopic->disableNotification($this->user->getId());
1904 $this->tpl->setOnScreenMessage('info', $this->lng->txt('forums_notification_disabled'));
1905 } else {
1906 $this->objCurrentTopic->enableNotification($this->user->getId());
1907 $this->tpl->setOnScreenMessage('info', $this->lng->txt('forums_notification_enabled'));
1908 }
1909
1910 $this->viewThreadObject();
1911 }
1912
1913 protected function toggleStickinessObject(): void
1914 {
1915 if (!$this->is_moderator) {
1916 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1917 }
1918
1919 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
1920 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1921 }
1922
1923 $this->ensureThreadBelongsToForum($this->object->getId(), $this->objCurrentTopic);
1924
1925 if ($this->objCurrentTopic->isSticky()) {
1926 $this->objCurrentTopic->unmakeSticky();
1927 } else {
1928 $this->objCurrentTopic->makeSticky();
1929 }
1930
1931 $this->viewThreadObject();
1932 }
1933
1934 public function cancelPostObject(): void
1935 {
1936 $draft_id = 0;
1937 if ($this->http->wrapper()->post()->has('draft_id')) {
1938 $draft_id = $this->http->wrapper()->post()->retrieve(
1939 'draft_id',
1940 $this->refinery->kindlyTo()->int()
1941 );
1942 }
1943
1944 $this->requestAction = '';
1945 if ($draft_id > 0) {
1946 $draft = ilForumPostDraft::newInstanceByDraftId($draft_id);
1947 $draft->deleteDraftsByDraftIds([$draft_id]);
1948 }
1949
1950 $this->viewThreadObject();
1951 }
1952
1953 public function cancelDraftObject(): void
1954 {
1955 $draft_id = $this->retrieveDraftId();
1956
1957 $this->requestAction = '';
1958 if ($draft_id > 0 && ilForumPostDraft::isAutoSavePostDraftAllowed()) {
1959 $history_obj = new ilForumDraftsHistory();
1960 $history_obj->getFirstAutosaveByDraftId($draft_id);
1961 $draft = ilForumPostDraft::newInstanceByDraftId($draft_id);
1962 $draft->setPostSubject($history_obj->getPostSubject());
1963 $draft->setPostMessage($history_obj->getPostMessage());
1964
1966 $history_obj->getPostMessage(),
1968 $history_obj->getHistoryId(),
1970 $draft->getDraftId()
1971 );
1972
1973 $draft->updateDraft();
1974
1975 $history_obj->deleteHistoryByDraftIds([$draft->getDraftId()]);
1976 }
1977 $this->ctrl->clearParameters($this);
1978 $this->viewThreadObject();
1979 }
1980
1981 public function getActivationFormHTML(): string
1982 {
1983 $form_tpl = new ilTemplate('tpl.frm_activation_post_form.html', true, true, 'Modules/Forum');
1984 $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
1985 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
1986 $this->ctrl->setParameter(
1987 $this,
1988 'orderby',
1989 $this->getOrderByParam()
1990 );
1991 $form_tpl->setVariable('FORM_ACTION', $this->ctrl->getFormAction($this, 'performPostActivation'));
1992 $form_tpl->setVariable('SPACER', '<hr noshade="noshade" width="100%" size="1" align="center" />');
1993 $form_tpl->setVariable('ANCHOR', $this->objCurrentPost->getId());
1994 $form_tpl->setVariable('TXT_ACT', $this->lng->txt('activate_post_txt'));
1995 $form_tpl->setVariable('CONFIRM_BUTTON', $this->lng->txt('activate_only_current'));
1996 $form_tpl->setVariable('CMD_CONFIRM', 'performPostActivation');
1997 $form_tpl->setVariable('CANCEL_BUTTON', $this->lng->txt('cancel'));
1998 $form_tpl->setVariable('CMD_CANCEL', 'viewThread');
1999 $this->ctrl->clearParameters($this);
2000
2001 return $form_tpl->get();
2002 }
2003
2004 public function getCensorshipFormHTML(): string
2005 {
2007 $frm = $this->object->Forum;
2008 $form_tpl = new ilTemplate('tpl.frm_censorship_post_form.html', true, true, 'Modules/Forum');
2009
2010 $form_tpl->setVariable('ANCHOR', $this->objCurrentPost->getId());
2011 $form_tpl->setVariable('SPACER', '<hr noshade="noshade" width="100%" size="1" align="center" />');
2012 $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
2013 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
2014 $this->ctrl->setParameter(
2015 $this,
2016 'orderby',
2017 $this->getOrderByParam()
2018 );
2019 $form_tpl->setVariable('FORM_ACTION', $this->ctrl->getFormAction($this, 'viewThread'));
2020 $this->ctrl->clearParameters($this);
2021 $form_tpl->setVariable('TXT_CENS_MESSAGE', $this->lng->txt('forums_the_post'));
2022 $form_tpl->setVariable('TXT_CENS_COMMENT', $this->lng->txt('forums_censor_comment') . ':');
2023 $form_tpl->setVariable('CENS_MESSAGE', $frm->prepareText((string) $this->objCurrentPost->getCensorshipComment(), 2));
2024
2025 if ($this->objCurrentPost->isCensored()) {
2026 $form_tpl->setVariable('TXT_CENS', $this->lng->txt('forums_info_censor2_post'));
2027 $form_tpl->setVariable('YES_BUTTON', $this->lng->txt('confirm'));
2028 $form_tpl->setVariable('NO_BUTTON', $this->lng->txt('cancel'));
2029 $form_tpl->setVariable('CMD_REVOKE_CENSORSHIP', 'revokeCensorship');
2030 $form_tpl->setVariable('CMD_CANCEL_REVOKE_CENSORSHIP', 'viewThread');
2031 } else {
2032 $form_tpl->setVariable('TXT_CENS', $this->lng->txt('forums_info_censor_post'));
2033 $form_tpl->setVariable('CANCEL_BUTTON', $this->lng->txt('cancel'));
2034 $form_tpl->setVariable('CONFIRM_BUTTON', $this->lng->txt('confirm'));
2035 $form_tpl->setVariable('CMD_ADD_CENSORSHIP', 'addCensorship');
2036 $form_tpl->setVariable('CMD_CANCEL_ADD_CENSORSHIP', 'viewThread');
2037 }
2038
2039 return $form_tpl->get();
2040 }
2041
2042 private function initReplyEditForm(): void
2043 {
2044 $isReply = in_array($this->requestAction, ['showreply', 'ready_showreply']);
2045 $isDraft = in_array($this->requestAction, ['publishDraft', 'editdraft']);
2046
2047 $draft_id = $this->retrieveDraftId();
2048
2049 // init objects
2050 $oForumObjects = $this->getForumObjects();
2051 $frm = $oForumObjects['frm'];
2052 $oFDForum = $oForumObjects['file_obj'];
2053
2054 $this->replyEditForm = new ilPropertyFormGUI();
2055 $this->replyEditForm->setId('id_showreply');
2056 $this->replyEditForm->setTableWidth('100%');
2057 $cancel_cmd = 'cancelPost';
2058 if (in_array($this->requestAction, ['showreply', 'ready_showreply'])) {
2059 $this->ctrl->setParameter($this, 'action', 'ready_showreply');
2060 } elseif (in_array($this->requestAction, ['showdraft', 'editdraft'])) {
2061 $this->ctrl->setParameter($this, 'action', $this->requestAction);
2062 $this->ctrl->setParameter($this, 'draft_id', $draft_id);
2063 } else {
2064 $this->ctrl->setParameter($this, 'action', 'ready_showedit');
2065 }
2066
2067 $this->ctrl->setParameter($this, 'page', (int) ($this->httpRequest->getQueryParams()['page'] ?? 0));
2068 $this->ctrl->setParameter(
2069 $this,
2070 'orderby',
2071 $this->getOrderByParam()
2072 );
2073 $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
2074 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
2075 if ($this->isTopLevelReplyCommand()) {
2076 $this->replyEditForm->setFormAction(
2077 $this->ctrl->getFormAction($this, 'saveTopLevelPost', 'frm_page_bottom')
2078 );
2079 } elseif (in_array($this->requestAction, ['publishDraft', 'editdraft'])) {
2080 $this->replyEditForm->setFormAction(
2081 $this->ctrl->getFormAction($this, 'publishDraft', (string) $this->objCurrentPost->getId())
2082 );
2083 } else {
2084 $this->replyEditForm->setFormAction(
2085 $this->ctrl->getFormAction($this, 'savePost', (string) $this->objCurrentPost->getId())
2086 );
2087 }
2088 $this->ctrl->clearParameters($this);
2089
2090 if ($isReply) {
2091 $this->replyEditForm->setTitle($this->lng->txt('forums_your_reply'));
2092 } elseif ($isDraft) {
2093 $this->replyEditForm->setTitle($this->lng->txt('forums_edit_draft'));
2094 } else {
2095 $this->replyEditForm->setTitle($this->lng->txt('forums_edit_post'));
2096 }
2097
2098 if (
2099 $this->isWritingWithPseudonymAllowed() &&
2100 in_array($this->requestAction, ['showreply', 'ready_showreply', 'editdraft'])
2101 ) {
2102 $oAnonymousNameGUI = new ilTextInputGUI($this->lng->txt('forums_your_name'), 'alias');
2103 $oAnonymousNameGUI->setMaxLength(64);
2104 $oAnonymousNameGUI->setInfo(sprintf($this->lng->txt('forums_use_alias'), $this->lng->txt('forums_anonymous')));
2105
2106 $this->replyEditForm->addItem($oAnonymousNameGUI);
2107 }
2108
2109 $oSubjectGUI = new ilTextInputGUI($this->lng->txt('forums_subject'), 'subject');
2110 $oSubjectGUI->setMaxLength(255);
2111 $oSubjectGUI->setRequired(true);
2112
2113 if ($this->objProperties->getSubjectSetting() === 'empty_subject') {
2114 $oSubjectGUI->setInfo($this->lng->txt('enter_new_subject'));
2115 }
2116
2117 $this->replyEditForm->addItem($oSubjectGUI);
2118
2119 $oPostGUI = new ilTextAreaInputGUI(
2120 $isReply ? $this->lng->txt('forums_your_reply') : $this->lng->txt('forums_edit_post'),
2121 'message'
2122 );
2123 $oPostGUI->setRequired(true);
2124 $oPostGUI->setRows(15);
2125 $oPostGUI->setUseRte(true);
2126 $oPostGUI->addPlugin('latex');
2127 $oPostGUI->addButton('latex');
2128 $oPostGUI->addButton('pastelatex');
2129
2130 $quotingAllowed = (
2131 !$this->isTopLevelReplyCommand() && (
2132 ($isReply && $this->objCurrentPost->getDepth() >= 2) ||
2133 (!$isDraft && !$isReply && $this->objCurrentPost->getDepth() > 2) ||
2134 ($isDraft && $this->objCurrentPost->getDepth() >= 2)
2135 )
2136 );
2137 if ($quotingAllowed) {
2138 $oPostGUI->addPlugin('ilfrmquote');
2139 $oPostGUI->addButton('ilFrmQuoteAjaxCall');
2140 }
2141
2142 $oPostGUI->removePlugin('advlink');
2143 $oPostGUI->setRTERootBlockElement('');
2144 $oPostGUI->usePurifier(true);
2145 $oPostGUI->disableButtons([
2146 'charmap',
2147 'undo',
2148 'redo',
2149 'justifyleft',
2150 'justifycenter',
2151 'justifyright',
2152 'justifyfull',
2153 'anchor',
2154 'fullscreen',
2155 'cut',
2156 'copy',
2157 'paste',
2158 'pastetext',
2159 'formatselect'
2160 ]);
2161
2162 if (in_array($this->requestAction, ['showreply', 'ready_showreply', 'showdraft', 'editdraft'])) {
2163 $oPostGUI->setRTESupport(
2164 $this->user->getId(),
2165 'frm~',
2166 'frm_post',
2167 'tpl.tinymce_frm_post.js',
2168 false,
2169 '5.6.0'
2170 );
2171 } else {
2172 $oPostGUI->setRTESupport(
2173 $this->objCurrentPost->getId(),
2174 'frm',
2175 'frm_post',
2176 'tpl.tinymce_frm_post.js',
2177 false,
2178 '5.6.0'
2179 );
2180 }
2181
2182 $oPostGUI->setPurifier(ilHtmlPurifierFactory::getInstanceByType('frm_post'));
2183
2184 $this->replyEditForm->addItem($oPostGUI);
2185
2186 $umail = new ilMail($this->user->getId());
2187 if (!$this->user->isAnonymous() &&
2188 !$this->objProperties->isAnonymized() &&
2189 $this->rbac->system()->checkAccess('internal_mail', $umail->getMailObjectReferenceId()) &&
2190 !$frm->isThreadNotificationEnabled($this->user->getId(), $this->objCurrentPost->getThreadId())) {
2191 $oNotificationGUI = new ilCheckboxInputGUI($this->lng->txt('forum_direct_notification'), 'notify');
2192 $oNotificationGUI->setInfo($this->lng->txt('forum_notify_me'));
2193 $this->replyEditForm->addItem($oNotificationGUI);
2194 }
2195
2196 if ($this->objProperties->isFileUploadAllowed()) {
2197 $oFileUploadGUI = new ilFileWizardInputGUI($this->lng->txt('forums_attachments_add'), 'userfile');
2198 $oFileUploadGUI->setFilenames([0 => '']);
2199 $this->replyEditForm->addItem($oFileUploadGUI);
2200 }
2201
2202 $attachments_of_node = $oFDForum->getFilesOfPost();
2203 if (count($attachments_of_node) && in_array($this->requestAction, ['showedit', 'ready_showedit'])) {
2204 $oExistingAttachmentsGUI = new ilCheckboxGroupInputGUI($this->lng->txt('forums_delete_file'), 'del_file');
2205 foreach ($oFDForum->getFilesOfPost() as $file) {
2206 $oExistingAttachmentsGUI->addOption(new ilCheckboxOption($file['name'], $file['md5']));
2207 }
2208 $this->replyEditForm->addItem($oExistingAttachmentsGUI);
2209 }
2210
2212 if (in_array($this->requestAction, ['showdraft', 'editdraft'])) {
2213 $draftInfoGUI = new ilNonEditableValueGUI('', 'autosave_info', true);
2214 $draftInfoGUI->setValue(sprintf(
2215 $this->lng->txt('autosave_draft_info'),
2217 ));
2218 $this->replyEditForm->addItem($draftInfoGUI);
2219 } elseif (!in_array($this->requestAction, ['showedit', 'ready_showedit'])) {
2220 $draftInfoGUI = new ilNonEditableValueGUI('', 'autosave_info', true);
2221 $draftInfoGUI->setValue(sprintf(
2222 $this->lng->txt('autosave_post_draft_info'),
2224 ));
2225 $this->replyEditForm->addItem($draftInfoGUI);
2226 }
2227 }
2228
2229 $selected_draft_id = $draft_id;
2230 $draftObj = new ilForumPostDraft(
2231 $this->user->getId(),
2232 $this->objCurrentPost->getId(),
2233 $selected_draft_id
2234 );
2235 if ($draftObj->getDraftId() > 0) {
2236 $oFDForumDrafts = new ilFileDataForumDrafts(0, $draftObj->getDraftId());
2237 if (count($oFDForumDrafts->getFilesOfPost())) {
2238 $oExistingAttachmentsGUI = new ilCheckboxGroupInputGUI(
2239 $this->lng->txt('forums_delete_file'),
2240 'del_file'
2241 );
2242 foreach ($oFDForumDrafts->getFilesOfPost() as $file) {
2243 $oExistingAttachmentsGUI->addOption(new ilCheckboxOption($file['name'], $file['md5']));
2244 }
2245 $this->replyEditForm->addItem($oExistingAttachmentsGUI);
2246 }
2247 }
2248
2249 if ($this->isTopLevelReplyCommand()) {
2250 $this->replyEditForm->addCommandButton('saveTopLevelPost', $this->lng->txt('create'));
2251 } elseif ($this->requestAction === 'editdraft' && ilForumPostDraft::isSavePostDraftAllowed()) {
2252 $this->replyEditForm->addCommandButton('publishDraft', $this->lng->txt('publish'));
2253 } else {
2254 $this->replyEditForm->addCommandButton('savePost', $this->lng->txt('save'));
2255 }
2256 $hidden_draft_id = new ilHiddenInputGUI('draft_id');
2257 $auto_save_draft_id = $this->retrieveDraftId();
2258
2259 $hidden_draft_id->setValue((string) $auto_save_draft_id);
2260 $this->replyEditForm->addItem($hidden_draft_id);
2261
2262 if (in_array($this->requestAction, ['showreply', 'ready_showreply', 'editdraft'])) {
2263 $rtestring = ilRTE::_getRTEClassname();
2264 $show_rte = 0;
2265 if ($this->http->wrapper()->post()->has('show_rte')) {
2266 $show_rte = $this->http->wrapper()->post()->retrieve(
2267 'show_rte',
2268 $this->refinery->kindlyTo()->int()
2269 );
2270 }
2271
2272 if ($show_rte) {
2274 }
2275
2276 if (strtolower($rtestring) !== 'iltinymce' || !ilObjAdvancedEditing::_getRichTextEditorUserState()) {
2277 if ($quotingAllowed) {
2278 $this->replyEditForm->addCommandButton('quotePost', $this->lng->txt('forum_add_quote'));
2279 }
2280 }
2281
2282 if (
2283 !$this->user->isAnonymous() &&
2284 in_array($this->requestAction, ['editdraft', 'showreply', 'ready_showreply']) &&
2286 ) {
2288 $this->decorateWithAutosave($this->replyEditForm);
2289 }
2290
2291 if ($this->requestAction === 'editdraft') {
2292 $this->replyEditForm->addCommandButton('updateDraft', $this->lng->txt('save_message'));
2293 } elseif ($this->isTopLevelReplyCommand()) {
2294 $this->replyEditForm->addCommandButton('saveTopLevelDraft', $this->lng->txt('save_message'));
2295 } else {
2296 $this->replyEditForm->addCommandButton('saveAsDraft', $this->lng->txt('save_message'));
2297 }
2298
2299 $cancel_cmd = 'cancelDraft';
2300 }
2301 }
2302 $this->replyEditForm->addCommandButton($cancel_cmd, $this->lng->txt('cancel'));
2303 }
2304
2306 {
2307 if (null === $this->replyEditForm) {
2308 $this->initReplyEditForm();
2309 }
2310
2311 return $this->replyEditForm;
2312 }
2313
2314 public function createTopLevelPostObject(): void
2315 {
2316 $draft_obj = null;
2317 $draft_id = $this->retrieveDraftId();
2318
2319 if ($draft_id > 0 && !$this->user->isAnonymous()
2321 $draft_obj = new ilForumPostDraft(
2322 $this->user->getId(),
2323 $this->objCurrentPost->getId(),
2324 $draft_id
2325 );
2326 }
2327
2328 if ($draft_obj instanceof ilForumPostDraft && $draft_obj->getDraftId() > 0) {
2329 $this->ctrl->setParameter($this, 'action', 'editdraft');
2330 $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
2331 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
2332 $this->ctrl->setParameter($this, 'draft_id', $draft_obj->getDraftId());
2333 $this->ctrl->setParameter($this, 'page', 0);
2334 $this->ctrl->setParameter(
2335 $this,
2336 'orderby',
2337 $this->getOrderByParam()
2338 );
2339 $this->ctrl->redirect($this, 'editDraft');
2340 } else {
2341 $this->viewThreadObject();
2342 }
2343 }
2344
2345 public function saveTopLevelPostObject(): void
2346 {
2347 $this->savePostObject();
2348 }
2349
2350 public function publishSelectedDraftObject(): void
2351 {
2352 $draft_id = $this->retrieveDraftId();
2353 if ($draft_id > 0) {
2354 $this->publishDraftObject(false);
2355 }
2356 }
2357
2358 public function publishDraftObject(bool $use_replyform = true): void
2359 {
2360 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
2361 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
2362 }
2363
2364 if (!$this->access->checkAccess('add_reply', '', $this->object->getRefId())) {
2365 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
2366 }
2367
2368 if (!$this->objCurrentTopic->getId()) {
2369 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('frm_action_not_possible_thr_deleted'), true);
2370 $this->ctrl->redirect($this);
2371 }
2372
2373 if ($this->objCurrentTopic->isClosed()) {
2374 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('frm_action_not_possible_thr_closed'), true);
2375 $this->ctrl->redirect($this);
2376 }
2377
2378 if (!$this->objCurrentPost->getId()) {
2379 $this->requestAction = '';
2380 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('frm_action_not_possible_parent_deleted'));
2381 $this->viewThreadObject();
2382 return;
2383 }
2384
2385 $post_id = $this->objCurrentPost->getId();
2386
2387 $draft_id = $this->retrieveDraftId();
2388 $draft_obj = new ilForumPostDraft($this->user->getId(), $post_id, $draft_id);
2389
2390 if ($use_replyform) {
2391 $oReplyEditForm = $this->getReplyEditForm();
2392 if (!$oReplyEditForm->checkInput()) {
2393 $oReplyEditForm->setValuesByPost();
2394 $this->viewThreadObject();
2395 return;
2396 }
2397 $post_subject = $oReplyEditForm->getInput('subject');
2398 $post_message = $oReplyEditForm->getInput('message');
2399 $mob_direction = 0;
2400 } else {
2401 $post_subject = $draft_obj->getPostSubject();
2402 $post_message = $draft_obj->getPostMessage();
2403 $mob_direction = 1;
2404 }
2405
2406 if ($draft_obj->getDraftId() > 0) {
2407 $oForumObjects = $this->getForumObjects();
2408 $frm = $oForumObjects['frm'];
2409 $frm->setMDB2WhereCondition(' top_frm_fk = %s ', ['integer'], [$frm->getForumId()]);
2410
2411 // reply: new post
2412 $status = true;
2413 $send_activation_mail = false;
2414
2415 if ($this->objProperties->isPostActivationEnabled()) {
2416 if (!$this->is_moderator) {
2417 $status = false;
2418 $send_activation_mail = true;
2419 } elseif ($this->objCurrentPost->isAnyParentDeactivated()) {
2420 $status = false;
2421 }
2422 }
2423
2424 $newPost = $frm->generatePost(
2425 $draft_obj->getForumId(),
2426 $draft_obj->getThreadId(),
2427 $this->user->getId(),
2428 $draft_obj->getPostDisplayUserId(),
2429 ilRTE::_replaceMediaObjectImageSrc($post_message, $mob_direction),
2430 $draft_obj->getPostId(),
2431 $draft_obj->isNotificationEnabled(),
2432 $this->handleFormInput($post_subject, false),
2433 $draft_obj->getPostUserAlias(),
2434 '',
2435 $status,
2436 $send_activation_mail
2437 );
2438
2439 $this->object->markPostRead(
2440 $this->user->getId(),
2441 $this->objCurrentTopic->getId(),
2442 $this->objCurrentPost->getId()
2443 );
2444
2445 $uploadedObjects = ilObjMediaObject::_getMobsOfObject('frm~:html', $this->user->getId());
2446
2447 foreach ($uploadedObjects as $mob) {
2448 ilObjMediaObject::_removeUsage($mob, 'frm~:html', $this->user->getId());
2449 ilObjMediaObject::_saveUsage($mob, 'frm:html', $newPost);
2450 }
2451 ilForumUtil::saveMediaObjects($post_message, 'frm:html', $newPost, $mob_direction);
2452
2453 if ($this->objProperties->isFileUploadAllowed()) {
2454 $file = $_FILES['userfile'] ?? [];
2455 if (is_array($file) && !empty($file)) {
2456 $tmp_file_obj = new ilFileDataForum($this->object->getId(), $newPost);
2457 $tmp_file_obj->storeUploadedFile($file);
2458 }
2459
2460 //move files of draft to posts directory
2461 $oFDForum = new ilFileDataForum($this->object->getId(), $newPost);
2462 $oFDForumDrafts = new ilFileDataForumDrafts($this->object->getId(), $draft_obj->getDraftId());
2463
2464 $oFDForumDrafts->moveFilesOfDraft($oFDForum->getForumPath(), $newPost);
2465 $oFDForumDrafts->delete();
2466 }
2467
2469 $GLOBALS['ilAppEventHandler']->raise(
2470 'Modules/Forum',
2471 'publishedDraft',
2472 [
2473 'draftObj' => $draft_obj,
2474 'obj_id' => $this->object->getId(),
2475 'is_file_upload_allowed' => $this->objProperties->isFileUploadAllowed()
2476 ]
2477 );
2478 }
2479 $draft_obj->deleteDraft();
2480
2481 $GLOBALS['ilAppEventHandler']->raise(
2482 'Modules/Forum',
2483 'createdPost',
2484 [
2485 'object' => $this->object,
2486 'ref_id' => $this->object->getRefId(),
2487 'post' => new ilForumPost($newPost),
2488 'notify_moderators' => $send_activation_mail
2489 ]
2490 );
2491
2492 $message = '';
2493 if (!$this->is_moderator && !$status) {
2494 $message .= $this->lng->txt('forums_post_needs_to_be_activated');
2495 } else {
2496 $message .= $this->lng->txt('forums_post_new_entry');
2497 }
2498
2499 $thr_pk = $this->retrieveThrPk();
2500
2501 $frm_session_values = ilSession::get('frm');
2502 if (is_array($frm_session_values)) {
2503 $frm_session_values[$thr_pk]['openTreeNodes'][] = $this->objCurrentPost->getId();
2504 }
2505 ilSession::set('frm', $frm_session_values);
2506
2507 $this->ctrl->clearParameters($this);
2508 $this->tpl->setOnScreenMessage('success', $message, true);
2509 $this->ctrl->setParameter($this, 'pos_pk', $newPost);
2510 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
2511
2512 $this->ctrl->redirect($this, 'viewThread');
2513 }
2514 }
2515
2516 public function savePostObject(): void
2517 {
2518 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
2519 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
2520 }
2521
2522 if (!$this->objCurrentTopic->getId()) {
2523 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('frm_action_not_possible_thr_deleted'), true);
2524 $this->ctrl->redirect($this);
2525 }
2526
2527 if ($this->objCurrentTopic->isClosed()) {
2528 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('frm_action_not_possible_thr_closed'), true);
2529 $this->ctrl->redirect($this);
2530 }
2531
2532 $this->ensureThreadBelongsToForum($this->object->getId(), $this->objCurrentTopic);
2533 $del_file = [];
2534 if ($this->http->wrapper()->post()->has('del_file')) {
2535 $del_file = $this->http->wrapper()->post()->retrieve(
2536 'del_file',
2537 $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->string())
2538 );
2539 }
2540
2541 $oReplyEditForm = $this->getReplyEditForm();
2542 if ($oReplyEditForm->checkInput()) {
2543 if (!$this->objCurrentPost->getId()) {
2544 $this->requestAction = '';
2545 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('frm_action_not_possible_parent_deleted'), true);
2546 $this->viewThreadObject();
2547 return;
2548 }
2549
2550 // init objects
2551 $oForumObjects = $this->getForumObjects();
2552 $forumObj = $oForumObjects['forumObj'];
2553 $frm = $oForumObjects['frm'];
2554 $frm->setMDB2WhereCondition(' top_frm_fk = %s ', ['integer'], [$frm->getForumId()]);
2555 $topicData = $frm->getOneTopic();
2556
2557 $ref_id = $this->retrieveRefId();
2558 $post_draft_id = 0;
2559 if ($this->http->wrapper()->post()->has('draft_id')) {
2560 $post_draft_id = $this->http->wrapper()->post()->retrieve(
2561 'draft_id',
2562 $this->refinery->kindlyTo()->int()
2563 );
2564 }
2565 // Generating new posting
2566 if ($this->requestAction === 'ready_showreply') {
2567 if (!$this->access->checkAccess('add_reply', '', $ref_id)) {
2568 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
2569 }
2570
2571 // reply: new post
2572 $status = true;
2573 $send_activation_mail = false;
2574
2575 if ($this->objProperties->isPostActivationEnabled()) {
2576 if (!$this->is_moderator) {
2577 $status = false;
2578 $send_activation_mail = true;
2579 } elseif ($this->objCurrentPost->isAnyParentDeactivated()) {
2580 $status = false;
2581 }
2582 }
2583
2584 if ($this->isWritingWithPseudonymAllowed()) {
2585 if ((string) $oReplyEditForm->getInput('alias') === '') {
2586 $user_alias = $this->lng->txt('forums_anonymous');
2587 } else {
2588 $user_alias = $oReplyEditForm->getInput('alias');
2589 }
2590 $display_user_id = 0;
2591 } else {
2592 $user_alias = $this->user->getLogin();
2593 $display_user_id = $this->user->getId();
2594 }
2595
2596 $newPost = $frm->generatePost(
2597 $topicData->getTopPk(),
2598 $this->objCurrentTopic->getId(),
2599 $this->user->getId(),
2600 $display_user_id,
2601 ilRTE::_replaceMediaObjectImageSrc($oReplyEditForm->getInput('message')),
2602 $this->objCurrentPost->getId(),
2603 $oReplyEditForm->getInput('notify') && !$this->user->isAnonymous(),
2604 $this->handleFormInput($oReplyEditForm->getInput('subject'), false),
2605 $user_alias,
2606 '',
2607 $status,
2608 $send_activation_mail
2609 );
2610
2612 $draft_id = 0;
2614 $draft_id = $post_draft_id; // info aus dem autosave?
2615 }
2616 $draft_obj = new ilForumPostDraft($this->user->getId(), $this->objCurrentPost->getId(), $draft_id);
2617 if ($draft_obj instanceof ilForumPostDraft) {
2618 $draft_obj->deleteDraft();
2619 }
2620 }
2621
2622 // mantis #8115: Mark parent as read
2623 $this->object->markPostRead(
2624 $this->user->getId(),
2625 $this->objCurrentTopic->getId(),
2626 $this->objCurrentPost->getId()
2627 );
2628
2629 // copy temporary media objects (frm~)
2631 $oReplyEditForm->getInput('message'),
2632 'frm~:html',
2633 $this->user->getId(),
2634 'frm:html',
2635 $newPost
2636 );
2637
2638 if ($this->objProperties->isFileUploadAllowed()) {
2639 $oFDForum = new ilFileDataForum($forumObj->getId(), $newPost);
2640 $file = $_FILES['userfile'];
2641 if (is_array($file) && !empty($file)) {
2642 $oFDForum->storeUploadedFile($file);
2643 }
2644 }
2645
2646 $GLOBALS['ilAppEventHandler']->raise(
2647 'Modules/Forum',
2648 'createdPost',
2649 [
2650 'object' => $this->object,
2651 'ref_id' => $this->object->getRefId(),
2652 'post' => new ilForumPost($newPost),
2653 'notify_moderators' => $send_activation_mail
2654 ]
2655 );
2656
2657 $message = '';
2658 if (!$this->is_moderator && !$status) {
2659 $message .= $this->lng->txt('forums_post_needs_to_be_activated');
2660 } else {
2661 $message .= $this->lng->txt('forums_post_new_entry');
2662 }
2663
2664 $this->tpl->setOnScreenMessage('success', $message, true);
2665 $this->ctrl->clearParameters($this);
2666 $this->ctrl->setParameter($this, 'post_created_below', $this->objCurrentPost->getId());
2667 $this->ctrl->setParameter($this, 'pos_pk', $newPost);
2668 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
2669 } else {
2670 if ((!$this->is_moderator &&
2671 !$this->objCurrentPost->isOwner($this->user->getId())) || $this->objCurrentPost->isCensored() ||
2672 $this->user->isAnonymous()) {
2673 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
2674 }
2675
2676 $this->ensureThreadBelongsToForum($this->object->getId(), $this->objCurrentPost->getThread());
2677
2678 $oldMediaObjects = ilObjMediaObject::_getMobsOfObject('frm:html', $this->objCurrentPost->getId());
2679 $curMediaObjects = ilRTE::_getMediaObjects($oReplyEditForm->getInput('message'));
2680 foreach ($oldMediaObjects as $oldMob) {
2681 $found = false;
2682 foreach ($curMediaObjects as $curMob) {
2683 if ($oldMob === $curMob) {
2684 $found = true;
2685 break;
2686 }
2687 }
2688 if (!$found && ilObjMediaObject::_exists($oldMob)) {
2689 ilObjMediaObject::_removeUsage($oldMob, 'frm:html', $this->objCurrentPost->getId());
2690 $mob_obj = new ilObjMediaObject($oldMob);
2691 $mob_obj->delete();
2692 }
2693 }
2694
2695 // save old activation status for send_notification decision
2696 $old_status_was_active = $this->objCurrentPost->isActivated();
2697
2698 // if active post has been edited posting mus be activated again by moderator
2699 $status = true;
2700 $send_activation_mail = false;
2701
2702 if ($this->objProperties->isPostActivationEnabled()) {
2703 if (!$this->is_moderator) {
2704 $status = false;
2705 $send_activation_mail = true;
2706 } elseif ($this->objCurrentPost->isAnyParentDeactivated()) {
2707 $status = false;
2708 }
2709 }
2710 $this->objCurrentPost->setStatus($status);
2711
2712 $this->objCurrentPost->setSubject($this->handleFormInput($oReplyEditForm->getInput('subject'), false));
2713 $this->objCurrentPost->setMessage(ilRTE::_replaceMediaObjectImageSrc(
2714 $oReplyEditForm->getInput('message')
2715 ));
2716 $this->objCurrentPost->setNotification($oReplyEditForm->getInput('notify') && !$this->user->isAnonymous());
2717 $this->objCurrentPost->setChangeDate(date('Y-m-d H:i:s'));
2718 $this->objCurrentPost->setUpdateUserId($this->user->getId());
2719
2720 if ($this->objCurrentPost->update()) {
2721 $this->objCurrentPost->reload();
2722
2723 // Change news item accordingly
2724 // note: $this->objCurrentPost->getForumId() does not give us the forum ID here (why?)
2726 $forumObj->getId(),
2727 'frm',
2728 $this->objCurrentPost->getId(),
2729 'pos'
2730 );
2731 if ($news_id > 0) {
2732 $news_item = new ilNewsItem($news_id);
2733 $news_item->setTitle($this->objCurrentPost->getSubject());
2734 $news_item->setContent(
2735 ilRTE::_replaceMediaObjectImageSrc($frm->prepareText(
2736 $this->objCurrentPost->getMessage()
2737 ), 1)
2738 );
2739
2740 if ($this->objCurrentPost->getMessage() !== strip_tags($this->objCurrentPost->getMessage())) {
2741 $news_item->setContentHtml(true);
2742 } else {
2743 $news_item->setContentHtml(false);
2744 }
2745 $news_item->update();
2746 }
2747
2748 $oFDForum = $oForumObjects['file_obj'];
2749
2750 $file2delete = $oReplyEditForm->getInput('del_file');
2751 if (is_array($file2delete) && count($file2delete)) {
2752 $oFDForum->unlinkFilesByMD5Filenames($file2delete);
2753 }
2754
2755 if ($this->objProperties->isFileUploadAllowed()) {
2756 $file = $_FILES['userfile'];
2757 if (is_array($file) && !empty($file)) {
2758 $oFDForum->storeUploadedFile($file);
2759 }
2760 }
2761
2762 $GLOBALS['ilAppEventHandler']->raise(
2763 'Modules/Forum',
2764 'updatedPost',
2765 [
2766 'ref_id' => $this->object->getRefId(),
2767 'post' => $this->objCurrentPost,
2768 'notify_moderators' => $send_activation_mail,
2769 'old_status_was_active' => $old_status_was_active
2770 ]
2771 );
2772
2773 $this->tpl->setOnScreenMessage('success', $this->lng->txt('forums_post_modified'), true);
2774 }
2775
2776 $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
2777 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
2778 $this->ctrl->setParameter($this, 'viewmode', $this->selectedSorting);
2779 }
2780 $this->ctrl->redirect($this, 'viewThread');
2781 } else {
2782 $this->requestAction = substr($this->requestAction, 6);
2783 }
2784 $this->viewThreadObject();
2785 }
2786
2787 private function hideToolbar($a_flag = null)
2788 {
2789 if (null === $a_flag) {
2790 return $this->hideToolbar;
2791 }
2792
2793 $this->hideToolbar = $a_flag;
2794 return $this;
2795 }
2796
2797 public function quotePostObject(): void
2798 {
2799 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
2800 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
2801 }
2802
2803 $del_file = [];
2804 if ($this->http->wrapper()->post()->has('del_file')) {
2805 $del_file = $this->http->wrapper()->post()->retrieve(
2806 'del_file',
2807 $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->string())
2808 );
2809 }
2810
2811 if ($this->objCurrentTopic->isClosed()) {
2812 $this->requestAction = '';
2813 $this->viewThreadObject();
2814 return;
2815 }
2816
2817 $oReplyEditForm = $this->getReplyEditForm();
2818
2819 $oReplyEditForm->getItemByPostVar('subject')->setRequired(false);
2820 $oReplyEditForm->getItemByPostVar('message')->setRequired(false);
2821
2822 $oReplyEditForm->checkInput();
2823
2824 $oReplyEditForm->getItemByPostVar('subject')->setRequired(true);
2825 $oReplyEditForm->getItemByPostVar('message')->setRequired(true);
2826
2827 $this->requestAction = 'showreply';
2828
2829 $this->viewThreadObject();
2830 }
2831
2832 public function getQuotationHTMLAsynchObject(): void
2833 {
2834 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
2835 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
2836 }
2837
2838 $this->ensureThreadBelongsToForum($this->object->getId(), $this->objCurrentPost->getThread());
2839
2840 $oForumObjects = $this->getForumObjects();
2841 $frm = $oForumObjects['frm'];
2842
2843 $authorinfo = new ilForumAuthorInformation(
2844 $this->objCurrentPost->getPosAuthorId(),
2845 $this->objCurrentPost->getDisplayUserId(),
2846 (string) $this->objCurrentPost->getUserAlias(),
2847 (string) $this->objCurrentPost->getImportName()
2848 );
2849
2850 $html = ilRTE::_replaceMediaObjectImageSrc($frm->prepareText(
2851 $this->objCurrentPost->getMessage(),
2852 1,
2853 $authorinfo->getAuthorName()
2854 ), 1);
2855
2856 $this->http->saveResponse($this->http->response()->withBody(
2857 \ILIAS\Filesystem\Stream\Streams::ofString($html)
2858 ));
2859 $this->http->sendResponse();
2860 $this->http->close();
2861 }
2862
2866 private function getForumObjects(): array
2867 {
2868 if (null === $this->forumObjects) {
2869 $forumObj = $this->object;
2870 $file_obj = new ilFileDataForum($forumObj->getId(), $this->objCurrentPost->getId());
2871 $frm = $forumObj->Forum;
2872 $frm->setForumId($forumObj->getId());
2873 $frm->setForumRefId($forumObj->getRefId());
2874
2875 $this->forumObjects['forumObj'] = $forumObj;
2876 $this->forumObjects['frm'] = $frm;
2877 $this->forumObjects['file_obj'] = $file_obj;
2878 }
2879
2880 return $this->forumObjects;
2881 }
2882
2883 public function checkUsersViewMode(): void
2884 {
2885 $this->selectedSorting = $this->objProperties->getDefaultView();
2886
2887 if (in_array((int) ilSession::get('viewmode'), [
2891 ], true)) {
2892 $this->selectedSorting = ilSession::get('viewmode');
2893 }
2894
2895 if (
2896 isset($this->httpRequest->getQueryParams()['viewmode']) &&
2897 (int) $this->httpRequest->getQueryParams()['viewmode'] !== $this->selectedSorting
2898 ) {
2899 $this->selectedSorting = (int) $this->httpRequest->getQueryParams()['viewmode'];
2900 }
2901
2902 if (!in_array($this->selectedSorting, [
2906 ], true)) {
2907 $this->selectedSorting = $this->objProperties->getDefaultView();
2908 }
2909
2910 ilSession::set('viewmode', $this->selectedSorting);
2911 }
2912
2913 public function resetLimitedViewObject(): void
2914 {
2915 $this->selected_post_storage->set($this->objCurrentTopic->getId(), 0);
2916 $this->ctrl->redirect($this, 'viewThread');
2917 }
2918
2919 public function viewThreadObject(): void
2920 {
2921 $ref_id = $this->retrieveRefId();
2922 $thr_pk = $this->retrieveThrPk();
2923
2924 $bottom_toolbar = clone $this->toolbar;
2925 $bottom_toolbar_split_button_items = [];
2926
2927 // quick and dirty: check for treeview
2928 $thread_control_session_values = ilSession::get('thread_control');
2929 if (is_array($thread_control_session_values)) {
2930 if (!isset($thread_control_session_values['old'])) {
2931 $thread_control_session_values['old'] = $thr_pk;
2932 $thread_control_session_values['new'] = $thr_pk;
2933 ilSession::set('thread_control', $thread_control_session_values);
2934 } elseif (isset($thread_control_session_values['old']) && $thr_pk !== $thread_control_session_values['old']) {
2935 $thread_control_session_values['new'] = $thr_pk;
2936 ilSession::set('thread_control', $thread_control_session_values);
2937 }
2938 }
2939
2940 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
2941 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
2942 }
2943
2944 $oForumObjects = $this->getForumObjects();
2945 $forumObj = $oForumObjects['forumObj'];
2946 $frm = $oForumObjects['frm'];
2947 $file_obj = $oForumObjects['file_obj'];
2948
2949 $selected_draft_id = (int) ($this->httpRequest->getQueryParams()['draft_id'] ?? 0);
2950 if (isset($this->httpRequest->getQueryParams()['file'])) {
2951 $file_obj_for_delivery = $file_obj;
2952 if ($selected_draft_id > 0 && ilForumPostDraft::isSavePostDraftAllowed()) {
2953 $file_obj_for_delivery = new ilFileDataForumDrafts($forumObj->getId(), $selected_draft_id);
2954 }
2955 $file_obj_for_delivery->deliverFile(ilUtil::stripSlashes($this->httpRequest->getQueryParams()['file']));
2956 }
2957
2958 if ($this->objCurrentTopic->getId() === 0) {
2959 $this->ctrl->redirect($this, 'showThreads');
2960 }
2961
2962 $pageIndex = 0;
2963 if (isset($this->httpRequest->getQueryParams()['page'])) {
2964 $pageIndex = max((int) $this->httpRequest->getQueryParams()['page'], $pageIndex);
2965 }
2966
2967 if ($this->selected_post_storage->get($this->objCurrentTopic->getId()) > 0) {
2968 $firstNodeInThread = new ilForumPost(
2969 $this->selected_post_storage->get($this->objCurrentTopic->getId()),
2970 $this->is_moderator,
2971 false
2972 );
2973 } else {
2974 $firstNodeInThread = $this->objCurrentTopic->getPostRootNode();
2975 }
2976
2977 $toolContext = $this->globalScreen
2978 ->tool()
2979 ->context()
2980 ->current();
2981
2982 $additionalDataExists = $toolContext->getAdditionalData()->exists(ForumGlobalScreenToolsProvider::SHOW_FORUM_THREADS_TOOL);
2983 if (false === $additionalDataExists && $this->selectedSorting === ilForumProperties::VIEW_TREE) {
2984 $toolContext
2986 ->addAdditionalData(ForumGlobalScreenToolsProvider::REF_ID, $this->ref_id)
2987 ->addAdditionalData(ForumGlobalScreenToolsProvider::FORUM_THEAD, $this->objCurrentTopic)
2988 ->addAdditionalData(ForumGlobalScreenToolsProvider::FORUM_THREAD_ROOT, $firstNodeInThread)
2990 ->addAdditionalData(ForumGlobalScreenToolsProvider::PAGE, $pageIndex);
2991 }
2992
2993 $this->ensureThreadBelongsToForum($this->object->getId(), $this->objCurrentTopic);
2994
2995 // Set context for login
2996 $append = '_' . $this->objCurrentTopic->getId() .
2997 ($this->objCurrentPost->getId() ? '_' . $this->objCurrentPost->getId() : '');
2998 $this->tpl->setLoginTargetPar('frm_' . $ref_id . $append);
2999
3000 // delete temporary media object (not in case a user adds media objects and wants to save an invalid form)
3001 if (!in_array($this->requestAction, ['showreply', 'showedit'])) {
3002 try {
3003 $mobs = ilObjMediaObject::_getMobsOfObject('frm~:html', $this->user->getId());
3004 foreach ($mobs as $mob) {
3005 if (ilObjMediaObject::_exists($mob)) {
3006 ilObjMediaObject::_removeUsage($mob, 'frm~:html', $this->user->getId());
3007 $mob_obj = new ilObjMediaObject($mob);
3008 $mob_obj->delete();
3009 }
3010 }
3011 } catch (Exception $e) {
3012 }
3013 }
3014
3015 if (!$this->getCreationMode() && $this->access->checkAccess('read', '', $this->object->getRefId())) {
3017 $this->object->getRefId(),
3018 ilLink::_getLink($this->object->getRefId(), 'frm'),
3019 'frm'
3020 );
3021 }
3022
3023 $forumObj->updateLastAccess($this->user->getId(), $this->objCurrentTopic->getId());
3024
3025 $this->prepareThreadScreen($forumObj);
3026
3027 $threadContentTemplate = new ilTemplate(
3028 'tpl.forums_threads_view.html',
3029 true,
3030 true,
3031 'Modules/Forum'
3032 );
3033
3034 if (isset($this->httpRequest->getQueryParams()['anchor'])) {
3035 $threadContentTemplate->setVariable('JUMP2ANCHOR_ID', (int) $this->httpRequest->getQueryParams()['anchor']);
3036 }
3037
3038 $currentSortation = ilForumProperties::VIEW_DATE_ASC;
3039 if ($this->selectedSorting === ilForumProperties::VIEW_TREE) {
3040 $orderField = 'frm_posts_tree.rgt';
3041 $this->objCurrentTopic->setOrderDirection('DESC');
3042 $threadContentTemplate->setVariable('LIST_TYPE', $this->viewModeOptions[$this->selectedSorting]);
3043 } else {
3044 $orderField = 'frm_posts.pos_date';
3045 $this->objCurrentTopic->setOrderDirection(
3046 $this->selectedSorting === ilForumProperties::VIEW_DATE_DESC ? 'DESC' : 'ASC'
3047 );
3048 $threadContentTemplate->setVariable('LIST_TYPE', $this->sortationOptions[$this->selectedSorting]);
3049 }
3050
3051 $numberOfPostings = 0;
3052
3053 $frm->setMDB2WhereCondition('top_frm_fk = %s ', ['integer'], [$frm->getForumId()]);
3054
3056 $this->object->getType(),
3057 $this->object->getRefId(),
3058 $this->object->getId(),
3059 $this->user->getId()
3060 );
3061
3062 if ($firstNodeInThread) {
3063 $this->objCurrentTopic->updateVisits();
3064
3065 $this->tpl->setTitle($this->lng->txt('forums_thread') . " \"" . $this->objCurrentTopic->getSubject() . "\"");
3066
3067 $this->locator->addRepositoryItems();
3068 $this->locator->addItem($this->object->getTitle(), $this->ctrl->getLinkTarget($this, ""), "_top");
3069 $this->tpl->setLocator();
3070
3071 if (
3072 !$this->user->isAnonymous() &&
3073 $forumObj->getCountUnread($this->user->getId(), $this->objCurrentTopic->getId(), true)
3074 ) {
3075 $this->ctrl->setParameter($this, 'mark_read', '1');
3076 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
3077
3078 $mark_thr_read_button = ilLinkButton::getInstance();
3079 $mark_thr_read_button->setCaption('forums_mark_read');
3080 $mark_thr_read_button->setUrl($this->ctrl->getLinkTarget($this, 'viewThread'));
3081
3082 $bottom_toolbar_split_button_items[] = $mark_thr_read_button;
3083
3084 $this->ctrl->clearParameters($this);
3085 }
3086
3087 $this->ctrl->setParameterByClass(ilForumExportGUI::class, 'print_thread', $this->objCurrentTopic->getId());
3088 $this->ctrl->setParameterByClass(
3089 ilForumExportGUI::class,
3090 'thr_top_fk',
3091 $this->objCurrentTopic->getForumId()
3092 );
3093
3094 $print_thr_button = ilLinkButton::getInstance();
3095 $print_thr_button->setCaption('forums_print_thread');
3096 $print_thr_button->setUrl($this->ctrl->getLinkTargetByClass(ilForumExportGUI::class, 'printThread'));
3097
3098 $bottom_toolbar_split_button_items[] = $print_thr_button;
3099
3100 $this->ctrl->clearParametersByClass(ilForumExportGUI::class);
3101
3102 $this->addHeaderAction();
3103
3104 if (isset($this->httpRequest->getQueryParams()['mark_read'])) {
3105 $forumObj->markThreadRead($this->user->getId(), $this->objCurrentTopic->getId());
3106 $this->tpl->setOnScreenMessage('info', $this->lng->txt('forums_thread_marked'), true);
3107 }
3108
3109 $this->objCurrentTopic->setOrderField($orderField);
3110 $subtree_nodes = $this->objCurrentTopic->getPostTree($firstNodeInThread);
3111
3112 if (
3113 $firstNodeInThread instanceof ilForumPost &&
3114 !$this->isTopLevelReplyCommand() &&
3115 !$this->objCurrentTopic->isClosed() &&
3116 $this->access->checkAccess('add_reply', '', $ref_id)
3117 ) {
3118 $reply_button = ilLinkButton::getInstance();
3119 $reply_button->setPrimary(true);
3120 $reply_button->setCaption('add_new_answer');
3121 $this->ctrl->setParameter($this, 'action', 'showreply');
3122 $this->ctrl->setParameter($this, 'pos_pk', $firstNodeInThread->getId());
3123 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
3124 $this->ctrl->setParameter(
3125 $this,
3126 'page',
3127 (int) ($this->httpRequest->getQueryParams()['page'] ?? 0)
3128 );
3129 $this->ctrl->setParameter(
3130 $this,
3131 'orderby',
3132 $this->getOrderByParam()
3133 );
3134
3135 $reply_button->setUrl($this->ctrl->getLinkTarget($this, 'createTopLevelPost', 'frm_page_bottom'));
3136
3137 $this->ctrl->clearParameters($this);
3138 array_unshift($bottom_toolbar_split_button_items, $reply_button);
3139 }
3140
3141 // no posts
3142 $numberOfPostings = count($subtree_nodes);
3143 if ($numberOfPostings === 0 && $firstNodeInThread->getId() === 0) {
3144 $this->tpl->setOnScreenMessage('info', $this->lng->txt('forums_no_posts_available'));
3145 }
3146
3147 $pageSize = $frm->getPageHits();
3148 $postIndex = 0;
3149
3150 if ($numberOfPostings > $pageSize) {
3151 $this->ctrl->setParameter($this, 'ref_id', $this->object->getRefId());
3152 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
3153 $this->ctrl->setParameter(
3154 $this,
3155 'orderby',
3156 $this->getOrderByParam()
3157 );
3158 $paginationUrl = $this->ctrl->getLinkTarget($this, 'viewThread', '');
3159 $this->ctrl->clearParameters($this);
3160
3161 $pagination = $this->uiFactory->viewControl()
3162 ->pagination()
3163 ->withTargetURL($paginationUrl, 'page')
3164 ->withTotalEntries($numberOfPostings)
3165 ->withPageSize($pageSize)
3166 ->withMaxPaginationButtons(10)
3167 ->withCurrentPage($pageIndex);
3168
3169 $threadContentTemplate->setVariable('THREAD_MENU', $this->uiRenderer->render(
3170 $pagination
3171 ));
3172 $threadContentTemplate->setVariable('THREAD_MENU_BOTTOM', $this->uiRenderer->render(
3173 $pagination
3174 ));
3175 }
3176
3177 $doRenderDrafts = ilForumPostDraft::isSavePostDraftAllowed() && !$this->user->isAnonymous();
3178 $draftsObjects = [];
3179 if ($doRenderDrafts) {
3180 $draftsObjects = ilForumPostDraft::getSortedDrafts(
3181 $this->user->getId(),
3182 $this->objCurrentTopic->getId(),
3183 $this->selectedSorting
3184 );
3185 }
3186
3187 $pagedPostings = array_slice($subtree_nodes, $pageIndex * $pageSize, $pageSize);
3188
3189 $this->ensureValidPageForCurrentPosting($subtree_nodes, $pagedPostings, $pageSize, $firstNodeInThread);
3190
3191 if (
3192 $doRenderDrafts && 0 === $pageIndex &&
3193 $this->selectedSorting === ilForumProperties::VIEW_DATE_DESC
3194 ) {
3195 foreach ($draftsObjects as $draft) {
3196 $referencePosting = array_values(array_filter(
3197 $subtree_nodes,
3198 static function (ilForumPost $post) use ($draft): bool {
3199 return $draft->getPostId() === $post->getId();
3200 }
3201 ))[0] ?? $firstNodeInThread;
3202
3203 $this->renderDraftContent(
3204 $threadContentTemplate,
3205 $this->requestAction,
3206 $referencePosting,
3207 [$draft]
3208 );
3209 }
3210 }
3211
3212 foreach ($pagedPostings as $node) {
3213 $this->ctrl->clearParameters($this);
3214
3215 if (!$this->isTopLevelReplyCommand() && $this->objCurrentPost->getId() === $node->getId()) {
3216 if ($this->is_moderator || $node->isActivated() || $node->isOwner($this->user->getId())) {
3217 if (!$this->objCurrentTopic->isClosed() && in_array($this->requestAction, [
3218 'showreply',
3219 'showedit',
3220 ])) {
3221 $this->renderPostingForm($threadContentTemplate, $frm, $node, $this->requestAction);
3222 } elseif ($this->requestAction === 'censor' && !$this->objCurrentTopic->isClosed()) {
3223 if ($this->is_moderator) {
3224 $threadContentTemplate->setVariable('FORM', $this->getCensorshipFormHTML());
3225 }
3226 } elseif (!$this->objCurrentTopic->isClosed() && $this->displayConfirmPostActivation()) {
3227 if ($this->is_moderator) {
3228 $threadContentTemplate->setVariable('FORM', $this->getActivationFormHTML());
3229 }
3230 }
3231 }
3232 }
3233
3234 $this->renderPostContent($threadContentTemplate, $node, $this->requestAction, $pageIndex, $postIndex);
3235 if ($doRenderDrafts && $this->selectedSorting === ilForumProperties::VIEW_TREE) {
3236 $this->renderDraftContent(
3237 $threadContentTemplate,
3238 $this->requestAction,
3239 $node,
3240 $draftsObjects[$node->getId()] ?? []
3241 );
3242 }
3243
3244 $postIndex++;
3245 }
3246
3247 if (
3248 $this->selectedSorting === ilForumProperties::VIEW_DATE_ASC &&
3249 $doRenderDrafts && $pageIndex === max(0, (int) (ceil($numberOfPostings / $pageSize) - 1))
3250 ) {
3251 foreach ($draftsObjects as $draft) {
3252 $referencePosting = array_values(array_filter(
3253 $subtree_nodes,
3254 static function (ilForumPost $post) use ($draft): bool {
3255 return $draft->getPostId() === $post->getId();
3256 }
3257 ))[0] ?? $firstNodeInThread;
3258
3259 $this->renderDraftContent(
3260 $threadContentTemplate,
3261 $this->requestAction,
3262 $referencePosting,
3263 [$draft]
3264 );
3265 }
3266 }
3267
3268 if (
3269 $firstNodeInThread instanceof ilForumPost && $doRenderDrafts &&
3270 $this->selectedSorting === ilForumProperties::VIEW_TREE
3271 ) {
3272 $this->renderDraftContent(
3273 $threadContentTemplate,
3274 $this->requestAction,
3275 $firstNodeInThread,
3276 $draftsObjects[$firstNodeInThread->getId()] ?? []
3277 );
3278 }
3279
3280 if (
3281 $firstNodeInThread instanceof ilForumPost &&
3282 !$this->objCurrentTopic->isClosed() &&
3283 in_array($this->ctrl->getCmd(), ['createTopLevelPost', 'saveTopLevelPost', 'saveTopLevelDraft'], true) &&
3284 $this->access->checkAccess('add_reply', '', $ref_id)) {
3285 // Important: Don't separate the following two lines (very fragile code ...)
3286 $this->objCurrentPost->setId($firstNodeInThread->getId());
3287 $form = $this->getReplyEditForm();
3288
3289 if (in_array($this->ctrl->getCmd(), ['saveTopLevelPost', 'saveTopLevelDraft'])) {
3290 $form->setValuesByPost();
3291 }
3292 $this->ctrl->setParameter($this, 'pos_pk', $firstNodeInThread->getId());
3293 $this->ctrl->setParameter($this, 'thr_pk', $firstNodeInThread->getThreadId());
3294 $jsTpl = new ilTemplate('tpl.forum_post_quoation_ajax_handler.js', true, true, 'Modules/Forum');
3295 $jsTpl->setVariable(
3296 'IL_FRM_QUOTE_CALLBACK_SRC',
3297 $this->ctrl->getLinkTarget($this, 'getQuotationHTMLAsynch', '', true)
3298 );
3299 $this->ctrl->clearParameters($this);
3300 $this->tpl->addOnLoadCode($jsTpl->get());
3301 $threadContentTemplate->setVariable('BOTTOM_FORM', $form->getHTML());
3302 }
3303 } else {
3304 $threadContentTemplate->setCurrentBlock('posts_no');
3305 $threadContentTemplate->setVariable(
3306 'TXT_MSG_NO_POSTS_AVAILABLE',
3307 $this->lng->txt('forums_posts_not_available')
3308 );
3309 $threadContentTemplate->parseCurrentBlock();
3310 }
3311
3312 if ($bottom_toolbar_split_button_items) {
3313 $bottom_split_button = ilSplitButtonGUI::getInstance();
3314 $i = 0;
3315 foreach ($bottom_toolbar_split_button_items as $item) {
3316 if ($i === 0) {
3317 $bottom_split_button->setDefaultButton($item);
3318 } else {
3319 $bottom_split_button->addMenuItem(new ilButtonToSplitButtonMenuItemAdapter($item));
3320 }
3321
3322 ++$i;
3323 }
3324 $bottom_toolbar->addStickyItem($bottom_split_button);
3325 $this->toolbar->addStickyItem($bottom_split_button);
3326 $bottom_toolbar->addSeparator();
3327 }
3328
3329 $to_top_button = ilLinkButton::getInstance();
3330 $to_top_button->setCaption('top_of_page');
3331 $to_top_button->setUrl('#frm_page_top');
3332 $bottom_toolbar->addButtonInstance($to_top_button);
3333 if ($numberOfPostings > 0) {
3334 $threadContentTemplate->setVariable('TOOLBAR_BOTTOM', $bottom_toolbar->getHTML());
3335 }
3336
3337 $this->renderViewModeControl($this->selectedSorting);
3338 if ($this->selectedSorting !== ilForumProperties::VIEW_TREE) {
3339 $this->renderSortationControl($this->selectedSorting);
3340 }
3341
3342 $this->tpl->setPermanentLink(
3343 $this->object->getType(),
3344 $this->object->getRefId(),
3345 '_' . $this->objCurrentTopic->getId(),
3346 '_top'
3347 );
3348
3349 $this->tpl->addOnLoadCode('$(".ilFrmPostContent img").each(function() {
3350 var $elm = $(this);
3351 $elm.css({
3352 maxWidth: $elm.attr("width") + "px",
3353 maxHeight: $elm.attr("height") + "px"
3354 });
3355 $elm.removeAttr("width");
3356 $elm.removeAttr("height");
3357 });');
3358
3359 if ($this->selectedSorting === ilForumProperties::VIEW_TREE && ($this->selected_post_storage->get($thr_pk) > 0)) {
3360 $info = $this->getResetLimitedViewInfo();
3361 }
3362
3363 $this->tpl->setContent(($info ?? '') . $threadContentTemplate->get() . $this->getModalActions());
3364 }
3365
3366 private function renderViewModeControl(int $currentViewMode): void
3367 {
3368 if ($currentViewMode === 3) {
3369 $currentViewMode = 2;
3370 }
3371 $translationKeys = [];
3372 foreach ($this->viewModeOptions as $sortingConstantKey => $languageKey) {
3373 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
3374 $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
3375 $this->ctrl->setParameter($this, 'viewmode', $sortingConstantKey);
3376
3377 $translationKeys[$this->lng->txt($languageKey)] = $this->ctrl->getLinkTarget(
3378 $this,
3379 'viewThread',
3380 ''
3381 );
3382
3383 $this->ctrl->clearParameters($this);
3384 }
3385
3386 if ($currentViewMode > ilForumProperties::VIEW_DATE_ASC) {
3387 $currentViewMode = ilForumProperties::VIEW_DATE_ASC;
3388 }
3389
3390 $sortViewControl = $this->uiFactory
3391 ->viewControl()
3392 ->mode($translationKeys, $this->lng->txt($this->viewModeOptions[$currentViewMode]))
3393 ->withActive($this->lng->txt($this->viewModeOptions[$currentViewMode]));
3394 $this->toolbar->addComponent($sortViewControl);
3395 }
3396
3397 private function renderSortationControl(int $currentSorting): void
3398 {
3399 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
3400 $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
3401 $target = $this->ctrl->getLinkTarget(
3402 $this,
3403 'viewThread',
3404 ''
3405 );
3406
3407 $translatedSortationOptions = array_map(function ($value) {
3408 return $this->lng->txt($value);
3409 }, $this->sortationOptions);
3410
3411 $sortingDirectionViewControl = $this->uiFactory
3412 ->viewControl()
3413 ->sortation($translatedSortationOptions)
3414 ->withLabel($this->lng->txt($this->sortationOptions[$currentSorting]))
3415 ->withTargetURL($target, 'viewmode');
3416 $this->toolbar->addComponent($sortingDirectionViewControl);
3417 }
3418
3419 private function getModifiedReOnSubject(): string
3420 {
3421 return (new PostingReplySubjectBuilder(
3422 $this->lng->txt('post_reply'),
3423 $this->lng->txt('post_reply_count')
3424 ))->build($this->objCurrentPost->getSubject());
3425 }
3426
3427 public function showUserObject(): void
3428 {
3429 $user_id = 0;
3430 if ($this->http->wrapper()->query()->has('user')) {
3431 $user_id = $this->http->wrapper()->query()->retrieve(
3432 'user',
3433 $this->refinery->kindlyTo()->int()
3434 );
3435 }
3436
3437 $ref_id = $this->retrieveRefId();
3438 $backurl = '';
3439 if ($this->http->wrapper()->query()->has('backurl')) {
3440 $backurl = $this->http->wrapper()->query()->retrieve(
3441 'backurl',
3442 $this->refinery->kindlyTo()->string()
3443 );
3444 }
3445
3446 $profile_gui = new ilPublicUserProfileGUI($user_id);
3447 $add = $this->getUserProfileAdditional($ref_id, $user_id);
3448 $profile_gui->setAdditional($add);
3449 $profile_gui->setBackUrl(ilUtil::stripSlashes($backurl));
3450 $this->tpl->setContent($this->ctrl->getHTML($profile_gui));
3451 }
3452
3453 protected function getUserProfileAdditional(int $a_forum_ref_id, int $a_user_id): array
3454 {
3455 if (!$this->access->checkAccess('read', '', $a_forum_ref_id)) {
3456 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3457 }
3458
3460 $ref_obj = ilObjectFactory::getInstanceByRefId($a_forum_ref_id);
3461 if ($ref_obj->getType() === 'frm') {
3462 $forumObj = new ilObjForum($a_forum_ref_id);
3463 $frm = $forumObj->Forum;
3464 $frm->setForumId($forumObj->getId());
3465 $frm->setForumRefId($forumObj->getRefId());
3466 } else {
3467 $frm = new ilForum();
3468 }
3469
3470 if ($this->access->checkAccess('moderate_frm', '', $a_forum_ref_id)) {
3471 $numPosts = $frm->countUserArticles($a_user_id);
3472 } else {
3473 $numPosts = $frm->countActiveUserArticles($a_user_id);
3474 }
3475
3476 return [$this->lng->txt('forums_posts') => $numPosts];
3477 }
3478
3479 public function performThreadsActionObject(): void
3480 {
3481 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
3482 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3483 }
3484
3485 ilSession::set('threads2move', []);
3486
3487 $thread_ids = $this->retrieveThreadIds();
3488 $cmd = $this->ctrl->getCmd();
3489 $message = null;
3490
3491 if ($thread_ids !== []) {
3492 if ($cmd === 'move') {
3493 if ($this->is_moderator) {
3494 ilSession::set('threads2move', $thread_ids);
3495 $this->moveThreadsObject();
3496 }
3497 } elseif ($cmd === 'enable_notifications' && (int) $this->settings->get('forum_notification', '0') !== 0) {
3498 for ($i = 0, $num_thread_ids = count($thread_ids); $i < $num_thread_ids; $i++) {
3499 $tmp_obj = new ilForumTopic($thread_ids[$i]);
3500 $this->ensureThreadBelongsToForum($this->object->getId(), $tmp_obj);
3501 $tmp_obj->enableNotification($this->user->getId());
3502 }
3503
3504 $this->ctrl->redirect($this, 'showThreads');
3505 } elseif ($cmd === 'disable_notifications' && (int) $this->settings->get('forum_notification', '0') !== 0) {
3506 for ($i = 0, $num_thread_ids = count($thread_ids); $i < $num_thread_ids; $i++) {
3507 $tmp_obj = new ilForumTopic($thread_ids[$i]);
3508 $this->ensureThreadBelongsToForum($this->object->getId(), $tmp_obj);
3509 $tmp_obj->disableNotification($this->user->getId());
3510 }
3511
3512 $this->ctrl->redirect($this, 'showThreads');
3513 } elseif ($cmd === 'close') {
3514 if ($this->is_moderator) {
3515 for ($i = 0, $num_thread_ids = count($thread_ids); $i < $num_thread_ids; $i++) {
3516 $tmp_obj = new ilForumTopic($thread_ids[$i]);
3517 $this->ensureThreadBelongsToForum($this->object->getId(), $tmp_obj);
3518 $tmp_obj->close();
3519 }
3520 }
3521 $this->tpl->setOnScreenMessage('success', $this->lng->txt('selected_threads_closed'), true);
3522 $this->ctrl->redirect($this, 'showThreads');
3523 } elseif ($cmd === 'reopen') {
3524 if ($this->is_moderator) {
3525 for ($i = 0, $num_thread_ids = count($thread_ids); $i < $num_thread_ids; $i++) {
3526 $tmp_obj = new ilForumTopic($thread_ids[$i]);
3527 $this->ensureThreadBelongsToForum($this->object->getId(), $tmp_obj);
3528 $tmp_obj->reopen();
3529 }
3530 }
3531
3532 $this->tpl->setOnScreenMessage('success', $this->lng->txt('selected_threads_reopened'), true);
3533 $this->ctrl->redirect($this, 'showThreads');
3534 } elseif ($cmd === 'makesticky') {
3535 if ($this->is_moderator) {
3536 $message = $this->lng->txt('sel_threads_make_sticky');
3537
3538 for ($i = 0, $num_thread_ids = count($thread_ids); $i < $num_thread_ids; $i++) {
3539 $tmp_obj = new ilForumTopic($thread_ids[$i]);
3540 $this->ensureThreadBelongsToForum($this->object->getId(), $tmp_obj);
3541 $makeSticky = $tmp_obj->makeSticky();
3542
3543 if (!$makeSticky) {
3544 $message = $this->lng->txt('sel_threads_already_sticky');
3545 }
3546 }
3547 }
3548 if ($message !== null) {
3549 $this->tpl->setOnScreenMessage('info', $message, true);
3550 }
3551 $this->ctrl->redirect($this, 'showThreads');
3552 } elseif ($cmd === 'unmakesticky') {
3553 if ($this->is_moderator) {
3554 $message = $this->lng->txt('sel_threads_make_unsticky');
3555 for ($i = 0, $num_thread_ids = count($thread_ids); $i < $num_thread_ids; $i++) {
3556 $tmp_obj = new ilForumTopic($thread_ids[$i]);
3557 $this->ensureThreadBelongsToForum($this->object->getId(), $tmp_obj);
3558 $unmakeSticky = $tmp_obj->unmakeSticky();
3559 if (!$unmakeSticky) {
3560 $message = $this->lng->txt('sel_threads_already_unsticky');
3561 }
3562 }
3563 }
3564
3565 if ($message !== null) {
3566 $this->tpl->setOnScreenMessage('info', $message, true);
3567 }
3568 $this->ctrl->redirect($this, 'showThreads');
3569 } elseif ($cmd === 'editThread') {
3570 if ($this->is_moderator) {
3571 $count = count($thread_ids);
3572 if ($count !== 1) {
3573 $this->tpl->setOnScreenMessage('info', $this->lng->txt('select_max_one_thread'), true);
3574 $this->ctrl->redirect($this, 'showThreads');
3575 } else {
3576 $this->editThreadObject(current($thread_ids));
3577 return;
3578 }
3579 }
3580
3581 $this->ctrl->redirect($this, 'showThreads');
3582 } elseif ($cmd === 'html') {
3583 $this->ctrl->setCmd('exportHTML');
3584 $this->ctrl->setCmdClass('ilForumExportGUI');
3585 $this->executeCommand();
3586 } elseif ($cmd === 'confirmDeleteThreads') {
3587 $this->confirmDeleteThreads();
3588 } elseif ($cmd === 'mergeThreads') {
3589 $this->mergeThreadsObject();
3590 } else {
3591 $this->tpl->setOnScreenMessage('info', $this->lng->txt('topics_please_select_one_action'), true);
3592 $this->ctrl->redirect($this, 'showThreads');
3593 }
3594 } else {
3595 $this->tpl->setOnScreenMessage('info', $this->lng->txt('select_at_least_one_thread'), true);
3596 $this->ctrl->redirect($this, 'showThreads');
3597 }
3598 }
3599
3600 public function performMoveThreadsObject(): void
3601 {
3602 if (!$this->is_moderator) {
3603 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3604 }
3605
3606 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
3607 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3608 }
3609
3610 $frm_ref_id = null;
3611 if ($this->http->wrapper()->post()->has('frm_ref_id')) {
3612 $frm_ref_id = $this->http->wrapper()->post()->retrieve(
3613 'frm_ref_id',
3614 $this->refinery->kindlyTo()->int()
3615 );
3616 } else {
3617 $this->error->raiseError('Please select a forum', $this->error->MESSAGE);
3618 }
3619
3620 $threads2move = ilSession::get('threads2move');
3621 if (!is_array($threads2move) || !count($threads2move)) {
3622 $this->tpl->setOnScreenMessage('info', $this->lng->txt('select_at_least_one_thread'), true);
3623 $this->ctrl->redirect($this, 'showThreads');
3624 }
3625
3626 if (!$this->access->checkAccess('read', '', (int) $frm_ref_id)) {
3627 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3628 }
3629
3630 $threads = [];
3631 array_walk($threads2move, function (int $threadId) use (&$threads) {
3632 $thread = new ilForumTopic($threadId);
3633 $this->ensureThreadBelongsToForum($this->object->getId(), $thread);
3634
3635 $threads[] = $threadId;
3636 });
3637
3638 if (isset($frm_ref_id) && (int) $frm_ref_id) {
3639 $errorMessages = $this->object->Forum->moveThreads(
3640 (array) (ilSession::get('threads2move') ?? []),
3641 $this->object,
3642 $this->ilObjDataCache->lookupObjId((int) $frm_ref_id)
3643 );
3644
3645 if ([] !== $errorMessages) {
3646 $this->tpl->setOnScreenMessage('failure', implode("<br><br>", $errorMessages), true);
3647 $this->ctrl->redirect($this, 'showThreads');
3648 }
3649
3650 ilSession::set('threads2move', []);
3651 $this->tpl->setOnScreenMessage('info', $this->lng->txt('threads_moved_successfully'), true);
3652 $this->ctrl->redirect($this, 'showThreads');
3653 } else {
3654 $this->tpl->setOnScreenMessage('info', $this->lng->txt('no_forum_selected'));
3655 $this->moveThreadsObject();
3656 }
3657 }
3658
3659 public function cancelMoveThreadsObject(): void
3660 {
3661 ilSession::set('threads2move', []);
3662 $this->ctrl->redirect($this, 'showThreads');
3663 }
3664
3665 public function moveThreadsObject(): bool
3666 {
3667 if (!$this->is_moderator) {
3668 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3669 }
3670
3671 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
3672 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3673 }
3674
3675 $frm_ref_id = null;
3676 if ($this->http->wrapper()->post()->has('frm_ref_id')) {
3677 $frm_ref_id = $this->http->wrapper()->post()->retrieve(
3678 'frm_ref_id',
3679 $this->refinery->kindlyTo()->int()
3680 );
3681 }
3682
3683 $threads2move = ilSession::get('threads2move');
3684 if (!is_array($threads2move) || !count($threads2move)) {
3685 $this->tpl->setOnScreenMessage('info', $this->lng->txt('select_at_least_one_thread'), true);
3686 $this->ctrl->redirect($this, 'showThreads');
3687 }
3688
3689 $threads = [];
3690 $isModerator = $this->is_moderator;
3691 array_walk($threads2move, function (int $threadId) use (&$threads, $isModerator) {
3692 $thread = new ilForumTopic($threadId, $isModerator);
3693 $this->ensureThreadBelongsToForum($this->object->getId(), $thread);
3694
3695 $threads[] = $thread;
3696 });
3697
3698 $exp = new ilForumMoveTopicsExplorer($this, 'moveThreads');
3699 $exp->setPathOpen($this->object->getRefId());
3700 $exp->setNodeSelected(isset($frm_ref_id) && (int) $frm_ref_id ? (int) $frm_ref_id : 0);
3701 $exp->setCurrentFrmRefId($this->object->getRefId());
3702 $exp->setHighlightedNode((string) $this->object->getRefId());
3703 if (!$exp->handleCommand()) {
3704 $moveThreadTemplate = new ilTemplate(
3705 'tpl.forums_threads_move.html',
3706 true,
3707 true,
3708 'Modules/Forum'
3709 );
3710
3711 if (!$this->hideToolbar()) {
3712 $this->toolbar->addButton($this->lng->txt('back'), $this->ctrl->getLinkTarget($this));
3713 }
3714
3715 $tblThr = new ilTable2GUI($this);
3716 $tblThr->setId('frmthrmv' . $this->object->getRefId());
3717 $tblThr->setTitle($this->lng->txt('move_chosen_topics'));
3718 $tblThr->addColumn($this->lng->txt('subject'), 'top_name', '100%');
3719 $tblThr->disable('header');
3720 $tblThr->disable('footer');
3721 $tblThr->disable('linkbar');
3722 $tblThr->disable('sort');
3723 $tblThr->disable('linkbar');
3724 $tblThr->setLimit(PHP_INT_MAX);
3725 $tblThr->setRowTemplate('tpl.forums_threads_move_thr_row.html', 'Modules/Forum');
3726 $tblThr->setDefaultOrderField('is_sticky');
3727 $counter = 0;
3728 $result = [];
3729 foreach ($threads as $thread) {
3730 $result[$counter]['num'] = $counter + 1;
3731 $result[$counter]['thr_subject'] = $thread->getSubject();
3732 ++$counter;
3733 }
3734 $tblThr->setData($result);
3735 $moveThreadTemplate->setVariable('THREADS_TABLE', $tblThr->getHTML());
3736
3737 $moveThreadTemplate->setVariable('FRM_SELECTION_TREE', $exp->getHTML());
3738 $moveThreadTemplate->setVariable('CMD_SUBMIT', 'performMoveThreads');
3739 $moveThreadTemplate->setVariable('TXT_SUBMIT', $this->lng->txt('move'));
3740 $moveThreadTemplate->setVariable('FORMACTION', $this->ctrl->getFormAction($this, 'performMoveThreads'));
3741
3742 $this->tpl->setContent($moveThreadTemplate->get());
3743 }
3744
3745 return true;
3746 }
3747
3748 private function isWritingWithPseudonymAllowed(): bool
3749 {
3750 return (
3751 $this->objProperties->isAnonymized() &&
3752 (!$this->is_moderator || !$this->objProperties->getMarkModeratorPosts())
3753 );
3754 }
3755
3756 protected function deleteThreadDraftsObject(): void
3757 {
3758 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
3759 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3760 }
3761
3762 $draftIds = array_filter((array) ($this->httpRequest->getParsedBody()['draft_ids'] ?? []));
3763 if (0 === count($draftIds)) {
3764 $draftIds = array_filter([(int) ($this->httpRequest->getQueryParams()['draft_id'] ?? 0)]);
3765 }
3766
3767 $instances = ilForumPostDraft::getDraftInstancesByUserId($this->user->getId());
3768 $checkedDraftIds = [];
3769 foreach ($draftIds as $draftId) {
3770 if (array_key_exists($draftId, $instances)) {
3771 $checkedDraftIds[] = $draftId;
3772 $draft = $instances[$draftId];
3773
3774 $this->deleteMobsOfDraft($draft->getDraftId(), $draft->getPostMessage());
3775
3776 $draftFileData = new ilFileDataForumDrafts(0, $draft->getDraftId());
3777 $draftFileData->delete();
3778
3779 $GLOBALS['ilAppEventHandler']->raise(
3780 'Modules/Forum',
3781 'deletedDraft',
3782 [
3783 'draftObj' => $draft,
3784 'obj_id' => $this->object->getId(),
3785 'is_file_upload_allowed' => $this->objProperties->isFileUploadAllowed(),
3786 ]
3787 );
3788
3789 $draft->deleteDraft();
3790 }
3791 }
3792
3793 if (count($checkedDraftIds) > 1) {
3794 $this->tpl->setOnScreenMessage('info', $this->lng->txt('delete_drafts_successfully'), true);
3795 } else {
3796 $this->tpl->setOnScreenMessage('info', $this->lng->txt('delete_draft_successfully'), true);
3797 }
3798 $this->ctrl->redirect($this, 'showThreads');
3799 }
3800
3801 private function buildThreadForm(bool $isDraft = false): ilForumThreadFormGUI
3802 {
3803 $draftId = (int) ($this->httpRequest->getQueryParams()['draft_id'] ?? 0);
3804 $allowNotification = !$this->objProperties->isAnonymized() && !$this->user->isAnonymous();
3805
3806 $mail = new ilMail($this->user->getId());
3807 if (!$this->rbac->system()->checkAccess('internal_mail', $mail->getMailObjectReferenceId())) {
3808 $allowNotification = false;
3809 }
3810
3811 $default_form = new ilForumThreadFormGUI(
3812 $this,
3813 $this->objProperties,
3814 $this->isWritingWithPseudonymAllowed(),
3815 $allowNotification,
3816 $isDraft,
3817 $draftId
3818 );
3819
3820 $default_form->addInputItem(ilForumThreadFormGUI::ALIAS_INPUT);
3821 $default_form->addInputItem(ilForumThreadFormGUI::SUBJECT_INPUT);
3822 $default_form->addInputItem(ilForumThreadFormGUI::MESSAGE_INPUT);
3823 $default_form->addInputItem(ilForumThreadFormGUI::FILE_UPLOAD_INPUT);
3824 $default_form->addInputItem(ilForumThreadFormGUI::ALLOW_NOTIFICATION_INPUT);
3825
3826 $default_form->generateDefaultForm();
3827
3828 $this->decorateWithAutosave($default_form);
3829
3830 return $default_form;
3831 }
3832
3833 private function buildMinimalThreadForm(bool $isDraft = false): ilForumThreadFormGUI
3834 {
3835 $draftId = (int) ($this->httpRequest->getQueryParams()['draft_id'] ?? 0);
3836 $allowNotification = !$this->objProperties->isAnonymized() && !$this->user->isAnonymous();
3837
3838 $mail = new ilMail($this->user->getId());
3839 if (!$this->rbac->system()->checkAccess('internal_mail', $mail->getMailObjectReferenceId())) {
3840 $allowNotification = false;
3841 }
3842
3843 $minimal_form = new ilForumThreadFormGUI(
3844 $this,
3845 $this->objProperties,
3846 $this->isWritingWithPseudonymAllowed(),
3847 $allowNotification,
3848 $isDraft,
3849 $draftId
3850 );
3851
3852 $minimal_form->addInputItem(ilForumThreadFormGUI::ALIAS_INPUT);
3853 $minimal_form->addInputItem(ilForumThreadFormGUI::SUBJECT_INPUT);
3854
3855 $minimal_form->generateMinimalForm();
3856
3857 return $minimal_form;
3858 }
3859
3860 private function createThreadObject(): void
3861 {
3862 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
3863 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3864 }
3865
3866 if (!$this->access->checkAccess('add_thread', '', $this->object->getRefId())) {
3867 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3868 }
3869
3870 $tpl = new ilTemplate('tpl.create_thread_form.html', true, true, 'Modules/Forum');
3871
3872 $accordion = new ilAccordionGUI();
3873 $accordion->setId('acc_' . $this->obj_id);
3874 $accordion->setBehaviour(ilAccordionGUI::FIRST_OPEN);
3875
3876 $accordion->addItem($this->lng->txt('new_thread_with_post'), $this->buildThreadForm()->getHTML());
3877 $accordion->addItem($this->lng->txt('empty_thread'), $this->buildMinimalThreadForm()->getHTML());
3878
3879 $tpl->setVariable('CREATE_FORM', $accordion->getHTML());
3880 $tpl->parseCurrentBlock();
3881
3882 $this->tpl->setContent($tpl->get());
3883 }
3884
3890 private function createThread(ilForumPostDraft $draft, bool $createFromDraft = false): void
3891 {
3892 if (
3893 !$this->access->checkAccess('add_thread', '', $this->object->getRefId()) ||
3894 !$this->access->checkAccess('read', '', $this->object->getRefId())
3895 ) {
3896 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3897 }
3898
3899 $frm = $this->object->Forum;
3900 $frm->setForumId($this->object->getId());
3901 $frm->setForumRefId($this->object->getRefId());
3902 $frm->setMDB2WhereCondition('top_frm_fk = %s ', ['integer'], [$frm->getForumId()]);
3903 $topicData = $frm->getOneTopic();
3904
3905 $form = $this->buildThreadForm($createFromDraft);
3906 $minimal_form = $this->buildMinimalThreadForm($createFromDraft);
3907
3908 if ($form->checkInput()) {
3909 $userIdForDisplayPurposes = $this->user->getId();
3910 if ($this->isWritingWithPseudonymAllowed()) {
3911 $userIdForDisplayPurposes = 0;
3912 }
3913
3914 $status = true;
3915 if (
3916 ($this->objProperties->isPostActivationEnabled() && !$this->is_moderator) ||
3917 $this->objCurrentPost->isAnyParentDeactivated()
3918 ) {
3919 $status = false;
3920 }
3921
3922 if ($createFromDraft) {
3923 $newThread = new ilForumTopic(0, true, true);
3924 $newThread->setForumId($topicData->getTopPk());
3925 $newThread->setThrAuthorId($draft->getPostAuthorId());
3926 $newThread->setDisplayUserId($draft->getPostDisplayUserId());
3927 $newThread->setSubject($this->handleFormInput($form->getInput('subject'), false));
3928 $newThread->setUserAlias($draft->getPostUserAlias());
3929
3930 $newPost = $frm->generateThread(
3931 $newThread,
3932 ilRTE::_replaceMediaObjectImageSrc($form->getInput('message')),
3933 $draft->isNotificationEnabled() && !$this->user->isAnonymous(),
3934 $draft->isPostNotificationEnabled() && !$this->user->isAnonymous(),
3935 $status
3936 );
3937 } else {
3939 $form->getInput('alias'),
3940 $this->objProperties->isAnonymized()
3941 );
3942 $newThread = new ilForumTopic(0, true, true);
3943 $newThread->setForumId($topicData->getTopPk());
3944 $newThread->setThrAuthorId($this->user->getId());
3945 $newThread->setDisplayUserId($userIdForDisplayPurposes);
3946 $newThread->setSubject($this->handleFormInput($form->getInput('subject'), false));
3947 $newThread->setUserAlias($userAlias);
3948
3949 $newPost = $frm->generateThread(
3950 $newThread,
3951 ilRTE::_replaceMediaObjectImageSrc($form->getInput('message')),
3952 $form->getItemByPostVar('notify') && $form->getInput('notify') && !$this->user->isAnonymous(),
3953 false, // #19980
3954 $status
3955 );
3956 }
3957
3958 if ($this->objProperties->isFileUploadAllowed()) {
3959 $file = $_FILES['userfile'];
3960 if (is_array($file) && !empty($file)) {
3961 $fileData = new ilFileDataForum($this->object->getId(), $newPost);
3962 $fileData->storeUploadedFile($file);
3963 }
3964 }
3965
3966 $frm->setDbTable('frm_data');
3967 $frm->setMDB2WhereCondition('top_pk = %s ', ['integer'], [$topicData->getTopPk()]);
3968 $frm->updateVisits($topicData->getTopPk());
3969
3970 if ($createFromDraft) {
3971 $mediaObjects = ilObjMediaObject::_getMobsOfObject('frm~:html', $this->user->getId());
3972 } else {
3973 $mediaObjects = ilRTE::_getMediaObjects($form->getInput('message'));
3974 }
3975 foreach ($mediaObjects as $mob) {
3976 if (ilObjMediaObject::_exists($mob)) {
3977 ilObjMediaObject::_removeUsage($mob, 'frm~:html', $this->user->getId());
3978 ilObjMediaObject::_saveUsage($mob, 'frm:html', $newPost);
3979 }
3980 }
3981
3982 if ($draft->getDraftId() > 0) {
3983 $draftHistory = new ilForumDraftsHistory();
3984 $draftHistory->deleteHistoryByDraftIds([$draft->getDraftId()]);
3985 if ($this->objProperties->isFileUploadAllowed()) {
3986 $forumFileData = new ilFileDataForum($this->object->getId(), $newPost);
3987 $draftFileData = new ilFileDataForumDrafts($this->object->getId(), $draft->getDraftId());
3988 $draftFileData->moveFilesOfDraft($forumFileData->getForumPath(), $newPost);
3989 }
3990 $draft->deleteDraft();
3991 }
3992
3993 $GLOBALS['ilAppEventHandler']->raise(
3994 'Modules/Forum',
3995 'createdPost',
3996 [
3997 'object' => $this->object,
3998 'ref_id' => $this->object->getRefId(),
3999 'post' => new ilForumPost($newPost),
4000 'notify_moderators' => !$status
4001 ]
4002 );
4003
4004 $this->tpl->setOnScreenMessage('success', $this->lng->txt('forums_thread_new_entry'), true);
4005 $this->ctrl->redirect($this);
4006 }
4007
4008 $form->setValuesByPost();
4009 if (!$this->objProperties->isAnonymized()) {
4010 $form->getItemByPostVar('alias')->setValue($this->user->getLogin());
4011 }
4012
4013 $accordion = new ilAccordionGUI();
4014 $accordion->setId('acc_' . $this->obj_id);
4015 $accordion->setBehaviour(ilAccordionGUI::FIRST_OPEN);
4016 $accordion->addItem($this->lng->txt('new_thread_with_post'), $form->getHTML());
4017 $accordion->addItem($this->lng->txt('empty_thread'), $minimal_form->getHTML());
4018
4019 $this->tpl->setContent($accordion->getHTML());
4020 }
4021
4027 private function createEmptyThread(ilForumPostDraft $draft, bool $createFromDraft = false): void
4028 {
4029 if (
4030 !$this->access->checkAccess('add_thread', '', $this->object->getRefId()) ||
4031 !$this->access->checkAccess('read', '', $this->object->getRefId())
4032 ) {
4033 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4034 }
4035
4036 $frm = $this->object->Forum;
4037 $frm->setForumId($this->object->getId());
4038 $frm->setForumRefId($this->object->getRefId());
4039 $frm->setMDB2WhereCondition('top_frm_fk = %s ', ['integer'], [$frm->getForumId()]);
4040 $topicData = $frm->getOneTopic();
4041
4042 $form = $this->buildThreadForm($createFromDraft);
4043 $minimal_form = $this->buildMinimalThreadForm($createFromDraft);
4044
4045 if ($minimal_form->checkInput()) {
4046 $userIdForDisplayPurposes = $this->user->getId();
4047 if ($this->isWritingWithPseudonymAllowed()) {
4048 $userIdForDisplayPurposes = 0;
4049 }
4050
4051 $status = true;
4052 if (
4053 ($this->objProperties->isPostActivationEnabled() && !$this->is_moderator) ||
4054 $this->objCurrentPost->isAnyParentDeactivated()
4055 ) {
4056 $status = false;
4057 }
4058
4060 $minimal_form->getInput('alias'),
4061 $this->objProperties->isAnonymized()
4062 );
4063 $newThread = new ilForumTopic(0, true, true);
4064 $newThread->setForumId($topicData->getTopPk());
4065 $newThread->setThrAuthorId($this->user->getId());
4066 $newThread->setDisplayUserId($userIdForDisplayPurposes);
4067 $newThread->setSubject($this->handleFormInput($minimal_form->getInput('subject'), false));
4068 $newThread->setUserAlias($userAlias);
4069
4070 $newPost = $frm->generateThread(
4071 $newThread,
4072 '',
4073 false,
4074 false, // #19980
4075 $status,
4076 false
4077 );
4078
4079 $frm->setDbTable('frm_data');
4080 $frm->setMDB2WhereCondition('top_pk = %s ', ['integer'], [$topicData->getTopPk()]);
4081 $frm->updateVisits($topicData->getTopPk());
4082
4083 $this->tpl->setOnScreenMessage('success', $this->lng->txt('forums_thread_new_entry'), true);
4084 $this->ctrl->redirect($this);
4085 }
4086
4087 $form->setValuesByPost();
4088
4089 if (!$this->objProperties->isAnonymized()) {
4090 $form->getItemByPostVar('alias')->setValue($this->user->getLogin());
4091 }
4092
4093 $accordion = new ilAccordionGUI();
4094 $accordion->setId('acc_' . $this->obj_id);
4095 $accordion->setBehaviour(ilAccordionGUI::FIRST_OPEN);
4096 $accordion->addItem($this->lng->txt('new_thread_with_post'), $form->getHTML());
4097 $accordion->addItem($this->lng->txt('empty_thread'), $minimal_form->getHTML());
4098
4099 $this->tpl->setContent($accordion->getHTML());
4100 }
4101
4102 protected function publishThreadDraftObject(): void
4103 {
4105 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4106 }
4107
4108 $draftId = (int) ($this->httpRequest->getQueryParams()['draft_id'] ?? 0);
4109 $draft = ilForumPostDraft::newInstanceByDraftId($draftId);
4110
4111 if ($draft->getDraftId() <= 0) {
4112 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4113 }
4114
4115 $this->createThread($draft, true);
4116 }
4117
4118 protected function addThreadObject(): void
4119 {
4120 $draft = new ilForumPostDraft();
4122 $draftId = (int) ($this->httpRequest->getParsedBody()['draft_id'] ?? 0);
4123 if ($draftId > 0) {
4124 $draft = ilForumPostDraft::newInstanceByDraftId($draftId);
4125 }
4126 }
4127
4128 $this->createThread($draft);
4129 }
4130
4131 protected function addEmptyThreadObject(): void
4132 {
4133 $draft = new ilForumPostDraft();
4135 $draftId = (int) ($this->httpRequest->getParsedBody()['draft_id'] ?? 0);
4136 if ($draftId > 0) {
4137 $draft = ilForumPostDraft::newInstanceByDraftId($draftId);
4138 }
4139 }
4140
4141 $this->createEmptyThread($draft);
4142 }
4143
4144 protected function enableForumNotificationObject(): void
4145 {
4146 if (!$this->access->checkAccess('read', '', $this->object->getRefId()) || $this->user->isAnonymous()) {
4147 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4148 }
4149
4150 $frm = $this->object->Forum;
4151 $frm->setForumId($this->object->getId());
4152 $frm->enableForumNotification($this->user->getId());
4153
4154 if ($this->objCurrentTopic->getId() > 0) {
4155 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
4156 $this->tpl->setOnScreenMessage('info', $this->lng->txt('forums_forum_notification_enabled'), true);
4157 $this->ctrl->redirect($this, 'viewThread');
4158 }
4159
4160 $this->tpl->setOnScreenMessage('info', $this->lng->txt('forums_forum_notification_enabled'));
4161 $this->showThreadsObject();
4162 }
4163
4164 protected function disableForumNotificationObject(): void
4165 {
4166 if (!$this->access->checkAccess('read', '', $this->object->getRefId()) || $this->user->isAnonymous()) {
4167 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4168 }
4169
4170 $frm = $this->object->Forum;
4171 $frm->setForumId($this->object->getId());
4172 $frm->disableForumNotification($this->user->getId());
4173
4174 if ($this->objCurrentTopic->getId() > 0) {
4175 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
4176 $this->tpl->setOnScreenMessage('info', $this->lng->txt('forums_forum_notification_disabled'), true);
4177 $this->ctrl->redirect($this, 'viewThread');
4178 }
4179
4180 $this->tpl->setOnScreenMessage('info', $this->lng->txt('forums_forum_notification_disabled'));
4181 $this->showThreadsObject();
4182 }
4183
4184 public function setColumnSettings(ilColumnGUI $column_gui): void
4185 {
4186 $column_gui->setBlockProperty('news', 'title', $this->lng->txt('frm_latest_postings'));
4187 $column_gui->setBlockProperty('news', 'prevent_aggregation', '1');
4188 $column_gui->setRepositoryMode(true);
4189
4190 if ($this->access->checkAccess('write', '', $this->object->getRefId())) {
4191 $news_set = new ilSetting('news');
4192 if ($news_set->get('enable_rss_for_internal')) {
4193 $column_gui->setBlockProperty('news', 'settings', '1');
4194 $column_gui->setBlockProperty('news', 'public_notifications_option', '1');
4195 }
4196 }
4197 }
4198
4199 protected function addLocatorItems(): void
4200 {
4201 if ($this->object instanceof ilObjForum) {
4202 $this->locator->addItem(
4203 $this->object->getTitle(),
4204 $this->ctrl->getLinkTarget($this),
4205 '',
4206 $this->object->getRefId()
4207 );
4208 }
4209 }
4210
4211 public function handleFormInput(string $a_text, bool $a_stripslashes = true): string
4212 {
4213 $a_text = str_replace(["<", ">"], ["&lt;", "&gt;"], $a_text);
4214 if ($a_stripslashes) {
4215 $a_text = ilUtil::stripSlashes($a_text);
4216 }
4217
4218 return $a_text;
4219 }
4220
4221 public function prepareFormOutput(string $a_text): string
4222 {
4223 $a_text = str_replace(["&lt;", "&gt;"], ["<", ">"], $a_text);
4225 return $a_text;
4226 }
4227
4228 protected function infoScreen(): void
4229 {
4230 if (
4231 !$this->access->checkAccess('visible', '', $this->object->getRefId()) &&
4232 !$this->access->checkAccess('read', '', $this->object->getRefId())
4233 ) {
4234 $this->error->raiseError($this->lng->txt('msg_no_perm_read'), $this->error->MESSAGE);
4235 }
4236
4237 $info = new ilInfoScreenGUI($this);
4238 $info->enablePrivateNotes();
4239 $info->addMetaDataSections($this->object->getId(), 0, $this->object->getType());
4240 $this->ctrl->forwardCommand($info);
4241 }
4242
4243 protected function markPostUnreadObject(): void
4244 {
4245 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
4246 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4247 }
4248
4249 if ($this->objCurrentPost->getId() > 0) {
4250 $this->ensureThreadBelongsToForum($this->object->getId(), $this->objCurrentPost->getThread());
4251
4252 $this->object->markPostUnread($this->user->getId(), $this->objCurrentPost->getId());
4253 }
4254 $this->viewThreadObject();
4255 }
4256
4257 protected function markPostReadObject(): void
4258 {
4259 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
4260 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4261 }
4262
4263 if ($this->objCurrentTopic->getId() > 0 && $this->objCurrentPost->getId() > 0) {
4264 $this->ensureThreadBelongsToForum($this->object->getId(), $this->objCurrentPost->getThread());
4265
4266 $this->object->markPostRead(
4267 $this->user->getId(),
4268 $this->objCurrentTopic->getId(),
4269 $this->objCurrentPost->getId()
4270 );
4271 }
4272
4273 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
4274 $this->ctrl->redirect($this, 'viewThread');
4275 }
4276
4277 protected function initHeaderAction(?string $sub_type = null, ?int $sub_id = null): ?ilObjectListGUI
4278 {
4279 $lg = parent::initHeaderAction();
4280
4281 if (!($lg instanceof ilObjForumListGUI) || !((bool) $this->settings->get('forum_notification', '0'))) {
4282 return $lg;
4283 }
4284
4285 if ($this->user->isAnonymous() || !$this->access->checkAccess('read', '', $this->object->getRefId())) {
4286 return $lg;
4287 }
4288
4289 $frm = $this->object->Forum;
4290 $frm->setForumId($this->object->getId());
4291 $frm->setForumRefId($this->object->getRefId());
4292 $frm->setMDB2Wherecondition('top_frm_fk = %s ', ['integer'], [$frm->getForumId()]);
4293
4294 $isForumNotificationEnabled = $frm->isForumNotificationEnabled($this->user->getId());
4295 $userMayDisableNotifications = $this->isUserAllowedToDeactivateNotification();
4296
4297 if ($this->objCurrentTopic->getId() > 0) {
4298 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
4299 }
4300
4301 if (!$this->user->isAnonymous()) {
4302 if ($this->isParentObjectCrsOrGrp()) {
4303 // special behaviour for CRS/GRP-Forum notification!!
4304 if ($isForumNotificationEnabled && $userMayDisableNotifications) {
4305 $lg->addCustomCommand(
4306 $this->ctrl->getLinkTarget($this, 'disableForumNotification'),
4307 'forums_disable_forum_notification'
4308 );
4309 } elseif (!$isForumNotificationEnabled) {
4310 $lg->addCustomCommand(
4311 $this->ctrl->getLinkTarget($this, 'enableForumNotification'),
4312 'forums_enable_forum_notification'
4313 );
4314 }
4315 } elseif ($isForumNotificationEnabled) {
4316 $lg->addCustomCommand(
4317 $this->ctrl->getLinkTarget($this, 'disableForumNotification'),
4318 'forums_disable_forum_notification'
4319 );
4320 } else {
4321 $lg->addCustomCommand(
4322 $this->ctrl->getLinkTarget($this, 'enableForumNotification'),
4323 'forums_enable_forum_notification'
4324 );
4325 }
4326 }
4327
4328 $ref_id = $this->retrieveRefId();
4329 if (!$this->user->isAnonymous() && $isForumNotificationEnabled && $userMayDisableNotifications) {
4330 $frm_noti = new ilForumNotification($ref_id);
4331 $frm_noti->setUserId($this->user->getId());
4332 $interested_events = $frm_noti->readInterestedEvents();
4333
4334 $events_form_builder = $this->eventsFormBuilder([
4335 'hidden_value' => '',
4336 'notify_modified' => (bool) ($interested_events & ilForumNotificationEvents::UPDATED),
4337 'notify_censored' => (bool) ($interested_events & ilForumNotificationEvents::CENSORED),
4338 'notify_uncensored' => (bool) ($interested_events & ilForumNotificationEvents::UNCENSORED),
4339 'notify_post_deleted' => (bool) ($interested_events & ilForumNotificationEvents::POST_DELETED),
4340 'notify_thread_deleted' => (bool) ($interested_events & ilForumNotificationEvents::THREAD_DELETED),
4341 ]);
4342
4343 $notificationsModal = $this->uiFactory->modal()->roundtrip(
4344 $this->lng->txt('notification_settings'),
4345 $events_form_builder->build()
4346 )->withActionButtons([
4347 $this->uiFactory
4348 ->button()
4349 ->primary($this->lng->txt('save'), '#')
4350 ->withOnLoadCode(function (string $id): string {
4351 return "
4352 $('#$id').closest('.modal').find('form').addClass('ilForumNotificationSettingsForm');
4353 $('#$id').closest('.modal').find('form .il-standard-form-header, .il-standard-form-footer').remove();
4354 $('#$id').click(function() { $(this).closest('.modal').find('form').submit(); return false; });
4355 ";
4356 })
4357 ]);
4358
4359 $showNotificationSettingsBtn = $this->uiFactory->button()
4360 ->shy($this->lng->txt('notification_settings'), '#')
4361 ->withOnClick(
4362 $notificationsModal->getShowSignal()
4363 );
4364
4365 $lg->addCustomCommandButton($showNotificationSettingsBtn, $notificationsModal);
4366 }
4367
4368 $isThreadNotificationEnabled = false;
4369 if (!$this->user->isAnonymous() && $this->objCurrentTopic->getId() > 0) {
4370 $isThreadNotificationEnabled = $this->objCurrentTopic->isNotificationEnabled($this->user->getId());
4371 if ($isThreadNotificationEnabled) {
4372 $lg->addCustomCommand(
4373 $this->ctrl->getLinkTarget($this, 'toggleThreadNotification'),
4374 'forums_disable_notification'
4375 );
4376 } else {
4377 $lg->addCustomCommand(
4378 $this->ctrl->getLinkTarget($this, 'toggleThreadNotification'),
4379 'forums_enable_notification'
4380 );
4381 }
4382 }
4383 $this->ctrl->setParameter($this, 'thr_pk', '');
4384
4385 if (!$this->user->isAnonymous()) {
4386 if ($isForumNotificationEnabled || $isThreadNotificationEnabled) {
4387 $lg->addHeaderIcon(
4388 'not_icon',
4389 ilUtil::getImagePath('notification_on.svg'),
4390 $this->lng->txt('frm_notification_activated')
4391 );
4392 } else {
4393 $lg->addHeaderIcon(
4394 'not_icon',
4395 ilUtil::getImagePath('notification_off.svg'),
4396 $this->lng->txt('frm_notification_deactivated')
4397 );
4398 }
4399 }
4400
4401 return $lg;
4402 }
4403
4409 private function eventsFormBuilder(?array $predefined_values = null): ilForumNotificationEventsFormGUI
4410 {
4411 if ($this->objCurrentTopic->getId() > 0) {
4412 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
4413 }
4414
4416 $this->ctrl->getFormAction($this, 'saveUserNotificationSettings'),
4417 $predefined_values,
4418 $this->uiFactory,
4419 $this->lng
4420 );
4421 }
4422
4424 {
4425 $events_form_builder = $this->eventsFormBuilder();
4426
4427 if ($this->httpRequest->getMethod() === 'POST') {
4428 $form = $events_form_builder->build()->withRequest($this->httpRequest);
4429 $formData = $form->getData();
4430
4431 $interested_events = ilForumNotificationEvents::DEACTIVATED;
4432
4433 foreach ($events_form_builder->getValidEvents() as $event) {
4434 $interested_events += isset($formData[$event]) && $formData[$event] ? $events_form_builder->getValueForEvent(
4435 $event
4436 ) : 0;
4437 }
4438
4439 $frm_noti = new ilForumNotification($this->object->getRefId());
4440 $frm_noti->setUserId($this->user->getId());
4441 $frm_noti->setInterestedEvents($interested_events);
4442 $frm_noti->updateInterestedEvents();
4443 }
4444
4445 $this->tpl->setOnScreenMessage('success', $this->lng->txt('saved_successfully'), true);
4446
4447 if ($this->objCurrentTopic->getId() > 0) {
4448 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
4449 $this->ctrl->redirect($this, 'viewThread');
4450 }
4451
4452 $this->ctrl->redirect($this, 'showThreads');
4453 }
4454
4456 {
4457 if ($this->objProperties->getNotificationType() === 'default') {
4458 return true;
4459 }
4460
4461 if ($this->objProperties->isUserToggleNoti() === false) {
4462 return true;
4463 }
4464
4465 $ref_id = $this->retrieveRefId();
4466 if ($this->isParentObjectCrsOrGrp()) {
4467 $frm_noti = new ilForumNotification($ref_id);
4468 $frm_noti->setUserId($this->user->getId());
4469
4470 return $frm_noti->isUserToggleNotification() === false;
4471 }
4472
4473 return false;
4474 }
4475
4476 public function isParentObjectCrsOrGrp(): bool
4477 {
4478 $grpRefId = $this->tree->checkForParentType($this->object->getRefId(), 'grp');
4479 $crsRefId = $this->tree->checkForParentType($this->object->getRefId(), 'crs');
4480
4481 return ($grpRefId > 0 || $crsRefId > 0);
4482 }
4483
4484 protected function saveThreadSortingObject(): void
4485 {
4486 if (!$this->is_moderator) {
4487 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4488 }
4489
4490 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
4491 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4492 }
4493
4494 $threadIdToSortValueMap = (array) ($this->httpRequest->getParsedBody()['thread_sorting'] ?? []);
4495
4496 array_walk($threadIdToSortValueMap, function ($sortValue, $threadId) {
4497 $this->ensureThreadBelongsToForum($this->object->getId(), new ilForumTopic((int) $threadId));
4498 });
4499
4500 foreach ($threadIdToSortValueMap as $threadId => $sortValue) {
4501 $sortValue = str_replace(',', '.', $sortValue);
4502 $sortValue = ((float) $sortValue) * 100;
4503 $this->object->setThreadSorting((int) $threadId, (int) $sortValue);
4504 }
4505
4506 $this->tpl->setOnScreenMessage('success', $this->lng->txt('saved_successfully'), true);
4507 $this->ctrl->redirect($this, 'showThreads');
4508 }
4509
4510 public function mergeThreadsObject(): void
4511 {
4512 if (!$this->is_moderator) {
4513 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4514 }
4515
4516 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
4517 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4518 }
4519
4520 $threadIdToMerge = (int) ($this->httpRequest->getQueryParams()['merge_thread_id'] ?? 0);
4521 if (!($threadIdToMerge > 0)) {
4522 $threadIds = array_values(
4523 array_filter(array_map('intval', (array) ($this->httpRequest->getParsedBody()['thread_ids'] ?? [])))
4524 );
4525 if (1 === count($threadIds)) {
4526 $threadIdToMerge = current($threadIds);
4527 } else {
4528 $this->tpl->setOnScreenMessage('info', $this->lng->txt('select_one'));
4529 $this->showThreadsObject();
4530 return;
4531 }
4532 }
4533
4534 $frm = $this->object->Forum;
4535 $frm->setForumId($this->object->getId());
4536 $frm->setForumRefId($this->object->getRefId());
4537
4538 $threadToMerge = new ilForumTopic($threadIdToMerge);
4539
4540 if (ilForum::_lookupObjIdForForumId($threadToMerge->getForumId()) !== $frm->getForumId()) {
4541 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('not_allowed_to_merge_into_another_forum'));
4542 $this->showThreadsObject();
4543 return;
4544 }
4545
4546 $frm->setMDB2Wherecondition('top_frm_fk = %s ', ['integer'], [$frm->getForumId()]);
4547
4548 $threadsTemplate = new ilTemplate(
4549 'tpl.forums_threads_liste.html',
4550 true,
4551 true,
4552 'Modules/Forum'
4553 );
4554
4555 $topicData = $frm->getOneTopic();
4556 if ($topicData->getTopPk() > 0) {
4557 $this->ctrl->setParameter($this, 'merge_thread_id', $threadIdToMerge);
4558 $tbl = new ilForumTopicTableGUI(
4559 $this,
4560 'mergeThreads',
4561 (int) $this->httpRequest->getQueryParams()['ref_id'],
4562 $topicData,
4563 $this->is_moderator,
4564 (int) (new ilSetting('frma'))->get('forum_overview', (string) ilForumProperties::FORUM_OVERVIEW_WITH_NEW_POSTS)
4565 );
4566 $tbl->setSelectedThread($threadToMerge);
4567 $tbl->setMapper($frm)->fetchData();
4568 $tbl->init();
4569 $threadsTemplate->setVariable('THREADS_TABLE', $tbl->getHTML());
4570 $this->tpl->setContent($threadsTemplate->get());
4571 } else {
4572 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'));
4573 $this->showThreadsObject();
4574 }
4575 }
4576
4577 public function confirmMergeThreadsObject(): void
4578 {
4579 if (!$this->is_moderator) {
4580 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4581 }
4582
4583 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
4584 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4585 }
4586
4587 $sourceThreadId = (int) ($this->httpRequest->getQueryParams()['merge_thread_id'] ?? 0);
4588 $targetThreadIds = array_values(
4589 array_filter(array_map('intval', (array) ($this->httpRequest->getParsedBody()['thread_ids'] ?? [])))
4590 );
4591
4592 if (!($sourceThreadId > 0) || 1 !== count($targetThreadIds)) {
4593 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'));
4594 $this->mergeThreadsObject();
4595 return;
4596 }
4597
4598 $targetThreadId = current($targetThreadIds);
4599 if ($sourceThreadId === $targetThreadId) {
4600 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('error_same_thread_ids'));
4601 $this->showThreadsObject();
4602 return;
4603 }
4604
4605 if (ilForumTopic::lookupForumIdByTopicId($sourceThreadId) !== ilForumTopic::lookupForumIdByTopicId($targetThreadId)) {
4606 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('not_allowed_to_merge_into_another_forum'));
4607 $this->ctrl->clearParameters($this);
4608 $this->showThreadsObject();
4609 return;
4610 }
4611
4612 if (ilForumTopic::lookupCreationDate($sourceThreadId) < ilForumTopic::lookupCreationDate($targetThreadId)) {
4613 $this->tpl->setOnScreenMessage('info', $this->lng->txt('switch_threads_for_merge'));
4614 }
4615
4616 $this->ensureThreadBelongsToForum($this->object->getId(), new ilForumTopic($sourceThreadId));
4617 $this->ensureThreadBelongsToForum($this->object->getId(), new ilForumTopic($targetThreadId));
4618
4619 $c_gui = new ilConfirmationGUI();
4620
4621 $c_gui->setFormAction($this->ctrl->getFormAction($this, 'performMergeThreads'));
4622 $c_gui->setHeaderText($this->lng->txt('frm_sure_merge_threads'));
4623 $c_gui->setCancel($this->lng->txt('cancel'), 'showThreads');
4624 $c_gui->setConfirm($this->lng->txt('confirm'), 'performMergeThreads');
4625
4626 $c_gui->addItem(
4627 'thread_ids[]',
4628 (string) $sourceThreadId,
4629 sprintf($this->lng->txt('frm_merge_src'), ilForumTopic::lookupTitle($sourceThreadId))
4630 );
4631 $c_gui->addItem(
4632 'thread_ids[]',
4633 (string) $targetThreadId,
4634 sprintf($this->lng->txt('frm_merge_target'), ilForumTopic::lookupTitle($targetThreadId))
4635 );
4636 $this->tpl->setContent($c_gui->getHTML());
4637 }
4638
4639 public function performMergeThreadsObject(): void
4640 {
4641 if (!$this->is_moderator) {
4642 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4643 }
4644
4645 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
4646 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4647 }
4648
4649 $threadIds = array_values(
4650 array_filter(array_map('intval', (array) ($this->httpRequest->getParsedBody()['thread_ids'] ?? [])))
4651 );
4652 if (2 !== count($threadIds)) {
4653 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'));
4654 $this->showThreadsObject();
4655 return;
4656 }
4657
4658 if ((int) $threadIds[0] === (int) $threadIds[1]) {
4659 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('error_same_thread_ids'));
4660 $this->showThreadsObject();
4661 return;
4662 }
4663
4664 try {
4665 $frm = new ilForum();
4666 $frm->setForumId($this->object->getId());
4667 $frm->setForumRefId($this->object->getRefId());
4668
4669 $this->ensureThreadBelongsToForum($this->object->getId(), new ilForumTopic((int) $threadIds[0]));
4670 $this->ensureThreadBelongsToForum($this->object->getId(), new ilForumTopic((int) $threadIds[1]));
4671
4672 $frm->mergeThreads((int) $threadIds[0], (int) $threadIds[1]);
4673 $this->tpl->setOnScreenMessage('success', $this->lng->txt('merged_threads_successfully'));
4674 } catch (ilException $e) {
4675 $this->tpl->setOnScreenMessage('failure', $this->lng->txt($e->getMessage()));
4676 }
4677
4678 $this->showThreadsObject();
4679 }
4680
4681 protected function setSideBlocks(): void
4682 {
4683 $content = $this->getRightColumnHTML();
4684 if (!$this->ctrl->isAsynch()) {
4685 $content = implode('', [
4686 ilRepositoryObjectSearchGUI::getSearchBlockHTML($this->lng->txt('frm_search')),
4687 $content,
4688 ]);
4689 }
4690 $this->tpl->setRightContent($content);
4691 }
4692
4693 protected function deliverDraftZipFileObject(): void
4694 {
4695 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
4696 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4697 }
4698
4699 $draftId = $this->httpRequest->getQueryParams()['draft_id'] ?? 0;
4700 $draft = ilForumPostDraft::newInstanceByDraftId((int) $draftId);
4701 if ($draft->getPostAuthorId() === $this->user->getId()) {
4702 $fileData = new ilFileDataForumDrafts(0, $draft->getDraftId());
4703 if (!$fileData->deliverZipFile()) {
4704 $this->ctrl->redirect($this);
4705 }
4706 }
4707 }
4708
4709 protected function deliverZipFileObject(): void
4710 {
4711 if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
4712 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4713 }
4714
4715 $this->ensureThreadBelongsToForum($this->object->getId(), $this->objCurrentPost->getThread());
4716
4717 $fileData = new ilFileDataForum($this->object->getId(), $this->objCurrentPost->getId());
4718 if (!$fileData->deliverZipFile()) {
4719 $this->ctrl->redirect($this);
4720 }
4721 }
4722
4726 protected function editThreadDraftObject(ilPropertyFormGUI $form = null): void
4727 {
4728 if (
4730 !$this->access->checkAccess('add_thread', '', $this->object->getRefId()) ||
4731 !$this->access->checkAccess('read', '', $this->object->getRefId())
4732 ) {
4733 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4734 }
4735
4736 $frm = $this->object->Forum;
4737 $frm->setForumId($this->object->getId());
4738 $frm->setForumRefId($this->object->getRefId());
4739
4740 $draft = new ilForumPostDraft();
4741 $draftId = (int) ($this->httpRequest->getQueryParams()['draft_id'] ?? 0);
4742 if ($draftId > 0) {
4743 $draft = ilForumPostDraft::newInstanceByDraftId($draftId);
4744 }
4745
4746 $historyCheck = (int) ($this->httpRequest->getQueryParams()['hist_check'] ?? 1);
4747 if (!($form instanceof ilPropertyFormGUI) && $historyCheck > 0) {
4748 $this->doHistoryCheck($draft->getDraftId());
4749 }
4750
4751 if (!$form instanceof ilPropertyFormGUI) {
4752 $form = $this->buildThreadForm(true);
4753 $form->setValuesByArray([
4754 'alias' => $draft->getPostUserAlias(),
4755 'subject' => $draft->getPostSubject(),
4756 'message' => ilRTE::_replaceMediaObjectImageSrc($frm->prepareText($draft->getPostMessage(), 2), 1),
4757 'notify' => $draft->isNotificationEnabled() && !$this->user->isAnonymous(),
4758 'userfile' => '',
4759 'del_file' => [],
4760 'draft_id' => $draftId
4761 ]);
4762 } else {
4763 $this->ctrl->setParameter($this, 'draft_id', $draftId);
4764 }
4765
4766 $this->tpl->setContent($form->getHTML() . $this->modal_history);
4767 }
4768
4769 protected function restoreFromHistoryObject(): void
4770 {
4771 $historyId = (int) ($this->httpRequest->getQueryParams()['history_id'] ?? 0);
4772 $history = new ilForumDraftsHistory($historyId);
4773
4774 $draft = $history->rollbackAutosave();
4775 if ($draft->getThreadId() === 0 && $draft->getPostId() === 0) {
4776 $this->ctrl->setParameter($this, 'draft_id', $history->getDraftId());
4777 $this->ctrl->redirect($this, 'editThreadDraft');
4778 }
4779
4780 $this->ctrl->clearParameters($this);
4781 $this->ctrl->setParameter($this, 'pos_pk', $draft->getPostId());
4782 $this->ctrl->setParameter($this, 'thr_pk', $draft->getThreadId());
4783 $this->ctrl->setParameter($this, 'draft_id', $draft->getDraftId());
4784 $this->ctrl->setParameter($this, 'action', 'editdraft');
4785
4786 ilForumPostDraft::createDraftBackup($draft->getDraftId());
4787
4788 $this->ctrl->redirect($this, 'viewThread');
4789 }
4790
4791 protected function saveThreadAsDraftObject(): void
4792 {
4793 if (
4795 !$this->access->checkAccess('add_thread', '', $this->object->getRefId()) ||
4796 !$this->access->checkAccess('read', '', $this->object->getRefId())
4797 ) {
4798 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4799 }
4800
4801 $autoSavedDraftId = (int) ($this->httpRequest->getParsedBody()['draft_id'] ?? 0);
4802 if ($autoSavedDraftId <= 0) {
4803 $autoSavedDraftId = (int) ($this->httpRequest->getQueryParams()['draft_id'] ?? 0);
4804 }
4805
4806 $frm = $this->object->Forum;
4807 $frm->setForumId($this->object->getId());
4808 $frm->setForumRefId($this->object->getRefId());
4809 $frm->setMDB2WhereCondition('top_frm_fk = %s ', ['integer'], [$frm->getForumId()]);
4810 $topicData = $frm->getOneTopic();
4811
4812 $form = $this->buildThreadForm();
4813 if ($form->checkInput()) {
4814 if (0 === $autoSavedDraftId) {
4815 $draft = new ilForumPostDraft();
4816 } else {
4817 $draft = ilForumPostDraft::newInstanceByDraftId($autoSavedDraftId);
4818 }
4819
4820 $draft->setForumId($topicData->getTopPk());
4821 $draft->setThreadId(0);
4822 $draft->setPostId(0);
4823 $draft->setPostSubject($this->handleFormInput($form->getInput('subject'), false));
4824 $draft->setPostMessage(ilRTE::_replaceMediaObjectImageSrc($form->getInput('message')));
4826 $form->getInput('alias'),
4827 $this->objProperties->isAnonymized()
4828 );
4829 $draft->setPostUserAlias($userAlias);
4830 $draft->setNotificationStatus($form->getInput('notify') && !$this->user->isAnonymous());
4831 $draft->setPostAuthorId($this->user->getId());
4832 $draft->setPostDisplayUserId($this->isWritingWithPseudonymAllowed() ? 0 : $this->user->getId());
4833
4834 if (0 === $autoSavedDraftId) {
4835 $draftId = $draft->saveDraft();
4836 } else {
4837 $draft->updateDraft();
4838 $draftId = $draft->getDraftId();
4839 }
4840
4841 $GLOBALS['ilAppEventHandler']->raise(
4842 'Modules/Forum',
4843 'savedAsDraft',
4844 [
4845 'draftObj' => $draft,
4846 'obj_id' => $this->object->getId(),
4847 'is_file_upload_allowed' => $this->objProperties->isFileUploadAllowed(),
4848 ]
4849 );
4850
4851 ilForumUtil::moveMediaObjects($form->getInput('message'), 'frm~d:html', $draftId, 'frm~d:html', $draftId);
4852
4853 $draftFileData = new ilFileDataForumDrafts($this->object->getId(), $draftId);
4854
4855 $files2delete = $form->getInput('del_file');
4856 if (is_array($files2delete) && count($files2delete) > 0) {
4857 $draftFileData->unlinkFilesByMD5Filenames($files2delete);
4858 }
4859
4860 if ($this->objProperties->isFileUploadAllowed()) {
4861 $file = $_FILES['userfile'];
4862 if (is_array($file) && !empty($file)) {
4863 $draftFileData->storeUploadedFile($file);
4864 }
4865 }
4866
4867 $this->tpl->setOnScreenMessage('success', $this->lng->txt('save_draft_successfully'), true);
4868 $this->ctrl->clearParameters($this);
4869 $this->ctrl->redirect($this, 'showThreads');
4870 }
4871
4872 $this->requestAction = substr($this->requestAction, 6);
4873 $form->setValuesByPost();
4874 $this->ctrl->setParameter($this, 'draft_id', $autoSavedDraftId);
4875 $this->tpl->setContent($form->getHTML());
4876 }
4877
4878 protected function updateThreadDraftObject(): void
4879 {
4880 if (
4882 !$this->access->checkAccess('add_thread', '', $this->object->getRefId()) ||
4883 !$this->access->checkAccess('read', '', $this->object->getRefId())
4884 ) {
4885 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4886 }
4887
4888 $draftId = (int) ($this->httpRequest->getQueryParams()['draft_id'] ?? 0);
4889 if ($draftId <= 0 || !$this->checkDraftAccess($draftId)) {
4890 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4891 }
4892
4893 $form = $this->buildThreadForm(true);
4894 if ($form->checkInput()) {
4896 $form->getInput('alias'),
4897 $this->objProperties->isAnonymized()
4898 );
4899
4900 $draft = ilForumPostDraft::newInstanceByDraftId($draftId);
4901 $draft->setPostSubject($this->handleFormInput($form->getInput('subject'), false));
4902 $draft->setPostMessage(ilRTE::_replaceMediaObjectImageSrc($form->getInput('message')));
4903 $draft->setPostUserAlias($userAlias);
4904 $draft->setNotificationStatus($form->getInput('notify') && !$this->user->isAnonymous());
4905 $draft->setPostAuthorId($this->user->getId());
4906 $draft->setPostDisplayUserId($this->isWritingWithPseudonymAllowed() ? 0 : $this->user->getId());
4907 $draft->updateDraft();
4908
4909 $GLOBALS['ilAppEventHandler']->raise(
4910 'Modules/Forum',
4911 'updatedDraft',
4912 [
4913 'draftObj' => $draft,
4914 'obj_id' => $this->object->getId(),
4915 'is_file_upload_allowed' => $this->objProperties->isFileUploadAllowed(),
4916 ]
4917 );
4918
4920 $form->getInput('message'),
4921 'frm~d:html',
4922 $draft->getDraftId(),
4923 'frm~d:html',
4924 $draft->getDraftId()
4925 );
4926
4927 $draftFileData = new ilFileDataForumDrafts($this->object->getId(), $draft->getDraftId());
4928
4929 $files2delete = $form->getInput('del_file');
4930 if (is_array($files2delete) && count($files2delete) > 0) {
4931 $draftFileData->unlinkFilesByMD5Filenames($files2delete);
4932 }
4933
4934 if ($this->objProperties->isFileUploadAllowed()) {
4935 $file = $_FILES['userfile'];
4936 if (is_array($file) && !empty($file)) {
4937 $draftFileData->storeUploadedFile($file);
4938 }
4939 }
4940
4941 $this->tpl->setOnScreenMessage('success', $this->lng->txt('save_draft_successfully'), true);
4942 $this->ctrl->clearParameters($this);
4943 $this->ctrl->redirect($this, 'showThreads');
4944 }
4945
4946 $form->setValuesByPost();
4947 $this->ctrl->setParameter($this, 'hist_check', 0);
4948 $this->ctrl->setParameter($this, 'draft_id', $draftId);
4949 $this->editThreadDraftObject($form);
4950 }
4951
4952 public function saveTopLevelDraftObject(): void
4953 {
4954 $this->saveAsDraftObject();
4955 }
4956
4957 public function saveAsDraftObject(): void
4958 {
4959 $ref_id = $this->retrieveRefId();
4960 $thr_pk = $this->retrieveThrPk();
4961
4962 $del_file = [];
4963 if ($this->http->wrapper()->post()->has('del_file')) {
4964 $del_file = $this->http->wrapper()->post()->retrieve(
4965 'del_file',
4966 $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->string())
4967 );
4968 }
4969 $draft_id = null;
4970 if ($this->http->wrapper()->post()->has('draft_id')) {
4971 $draft_id = $this->http->wrapper()->post()->retrieve(
4972 'draft_id',
4973 $this->refinery->kindlyTo()->string()
4974 );
4975 }
4976
4977 if (!$this->objCurrentTopic->getId()) {
4978 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('frm_action_not_possible_thr_deleted'), true);
4979 $this->ctrl->redirect($this);
4980 }
4981
4982 if ($this->objCurrentTopic->isClosed()) {
4983 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('frm_action_not_possible_thr_closed'), true);
4984 $this->ctrl->redirect($this);
4985 }
4986
4987 $autosave_draft_id = 0;
4988 if (isset($draft_id) && ilForumPostDraft::isAutoSavePostDraftAllowed()) {
4989 $autosave_draft_id = (int) $draft_id;
4990 }
4991 $oReplyEditForm = $this->getReplyEditForm();
4992 if ($oReplyEditForm->checkInput()) {
4993 if (!$this->objCurrentPost->getId()) {
4994 $this->requestAction = '';
4995 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('frm_action_not_possible_parent_deleted'), true);
4996 $this->viewThreadObject();
4997 return;
4998 }
4999
5000 $oForumObjects = $this->getForumObjects();
5001 $forumObj = $oForumObjects['forumObj'];
5002 $frm = $oForumObjects['frm'];
5003 $frm->setMDB2WhereCondition(' top_frm_fk = %s ', ['integer'], [$frm->getForumId()]);
5004 $topicData = $frm->getOneTopic();
5005
5006 if ($this->requestAction === 'ready_showreply') {
5007 if (!$this->access->checkAccess('add_reply', '', $ref_id)) {
5008 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
5009 }
5010
5011 $user_alias = ilForumUtil::getPublicUserAlias(
5012 $oReplyEditForm->getInput('alias'),
5013 $this->objProperties->isAnonymized()
5014 );
5015
5016 if ($autosave_draft_id === 0) {
5017 $draftObj = new ilForumPostDraft();
5018 } else {
5019 $draftObj = ilForumPostDraft::newInstanceByDraftId($autosave_draft_id);
5020 }
5021 $draftObj->setForumId($topicData->getTopPk());
5022 $draftObj->setThreadId($this->objCurrentTopic->getId());
5023 $draftObj->setPostId($this->objCurrentPost->getId());
5024
5025 $draftObj->setPostSubject($this->handleFormInput($oReplyEditForm->getInput('subject'), false));
5026 $draftObj->setPostMessage(ilRTE::_replaceMediaObjectImageSrc($oReplyEditForm->getInput('message')));
5027 $draftObj->setPostUserAlias($user_alias);
5028 $draftObj->setNotificationStatus($oReplyEditForm->getInput('notify') && !$this->user->isAnonymous());
5029 $draftObj->setPostNotificationStatus($oReplyEditForm->getInput('notify_post') && !$this->user->isAnonymous());
5030
5031 $draftObj->setPostAuthorId($this->user->getId());
5032 $draftObj->setPostDisplayUserId(($this->isWritingWithPseudonymAllowed() ? 0 : $this->user->getId()));
5033
5034 if ($autosave_draft_id === 0) {
5035 $draft_id = $draftObj->saveDraft();
5036 } else {
5037 $draftObj->updateDraft();
5038 $draft_id = $draftObj->getDraftId();
5039 }
5040
5042 $GLOBALS['ilAppEventHandler']->raise(
5043 'Modules/Forum',
5044 'savedAsDraft',
5045 [
5046 'draftObj' => $draftObj,
5047 'obj_id' => $this->object->getId(),
5048 'is_file_upload_allowed' => $this->objProperties->isFileUploadAllowed()
5049 ]
5050 );
5051 }
5052
5053 if ($this->objProperties->isFileUploadAllowed()) {
5054 $file = $_FILES['userfile'];
5055 if (is_array($file) && !empty($file)) {
5056 $oFDForumDrafts = new ilFileDataForumDrafts($this->object->getId(), $draftObj->getDraftId());
5057 $oFDForumDrafts->storeUploadedFile($file);
5058 }
5059 }
5060
5061 // copy temporary media objects (frm~)
5063 $oReplyEditForm->getInput('message'),
5064 'frm~d:html',
5065 $draft_id,
5066 'frm~d:html',
5067 $draft_id
5068 );
5069
5070 $frm_session_values = ilSession::get('frm');
5071 if (is_array($frm_session_values)) {
5072 $frm_session_values[$thr_pk]['openTreeNodes'][] = $this->objCurrentPost->getId();
5073 }
5074 ilSession::set('frm', $frm_session_values);
5075
5076 $this->tpl->setOnScreenMessage('success', $this->lng->txt('save_draft_successfully'), true);
5077 $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
5078 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
5079 $this->ctrl->redirect($this, 'viewThread');
5080 }
5081 } else {
5082 $oReplyEditForm->setValuesByPost();
5083 $this->requestAction = substr($this->requestAction, 6);
5084 }
5085 $this->viewThreadObject();
5086 }
5087
5088 protected function editDraftObject(): void
5089 {
5091 $draftId = $this->retrieveDraftId();
5092 if ($this->checkDraftAccess($draftId)) {
5093 $this->doHistoryCheck($draftId);
5094 }
5095 }
5096
5097 $this->viewThreadObject();
5098 }
5099
5100 public function updateDraftObject(): void
5101 {
5102 $ref_id = $this->retrieveRefId();
5103 $draft_id = $this->retrieveDraftId();
5104 $thr_pk = $this->retrieveThrPk();
5105
5106 if (!$this->objCurrentTopic->getId()) {
5107 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('frm_action_not_possible_thr_deleted'), true);
5108 $this->ctrl->redirect($this);
5109 }
5110
5111 if ($this->objCurrentTopic->isClosed()) {
5112 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('frm_action_not_possible_thr_closed'), true);
5113 $this->ctrl->redirect($this);
5114 }
5115
5116 if (!$this->objCurrentPost->getId()) {
5117 $this->requestAction = '';
5118 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('frm_action_not_possible_parent_deleted'));
5119 $this->viewThreadObject();
5120 return;
5121 }
5122
5123 $del_file = [];
5124 if ($this->http->wrapper()->post()->has('del_file')) {
5125 $del_file = $this->http->wrapper()->post()->retrieve(
5126 'del_file',
5127 $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->string())
5128 );
5129 }
5130
5131 $oReplyEditForm = $this->getReplyEditForm();
5132 if ($oReplyEditForm->checkInput()) {
5133 // init objects
5134 $oForumObjects = $this->getForumObjects();
5135 $forumObj = $oForumObjects['forumObj'];
5136
5137 if (!$this->user->isAnonymous() && in_array($this->requestAction, ['showdraft', 'editdraft'])) {
5138 if (!$this->access->checkAccess('add_reply', '', $ref_id)) {
5139 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
5140 }
5141 if (!$this->checkDraftAccess($draft_id)) {
5142 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
5143 }
5144
5145 $user_alias = ilForumUtil::getPublicUserAlias(
5146 $oReplyEditForm->getInput('alias'),
5147 $this->objProperties->isAnonymized()
5148 );
5149
5150 // generateDraft
5151 $update_draft = new ilForumPostDraft(
5152 $this->user->getId(),
5153 $this->objCurrentPost->getId(),
5154 $draft_id
5155 );
5156
5157 $update_draft->setPostSubject($this->handleFormInput($oReplyEditForm->getInput('subject'), false));
5158 $update_draft->setPostMessage(ilRTE::_replaceMediaObjectImageSrc(
5159 $oReplyEditForm->getInput('message')
5160 ));
5161 $update_draft->setPostUserAlias($user_alias);
5162 $update_draft->setNotificationStatus($oReplyEditForm->getInput('notify') && !$this->user->isAnonymous());
5163 $update_draft->setUpdateUserId($this->user->getId());
5164 $update_draft->setPostAuthorId($this->user->getId());
5165 $update_draft->setPostDisplayUserId($this->isWritingWithPseudonymAllowed() ? 0 : $this->user->getId());
5166
5167 $update_draft->updateDraft();
5168
5170 $GLOBALS['ilAppEventHandler']->raise(
5171 'Modules/Forum',
5172 'updatedDraft',
5173 [
5174 'draftObj' => $update_draft,
5175 'obj_id' => $this->object->getId(),
5176 'is_file_upload_allowed' => $this->objProperties->isFileUploadAllowed()
5177 ]
5178 );
5179 }
5180
5181 $uploadedObjects = ilObjMediaObject::_getMobsOfObject('frm~:html', $this->user->getId());
5182
5183 foreach ($uploadedObjects as $mob) {
5184 ilObjMediaObject::_removeUsage($mob, 'frm~:html', $this->user->getId());
5185 ilObjMediaObject::_saveUsage($mob, 'frm~d:html', $update_draft->getDraftId());
5186 }
5188 $oReplyEditForm->getInput('message'),
5189 'frm~d:html',
5190 $update_draft->getDraftId()
5191 );
5192
5193 $oFDForumDrafts = new ilFileDataForumDrafts($forumObj->getId(), $update_draft->getDraftId());
5194
5195 $file2delete = $oReplyEditForm->getInput('del_file');
5196 if (is_array($file2delete) && count($file2delete)) {
5197 $oFDForumDrafts->unlinkFilesByMD5Filenames($file2delete);
5198 }
5199
5200 if ($this->objProperties->isFileUploadAllowed()) {
5201 $file = $_FILES['userfile'];
5202 if (is_array($file) && !empty($file)) {
5203 $oFDForumDrafts->storeUploadedFile($file);
5204 }
5205 }
5206
5207 $frm_session_values = ilSession::get('frm');
5208 if (is_array($frm_session_values)) {
5209 $frm_session_values[$thr_pk]['openTreeNodes'][] = $this->objCurrentPost->getId();
5210 }
5211 ilSession::set('frm', $frm_session_values);
5212 $this->tpl->setOnScreenMessage('success', $this->lng->txt('save_draft_successfully'), true);
5213 $this->ctrl->clearParameters($this);
5214 $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
5215 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
5216 $this->ctrl->setParameter($this, 'draft_id', $update_draft->getDraftId());
5217 }
5218 } else {
5219 $this->ctrl->clearParameters($this);
5220 $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
5221 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
5222 $this->ctrl->setParameter($this, 'draft_id', $draft_id);
5223 $this->ctrl->setParameter($this, 'action', 'editdraft');
5224 $oReplyEditForm->setValuesByPost();
5225 $this->viewThreadObject();
5226 return;
5227 }
5228 $this->ctrl->clearParameters($this);
5229 $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
5230 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
5231 $this->ctrl->redirect($this, 'viewThread');
5232 }
5233
5234 protected function deleteMobsOfDraft(int $draft_id, string $message): void
5235 {
5236 // remove usage of deleted media objects
5237 $oldMediaObjects = ilObjMediaObject::_getMobsOfObject('frm~d:html', $draft_id);
5238 $curMediaObjects = ilRTE::_getMediaObjects($message);
5239 foreach ($oldMediaObjects as $oldMob) {
5240 $found = false;
5241 foreach ($curMediaObjects as $curMob) {
5242 if ($oldMob === $curMob) {
5243 $found = true;
5244 break;
5245 }
5246 }
5247 if (!$found && ilObjMediaObject::_exists($oldMob)) {
5248 ilObjMediaObject::_removeUsage($oldMob, 'frm~d:html', $draft_id);
5249 $mob_obj = new ilObjMediaObject($oldMob);
5250 $mob_obj->delete();
5251 }
5252 }
5253 }
5254
5255 protected function deleteSelectedDraft(ilForumPostDraft $draft_obj = null): void
5256 {
5257 $ref_id = $this->retrieveRefId();
5258 $draft_id = $this->retrieveDraftId();
5259
5260 if (
5261 !$this->access->checkAccess('add_reply', '', $ref_id) ||
5262 $this->user->isAnonymous() ||
5263 ($draft_obj instanceof ilForumPostDraft && $this->user->getId() !== $draft_obj->getPostAuthorId())) {
5264 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
5265 }
5266
5267 $post_id = $this->objCurrentPost->getId();
5268 if (!($draft_obj instanceof ilForumPostDraft)) {
5269 $draft_id_to_delete = $draft_id;
5270 $draft_obj = new ilForumPostDraft($this->user->getId(), $post_id, $draft_id_to_delete);
5271
5272 if (!$draft_obj->getDraftId() || ($draft_obj->getDraftId() !== $draft_id_to_delete)) {
5273 $this->ctrl->clearParameters($this);
5274 $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
5275 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
5276 $this->ctrl->redirect($this, 'viewThread');
5277 }
5278 }
5279
5280 $this->deleteMobsOfDraft($draft_obj->getDraftId(), $draft_obj->getPostMessage());
5281
5282 $objFileDataForumDrafts = new ilFileDataForumDrafts(0, $draft_obj->getDraftId());
5283 $objFileDataForumDrafts->delete();
5284
5286 $GLOBALS['ilAppEventHandler']->raise(
5287 'Modules/Forum',
5288 'deletedDraft',
5289 [
5290 'draftObj' => $draft_obj,
5291 'obj_id' => $this->object->getId(),
5292 'is_file_upload_allowed' => $this->objProperties->isFileUploadAllowed()
5293 ]
5294 );
5295 }
5296 $draft_obj->deleteDraft();
5297
5298 $this->tpl->setOnScreenMessage('success', $this->lng->txt('delete_draft_successfully'), true);
5299 $this->ctrl->clearParameters($this);
5300 $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
5301 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
5302 $this->ctrl->redirect($this, 'viewThread');
5303 }
5304
5305 protected function autosaveDraftAsyncObject(): void
5306 {
5307 if (
5308 $this->requestAction !== 'ready_showreply' &&
5309 $this->access->checkAccess('read', '', $this->object->getRefId()) &&
5310 $this->access->checkAccess('add_reply', '', $this->object->getRefId())
5311 ) {
5312 $action = new ilForumAutoSaveAsyncDraftAction(
5313 $this->user,
5314 $this->getReplyEditForm(),
5315 $this->objProperties,
5316 $this->objCurrentTopic,
5317 $this->objCurrentPost,
5318 function (string $message): string {
5319 return $this->handleFormInput($message);
5320 },
5321 $this->retrieveDraftId(),
5322 ilObjForum::lookupForumIdByRefId($this->ref_id),
5323 ilUtil::stripSlashes($this->requestAction)
5324 );
5325
5326 $this->http->saveResponse($this->http->response()->withBody(
5327 \ILIAS\Filesystem\Stream\Streams::ofString(json_encode(
5328 $action->executeAndGetResponseObject(),
5329 JSON_THROW_ON_ERROR
5330 ))
5331 ));
5332 }
5333
5334 $this->http->sendResponse();
5335 $this->http->close();
5336 }
5337
5338 protected function autosaveThreadDraftAsyncObject(): void
5339 {
5340 if (
5341 $this->requestAction !== 'ready_showreply' &&
5342 $this->access->checkAccess('read', '', $this->object->getRefId()) &&
5343 $this->access->checkAccess('add_thread', '', $this->object->getRefId())
5344 ) {
5345 $action = new ilForumAutoSaveAsyncDraftAction(
5346 $this->user,
5347 $this->buildThreadForm(),
5348 $this->objProperties,
5349 $this->objCurrentTopic,
5350 $this->objCurrentPost,
5351 function (string $message): string {
5352 return $this->handleFormInput($message, false);
5353 },
5354 $this->retrieveDraftId(),
5355 ilObjForum::lookupForumIdByRefId($this->ref_id),
5356 ilUtil::stripSlashes($this->requestAction)
5357 );
5358
5359 $this->http->saveResponse($this->http->response()->withBody(
5360 \ILIAS\Filesystem\Stream\Streams::ofString(json_encode(
5361 $action->executeAndGetResponseObject(),
5362 JSON_THROW_ON_ERROR
5363 ))
5364 ));
5365 }
5366
5367 $this->http->sendResponse();
5368 $this->http->close();
5369 }
5370
5371 private function renderSplitButton(
5373 string $action,
5374 bool $is_post,
5375 ilForumPost $node,
5376 int $pageIndex = 0,
5377 ilForumPostDraft $draft = null
5378 ): void {
5379 $draft_id = $this->retrieveDraftId();
5380
5381 $actions = [];
5382 $modalActions = [];
5383 if ($is_post) {
5384 if (
5385 $this->objCurrentPost->getId() !== $node->getId() || (
5386 !in_array($action, ['showreply', 'showedit', 'censor', 'delete'], true) &&
5387 !$this->displayConfirmPostActivation()
5388 )
5389 ) {
5390 if ($this->is_moderator || $node->isActivated() || $node->isOwner($this->user->getId())) {
5391 if ($this->is_moderator && !$this->objCurrentTopic->isClosed() && !$node->isActivated()) {
5392 $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
5393 $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
5394 $this->ctrl->setParameter($this, 'page', $pageIndex);
5395 $this->ctrl->setParameter(
5396 $this,
5397 'orderby',
5398 $this->getOrderByParam()
5399 );
5400 $actions['activate_post'] = $this->ctrl->getLinkTarget(
5401 $this,
5402 'askForPostActivation',
5403 (string) $node->getId()
5404 );
5405 $this->ctrl->clearParameters($this);
5406 }
5407
5408 if (
5409 !$this->objCurrentTopic->isClosed() && $node->isActivated() && !$node->isCensored() &&
5410 $this->access->checkAccess('add_reply', '', $this->object->getRefId())
5411 ) {
5412 $this->ctrl->setParameter($this, 'action', 'showreply');
5413 $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
5414 $this->ctrl->setParameter($this, 'page', $pageIndex);
5415 $this->ctrl->setParameter(
5416 $this,
5417 'orderby',
5418 $this->getOrderByParam()
5419 );
5420 $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
5421 $actions['reply_to_postings'] = $this->ctrl->getLinkTarget(
5422 $this,
5423 'viewThread',
5424 'reply_' . $node->getId()
5425 );
5426 $this->ctrl->clearParameters($this);
5427 }
5428
5429 if (
5430 !$this->objCurrentTopic->isClosed() &&
5431 !$node->isCensored() &&
5432 !$this->user->isAnonymous() &&
5433 ($node->isOwner($this->user->getId()) || $this->is_moderator)
5434 ) {
5435 $this->ctrl->setParameter($this, 'action', 'showedit');
5436 $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
5437 $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
5438 $this->ctrl->setParameter($this, 'page', $pageIndex);
5439 $this->ctrl->setParameter(
5440 $this,
5441 'orderby',
5442 $this->getOrderByParam()
5443 );
5444 $actions['edit'] = $this->ctrl->getLinkTarget($this, 'viewThread', (string) $node->getId());
5445 $this->ctrl->clearParameters($this);
5446 }
5447
5448 if (!$this->user->isAnonymous()) {
5449 $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
5450 $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
5451 $this->ctrl->setParameter($this, 'page', $pageIndex);
5452 $this->ctrl->setParameter(
5453 $this,
5454 'orderby',
5455 $this->getOrderByParam()
5456 );
5457 $this->ctrl->setParameter($this, 'viewmode', $this->selectedSorting);
5458
5459 $read_undread_txt = 'frm_mark_as_read';
5460 $read_undread_cmd = 'markPostRead';
5461 if ($node->isPostRead()) {
5462 $read_undread_txt = 'frm_mark_as_unread';
5463 $read_undread_cmd = 'markPostUnread';
5464 }
5465 $actions[$read_undread_txt] = $this->ctrl->getLinkTarget(
5466 $this,
5467 $read_undread_cmd,
5468 (string) $node->getId()
5469 );
5470
5471 $this->ctrl->clearParameters($this);
5472 }
5473
5474 if (!$node->isCensored()) {
5475 $this->ctrl->setParameterByClass(ilForumExportGUI::class, 'print_post', $node->getId());
5476 $this->ctrl->setParameterByClass(ilForumExportGUI::class, 'top_pk', $node->getForumId());
5477 $this->ctrl->setParameterByClass(ilForumExportGUI::class, 'thr_pk', $node->getThreadId());
5478
5479 $actions['print'] = $this->ctrl->getLinkTargetByClass(ilForumExportGUI::class, 'printPost');
5480
5481 $this->ctrl->clearParameters($this);
5482 }
5483
5484 if (
5485 !$this->objCurrentTopic->isClosed() &&
5486 !$this->user->isAnonymous() &&
5487 ($this->is_moderator || ($node->isOwner($this->user->getId()) && !$node->hasReplies()))
5488 ) {
5489 $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
5490 $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
5491 $this->ctrl->setParameter($this, 'page', $pageIndex);
5492 $this->ctrl->setParameter(
5493 $this,
5494 'orderby',
5495 $this->getOrderByParam()
5496 );
5497 $actions['delete'] = $this->ctrl->getFormAction($this, 'deletePosting');
5498 $this->ctrl->clearParameters($this);
5499 }
5500
5501 if ($this->is_moderator && !$this->objCurrentTopic->isClosed()) {
5502 $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
5503 $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
5504 $this->ctrl->setParameter($this, 'page', $pageIndex);
5505 $this->ctrl->setParameter(
5506 $this,
5507 'orderby',
5508 $this->getOrderByParam()
5509 );
5510 if ($node->isCensored()) {
5511 $this->ctrl->setParameter($this, 'action', 'viewThread');
5512 $actions['frm_revoke_censorship'] = $this->ctrl->getFormAction($this, 'revokeCensorship');
5513 } else {
5514 $actions['frm_censorship'] = $this->ctrl->getFormAction($this, 'addCensorship');
5515 }
5516 $this->ctrl->clearParameters($this);
5517 }
5518 }
5519 }
5520 } elseif ($draft_id !== $draft->getDraftId() || !in_array($action, ['deletedraft', 'editdraft'])) {
5521 // get actions for drafts
5522 $this->ctrl->setParameter($this, 'action', 'publishdraft');
5523 $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
5524 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
5525 $this->ctrl->setParameter($this, 'page', $pageIndex);
5526 $this->ctrl->setParameter($this, 'draft_id', $draft->getDraftId());
5527 $this->ctrl->setParameter(
5528 $this,
5529 'orderby',
5530 $this->getOrderByParam()
5531 );
5532 $actions['publish'] = $this->ctrl->getLinkTarget($this, 'publishSelectedDraft', (string) $node->getId());
5533 $this->ctrl->clearParameters($this);
5534
5535 $this->ctrl->setParameter($this, 'action', 'editdraft');
5536 $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
5537 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
5538 $this->ctrl->setParameter($this, 'draft_id', $draft->getDraftId());
5539 $this->ctrl->setParameter($this, 'page', $pageIndex);
5540 $this->ctrl->setParameter(
5541 $this,
5542 'orderby',
5543 $this->getOrderByParam()
5544 );
5545 $actions['edit'] = $this->ctrl->getLinkTarget($this, 'editDraft', 'draft_edit_' . $draft->getDraftId());
5546 $this->ctrl->clearParameters($this);
5547
5548 $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
5549 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
5550 $this->ctrl->setParameter($this, 'draft_id', $draft->getDraftId());
5551 $this->ctrl->setParameter($this, 'page', $pageIndex);
5552 $this->ctrl->setParameter(
5553 $this,
5554 'orderby',
5555 $this->getOrderByParam()
5556 );
5557 $actions['delete'] = $this->ctrl->getFormAction($this, 'deletePostingDraft');
5558 $this->ctrl->clearParameters($this);
5559
5560 if ($draft_id !== 0 && $action === 'editdraft') {
5561 $actions = [];
5562 }
5563 }
5564
5565 $tpl->setCurrentBlock('posts_row');
5566 if (count($actions) > 0 && !$this->objCurrentTopic->isClosed()) {
5567 $action_button = ilSplitButtonGUI::getInstance();
5568
5569 $i = 0;
5570 foreach ($actions as $lng_id => $url) {
5571 if ($i === 0) {
5572 $sb_item = ilLinkButton::getInstance();
5573 $sb_item->setCaption($lng_id);
5574 $sb_item->setUrl($url);
5575
5576 $action_button->setDefaultButton($sb_item);
5577 ++$i;
5578 } else {
5579 if ('frm_revoke_censorship' === $lng_id || 'frm_censorship' === $lng_id) {
5580 $modalTemplate = new ilTemplate("tpl.forums_censor_modal.html", true, true, 'Modules/Forum');
5581 $formID = str_replace('.', '_', uniqid('form', true));
5582 $modalTemplate->setVariable('FORM_ID', $formID);
5583
5584 if ($node->isCensored()) {
5585 $modalTemplate->setVariable('BODY', $this->lng->txt('forums_info_censor2_post'));
5586 } else {
5587 $modalTemplate->setVariable('BODY', $this->lng->txt('forums_info_censor_post'));
5588 $modalTemplate->touchBlock('message');
5589 }
5590
5591 $modalTemplate->setVariable('FORM_ACTION', $url);
5592
5593 $content = $this->uiFactory->legacy($modalTemplate->get());
5594 $submitBtn = $this->uiFactory->button()->primary(
5595 $this->lng->txt('submit'),
5596 '#'
5597 )->withOnLoadCode(
5598 static function (string $id) use ($formID): string {
5599 return "$('#$id').click(function() { $('#$formID').submit(); return false; });";
5600 }
5601 );
5602 $modal = $this->uiFactory->modal()->roundtrip(
5603 $this->lng->txt($lng_id),
5604 $content
5605 )->withActionButtons([$submitBtn]);
5606 $sb_item = $this->uiFactory->button()->shy($this->lng->txt($lng_id), '#')->withOnClick(
5607 $modal->getShowSignal()
5608 );
5609
5610 $this->modalActionsContainer[] = $modal;
5611
5612 $action_button->addMenuItem(new ilUiLinkToSplitButtonMenuItemAdapter(
5613 $sb_item,
5614 $this->uiRenderer
5615 ));
5616 continue;
5617 } elseif ('delete' === $lng_id) {
5618 $modal = $this->uiFactory->modal()->interruptive(
5619 $this->lng->txt($lng_id),
5620 strpos($url, 'deletePostingDraft') !== false ?
5621 $this->lng->txt('forums_info_delete_draft') :
5622 $this->lng->txt('forums_info_delete_post'),
5623 $url
5624 )->withActionButtonLabel(
5625 strpos($url, 'deletePostingDraft') !== false ? 'deletePostingDraft' : 'deletePosting'
5626 );
5627
5628 $deleteAction = $this->uiFactory->button()->shy($this->lng->txt($lng_id), '#')->withOnClick(
5629 $modal->getShowSignal()
5630 );
5631
5632 $this->modalActionsContainer[] = $modal;
5633
5634 $action_button->addMenuItem(
5635 new ilUiLinkToSplitButtonMenuItemAdapter($deleteAction, $this->uiRenderer)
5636 );
5637 continue;
5638 }
5639
5640 $sb_item = ilLinkButton::getInstance();
5641 $sb_item->setCaption($lng_id);
5642 $sb_item->setUrl($url);
5643
5644 $action_button->addMenuItem(new ilButtonToSplitButtonMenuItemAdapter($sb_item));
5645 }
5646 }
5647
5648 $tpl->setVariable('COMMANDS', $action_button->render());
5649 }
5650 }
5651
5652 public function checkDraftAccess(int $draftId): bool
5653 {
5654 $draft = ilForumPostDraft::newInstanceByDraftId($draftId);
5655 if (
5656 $this->user->isAnonymous() || !$this->access->checkAccess('add_reply', '', $this->object->getRefId()) ||
5657 $this->user->getId() !== $draft->getPostAuthorId()
5658 ) {
5659 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
5660 }
5661
5662 return true;
5663 }
5664
5665 private function doHistoryCheck(int $draftId): void
5666 {
5667 if (!$this->checkDraftAccess($draftId)) {
5668 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
5669 }
5670
5672 return;
5673 }
5674
5676 $draftsFromHistory = ilForumDraftsHistory::getInstancesByDraftId($draftId);
5677 if ($draftsFromHistory !== []) {
5678 $modal = ilModalGUI::getInstance();
5679 $modal->setHeading($this->lng->txt('restore_draft_from_autosave'));
5680 $modal->setId('frm_autosave_restore');
5681 $form_tpl = new ilTemplate('tpl.restore_thread_draft.html', true, true, 'Modules/Forum');
5682
5683 foreach ($draftsFromHistory as $key => $history_instance) {
5684 $accordion = new ilAccordionGUI();
5685 $accordion->setId('acc_' . $history_instance->getHistoryId());
5686
5687 $form_tpl->setCurrentBlock('list_item');
5688 $message = ilRTE::_replaceMediaObjectImageSrc($history_instance->getPostMessage(), 1);
5689
5690 $history_date = ilDatePresentation::formatDate(new ilDateTime(
5691 $history_instance->getDraftDate(),
5693 ));
5694 $this->ctrl->setParameter($this, 'history_id', $history_instance->getHistoryId());
5695 $header = $history_date;
5696
5697 $accordion_tpl = new ilTemplate(
5698 'tpl.restore_thread_draft_accordion_content.html',
5699 true,
5700 true,
5701 'Modules/Forum'
5702 );
5703 $accordion_tpl->setVariable('HEADER', $history_instance->getPostSubject());
5704 $accordion_tpl->setVariable('MESSAGE', $message);
5705 $accordion_tpl->setVariable(
5706 'BUTTON',
5707 $this->uiRenderer->render(
5708 $this->uiFactory->button()->standard(
5709 $this->lng->txt('restore'),
5710 $this->ctrl->getLinkTarget($this, 'restoreFromHistory')
5711 )
5712 )
5713 );
5714 $accordion->addItem($header, $accordion_tpl->get());
5715
5716 $form_tpl->setVariable('ACC_AUTO_SAVE', $accordion->getHTML());
5717 $form_tpl->parseCurrentBlock();
5718 }
5719
5720 $form_tpl->setVariable('RESTORE_DATA_EXISTS', 'found_threat_history_to_restore');
5721 $modal->setBody($form_tpl->get());
5723 $this->modal_history = $modal->getHTML();
5724 } else {
5726 }
5727 }
5728
5729 private function renderPostingForm(ilTemplate $tpl, ilForum $frm, ilForumPost $node, string $action): void
5730 {
5731 $ref_id = $this->retrieveRefId();
5732 $draft_id = $this->retrieveDraftId();
5733
5734 if (
5735 $action === 'showedit' && (
5736 (!$this->is_moderator && !$node->isOwner($this->user->getId())) ||
5737 $this->user->isAnonymous() ||
5738 $node->isCensored()
5739 )
5740 ) {
5741 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
5742 } elseif ($action === 'showreply' && !$this->access->checkAccess('add_reply', '', $ref_id)) {
5743 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
5744 }
5745
5746 $tpl->setVariable('REPLY_ANKER', 'reply_' . $this->objCurrentPost->getId());
5747 $oEditReplyForm = $this->getReplyEditForm();
5748 $subject = '';
5749 if ($action !== 'editdraft') {
5750 switch ($this->objProperties->getSubjectSetting()) {
5751 case 'add_re_to_subject':
5752 $subject = $this->getModifiedReOnSubject();
5753 break;
5754
5755 case 'preset_subject':
5756 $subject = $this->objCurrentPost->getSubject();
5757 break;
5758
5759 case 'empty_subject':
5760 $subject = '';
5761 break;
5762 }
5763 }
5764
5765 switch ($action) {
5766 case 'showreply':
5767 if ($this->ctrl->getCmd() === 'savePost' || $this->ctrl->getCmd() === 'saveAsDraft') {
5768 $oEditReplyForm->setValuesByPost();
5769 } elseif ($this->ctrl->getCmd() === 'quotePost') {
5770 $authorinfo = new ilForumAuthorInformation(
5771 $node->getPosAuthorId(),
5772 $node->getDisplayUserId(),
5773 (string) $node->getUserAlias(),
5774 (string) $node->getImportName()
5775 );
5776
5777 $oEditReplyForm->setValuesByPost();
5778 $oEditReplyForm->getItemByPostVar('message')->setValue(
5780 $frm->prepareText(
5781 $node->getMessage(),
5782 1,
5783 $authorinfo->getAuthorName()
5784 ) . "\n" . $oEditReplyForm->getInput('message'),
5785 1
5786 )
5787 );
5788 } else {
5789 $oEditReplyForm->setValuesByArray([
5790 'draft_id' => $draft_id,
5791 'alias' => '',
5792 'subject' => $subject,
5793 'message' => '',
5794 'notify' => 0,
5795 'userfile' => '',
5796 'del_file' => []
5797 ]);
5798 }
5799
5800 $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
5801 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
5802
5803 $jsTpl = new ilTemplate('tpl.forum_post_quoation_ajax_handler.js', true, true, 'Modules/Forum');
5804 $jsTpl->setVariable(
5805 'IL_FRM_QUOTE_CALLBACK_SRC',
5806 $this->ctrl->getLinkTarget($this, 'getQuotationHTMLAsynch', '', true)
5807 );
5808 $this->ctrl->clearParameters($this);
5809 $this->tpl->addOnLoadCode($jsTpl->get());
5810 break;
5811
5812 case 'showedit':
5813 if ($this->ctrl->getCmd() === 'savePost') {
5814 $oEditReplyForm->setValuesByPost();
5815 } else {
5816 $oEditReplyForm->setValuesByArray([
5817 'alias' => '',
5818 'subject' => $this->objCurrentPost->getSubject(),
5820 $this->objCurrentPost->getMessage(),
5821 2
5822 ), 1),
5823 'notify' => $this->objCurrentPost->isNotificationEnabled() && !$this->user->isAnonymous(),
5824 'userfile' => '',
5825 'del_file' => [],
5826 'draft_id' => $draft_id
5827 ]);
5828 }
5829
5830 $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getParentId());
5831 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
5832 $jsTpl = new ilTemplate('tpl.forum_post_quoation_ajax_handler.js', true, true, 'Modules/Forum');
5833 $jsTpl->setVariable(
5834 'IL_FRM_QUOTE_CALLBACK_SRC',
5835 $this->ctrl->getLinkTarget($this, 'getQuotationHTMLAsynch', '', true)
5836 );
5837 $this->ctrl->clearParameters($this);
5838 $this->tpl->addOnLoadCode($jsTpl->get());
5839 break;
5840
5841 case 'editdraft':
5842 if (in_array($this->ctrl->getCmd(), ['saveDraft', 'updateDraft', 'publishDraft'])) {
5843 $oEditReplyForm->setValuesByPost();
5844 } elseif ($draft_id > 0) {
5846 $draftObject = new ilForumPostDraft(
5847 $this->user->getId(),
5848 $this->objCurrentPost->getId(),
5849 $draft_id
5850 );
5851 $oEditReplyForm->setValuesByArray([
5852 'alias' => $draftObject->getPostUserAlias(),
5853 'subject' => $draftObject->getPostSubject(),
5855 $draftObject->getPostMessage(),
5856 2
5857 ), 1),
5858 'notify' => $draftObject->isNotificationEnabled() && !$this->user->isAnonymous(),
5859 'userfile' => '',
5860 'del_file' => [],
5861 'draft_id' => $draft_id
5862 ]);
5863 }
5864
5865 $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
5866 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
5867
5868 $jsTpl = new ilTemplate('tpl.forum_post_quoation_ajax_handler.js', true, true, 'Modules/Forum');
5869 $jsTpl->setVariable(
5870 'IL_FRM_QUOTE_CALLBACK_SRC',
5871 $this->ctrl->getLinkTarget($this, 'getQuotationHTMLAsynch', '', true)
5872 );
5873 $this->ctrl->clearParameters($this);
5874 $this->tpl->addOnLoadCode($jsTpl->get());
5875 break;
5876 }
5877
5878 $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
5879 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
5880 $this->ctrl->setParameter($this, 'page', (int) ($this->httpRequest->getQueryParams()['page'] ?? 0));
5881 $this->ctrl->setParameter(
5882 $this,
5883 'orderby',
5884 $this->getOrderByParam()
5885 );
5886 $this->ctrl->setParameter(
5887 $this,
5888 'action',
5889 ilUtil::stripSlashes($this->requestAction)
5890 );
5891 if ($action !== 'editdraft') {
5892 $tpl->setVariable('FORM', $oEditReplyForm->getHTML());
5893 }
5894 $this->ctrl->clearParameters($this);
5895 }
5896
5897 private function getResetLimitedViewInfo(): string
5898 {
5899 $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
5900
5901 $buttons = [
5902 $this->uiFactory->button()->standard(
5903 $this->lng->txt('reset_limited_view_button'),
5904 $this->ctrl->getLinkTarget($this, 'resetLimitedView')
5905 )
5906 ];
5907
5908 return $this->uiRenderer->render(
5909 $this->uiFactory
5910 ->messageBox()
5911 ->info($this->lng->txt('reset_limited_view_info'))
5912 ->withButtons($buttons)
5913 );
5914 }
5915
5916 private function getOrderByParam(): string
5917 {
5918 $order_by = '';
5919 if ($this->http->wrapper()->query()->has('orderby')) {
5920 $order_by = $this->http->wrapper()->query()->retrieve(
5921 'orderby',
5922 $this->refinery->kindlyTo()->string()
5923 );
5924 }
5925
5926 return ilUtil::stripSlashes($order_by);
5927 }
5928}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
static return function(ContainerConfigurator $containerConfigurator)
Definition: basic_rector.php:9
setVariable($variable, $value='')
Sets a variable value.
Definition: IT.php:514
const IL_CAL_DATETIME
error(string $a_errmsg)
return true
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _recordReadEvent(string $a_type, int $a_ref_id, int $obj_id, int $usr_id, bool $isCatchupWriteEvents=true, $a_ext_rc=null, $a_ext_time=null)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This class represents a checkbox property in a property form.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Column user interface class.
setRepositoryMode(bool $a_repositorymode)
setBlockProperty(string $a_block_type, string $a_property, string $a_value)
This function is supposed to be used for block type specific properties, that should be passed to ilB...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false)
@classDescription Date and time handling
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This class handles all operations on files for the drafts of a forum object.
This class handles all operations on files for the forum object.
This class represents a file wizard property in a property form.
Class ilForumDraftHistory.
static getInstancesByDraftId(int $draft_id)
Class ilForumDraftsTableGUI.
Class ilForumExplorerGUI.
Forum export to HTML and Print.
Class ilForumModeratorsGUI.
const PRESENTATION_MODE_PRESENTATION
presentation mode for requesting
Class ilForumPostDraft.
static getThreadDraftData(int $post_author_id, int $forum_id)
static createDraftBackup(int $draft_id)
static newInstanceByDraftId(int $draft_id)
static getDraftInstancesByUserId(int $user_id)
static getSortedDrafts(int $usrId, int $threadId, int $sorting=ilForumProperties::VIEW_DATE_ASC)
setMessage(string $a_message)
isOwner(int $a_user_id=0)
setChangeDate(?string $a_changedate)
static getInstance(int $a_obj_id=0)
Class ilForumSettingsGUI.
Class ilForumStatisticsTableGUI.
Class ilForumThreadFormGUI.
Class ilForumTopicTableGUI.
static lookupTitle(int $a_topic_id)
static lookupCreationDate(int $thread_id)
static lookupForumIdByTopicId(int $a_topic_id)
static getPublicUserAlias(string $user_alias, bool $is_anonymized)
static saveMediaObjects(string $post_message, string $target_type, int $target_id, int $direction=0)
static moveMediaObjects(string $post_message, string $source_type, int $source_id, string $target_type, int $target_id, int $direction=0)
Class Forum core functions for forum.
static _lookupObjIdForForumId(int $a_for_id)
prepareText(string $text, int $edit=0, string $quote_user='', string $type='')
static _isModerator(int $a_ref_id, int $a_usr_id)
static get(string $a_glyph, string $a_text="")
Help GUI class.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getInstanceByType(string $type)
Class ilInfoScreenGUI.
Learning progress access checks.
static checkAccess(int $a_ref_id, bool $a_allow_only_read=true)
check access to learning progress
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static prepareFormOutput($a_str, bool $a_strip=false)
static getInstance()
static initJS(ilGlobalTemplateInterface $a_main_tpl=null)
Navigation History of Repository Items.
addItem(int $a_ref_id, string $a_link, string $a_type, string $a_title="", ?int $a_sub_obj_id=null, string $a_goto_link="")
Add an item to the stack.
A news item can be created by different sources.
static getFirstNewsIdForContext(int $a_context_obj_id, string $a_context_obj_type, int $a_context_sub_obj_id=0, string $a_context_sub_obj_type="")
Get first new id of news set related to a certain context.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _setRichTextEditorUserState(int $a_state)
Sets the state of the rich text editor visibility for the current user.
static _getRichTextEditorUserState()
Gets the state of the rich text editor visibility for the current user.
Class ilObjForumGUI.
setDisplayConfirmPostActivation(bool $status=false)
getThreadEditingForm(int $a_thread_id)
editThreadDraftObject(ilPropertyFormGUI $form=null)
addLocatorItems()
should be overwritten to add object specific items (repository items are preloaded)
afterSave(ilObject $new_object)
createEmptyThread(ilForumPostDraft $draft, bool $createFromDraft=false)
Refactored thread creation to method, refactoring to a separate class should be done in next refactor...
ilForumProperties $objProperties
ilForumPost $objCurrentPost
ilPropertyFormGUI $replyEditForm
getTabs()
@abstract overwrite in derived GUI class of your object type
getSubTabs($subtab='showThreads')
getEditFormCustomValues(array &$a_values)
Add values to custom edit fields.
static _goto($a_target, $a_thread=0, $a_posting=0)
renderDraftContent(ilTemplate $tpl, string $action, ilForumPost $referencePosting, array $drafts)
decorateWithAutosave(ilPropertyFormGUI $form)
initHeaderAction(?string $sub_type=null, ?int $sub_id=null)
Add header action menu.
renderSplitButton(ilTemplate $tpl, string $action, bool $is_post, ilForumPost $node, int $pageIndex=0, ilForumPostDraft $draft=null)
ILIAS GlobalScreen Services $globalScreen
ilForumSettingsGUI $forum_settings_gui
hideToolbar($a_flag=null)
setColumnSettings(ilColumnGUI $column_gui)
eventsFormBuilder(?array $predefined_values=null)
createThread(ilForumPostDraft $draft, bool $createFromDraft=false)
Refactored thread creation to method, refactoring to a separate class should be done in next refactor...
buildMinimalThreadForm(bool $isDraft=false)
updateCustom(ilPropertyFormGUI $form)
Insert custom update form values into object.
getSafePostCommands()
This method must return a list of safe POST commands.
ILIAS DI RBACServices $rbac
ilForumThreadSettingsSessionStorage $selected_post_storage
getUnsafeGetCommands()
This method must return a list of unsafe GET commands.
bool $display_confirm_post_activation
doHistoryCheck(int $draftId)
editThreadObject(int $threadId, ilPropertyFormGUI $form=null)
prepareFormOutput(string $a_text)
deleteMobsOfDraft(int $draft_id, string $message)
ILIAS Style Content Object ObjectFacade $content_style_domain
ilObjectDataCache $ilObjDataCache
ILIAS HTTP Services $http
deleteSelectedDraft(ilForumPostDraft $draft_obj=null)
ilForumTopic $objCurrentTopic
renderPostContent(ilTemplate $tpl, ilForumPost $node, string $action, int $pageIndex, int $postIndex)
handleFormInput(string $a_text, bool $a_stripslashes=true)
ilNavigationHistory $ilNavigationHistory
handleCensorship($wasRevoked=false)
ensureValidPageForCurrentPosting(array $subtree_nodes, array $pagedPostings, int $pageSize, ilForumPost $firstForumPost)
publishDraftObject(bool $use_replyform=true)
buildThreadForm(bool $isDraft=false)
ensureThreadBelongsToForum(int $objId, ilForumTopic $thread)
initEditCustomForm(ilPropertyFormGUI $a_form)
Add custom fields to update form.
renderSortationControl(int $currentSorting)
renderViewModeControl(int $currentViewMode)
ILIAS Style Content GUIService $content_style_gui
checkDraftAccess(int $draftId)
__construct($data, int $id=0, bool $call_by_reference=true, bool $prepare_output=true)
Class ilObjForumListGUI.
Class ilObjForum.
static lookupForumIdByRefId(int $ref_id)
static lookupForumIdByObjId(int $obj_id)
static _exists(int $id, bool $reference=false, ?string $type=null)
checks if an object exists in object_data
static _getMobsOfObject(string $a_type, int $a_id, int $a_usage_hist_nr=0, string $a_lang="-")
static _removeUsage(int $a_mob_id, string $a_type, int $a_id, int $a_usage_hist_nr=0, string $a_lang="-")
Remove usage of mob in another container.
static _saveUsage(int $a_mob_id, string $a_type, int $a_id, int $a_usage_hist_nr=0, string $a_lang="-")
Save usage of mob within another container (e.g.
GUI class for the workflow of copying objects.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getInstanceByRefId(int $ref_id, bool $stop_on_error=true)
get an instance of an Ilias object by reference id
Class ilObjectGUI Basic methods of all Output classes.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _lookupObjectId(int $ref_id)
static _getIcon(int $obj_id=0, string $size="big", string $type="", bool $offline=false)
Get icon for repository item.
static _getAllReferences(int $id)
get all reference ids for object ID
static _lookupObjId(int $ref_id)
static _lookupTitle(int $obj_id)
New PermissionGUI (extends from old ilPermission2GUI) RBAC related output.
This class represents a property form user interface.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _getRTEClassname()
static _replaceMediaObjectImageSrc(string $a_text, int $a_direction=0, string $nic='')
Replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
static _getMediaObjects(string $a_text, int $a_direction=0)
Returns all media objects found in the passed string.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getOverallRatingForObject(int $a_obj_id, string $a_obj_type, int $a_sub_obj_id=null, string $a_sub_obj_type=null, int $a_category_id=null)
Get overall rating for an object.
static get(string $a_var)
static set(string $a_var, $a_val)
Set a value.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
special template class to simplify handling of ITX/PEAR
This class represents a text area property in a property form.
This class represents a text property in a property form.
static getImagePath(string $img, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
static switchColor(int $a_num, string $a_css1, string $a_css2)
switches style sheets for each even $a_num (used for changing colors of different result rows)
static initjQuery(ilGlobalTemplateInterface $a_tpl=null)
inits and adds the jQuery JS-File to the global or a passed template
if(!file_exists(getcwd() . '/ilias.ini.php'))
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: confirmReg.php:20
const ROOT_FOLDER_ID
Definition: constants.php:32
global $DIC
Definition: feed.php:28
$mobs
Definition: imgupload.php:70
This is how the factory for UI elements looks.
Definition: Factory.php:38
An entity that renders components to a string output.
Definition: Renderer.php:31
Interface ilCtrlSecurityInterface provides ilCtrl security information.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
if($DIC->http() ->request() ->getMethod()=="GET" &&isset($DIC->http() ->request() ->getQueryParams()['tex'])) $tpl
Definition: latex.php:41
$ref_id
Definition: ltiauth.php:67
$post
Definition: ltitoken.php:49
$i
Definition: metadata.php:41
Class FlySystemFileAccessTest \Provider\FlySystem @runTestsInSeparateProcesses @preserveGlobalState d...
static http()
Fetches the global http state from ILIAS.
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
string $key
Consumer key/client ID value.
Definition: System.php:193
Class ChatMainBarProvider \MainMenu\Provider.
$url
$ilErr
Definition: raiseError.php:17
$lng
$message
Definition: xapiexit.php:32
$objId
Definition: xapitoken.php:57