1<?php
2/* Copyright (c) 1998-2012 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4use ILIAS\UI\Factory;
5use ILIAS\UI\Renderer;
6
7/**
8 * Class ilObjForumGUI
9 * @author Stefan Meyer <meyer@leifos.com>
10 * @author Nadia Matuschek <nmatuschek@databay.de>
11 * @ilCtrl_Calls ilObjForumGUI: ilPermissionGUI, ilForumExportGUI, ilInfoScreenGUI
12 * @ilCtrl_Calls ilObjForumGUI: ilColumnGUI, ilPublicUserProfileGUI, ilForumModeratorsGUI, ilRepositoryObjectSearchGUI
13 * @ilCtrl_Calls ilObjForumGUI: ilObjectCopyGUI, ilExportGUI, ilCommonActionDispatcherGUI, ilRatingGUI
14 * @ilCtrl_Calls ilObjForumGUI: ilForumSettingsGUI, ilContainerNewsSettingsGUI
15 *
16 * @ingroup ModulesForum
17 */
18class ilObjForumGUI extends \ilObjectGUI implements \ilDesktopItemHandling
19{
20    /** @var string */
21    public $modal_history = '';
22
23    /** @var ilForumProperties */
24    public $objProperties;
25
26    /** @var ilForumTopic */
27    private $objCurrentTopic;
28
29    /** @var ilForumPost */
30    private $objCurrentPost;
31
32    /** @var int */
33    private $display_confirm_post_activation = 0;
34
35    /** @var bool */
36    private $is_moderator = false;
37
38    /** @var ilPropertyFormGUI */
39    private $create_form_gui;
40
41    /** @var ilPropertyFormGUI */
42    private $replyEditForm;
43
44    /** @var bool */
45    private $hideToolbar = false;
46
47    /** @var ilObjForum */
48    public $object;
49
50    /** @var \Psr\Http\Message\ServerRequestInterface */
51    private $httpRequest;
52
53    /** @var Factory */
54    private $uiFactory;
55
56    /** @var Renderer */
57    private $uiRenderer;
58
59    /** @var array|null */
60    private $forumObjects = null;
61
62    /** @var string */
63    private $confirmation_gui_html = '';
64
65    /** @var ilForumSettingsGUI */
66    private $forum_settings_gui;
67
68    /** @var \ilNavigationHistory */
69    public $ilNavigationHistory;
70    /** @var string */
71    private $requestAction = '';
72
73    public $access;
74    public $ilObjDataCache;
75    public $tabs;
76    public $error;
77    public $user;
78    public $settings;
79    public $toolbar;
80    public $repositoryTree;
81    public $rbac;
82    public $locator;
83    public $ilHelp;
84
85    public function __construct($a_data, $a_id, $a_call_by_reference = true, $a_prepare_output = true)
86    {
87        global $DIC;
88
89        $this->ctrl = $DIC->ctrl();
90        $this->ctrl->saveParameter($this, array('ref_id', 'cmdClass'));
91
92        $this->tpl = $DIC->ui()->mainTemplate();
93        $this->lng = $DIC->language();
94        $this->httpRequest = $DIC->http()->request();
95        $this->uiFactory = $DIC->ui()->factory();
96        $this->uiRenderer = $DIC->ui()->renderer();
97
98        $this->access = $DIC->access();
99        $this->ilObjDataCache = $DIC['ilObjDataCache'];
100        $this->tabs = $DIC->tabs();
101        $this->error = $DIC['ilErr'];
102        $this->ilNavigationHistory = $DIC['ilNavigationHistory'];
103        $this->user = $DIC->user();
104        $this->settings = $DIC->settings();
105        $this->toolbar = $DIC->toolbar();
106        $this->repositoryTree = $DIC->repositoryTree();
107        $this->ilHelp = $DIC['ilHelp'];
108        $this->rbac = $DIC->rbac();
109        $this->locator = $DIC['ilLocator'];
110
111        $this->type = 'frm';
112        parent::__construct($a_data, $a_id, $a_call_by_reference, false);
113
114        $this->lng->loadLanguageModule('forum');
115
116        $this->initSessionStorage();
117
118        $this->objProperties = \ilForumProperties::getInstance($this->ilObjDataCache->lookupObjId($_GET['ref_id']));
119
120        // Stored due to performance issues
121        $this->is_moderator = $this->access->checkAccess('moderate_frm', '', $_GET['ref_id']);
122
123        // Model of current topic/thread
124        $this->objCurrentTopic = new ilForumTopic((int) $_GET['thr_pk'], $this->is_moderator);
125
126        // Model of current post
127        $this->objCurrentPost = new ilForumPost((int) $_GET['pos_pk'], $this->is_moderator);
128
129        $this->requestAction = (string) ($this->httpRequest->getQueryParams()['action'] ?? '');
130    }
131
132    protected function initSessionStorage()
133    {
134        $forumValues = \ilSession::get('frm');
135        if (!is_array($forumValues)) {
136            $forumValues = [];
137            \ilSession::set('frm', $forumValues);
138        }
139
140        $threadId = $this->httpRequest->getQueryParams()['thr_pk'] ?? 0;
141        if ((int) $threadId > 0 && !is_array($forumValues[(int) $threadId])) {
142            $forumValues[(int) $threadId] = [];
143            \ilSession::set('frm', $forumValues);
144        }
145    }
146
147    /**
148     * @param int $objId
149     * @param ilForumTopic $thread
150     */
151    public function ensureThreadBelongsToForum(int $objId, \ilForumTopic $thread)
152    {
153        $forumId = \ilObjForum::lookupForumIdByObjId($objId);
154        if ((int) $thread->getForumId() !== (int) $forumId) {
155            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
156        }
157    }
158
159    /**
160     * @param \ilPropertyFormGUI $form
161     */
162    private function decorateWithAutosave(\ilPropertyFormGUI $form)
163    {
164        if (\ilForumPostDraft::isAutoSavePostDraftAllowed()) {
165            $interval = ilForumPostDraft::lookupAutosaveInterval();
166
167            $this->tpl->addJavascript('./Modules/Forum/js/autosave.js');
168            $autosave_cmd = 'autosaveDraftAsync';
169            if ($this->objCurrentPost->getId() == 0 && $this->objCurrentPost->getThreadId() == 0) {
170                $autosave_cmd = 'autosaveThreadDraftAsync';
171            }
172            $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
173            $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
174            $draft_id = (int) $_GET['draft_id'] > 0 ?  (int) $_GET['draft_id'] : 0;
175            $this->ctrl->setParameter($this, 'draft_id', $draft_id);
176            $this->ctrl->setParameter($this, 'action', \ilUtil::stripSlashes($this->requestAction));
177            $this->tpl->addOnLoadCode(
178                "il.Language.setLangVar('saving', " . json_encode($this->lng->txt('saving')) . ");"
179            );
180
181            $this->tpl->addOnLoadCode('il.ForumDraftsAutosave.init(' . json_encode(array(
182                    'loading_img_src' => \ilUtil::getImagePath('loader.svg'),
183                    'draft_id' => $draft_id,
184                    'interval' => $interval * 1000,
185                    'url' => $this->ctrl->getFormAction($this, $autosave_cmd, '', true, false),
186                    'selectors' => array(
187                        'form' => '#form_' . $form->getId()
188                    )
189                )) . ');');
190        }
191    }
192
193    /**
194     * @return bool
195     */
196    private function isHierarchicalView() : bool
197    {
198        return (
199            $_SESSION['viewmode'] == 'answers' ||
200            $_SESSION['viewmode'] == ilForumProperties::VIEW_TREE
201        ) || !(
202            $_SESSION['viewmode'] == 'date' ||
203            $_SESSION['viewmode'] == ilForumProperties::VIEW_DATE
204        );
205    }
206
207    /**
208     * @return bool
209     */
210    private function isTopLevelReplyCommand() : bool
211    {
212        return in_array(
213            strtolower($this->ctrl->getCmd()),
214            array_map('strtolower', array('createTopLevelPost', 'saveTopLevelPost'))
215        );
216    }
217
218    public function executeCommand()
219    {
220        $next_class = $this->ctrl->getNextClass($this);
221        $cmd = $this->ctrl->getCmd();
222
223        $exclude_cmds = array(
224            'viewThread', 'markPostUnread','markPostRead', 'showThreadNotification',
225            'performPostActivation',
226            'askForPostActivation', 'askForPostDeactivation',
227            'toggleThreadNotification', 'toggleThreadNotificationTab',
228            'toggleStickiness', 'cancelPost', 'savePost', 'saveTopLevelPost', 'createTopLevelPost', 'quotePost', 'getQuotationHTMLAsynch',
229            'autosaveDraftAsync', 'autosaveThreadDraftAsync',
230            'saveAsDraft', 'editDraft', 'updateDraft', 'deliverDraftZipFile', 'deliverZipFile', 'cancelDraft',
231            'deleteThreadDrafts',
232            'deletePosting', 'deletePostingDraft', 'revokeCensorship', 'addCensorship',
233        );
234
235        if (!in_array($cmd, $exclude_cmds)) {
236            $this->prepareOutput();
237        }
238
239        if (!$this->getCreationMode() && !$this->ctrl->isAsynch() && $this->access->checkAccess('read', '', $_GET['ref_id'])) {
240            $this->ilNavigationHistory->addItem(
241                (int) $_GET['ref_id'],
242                \ilLink::_getLink((int) $_GET['ref_id'], 'frm'),
243                'frm'
244            );
245        }
246
247        switch ($next_class) {
248            case 'ilforumsettingsgui':
249                $forum_settings_gui = new ilForumSettingsGUI($this);
250                $this->ctrl->forwardCommand($forum_settings_gui);
251                break;
252
253            case 'ilrepositoryobjectsearchgui':
254                $this->addHeaderAction();
255                $this->setSideBlocks();
256                $this->tabs->activateTab("forums_threads");
257                $this->ctrl->setReturn($this, 'view');
258                $search_gui = new ilRepositoryObjectSearchGUI(
259                    $this->object->getRefId(),
260                    $this,
261                    'view'
262                );
263                $this->ctrl->forwardCommand($search_gui);
264                break;
265
266            case 'ilpermissiongui':
267                $perm_gui = new ilPermissionGUI($this);
268                $this->ctrl->forwardCommand($perm_gui);
269                break;
270
271            case 'ilforumexportgui':
272                $fex_gui = new ilForumExportGUI();
273                $this->ctrl->forwardCommand($fex_gui);
274                exit();
275                break;
276
277            case 'ilforummoderatorsgui':
278                $fm_gui = new ilForumModeratorsGUI();
279                $this->ctrl->forwardCommand($fm_gui);
280                break;
281
282            case 'ilinfoscreengui':
283                $this->infoScreen();
284                break;
285
286            case 'ilcolumngui':
287                $this->showThreadsObject();
288                break;
289
290            case 'ilpublicuserprofilegui':
291                $profile_gui = new ilPublicUserProfileGUI((int) $_GET['user']);
292                $add = $this->getUserProfileAdditional((int) $_GET['ref_id'], (int) $_GET['user']);
293                $profile_gui->setAdditional($add);
294                $ret = $this->ctrl->forwardCommand($profile_gui);
295                $this->tpl->setContent($ret);
296                break;
297
298            case 'ilobjectcopygui':
299                $cp = new ilObjectCopyGUI($this);
300                $cp->setType('frm');
301                $this->ctrl->forwardCommand($cp);
302                break;
303
304            case 'ilexportgui':
305                $this->tabs->activateTab('export');
306                $exp = new ilExportGUI($this);
307                $exp->addFormat('xml');
308                $this->ctrl->forwardCommand($exp);
309                break;
310
311            case "ilratinggui":
312                if (!$this->objProperties->isIsThreadRatingEnabled() || $this->user->isAnonymous()) {
313                    $this->error->raiseError($this->lng->txt('msg_no_perm_read'), $this->error->MESSAGE);
314                }
315
316                if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
317                    $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
318                }
319
320                $this->ensureThreadBelongsToForum((int) $this->object->getId(), $this->objCurrentTopic);
321
322                $rating_gui = new ilRatingGUI();
323                $rating_gui->setObject($this->object->getId(), $this->object->getType(), $this->objCurrentTopic->getId(), 'thread');
324
325                $this->ctrl->setParameter($this, 'thr_pk', (int) $this->objCurrentTopic->getId());
326                $this->ctrl->forwardCommand($rating_gui);
327
328                $avg = ilRating::getOverallRatingForObject($this->object->getId(), $this->object->getType(), (int) $this->objCurrentTopic->getId(), 'thread');
329                $this->objCurrentTopic->setAverageRating($avg['avg']);
330                $this->objCurrentTopic->update();
331
332                $this->ctrl->redirect($this, "showThreads");
333                break;
334
335            case 'ilcommonactiondispatchergui':
336                $gui = ilCommonActionDispatcherGUI::getInstanceFromAjaxCall();
337                $this->ctrl->forwardCommand($gui);
338                break;
339
340            case "ilcontainernewssettingsgui":
341                $forum_settings_gui = new ilForumSettingsGUI($this);
342                $forum_settings_gui->settingsTabs();
343
344                $this->lng->loadLanguageModule('cont');
345                $this->tabs_gui->activateSubTab('cont_news_settings');
346                $news_set_gui = new ilContainerNewsSettingsGUI($this);
347                $news_set_gui->setNewsBlockForced(true);
348                $news_set_gui->setPublicNotification(true);
349                $this->ctrl->forwardCommand($news_set_gui);
350                break;
351
352            default:
353                // alex, 11 Jan 2011:
354                // I inserted this workaround due to bug report 6971.
355                // In general the command handling is quite obscure here.
356                // The form action of the table should be filled
357                // with $ilCtrl->getFormAction(..) not with $ilCtrl->getLinkTarget(..)
358                // Commands should be determined with $ilCtrl->getCmd() not
359                // with accessing $_POST['selected_cmd'], since this is internal
360                // of ilTable2GUI/ilCtrl and may change.
361                if (isset($_POST['select_cmd2'])) {
362                    $_POST['selected_cmd'] = $_POST["selected_cmd2"];
363                }
364
365                if (isset($_POST['selected_cmd']) && $_POST['selected_cmd'] != null) {
366                    $member_cmd = array('enableAdminForceNoti', 'disableAdminForceNoti', 'enableHideUserToggleNoti', 'disableHideUserToggleNoti');
367                    in_array($_POST['selected_cmd'], $member_cmd) ? $cmd = $_POST['selected_cmd'] : $cmd = 'performThreadsAction';
368                } elseif (!$cmd && !$_POST['selected_cmd']) {
369                    $cmd = 'showThreads';
370                }
371
372                $cmd .= 'Object';
373                $this->$cmd();
374
375                break;
376        }
377
378        // suppress for topic level
379        if ($cmd != 'viewThreadObject' && $cmd != 'showUserObject') {
380            $this->addHeaderAction();
381        }
382    }
383
384    /**
385     *
386     */
387    public function infoScreenObject()
388    {
389        $this->ctrl->setCmd('showSummary');
390        $this->ctrl->setCmdClass('ilinfoscreengui');
391        $this->infoScreen();
392    }
393
394    /**
395     * @param ilPropertyFormGUI $a_form
396     */
397    protected function initEditCustomForm(ilPropertyFormGUI $a_form)
398    {
399        $this->forum_settings_gui = new ilForumSettingsGUI($this);
400        $this->forum_settings_gui->getCustomForm($a_form);
401    }
402
403    /**
404     * @param array $a_values
405     */
406    protected function getEditFormCustomValues(array &$a_values)
407    {
408        $this->forum_settings_gui->getCustomValues($a_values);
409    }
410
411    /**
412     * @param ilPropertyFormGUI $a_form
413     */
414    protected function updateCustom(ilPropertyFormGUI $a_form)
415    {
416        $this->forum_settings_gui->updateCustomValues($a_form);
417    }
418
419    /**
420     * @param  int $a_thread_id
421     * @return ilPropertyFormGUI
422     */
423    private function getThreadEditingForm($a_thread_id)
424    {
425        $form = new ilPropertyFormGUI();
426        $this->ctrl->setParameter($this, 'thr_pk', $a_thread_id);
427        $form->setFormAction($this->ctrl->getFormAction($this, 'updateThread'));
428
429        $ti_prop = new ilTextInputGUI($this->lng->txt('title'), 'title');
430        $ti_prop->setRequired(true);
431        $ti_prop->setMaxLength(255);
432        $ti_prop->setSize(50);
433        $form->addItem($ti_prop);
434
435        $form->addCommandButton('updateThread', $this->lng->txt('save'));
436        $form->addCommandButton('showThreads', $this->lng->txt('cancel'));
437
438        return $form;
439    }
440
441    /**
442     * @param int $threadId
443     * @param ilPropertyFormGUI $form
444     */
445    public function editThreadObject($threadId, ilPropertyFormGUI $form = null)
446    {
447        if (!$this->is_moderator) {
448            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
449        }
450
451        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
452            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
453        }
454
455        $thread = new \ilForumTopic($threadId);
456        $this->ensureThreadBelongsToForum((int) $this->object->getId(), $thread);
457
458        $this->tabs->activateTab('forums_threads');
459
460        if (!($form instanceof \ilPropertyFormGUI)) {
461            $form = $this->getThreadEditingForm($threadId);
462            $form->setValuesByArray(array(
463                'title' => $thread->getSubject()
464            ));
465        }
466
467        $this->tpl->setContent($form->getHTML());
468    }
469
470    /**
471     *
472     */
473    public function updateThreadObject()
474    {
475        if (!$this->is_moderator) {
476            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
477        }
478
479        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
480            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
481        }
482
483        if (!$this->objCurrentTopic->getId()) {
484            $this->showThreadsObject();
485            return;
486        }
487
488        $this->ensureThreadBelongsToForum((int) $this->object->getId(), $this->objCurrentTopic);
489
490        $form = $this->getThreadEditingForm($this->objCurrentTopic->getId());
491        if (!$form->checkInput()) {
492            $form->setValuesByPost();
493            $this->editThreadObject($this->objCurrentTopic->getId(), $form);
494            return;
495        }
496
497        $this->objCurrentTopic->setSubject($form->getInput('title'));
498        $this->objCurrentTopic->updateThreadTitle();
499
500        ilUtil::sendSuccess($this->lng->txt('saved_successfully'));
501        $this->showThreadsObject();
502    }
503
504    public function markAllReadObject()
505    {
506        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
507            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
508        }
509
510        $this->object->markAllThreadsRead($this->user->getId());
511        ilUtil::sendInfo($this->lng->txt('forums_all_threads_marked_read'));
512        $this->showThreadsObject();
513    }
514
515    public function showThreadsObject()
516    {
517        $this->getSubTabs('showThreads');
518        $this->setSideBlocks();
519        $this->getCenterColumnHTML();
520    }
521
522    public function sortThreadsObject()
523    {
524        $this->getSubTabs('sortThreads');
525        $this->setSideBlocks();
526        $this->getCenterColumnHTML();
527    }
528
529    public function getSubTabs($subtab = 'showThreads')
530    {
531        if ($this->objProperties->getThreadSorting() == 1 && $this->is_moderator) {
532            $this->tabs->addSubTabTarget('show', $this->ctrl->getLinkTarget($this, 'showThreads'), 'showThreads', get_class($this), '', $subtab == 'showThreads'? true : false);
533            $this->tabs->addSubTabTarget('sorting_header', $this->ctrl->getLinkTarget($this, 'sortThreads'), 'sortThreads', get_class($this), '', $subtab == 'sortThreads'? true : false);
534        }
535    }
536
537    public function getContent()
538    {
539        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
540            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
541        }
542
543        $cmd = $this->ctrl->getCmd();
544        $frm = $this->object->Forum;
545        $frm->setForumId($this->object->getId());
546        $frm->setForumRefId($this->object->getRefId());
547        $frm->setMDB2Wherecondition('top_frm_fk = %s ', array('integer'), array($frm->getForumId()));
548
549        $this->tpl->addBlockFile('ADM_CONTENT', 'adm_content', 'tpl.forums_threads_liste.html', 'Modules/Forum');
550
551        if ((int) strlen($this->confirmation_gui_html)) {
552            $this->tpl->setVariable('CONFIRMATION_GUI', $this->confirmation_gui_html);
553        }
554
555        // Create topic button
556        if ($this->access->checkAccess('add_thread', '', $this->object->getRefId()) && !$this->hideToolbar()) {
557            $btn = ilLinkButton::getInstance();
558            $btn->setUrl($this->ctrl->getLinkTarget($this, 'createThread'));
559            $btn->setCaption('forums_new_thread');
560            $this->toolbar->addStickyItem($btn);
561        }
562
563        // Mark all topics as read button
564        if ($this->user->getId() != ANONYMOUS_USER_ID && !(int) strlen($this->confirmation_gui_html)) {
565            $this->toolbar->addButton(
566                $this->lng->txt('forums_mark_read'),
567                $this->ctrl->getLinkTarget($this, 'markAllRead'),
568                '',
569                ilAccessKey::MARK_ALL_READ
570            );
571            $this->ctrl->clearParameters($this);
572        }
573
574        if (\ilForumPostDraft::isSavePostDraftAllowed()) {
575            $drafts = \ilForumPostDraft::getThreadDraftData(
576                $this->user->getId(),
577                ilObjForum::lookupForumIdByObjId($this->object->getId())
578            );
579            if (count($drafts) > 0) {
580                $draftsTable = new ilForumDraftsTableGUI(
581                    $this,
582                    $cmd,
583                    $this->access->checkAccess('add_thread', '', $this->object->getRefId())
584                );
585                $draftsTable->setData($drafts);
586                $this->tpl->setVariable('THREADS_DRAFTS_TABLE', $draftsTable->getHTML());
587            }
588        }
589
590        // Import information: Topic (variable $topicData) means frm object, not thread
591        $topicData = $frm->getOneTopic();
592        if ($topicData) {
593            // Visit-Counter
594            $frm->setDbTable('frm_data');
595            $frm->setMDB2WhereCondition('top_pk = %s ', array('integer'), array($topicData['top_pk']));
596            $frm->updateVisits($topicData['top_pk']);
597
598            if (!in_array($cmd, array('showThreads', 'sortThreads'))) {
599                $cmd = 'showThreads';
600            }
601
602            $tbl = new ilForumTopicTableGUI(
603                $this,
604                $cmd,
605                '',
606                (int) $_GET['ref_id'],
607                $topicData,
608                $this->is_moderator,
609                $this->settings->get('forum_overview')
610            );
611            $tbl->init();
612            $tbl->setMapper($frm)->fetchData();
613            $this->tpl->setVariable('THREADS_TABLE', $tbl->getHTML());
614        }
615
616        // Permanent link
617        $permalink = new ilPermanentLinkGUI('frm', $this->object->getRefId());
618        $this->tpl->setVariable('PRMLINK', $permalink->getHTML());
619    }
620
621    /**
622     * @param string $action
623     * @param bool $render_drafts
624     * @param      $node
625     * @param null $edit_draft_id
626     * @return bool
627     * @throws ilSplitButtonException
628     */
629    protected function renderDraftContent(string $action, bool $render_drafts, $node, $edit_draft_id = null)
630    {
631        if (!$render_drafts) {
632            return false;
633        }
634
635        $frm = $this->object->Forum;
636
637        $draftsObjects = ilForumPostDraft::getInstancesByUserIdAndThreadId($this->user->getId(), $this->objCurrentTopic->getId());
638        $drafts = $draftsObjects[$node->getId()];
639
640        if (is_array($drafts)) {
641            foreach ($drafts as $draft) {
642                if (!$draft instanceof ilForumPostDraft) {
643                    continue 1;
644                }
645
646                if (isset($edit_draft_id) && $edit_draft_id == $node->getId()) {
647                    // do not render a draft that is in 'edit'-mode
648                    return false;
649                }
650
651                $tmp_file_obj = new ilFileDataForumDrafts($this->object->getId(), $draft->getDraftId());
652                $filesOfDraft = $tmp_file_obj->getFilesOfPost();
653                ksort($filesOfDraft);
654
655                if (count($filesOfDraft)) {
656                    if ($action !== 'showdraft') {
657                        foreach ($filesOfDraft as $file) {
658                            $this->tpl->setCurrentBlock('attachment_download_row');
659                            $this->ctrl->setParameter($this, 'draft_id', $tmp_file_obj->getDraftId());
660                            $this->ctrl->setParameter($this, 'file', $file['md5']);
661                            $this->tpl->setVariable('HREF_DOWNLOAD', $this->ctrl->getLinkTarget($this, 'viewThread'));
662                            $this->tpl->setVariable('TXT_FILENAME', $file['name']);
663                            $this->ctrl->setParameter($this, 'file', '');
664                            $this->ctrl->setParameter($this, 'draft_id', '');
665                            $this->ctrl->clearParameters($this);
666                            $this->tpl->parseCurrentBlock();
667                        }
668
669                        $this->tpl->setCurrentBlock('attachments');
670                        $this->tpl->setVariable('TXT_ATTACHMENTS_DOWNLOAD', $this->lng->txt('forums_attachments'));
671                        $this->tpl->setVariable('DOWNLOAD_IMG', ilGlyphGUI::get(ilGlyphGUI::ATTACHMENT, $this->lng->txt('forums_download_attachment')));
672                        if (count($filesOfDraft) > 1) {
673                            $download_zip_button = ilLinkButton::getInstance();
674                            $download_zip_button->setCaption($this->lng->txt('download'), false);
675                            $this->ctrl->setParameter($this, 'draft_id', $draft->getDraftId());
676                            $download_zip_button->setUrl($this->ctrl->getLinkTarget($this, 'deliverDraftZipFile'));
677                            $this->ctrl->setParameter($this, 'draft_id', '');
678                            $this->tpl->setVariable('DOWNLOAD_ZIP', $download_zip_button->render());
679                        }
680                        $this->tpl->parseCurrentBlock();
681                    }
682                }
683
684                // render splitButton for drafts
685                $this->renderSplitButton($action, false, $node, (int) $_GET['offset'], $draft);
686
687                // highlight drafts
688                $rowCol = 'tblrowmarked';
689                // set row color
690                $this->tpl->setVariable('ROWCOL', ' ' . $rowCol);
691                $this->tpl->setVariable('DEPTH', (int) ($node->getDepth() - 1));
692
693                // Author
694                $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
695                $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
696                $this->ctrl->setParameter($this, 'draft_id', $draft->getDraftId());
697
698                $backurl = urlencode($this->ctrl->getLinkTarget($this, 'viewThread', $node->getId()));
699
700                $this->ctrl->setParameter($this, 'backurl', $backurl);
701                $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
702                $this->ctrl->setParameter($this, 'user', $draft->getPostDisplayUserId());
703
704                $authorinfo = new ilForumAuthorInformation(
705                    $draft->getPostAuthorId(),
706                    $draft->getPostDisplayUserId(),
707                    $draft->getPostUserAlias(),
708                    '',
709                    array(
710                        'href' => $this->ctrl->getLinkTarget($this, 'showUser')
711                    )
712                );
713
714                $this->ctrl->clearParameters($this);
715
716                if ($authorinfo->hasSuffix()) {
717                    $this->tpl->setVariable('AUTHOR', $authorinfo->getSuffix());
718                    $this->tpl->setVariable('USR_NAME', $draft->getPostUserAlias());
719                } else {
720                    $this->tpl->setVariable('AUTHOR', $authorinfo->getLinkedAuthorShortName());
721                    if ($authorinfo->getAuthorName(true) && !$this->objProperties->isAnonymized()) {
722                        $this->tpl->setVariable('USR_NAME', $authorinfo->getAuthorName(true));
723                    }
724                }
725                $this->tpl->setVariable('DRAFT_ANCHOR', 'draft_' . $draft->getDraftId());
726
727                $this->tpl->setVariable('USR_IMAGE', $authorinfo->getProfilePicture());
728                $this->tpl->setVariable('USR_ICON_ALT', ilUtil::prepareFormOutput($authorinfo->getAuthorShortName()));
729                if ($authorinfo->getAuthor()->getId() && ilForum::_isModerator((int) $_GET['ref_id'], $draft->getPostAuthorId())) {
730                    if ($authorinfo->getAuthor()->getGender() == 'f') {
731                        $this->tpl->setVariable('ROLE', $this->lng->txt('frm_moderator_f'));
732                    } elseif ($authorinfo->getAuthor()->getGender() == 'm') {
733                        $this->tpl->setVariable('ROLE', $this->lng->txt('frm_moderator_m'));
734                    } elseif ($authorinfo->getAuthor()->getGender() == 'n') {
735                        $this->tpl->setVariable('ROLE', $this->lng->txt('frm_moderator_n'));
736                    }
737                }
738
739                // get create- and update-dates
740                if ($draft->getUpdateUserId() > 0) {
741                    $spanClass = 'small';
742
743                    if (ilForum::_isModerator($this->ref_id, $node->getUpdateUserId())) {
744                        $spanClass = 'moderator_small';
745                    }
746
747                    $draft->setPostUpdate($draft->getPostUpdate());
748
749                    $this->ctrl->setParameter($this, 'backurl', $backurl);
750                    $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
751                    $this->ctrl->setParameter($this, 'user', $node->getUpdateUserId());
752                    $this->ctrl->setParameter($this, 'draft_id', $draft->getDraftId());
753
754                    $authorinfo = new ilForumAuthorInformation(
755                        $draft->getPostAuthorId(),
756                        $draft->getUpdateUserId(),
757                        $draft->getPostUserAlias(),
758                        '',
759                        array(
760                            'href' => $this->ctrl->getLinkTarget($this, 'showUser')
761                        )
762                    );
763
764                    $this->ctrl->clearParameters($this);
765
766                    $this->tpl->setVariable('POST_UPDATE_TXT', $this->lng->txt('edited_on') . ': ' . $frm->convertDate($draft->getPostUpdate()) . ' - ' . strtolower($this->lng->txt('by')));
767                    $this->tpl->setVariable('UPDATE_AUTHOR', $authorinfo->getLinkedAuthorShortName());
768                    if ($authorinfo->getAuthorName(true) && !$this->objProperties->isAnonymized() && !$authorinfo->hasSuffix()) {
769                        $this->tpl->setVariable('UPDATE_USR_NAME', $authorinfo->getAuthorName(true));
770                    }
771                }
772                // Author end
773
774                // prepare post
775                $draft->setPostMessage($frm->prepareText($draft->getPostMessage()));
776
777                $this->tpl->setVariable('SUBJECT', $draft->getPostSubject());
778                $this->tpl->setVariable('POST_DATE', $frm->convertDate($draft->getPostDate()));
779
780                if (!$node->isCensored() || ($this->objCurrentPost->getId() == $node->getId() && $action === 'censor')) {
781                    $spanClass = "";
782
783                    if (ilForum::_isModerator($this->ref_id, $draft->getPostDisplayUserId())) {
784                        $spanClass = 'moderator';
785                    }
786
787                    if ($draft->getPostMessage() == strip_tags($draft->getPostMessage())) {
788                        // We can be sure, that there are not html tags
789                        $draft->setPostMessage(nl2br($draft->getPostMessage()));
790                    }
791
792                    if ($spanClass != "") {
793                        $this->tpl->setVariable('POST', "<span class=\"" . $spanClass . "\">" . ilRTE::_replaceMediaObjectImageSrc($draft->getPostMessage(), 1) . "</span>");
794                    } else {
795                        $this->tpl->setVariable('POST', ilRTE::_replaceMediaObjectImageSrc($draft->getPostMessage(), 1));
796                    }
797                }
798
799                if (!$this->objCurrentTopic->isClosed() && $action === 'deletedraft') {
800                    if ($this->user->getId() != ANONYMOUS_USER_ID && $draft->getDraftId() == (int) $_GET['draft_id']) {
801                        // confirmation: delete
802                        $this->tpl->setVariable('FORM', $this->getDeleteDraftFormHTML());
803                    }
804                } elseif ($action === 'editdraft' && (int) $draft->getDraftId() == (int) $_GET['draft_id']) {
805                    $oEditReplyForm = $this->getReplyEditForm();
806                    $this->tpl->setVariable('EDIT_DRAFT_ANCHOR', 'draft_edit_' . $draft->getDraftId());
807                    $this->tpl->setVariable('DRAFT_FORM', $oEditReplyForm->getHTML() . $this->modal_history);
808                }
809
810                $this->tpl->parseCurrentBlock();
811            }
812            return true;
813        }
814        return true;
815    }
816
817    /**
818     * @param ilForumPost $node
819     * @param string $action
820     * @param $Start
821     * @param $z
822     * @return bool
823     * @throws ilSplitButtonException
824     */
825    protected function renderPostContent(ilForumPost $node, string $action, $Start, $z)
826    {
827        $forumObj = $this->object;
828        $frm = $this->object->Forum;
829
830        // download post attachments
831        $tmp_file_obj = new ilFileDataForum($forumObj->getId(), $node->getId());
832
833        $filesOfPost = $tmp_file_obj->getFilesOfPost();
834        ksort($filesOfPost);
835        if (count($filesOfPost)) {
836            if ($node->getId() != $this->objCurrentPost->getId() || $action !== 'showedit') {
837                foreach ($filesOfPost as $file) {
838                    $this->tpl->setCurrentBlock('attachment_download_row');
839                    $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
840                    $this->ctrl->setParameter($this, 'file', $file['md5']);
841                    $this->tpl->setVariable('HREF_DOWNLOAD', $this->ctrl->getLinkTarget($this, 'viewThread'));
842                    $this->tpl->setVariable('TXT_FILENAME', $file['name']);
843                    $this->ctrl->clearParameters($this);
844                    $this->tpl->parseCurrentBlock();
845                }
846                $this->tpl->setCurrentBlock('attachments');
847                $this->tpl->setVariable('TXT_ATTACHMENTS_DOWNLOAD', $this->lng->txt('forums_attachments'));
848                $this->tpl->setVariable('DOWNLOAD_IMG', ilGlyphGUI::get(ilGlyphGUI::ATTACHMENT, $this->lng->txt('forums_download_attachment')));
849                if (count($filesOfPost) > 1) {
850                    $download_zip_button = ilLinkButton::getInstance();
851                    $download_zip_button->setCaption($this->lng->txt('download'), false);
852                    $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
853                    $download_zip_button->setUrl($this->ctrl->getLinkTarget($this, 'deliverZipFile'));
854
855                    $this->tpl->setVariable('DOWNLOAD_ZIP', $download_zip_button->render());
856                }
857
858                $this->tpl->parseCurrentBlock();
859            }
860        }
861        // render splitbutton for posts
862        $this->renderSplitButton($action, true, $node, $Start);
863
864        // anker for every post
865        $this->tpl->setVariable('POST_ANKER', $node->getId());
866
867        //permanent link for every post
868        $this->tpl->setVariable('TXT_PERMA_LINK', $this->lng->txt('perma_link'));
869        $this->tpl->setVariable('PERMA_TARGET', '_top');
870
871        if (!$node->isActivated() && !$this->objCurrentTopic->isClosed() && $this->is_moderator) {
872            $rowCol = 'ilPostingNeedsActivation';
873        } elseif ($this->objProperties->getMarkModeratorPosts() == 1) {
874            if ($node->getIsAuthorModerator() === null && $is_moderator = ilForum::_isModerator($_GET['ref_id'], $node->getPosAuthorId())) {
875                $rowCol = 'ilModeratorPosting';
876            } elseif ($node->getIsAuthorModerator()) {
877                $rowCol = 'ilModeratorPosting';
878            } else {
879                $rowCol = ilUtil::switchColor($z, 'tblrow1', 'tblrow2');
880            }
881        } else {
882            $rowCol = ilUtil::switchColor($z, 'tblrow1', 'tblrow2');
883        }
884
885        if (
886            (!in_array($action, ['delete', 'censor']) && !$this->displayConfirmPostActivation()) ||
887            $this->objCurrentPost->getId() != $node->getId()
888        ) {
889            $this->tpl->setVariable('ROWCOL', ' ' . $rowCol);
890        } else {
891            // highlight censored posts
892            $rowCol = 'tblrowmarked';
893        }
894
895        // post is censored
896        if ($node->isCensored()) {
897            // display censorship advice
898            if ($action !== 'censor') {
899                $this->tpl->setVariable('TXT_CENSORSHIP_ADVICE', $this->lng->txt('post_censored_comment_by_moderator'));
900            }
901
902            // highlight censored posts
903            $rowCol = 'tblrowmarked';
904        }
905
906        // set row color
907        $this->tpl->setVariable('ROWCOL', ' ' . $rowCol);
908        $this->tpl->setVariable('DEPTH', (int) ($node->getDepth() - 1));
909        // if post is not activated display message for the owner
910        if (!$node->isActivated() && $node->isOwner($this->user->getId())) {
911            $this->tpl->setVariable('POST_NOT_ACTIVATED_YET', $this->lng->txt('frm_post_not_activated_yet'));
912        }
913
914        // Author
915        $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
916        $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
917        $backurl = urlencode($this->ctrl->getLinkTarget($this, 'viewThread', $node->getId()));
918        $this->ctrl->clearParameters($this);
919
920        $this->ctrl->setParameter($this, 'backurl', $backurl);
921        $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
922        $this->ctrl->setParameter($this, 'user', $node->getDisplayUserId());
923
924        $authorinfo = new ilForumAuthorInformation(
925            $node->getPosAuthorId(),
926            $node->getDisplayUserId(),
927            $node->getUserAlias(),
928            $node->getImportName(),
929            array(
930                'href' => $this->ctrl->getLinkTarget($this, 'showUser')
931            )
932        );
933
934        $this->ctrl->clearParameters($this);
935
936        if ($authorinfo->hasSuffix()) {
937            $this->tpl->setVariable('AUTHOR', $authorinfo->getSuffix());
938            if (!$authorinfo->isDeleted()) {
939                $this->tpl->setVariable('USR_NAME', $authorinfo->getAlias());
940            }
941        } else {
942            $this->tpl->setVariable('AUTHOR', $authorinfo->getLinkedAuthorShortName());
943            if ($authorinfo->getAuthorName(true) && !$this->objProperties->isAnonymized()) {
944                $this->tpl->setVariable('USR_NAME', $authorinfo->getAuthorName(true));
945            }
946        }
947
948        $this->tpl->setVariable('USR_IMAGE', $authorinfo->getProfilePicture());
949        $this->tpl->setVariable('USR_ICON_ALT', ilUtil::prepareFormOutput($authorinfo->getAuthorShortName()));
950        if ($authorinfo->getAuthor()->getId() && ilForum::_isModerator((int) $_GET['ref_id'], $node->getPosAuthorId())) {
951            if ($authorinfo->getAuthor()->getGender() == 'f') {
952                $this->tpl->setVariable('ROLE', $this->lng->txt('frm_moderator_f'));
953            } elseif ($authorinfo->getAuthor()->getGender() == 'm') {
954                $this->tpl->setVariable('ROLE', $this->lng->txt('frm_moderator_m'));
955            }
956        }
957
958        // get create- and update-dates
959        if ($node->getUpdateUserId() > 0) {
960            $spanClass = 'small';
961
962            if (ilForum::_isModerator($this->ref_id, $node->getUpdateUserId())) {
963                $spanClass = 'moderator_small';
964            }
965
966            $node->setChangeDate($node->getChangeDate());
967
968            $this->ctrl->setParameter($this, 'backurl', $backurl);
969            $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
970            $this->ctrl->setParameter($this, 'user', $node->getUpdateUserId());
971
972            $update_user_id = $node->getUpdateUserId();
973            if ($node->getPosAuthorId() == $node->getUpdateUserId()
974            && $node->getDisplayUserId() == 0) {
975                $update_user_id = $node->getDisplayUserId();
976            }
977
978            $authorinfo = new ilForumAuthorInformation(
979                $node->getPosAuthorId(),
980                $update_user_id,
981                $node->getUserAlias(),
982                $node->getImportName(),
983                array(
984                    'href' => $this->ctrl->getLinkTarget($this, 'showUser')
985                )
986            );
987
988            $this->ctrl->clearParameters($this);
989
990            $this->tpl->setVariable('POST_UPDATE_TXT', $this->lng->txt('edited_on') . ': ' . $frm->convertDate($node->getChangeDate()) . ' - ' . strtolower($this->lng->txt('by')));
991            $this->tpl->setVariable('UPDATE_AUTHOR', $authorinfo->getLinkedAuthorShortName());
992            if ($authorinfo->getAuthorName(true) && !$this->objProperties->isAnonymized() && !$authorinfo->hasSuffix()) {
993                $this->tpl->setVariable('UPDATE_USR_NAME', $authorinfo->getAuthorName(true));
994            }
995        } // if ($node->getUpdateUserId() > 0)*/
996        // Author end
997
998        // prepare post
999        $node->setMessage($frm->prepareText($node->getMessage()));
1000
1001        if ($this->user->getId() == ANONYMOUS_USER_ID ||
1002            $node->isPostRead()
1003        ) {
1004            $this->tpl->setVariable('SUBJECT', $node->getSubject());
1005        } else {
1006            $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
1007            $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
1008            $this->ctrl->setParameter($this, 'offset', $Start);
1009            $this->ctrl->setParameter($this, 'orderby', $_GET['orderby']);
1010            $this->ctrl->setParameter($this, 'viewmode', $_SESSION['viewmode']);
1011            $mark_post_target = $this->ctrl->getLinkTarget($this, 'markPostRead', $node->getId());
1012
1013            $this->tpl->setVariable('SUBJECT', "<a href=\"" . $mark_post_target . "\"><b>" . $node->getSubject() . "</b></a>");
1014        }
1015
1016        $this->tpl->setVariable('POST_DATE', $frm->convertDate($node->getCreateDate()));
1017
1018        if (!$node->isCensored() ||
1019            ($this->objCurrentPost->getId() == $node->getId() && $action === 'censor')
1020        ) {
1021            $spanClass = "";
1022            if (ilForum::_isModerator($this->ref_id, $node->getDisplayUserId())) {
1023                $spanClass = 'moderator';
1024            }
1025            // possible bugfix for mantis #8223
1026            if ($node->getMessage() == strip_tags($node->getMessage())) {
1027                // We can be sure, that there are not html tags
1028                $node->setMessage(nl2br($node->getMessage()));
1029            }
1030
1031            if ($spanClass != "") {
1032                $this->tpl->setVariable('POST', "<span class=\"" . $spanClass . "\">" . ilRTE::_replaceMediaObjectImageSrc($node->getMessage(), 1) . "</span>");
1033            } else {
1034                $this->tpl->setVariable('POST', ilRTE::_replaceMediaObjectImageSrc($node->getMessage(), 1));
1035            }
1036        } else {
1037            $this->tpl->setVariable('POST', "<span class=\"moderator\">" . nl2br($node->getCensorshipComment()) . "</span>");
1038        }
1039
1040        $this->tpl->parseCurrentBlock();
1041        return true;
1042    }
1043
1044    /**
1045     * @param ilObject|ilObjForum $a_new_object
1046     */
1047    protected function afterSave(ilObject $a_new_object)
1048    {
1049        \ilUtil::sendSuccess($this->lng->txt('frm_added'), true);
1050        $this->ctrl->setParameter($this, 'ref_id', $a_new_object->getRefId());
1051        $this->ctrl->redirect($this, 'createThread');
1052    }
1053
1054    protected function getTabs()
1055    {
1056        $this->ilHelp->setScreenIdComponent("frm");
1057
1058        $this->ctrl->setParameter($this, 'ref_id', $this->ref_id);
1059
1060        $active = array(
1061            '', 'showThreads', 'view', 'markAllRead',
1062            'enableForumNotification', 'disableForumNotification', 'moveThreads', 'performMoveThreads',
1063            'cancelMoveThreads', 'performThreadsAction', 'createThread', 'addThread',
1064            'showUser', 'confirmDeleteThreads',
1065            'merge','mergeThreads', 'performMergeThreads'
1066        );
1067
1068        (in_array($this->ctrl->getCmd(), $active)) ? $force_active = true : $force_active = false;
1069        $this->tabs->addTarget('forums_threads', $this->ctrl->getLinkTarget($this, 'showThreads'), $this->ctrl->getCmd(), get_class($this), '', $force_active);
1070
1071        // info tab
1072        if ($this->access->checkAccess('visible', '', $this->ref_id) || $this->access->checkAccess('read', '', $this->ref_id)) {
1073            $force_active = ($this->ctrl->getNextClass() == 'ilinfoscreengui' || strtolower($_GET['cmdClass']) == 'ilnotegui') ? true : false;
1074            $this->tabs->addTarget(
1075                'info_short',
1076                $this->ctrl->getLinkTargetByClass(array('ilobjforumgui', 'ilinfoscreengui'), 'showSummary'),
1077                array('showSummary', 'infoScreen'),
1078                '',
1079                '',
1080                $force_active
1081            );
1082        }
1083
1084        if ($this->access->checkAccess('write', '', $this->ref_id)) {
1085            $force_active = ($this->ctrl->getCmd() == 'edit') ? true	: false;
1086            $this->tabs->addTarget('settings', $this->ctrl->getLinkTarget($this, 'edit'), 'edit', get_class($this), '', $force_active);
1087        }
1088
1089        if ($this->access->checkAccess('write', '', $this->ref_id)) {
1090            $this->tabs->addTarget('frm_moderators', $this->ctrl->getLinkTargetByClass('ilForumModeratorsGUI', 'showModerators'), 'showModerators', get_class($this));
1091        }
1092
1093        if ($this->settings->get('enable_fora_statistics', false) &&
1094           ($this->objProperties->isStatisticEnabled() || $this->access->checkAccess('write', '', $this->ref_id))) {
1095            $force_active = ($this->ctrl->getCmd() == 'showStatistics') ? true	: false;
1096            $this->tabs->addTarget('frm_statistics', $this->ctrl->getLinkTarget($this, 'showStatistics'), 'showStatistics', get_class($this), '', $force_active); //false
1097        }
1098
1099        if ($this->access->checkAccess('write', '', $this->object->getRefId())) {
1100            $this->tabs->addTarget('export', $this->ctrl->getLinkTargetByClass('ilexportgui', ''), '', 'ilexportgui');
1101        }
1102
1103        if ($this->access->checkAccess('edit_permission', '', $this->ref_id)) {
1104            $this->tabs->addTarget('perm_settings', $this->ctrl->getLinkTargetByClass(array(get_class($this),'ilpermissiongui'), 'perm'), array('perm', 'info', 'owner'), 'ilpermissiongui');
1105        }
1106    }
1107
1108    public function showStatisticsObject()
1109    {
1110        /// if globally deactivated, skip!!! intrusion detected
1111        if (!$this->settings->get('enable_fora_statistics', false)) {
1112            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1113        }
1114
1115        // if no read access -> intrusion detected
1116        if (!$this->access->checkAccess('read', '', (int) $_GET['ref_id'])) {
1117            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1118        }
1119
1120        // if read access and statistics disabled -> intrusion detected
1121        if (!$this->objProperties->isStatisticEnabled()) {
1122            // if write access and statistics disabled -> ok, for forum admin
1123            if ($this->access->checkAccess('write', '', (int) $_GET['ref_id'])) {
1124                ilUtil::sendInfo($this->lng->txt('frm_statistics_disabled_for_participants'));
1125            } else {
1126                $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1127            }
1128        }
1129
1130        $this->object->Forum->setForumId($this->object->getId());
1131
1132        $tbl = new ilForumStatisticsTableGUI($this, 'showStatistics');
1133        $tbl->setId('il_frm_statistic_table_' . (int) (int) $_GET['ref_id']);
1134        $tbl->setTitle($this->lng->txt('statistic'), 'icon_usr.svg', $this->lng->txt('obj_' . $this->object->getType()));
1135
1136        $data = $this->object->Forum->getUserStatistic($this->is_moderator);
1137        $result = array();
1138        $counter = 0;
1139        foreach ($data as $row) {
1140            $result[$counter]['ranking'] = $row[0];
1141            $result[$counter]['login'] = $row[1];
1142            $result[$counter]['lastname'] = $row[2];
1143            $result[$counter]['firstname'] = $row[3];
1144
1145            ++$counter;
1146        }
1147        $tbl->setData($result);
1148
1149        $this->tpl->setContent($tbl->getHTML());
1150    }
1151
1152    public static function _goto($a_target, $a_thread = 0, $a_posting = 0)
1153    {
1154        global $DIC;
1155
1156        $ilAccess = $DIC->access();
1157        $lng = $DIC->language();
1158        $ilErr = $DIC['ilErr'];
1159
1160        if ($ilAccess->checkAccess('read', '', $a_target)) {
1161            if ($a_thread != 0) {
1162                $objTopic = new ilForumTopic($a_thread);
1163                if ($objTopic->getFrmObjId() &&
1164                    $objTopic->getFrmObjId() != ilObject::_lookupObjectId($a_target)) {
1165                    $ref_ids = ilObject::_getAllReferences($objTopic->getFrmObjId());
1166                    foreach ($ref_ids as $ref_id) {
1167                        if ($ilAccess->checkAccess('read', '', $ref_id)) {
1168                            $new_ref_id = $ref_id;
1169                            break;
1170                        }
1171                    }
1172
1173                    if (isset($new_ref_id) && $new_ref_id != $a_target) {
1174                        ilUtil::redirect(ILIAS_HTTP_PATH . "/goto.php?target=frm_" . $new_ref_id . "_" . $a_thread . "_" . $a_posting);
1175                    }
1176                }
1177
1178                $_GET['ref_id'] = $a_target;
1179                $_GET['pos_pk'] = $a_posting;
1180                $_GET['thr_pk'] = $a_thread;
1181                $_GET['anchor'] = $a_posting;
1182                $_GET['cmdClass'] = 'ilObjForumGUI';
1183                $_GET['cmd'] = 'viewThread';
1184                $_GET['baseClass'] = 'ilRepositoryGUI';
1185                include_once('ilias.php');
1186                exit();
1187            } else {
1188                $_GET['ref_id'] = $a_target;
1189                $_GET['baseClass'] = 'ilRepositoryGUI';
1190                include_once('ilias.php');
1191                exit();
1192            }
1193        } elseif ($ilAccess->checkAccess('read', '', ROOT_FOLDER_ID)) {
1194            $_GET['target'] = '';
1195            $_GET['ref_id'] = ROOT_FOLDER_ID;
1196            ilUtil::sendInfo(sprintf(
1197                $lng->txt('msg_no_perm_read_item'),
1198                ilObject::_lookupTitle(ilObject::_lookupObjId($a_target))
1199            ), true);
1200            $_GET['baseClass'] = 'ilRepositoryGUI';
1201            include_once('ilias.php');
1202            exit();
1203        }
1204
1205        $ilErr->raiseError($lng->txt('msg_no_perm_read'), $ilErr->FATAL);
1206    }
1207
1208    public function performDeleteThreadsObject()
1209    {
1210        if (!$this->is_moderator) {
1211            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1212        }
1213
1214        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
1215            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1216        }
1217
1218        if (!isset($_POST['thread_ids']) || !is_array($_POST['thread_ids'])) {
1219            ilUtil::sendInfo($this->lng->txt('select_at_least_one_thread'));
1220            return $this->showThreadsObject();
1221        }
1222
1223        $forumObj = new ilObjForum($this->object->getRefId());
1224        $this->objProperties->setObjId($forumObj->getId());
1225
1226        $frm = new ilForum();
1227
1228        $success_message = "forums_thread_deleted";
1229        if (count($_POST['thread_ids']) > 1) {
1230            $success_message = "forums_threads_deleted";
1231        }
1232
1233        $threadIds = [];
1234        if (isset($_POST['thread_ids']) && is_array($_POST['thread_ids'])) {
1235            $threadIds = $_POST['thread_ids'];
1236        }
1237
1238        $threads = [];
1239        array_walk($threadIds, function ($threadId) use (&$threads) {
1240            $thread = new \ilForumTopic($threadId);
1241            $this->ensureThreadBelongsToForum((int) $this->object->getId(), $thread);
1242
1243            $threads[] = $thread;
1244        });
1245
1246        foreach ($threads as $thread) {
1247            $frm->setForumId($forumObj->getId());
1248            $frm->setForumRefId($forumObj->getRefId());
1249
1250            $first_node = $frm->getFirstPostNode($thread->getId());
1251            if ((int) $first_node['pos_pk']) {
1252                $frm->deletePost($first_node['pos_pk']);
1253                ilUtil::sendInfo($this->lng->txt($success_message), true);
1254            }
1255        }
1256        $this->ctrl->redirect($this, 'showThreads');
1257    }
1258
1259    public function confirmDeleteThreads()
1260    {
1261        if (!isset($_POST['thread_ids']) || !is_array($_POST['thread_ids'])) {
1262            ilUtil::sendInfo($this->lng->txt('select_at_least_one_thread'));
1263            return $this->showThreadsObject();
1264        }
1265
1266        if (!$this->is_moderator) {
1267            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1268        }
1269
1270        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
1271            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1272        }
1273
1274        $threads = [];
1275        array_walk($_POST['thread_ids'], function ($threadId) use (&$threads) {
1276            $thread = new \ilForumTopic($threadId);
1277            $this->ensureThreadBelongsToForum((int) $this->object->getId(), $thread);
1278
1279            $threads[] = $thread;
1280        });
1281
1282        $c_gui = new ilConfirmationGUI();
1283
1284        $c_gui->setFormAction($this->ctrl->getFormAction($this, 'performDeleteThreads'));
1285        $c_gui->setHeaderText($this->lng->txt('frm_sure_delete_threads'));
1286        $c_gui->setCancel($this->lng->txt('cancel'), 'showThreads');
1287        $c_gui->setConfirm($this->lng->txt('confirm'), 'performDeleteThreads');
1288
1289        foreach ($threads as $thread) {
1290            $c_gui->addItem('thread_ids[]', $thread->getId(), $thread->getSubject());
1291        }
1292
1293        $this->confirmation_gui_html = $c_gui->getHTML();
1294
1295        $this->hideToolbar(true);
1296
1297        return $this->tpl->setContent($c_gui->getHTML());
1298    }
1299
1300    protected function confirmDeleteThreadDraftsObject()
1301    {
1302        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
1303            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1304        }
1305
1306        $draftIds = array_filter((array) ($this->httpRequest->getParsedBody()['draft_ids'] ?? []));
1307        if (0 === count($draftIds)) {
1308            \ilUtil::sendInfo($this->lng->txt('select_at_least_one_thread'));
1309            $this->showThreadsObject();
1310            return;
1311        }
1312
1313        $confirmation = new ilConfirmationGUI();
1314        $confirmation->setFormAction($this->ctrl->getFormAction($this, 'deleteThreadDrafts'));
1315        $confirmation->setHeaderText($this->lng->txt('sure_delete_drafts'));
1316        $confirmation->setCancel($this->lng->txt('cancel'), 'showThreads');
1317        $confirmation->setConfirm($this->lng->txt('confirm'), 'deleteThreadDrafts');
1318        $instances = \ilForumPostDraft::getDraftInstancesByUserId($this->user->getId());
1319        foreach ($draftIds as $draftId) {
1320            if (array_key_exists($draftId, $instances)) {
1321                $confirmation->addItem('draft_ids[]', $draftId, $instances[$draftId]->getPostSubject());
1322            }
1323        }
1324
1325        $this->tpl->setContent($confirmation->getHTML());
1326    }
1327
1328    public function prepareThreadScreen(ilObjForum $a_forum_obj)
1329    {
1330        $this->ilHelp->setScreenIdComponent("frm");
1331
1332        $this->tpl->getStandardTemplate();
1333        ilUtil::sendInfo();
1334        ilUtil::infoPanel();
1335
1336        $this->tpl->setTitleIcon(ilObject::_getIcon("", "big", "frm"));
1337
1338        $this->tabs->setBackTarget($this->lng->txt('all_topics'), 'ilias.php?baseClass=ilRepositoryGUI&amp;ref_id=' . $_GET['ref_id']);
1339
1340        // by answer view
1341        $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
1342        $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
1343        $this->ctrl->setParameter($this, 'viewmode', ilForumProperties::VIEW_TREE);
1344        $this->tabs->addTarget('sort_by_posts', $this->ctrl->getLinkTarget($this, 'viewThread'));
1345
1346        // by date view
1347        $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
1348        $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
1349        $this->ctrl->setParameter($this, 'viewmode', ilForumProperties::VIEW_DATE);
1350        $this->tabs->addTarget('order_by_date', $this->ctrl->getLinkTarget($this, 'viewThread'));
1351
1352        $this->ctrl->clearParameters($this);
1353
1354        if ($this->isHierarchicalView()) {
1355            $this->tabs->activateTab('sort_by_posts');
1356        } else {
1357            $this->tabs->activateTab('order_by_date');
1358        }
1359
1360        /**
1361         * @var $frm ilForum
1362         */
1363        $frm = $a_forum_obj->Forum;
1364        $frm->setForumId($a_forum_obj->getId());
1365    }
1366
1367    public function performPostActivationObject()
1368    {
1369        if (!$this->is_moderator) {
1370            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1371        }
1372
1373        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
1374            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1375        }
1376
1377        $this->ensureThreadBelongsToForum((int) $this->object->getId(), $this->objCurrentPost->getThread());
1378
1379        $this->objCurrentPost->activatePost();
1380        $GLOBALS['ilAppEventHandler']->raise(
1381            'Modules/Forum',
1382            'activatedPost',
1383            array(
1384                'ref_id' => $this->object->getRefId(),
1385                'post' => $this->objCurrentPost
1386            )
1387        );
1388        ilUtil::sendInfo($this->lng->txt('forums_post_was_activated'), true);
1389
1390        $this->viewThreadObject();
1391    }
1392
1393    private function deletePostingObject()
1394    {
1395        if (
1396            !$this->objCurrentTopic->isClosed() && (
1397                $this->is_moderator ||
1398                ($this->objCurrentPost->isOwner($this->user->getId()) && !$this->objCurrentPost->hasReplies())
1399            ) &&
1400            !$this->user->isAnonymous()
1401        ) {
1402            $this->ensureThreadBelongsToForum((int) $this->object->getId(), $this->objCurrentPost->getThread());
1403
1404            $oForumObjects = $this->getForumObjects();
1405            /** @var $forumObj ilObjForum */
1406            $forumObj = $oForumObjects['forumObj'];
1407
1408            $frm = new ilForum();
1409            $frm->setForumId($forumObj->getId());
1410            $frm->setForumRefId($forumObj->getRefId());
1411            $dead_thr = $frm->deletePost($this->objCurrentPost->getId());
1412
1413            // if complete thread was deleted ...
1414            if ($dead_thr == $this->objCurrentTopic->getId()) {
1415                $frm->setMDB2WhereCondition('top_frm_fk = %s ', array('integer'), array($forumObj->getId()));
1416                $topicData = $frm->getOneTopic();
1417                ilUtil::sendInfo($this->lng->txt('forums_post_deleted'), true);
1418                if ($topicData['top_num_threads'] > 0) {
1419                    $this->ctrl->redirect($this, 'showThreads');
1420                } else {
1421                    $this->ctrl->redirect($this, 'createThread');
1422                }
1423            }
1424            ilUtil::sendInfo($this->lng->txt('forums_post_deleted'), true);
1425            $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
1426            $this->ctrl->redirect($this, 'viewThread');
1427        }
1428
1429        $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1430    }
1431
1432    private function deletePostingDraftObject()
1433    {
1434        $this->deleteSelectedDraft();
1435    }
1436
1437    private function revokeCensorshipObject()
1438    {
1439        $this->handleCensorship(true);
1440    }
1441
1442    private function addCensorshipObject()
1443    {
1444        $this->handleCensorship();
1445    }
1446
1447    private function handleCensorship($wasRevoked = false)
1448    {
1449        if (!$this->objCurrentTopic->isClosed() && $this->is_moderator) {
1450            $message = $this->handleFormInput($_POST['formData']['cens_message']);
1451            $this->ensureThreadBelongsToForum((int) $this->object->getId(), $this->objCurrentPost->getThread());
1452
1453            $oForumObjects = $this->getForumObjects();
1454            /** @var $frm ilForum */
1455            $frm = $oForumObjects['frm'];
1456
1457            if ($wasRevoked) {
1458                $frm->postCensorship($message, $this->objCurrentPost->getId());
1459                ilUtil::sendSuccess($this->lng->txt('frm_censorship_revoked'));
1460            } else {
1461                $frm->postCensorship($message, $this->objCurrentPost->getId(), 1);
1462                ilUtil::sendSuccess($this->lng->txt('frm_censorship_applied'));
1463            }
1464
1465            $this->viewThreadObject();
1466            return;
1467        }
1468
1469        $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1470    }
1471
1472    public function askForPostActivationObject()
1473    {
1474        if (!$this->is_moderator) {
1475            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1476        }
1477
1478        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
1479            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1480        }
1481
1482        $this->setDisplayConfirmPostActivation(true);
1483
1484        $this->viewThreadObject();
1485    }
1486
1487    public function setDisplayConfirmPostActivation($status = 0)
1488    {
1489        $this->display_confirm_post_activation = $status;
1490    }
1491
1492    public function displayConfirmPostActivation()
1493    {
1494        return $this->display_confirm_post_activation;
1495    }
1496
1497    protected function toggleThreadNotificationObject()
1498    {
1499        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
1500            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1501        }
1502
1503        $this->ensureThreadBelongsToForum((int) $this->object->getId(), $this->objCurrentTopic);
1504
1505        if ($this->objCurrentTopic->isNotificationEnabled($this->user->getId())) {
1506            $this->objCurrentTopic->disableNotification($this->user->getId());
1507            \ilUtil::sendInfo($this->lng->txt('forums_notification_disabled'));
1508        } else {
1509            $this->objCurrentTopic->enableNotification($this->user->getId());
1510            \ilUtil::sendInfo($this->lng->txt('forums_notification_enabled'));
1511        }
1512
1513        $this->viewThreadObject();
1514    }
1515
1516    protected function toggleStickinessObject()
1517    {
1518        if (!$this->is_moderator) {
1519            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1520        }
1521
1522        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
1523            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1524        }
1525
1526        $this->ensureThreadBelongsToForum((int) $this->object->getId(), $this->objCurrentTopic);
1527
1528        if ($this->objCurrentTopic->isSticky()) {
1529            $this->objCurrentTopic->unmakeSticky();
1530        } else {
1531            $this->objCurrentTopic->makeSticky();
1532        }
1533
1534        $this->viewThreadObject();
1535    }
1536
1537    public function cancelPostObject()
1538    {
1539        $this->requestAction = '';
1540        if (isset($_POST['draft_id']) && (int) $_POST['draft_id'] > 0) {
1541            $draft = ilForumPostDraft::newInstanceByDraftId((int) $_POST['draft_id']);
1542            $draft->deleteDraftsByDraftIds(array( (int) $_POST['draft_id']));
1543        }
1544
1545        $this->viewThreadObject();
1546    }
1547
1548    public function cancelDraftObject()
1549    {
1550        $this->requestAction = '';
1551        if (isset($_GET['draft_id']) && (int) $_GET['draft_id'] > 0) {
1552            if (ilForumPostDraft::isAutoSavePostDraftAllowed()) {
1553                $history_obj = new ilForumDraftsHistory();
1554                $history_obj->getFirstAutosaveByDraftId((int) $_GET['draft_id']);
1555                $draft = ilForumPostDraft::newInstanceByDraftId((int) $_GET['draft_id']);
1556                $draft->setPostSubject($history_obj->getPostSubject());
1557                $draft->setPostMessage($history_obj->getPostMessage());
1558
1559                ilForumUtil::moveMediaObjects(
1560                    $history_obj->getPostMessage(),
1561                    ilForumDraftsHistory::MEDIAOBJECT_TYPE,
1562                    $history_obj->getHistoryId(),
1563                    ilForumPostDraft::MEDIAOBJECT_TYPE,
1564                    $draft->getDraftId()
1565                );
1566
1567                $draft->updateDraft();
1568
1569                $history_obj->deleteHistoryByDraftIds(array($draft->getDraftId()));
1570            }
1571        }
1572        $this->ctrl->clearParameters($this);
1573        $this->viewThreadObject();
1574    }
1575
1576    public function getDeleteFormHTML()
1577    {
1578        /** @var $form_tpl ilTemplate */
1579        $form_tpl = new ilTemplate('tpl.frm_delete_post_form.html', true, true, 'Modules/Forum');
1580        $form_tpl->setVariable('ANKER', $this->objCurrentPost->getId());
1581        $form_tpl->setVariable('SPACER', '<hr noshade="noshade" width="100%" size="1" align="center" />');
1582        $form_tpl->setVariable('TXT_DELETE', $this->lng->txt('forums_info_delete_post'));
1583        $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
1584        $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
1585        $this->ctrl->setParameter($this, 'orderby', ilUtil::stripSlashes($_GET['orderby']));
1586        $form_tpl->setVariable('FORM_ACTION', $this->ctrl->getFormAction($this, 'viewThread'));
1587        $this->ctrl->clearParameters($this);
1588        $form_tpl->setVariable('CMD_CONFIRM', 'deletePosting');
1589        $form_tpl->setVariable('CMD_CANCEL', 'viewThread');
1590        $form_tpl->setVariable('CANCEL_BUTTON', $this->lng->txt('cancel'));
1591        $form_tpl->setVariable('CONFIRM_BUTTON', $this->lng->txt('confirm'));
1592
1593        return $form_tpl->get();
1594    }
1595    public function getDeleteDraftFormHTML()
1596    {
1597        /** @var $form_tpl ilTemplate */
1598        $form_tpl = new ilTemplate('tpl.frm_delete_post_form.html', true, true, 'Modules/Forum');
1599        $form_tpl->setVariable('SPACER', '<hr noshade="noshade" width="100%" size="1" align="center" />');
1600        $form_tpl->setVariable('TXT_DELETE', $this->lng->txt('forums_info_delete_draft'));
1601        $this->ctrl->setParameter($this, 'draft_id', (int) $_GET['draft_id']);
1602        $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
1603        $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
1604        $this->ctrl->setParameter($this, 'orderby', ilUtil::stripSlashes($_GET['orderby']));
1605        $form_tpl->setVariable('FORM_ACTION', $this->ctrl->getFormAction($this, 'viewThread'));
1606        $this->ctrl->clearParameters($this);
1607        $form_tpl->setVariable('CMD_CONFIRM', 'deletePostingDraft');
1608        $form_tpl->setVariable('CMD_CANCEL', 'viewThread');
1609        $form_tpl->setVariable('CANCEL_BUTTON', $this->lng->txt('cancel'));
1610        $form_tpl->setVariable('CONFIRM_BUTTON', $this->lng->txt('confirm'));
1611
1612        return $form_tpl->get();
1613    }
1614
1615    public function getActivationFormHTML()
1616    {
1617        $form_tpl = new ilTemplate('tpl.frm_activation_post_form.html', true, true, 'Modules/Forum');
1618        $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
1619        $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
1620        $this->ctrl->setParameter($this, 'orderby', ilUtil::stripSlashes($_GET['orderby']));
1621        $form_tpl->setVariable('FORM_ACTION', $this->ctrl->getFormAction($this, 'performPostActivation'));
1622        $form_tpl->setVariable('SPACER', '<hr noshade="noshade" width="100%" size="1" align="center" />');
1623        $form_tpl->setVariable('ANCHOR', $this->objCurrentPost->getId());
1624        $form_tpl->setVariable('TXT_ACT', $this->lng->txt('activate_post_txt'));
1625        $form_tpl->setVariable('CONFIRM_BUTTON', $this->lng->txt('activate_only_current'));
1626        $form_tpl->setVariable('CMD_CONFIRM', 'performPostActivation');
1627        $form_tpl->setVariable('CANCEL_BUTTON', $this->lng->txt('cancel'));
1628        $form_tpl->setVariable('CMD_CANCEL', 'viewThread');
1629        $this->ctrl->clearParameters($this);
1630
1631        return $form_tpl->get();
1632    }
1633
1634    public function getCensorshipFormHTML()
1635    {
1636        $frm = $this->object->Forum;
1637        $form_tpl = new ilTemplate('tpl.frm_censorship_post_form.html', true, true, 'Modules/Forum');
1638
1639        $form_tpl->setVariable('ANCHOR', $this->objCurrentPost->getId());
1640        $form_tpl->setVariable('SPACER', '<hr noshade="noshade" width="100%" size="1" align="center" />');
1641        $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
1642        $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
1643        $this->ctrl->setParameter($this, 'orderby', ilUtil::stripSlashes($_GET['orderby']));
1644        $form_tpl->setVariable('FORM_ACTION', $this->ctrl->getFormAction($this, 'viewThread'));
1645        $this->ctrl->clearParameters($this);
1646        $form_tpl->setVariable('TXT_CENS_MESSAGE', $this->lng->txt('forums_the_post'));
1647        $form_tpl->setVariable('TXT_CENS_COMMENT', $this->lng->txt('forums_censor_comment') . ':');
1648        $form_tpl->setVariable('CENS_MESSAGE', $frm->prepareText($this->objCurrentPost->getCensorshipComment(), 2));
1649
1650        if ($this->objCurrentPost->isCensored()) {
1651            $form_tpl->setVariable('TXT_CENS', $this->lng->txt('forums_info_censor2_post'));
1652            $form_tpl->setVariable('YES_BUTTON', $this->lng->txt('confirm'));
1653            $form_tpl->setVariable('NO_BUTTON', $this->lng->txt('cancel'));
1654            $form_tpl->setVariable('CMD_REVOKE_CENSORSHIP', 'revokeCensorship');
1655            $form_tpl->setVariable('CMD_CANCEL_REVOKE_CENSORSHIP', 'viewThread');
1656        } else {
1657            $form_tpl->setVariable('TXT_CENS', $this->lng->txt('forums_info_censor_post'));
1658            $form_tpl->setVariable('CANCEL_BUTTON', $this->lng->txt('cancel'));
1659            $form_tpl->setVariable('CONFIRM_BUTTON', $this->lng->txt('confirm'));
1660            $form_tpl->setVariable('CMD_ADD_CENSORSHIP', 'addCensorship');
1661            $form_tpl->setVariable('CMD_CANCEL_ADD_CENSORSHIP', 'viewThread');
1662        }
1663
1664        return $form_tpl->get();
1665    }
1666
1667    /**
1668     * @throws ilHtmlPurifierNotFoundException
1669     */
1670    private function initReplyEditForm()
1671    {
1672        /**
1673         * @var $oFDForum ilFileDataForum
1674         */
1675        $isReply = in_array($this->requestAction, ['showreply', 'ready_showreply']);
1676        $isDraft = in_array($this->requestAction, ['publishDraft', 'editdraft']);
1677
1678        // init objects
1679        $oForumObjects = $this->getForumObjects();
1680        $frm = $oForumObjects['frm'];
1681        $oFDForum = $oForumObjects['file_obj'];
1682
1683        $this->replyEditForm = new ilPropertyFormGUI();
1684        $this->replyEditForm->setId('id_showreply');
1685        $this->replyEditForm->setTableWidth('100%');
1686        $cancel_cmd = 'cancelPost';
1687        if (in_array($this->requestAction, ['showreply', 'ready_showreply'])) {
1688            $this->ctrl->setParameter($this, 'action', 'ready_showreply');
1689        } elseif (in_array($this->requestAction, ['showdraft', 'editdraft'])) {
1690            $this->ctrl->setParameter($this, 'action', $this->requestAction);
1691            $this->ctrl->setParameter($this, 'draft_id', (int) $_GET['draft_id']);
1692        } else {
1693            $this->ctrl->setParameter($this, 'action', 'ready_showedit');
1694        }
1695
1696        $this->ctrl->setParameter($this, 'offset', (int) $_GET['offset']);
1697        $this->ctrl->setParameter($this, 'orderby', $_GET['orderby']);
1698        $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
1699        $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
1700        if ($this->isTopLevelReplyCommand()) {
1701            $this->replyEditForm->setFormAction($this->ctrl->getFormAction($this, 'saveTopLevelPost'), 'frm_page_bottom');
1702        } elseif (in_array($this->requestAction, ['publishDraft', 'editdraft'])) {
1703            $this->replyEditForm->setFormAction($this->ctrl->getFormAction($this, 'publishDraft'), $this->objCurrentPost->getId());
1704        } else {
1705            $this->replyEditForm->setFormAction($this->ctrl->getFormAction($this, 'savePost'), $this->objCurrentPost->getId());
1706        }
1707        $this->ctrl->clearParameters($this);
1708
1709        if ($isReply) {
1710            $this->replyEditForm->setTitle($this->lng->txt('forums_your_reply'));
1711        } elseif ($isDraft) {
1712            $this->replyEditForm->setTitle($this->lng->txt('forums_edit_draft'));
1713        } else {
1714            $this->replyEditForm->setTitle($this->lng->txt('forums_edit_post'));
1715        }
1716
1717        if (
1718            $this->isWritingWithPseudonymAllowed() &&
1719            in_array($this->requestAction, array('showreply', 'ready_showreply', 'editdraft'))
1720        ) {
1721            $oAnonymousNameGUI = new ilTextInputGUI($this->lng->txt('forums_your_name'), 'alias');
1722            $oAnonymousNameGUI->setMaxLength(64);
1723            $oAnonymousNameGUI->setInfo($this->lng->txt('forums_use_alias'));
1724
1725            $this->replyEditForm->addItem($oAnonymousNameGUI);
1726        }
1727
1728        $oSubjectGUI = new ilTextInputGUI($this->lng->txt('forums_subject'), 'subject');
1729        $oSubjectGUI->setMaxLength(255);
1730        $oSubjectGUI->setRequired(true);
1731
1732        if ($this->objProperties->getSubjectSetting() == 'empty_subject') {
1733            $oSubjectGUI->setInfo($this->lng->txt('enter_new_subject'));
1734        }
1735
1736        $this->replyEditForm->addItem($oSubjectGUI);
1737
1738        $oPostGUI = new ilTextAreaInputGUI(
1739            $isReply ? $this->lng->txt('forums_your_reply') : $this->lng->txt('forums_edit_post'),
1740            'message'
1741        );
1742        $oPostGUI->setRequired(true);
1743        $oPostGUI->setRows(15);
1744        $oPostGUI->setUseRte(true);
1745        $oPostGUI->addPlugin('latex');
1746        $oPostGUI->addButton('latex');
1747        $oPostGUI->addButton('pastelatex');
1748
1749        $quotingAllowed = (
1750            !$this->isTopLevelReplyCommand() && (
1751                ($isReply && $this->objCurrentPost->getDepth() >= 2) ||
1752                (!$isDraft && !$isReply && $this->objCurrentPost->getDepth() > 2) ||
1753                ($isDraft && $this->objCurrentPost->getDepth() >= 2)
1754            )
1755        );
1756
1757        if ($quotingAllowed) {
1758            $oPostGUI->addButton('ilFrmQuoteAjaxCall');
1759            $oPostGUI->addPlugin('ilfrmquote');
1760        }
1761
1762        $oPostGUI->removePlugin('advlink');
1763        $oPostGUI->setRTERootBlockElement('');
1764        $oPostGUI->usePurifier(true);
1765        $oPostGUI->disableButtons(array(
1766            'charmap',
1767            'undo',
1768            'redo',
1769            'justifyleft',
1770            'justifycenter',
1771            'justifyright',
1772            'justifyfull',
1773            'anchor',
1774            'fullscreen',
1775            'cut',
1776            'copy',
1777            'paste',
1778            'pastetext',
1779            'formatselect'
1780        ));
1781
1782        if (in_array($this->requestAction, ['showreply', 'ready_showreply', 'showdraft', 'editdraft'])) {
1783            $oPostGUI->setRTESupport($this->user->getId(), 'frm~', 'frm_post', 'tpl.tinymce_frm_post.html', false, '3.5.11');
1784        } else {
1785            $oPostGUI->setRTESupport($this->objCurrentPost->getId(), 'frm', 'frm_post', 'tpl.tinymce_frm_post.html', false, '3.5.11');
1786        }
1787        // purifier
1788        $oPostGUI->setPurifier(ilHtmlPurifierFactory::_getInstanceByType('frm_post'));
1789
1790        $this->replyEditForm->addItem($oPostGUI);
1791
1792        // notification only if gen. notification is disabled and forum isn't anonymous
1793        $umail = new ilMail($this->user->getId());
1794        if ($this->rbac->system()->checkAccess('internal_mail', $umail->getMailObjectReferenceId()) &&
1795           !$frm->isThreadNotificationEnabled($this->user->getId(), $this->objCurrentPost->getThreadId()) &&
1796           !$this->objProperties->isAnonymized()) {
1797            $oNotificationGUI = new ilCheckboxInputGUI($this->lng->txt('forum_direct_notification'), 'notify');
1798            $oNotificationGUI->setInfo($this->lng->txt('forum_notify_me'));
1799
1800            $this->replyEditForm->addItem($oNotificationGUI);
1801        }
1802
1803        if ($this->objProperties->isFileUploadAllowed()) {
1804            $oFileUploadGUI = new ilFileWizardInputGUI($this->lng->txt('forums_attachments_add'), 'userfile');
1805            $oFileUploadGUI->setFilenames(array(0 => ''));
1806            $this->replyEditForm->addItem($oFileUploadGUI);
1807        }
1808
1809        if (
1810            $this->user->isAnonymous() &&
1811            !$this->user->isCaptchaVerified() &&
1812            ilCaptchaUtil::isActiveForForum()
1813        ) {
1814            $captcha = new ilCaptchaInputGUI($this->lng->txt('cont_captcha_code'), 'captcha_code');
1815            $captcha->setRequired(true);
1816            $this->replyEditForm->addItem($captcha);
1817        }
1818
1819        $attachments_of_node = $oFDForum->getFilesOfPost();
1820        if (count($attachments_of_node) && in_array($this->requestAction, ['showedit', 'ready_showedit'])) {
1821            $oExistingAttachmentsGUI = new ilCheckboxGroupInputGUI($this->lng->txt('forums_delete_file'), 'del_file');
1822            foreach ($oFDForum->getFilesOfPost() as $file) {
1823                $oAttachmentGUI = new ilCheckboxInputGUI($file['name'], 'del_file');
1824                $oAttachmentGUI->setValue($file['md5']);
1825                $oExistingAttachmentsGUI->addOption($oAttachmentGUI);
1826            }
1827            $this->replyEditForm->addItem($oExistingAttachmentsGUI);
1828        }
1829
1830        if (ilForumPostDraft::isAutoSavePostDraftAllowed()) {
1831            if (in_array($this->requestAction, ['showdraft', 'editdraft'])) {
1832                $draftInfoGUI = new ilNonEditableValueGUI('', 'autosave_info', true);
1833                $draftInfoGUI->setValue(sprintf($this->lng->txt('autosave_draft_info'), ilForumPostDraft::lookupAutosaveInterval()));
1834                $this->replyEditForm->addItem($draftInfoGUI);
1835            } elseif (!in_array($this->requestAction, ['showedit', 'ready_showedit'])) {
1836                $draftInfoGUI = new ilNonEditableValueGUI('', 'autosave_info', true);
1837                $draftInfoGUI->setValue(sprintf($this->lng->txt('autosave_post_draft_info'), ilForumPostDraft::lookupAutosaveInterval()));
1838                $this->replyEditForm->addItem($draftInfoGUI);
1839            }
1840
1841            $selected_draft_id = (int) $_GET['draft_id'];
1842            $draftObj = new ilForumPostDraft($this->user->getId(), $this->objCurrentPost->getId(), $selected_draft_id);
1843            if ($draftObj->getDraftId() > 0) {
1844                $oFDForumDrafts = new ilFileDataForumDrafts(0, $draftObj->getDraftId());
1845                if (count($oFDForumDrafts->getFilesOfPost())) {
1846                    $oExistingAttachmentsGUI = new ilCheckboxGroupInputGUI($this->lng->txt('forums_delete_file'), 'del_file');
1847                    foreach ($oFDForumDrafts->getFilesOfPost() as $file) {
1848                        $oAttachmentGUI = new ilCheckboxInputGUI($file['name'], 'del_file');
1849                        $oAttachmentGUI->setValue($file['md5']);
1850                        $oExistingAttachmentsGUI->addOption($oAttachmentGUI);
1851                    }
1852                    $this->replyEditForm->addItem($oExistingAttachmentsGUI);
1853                }
1854            }
1855        }
1856
1857        if ($this->isTopLevelReplyCommand()) {
1858            $this->replyEditForm->addCommandButton('saveTopLevelPost', $this->lng->txt('create'));
1859        } elseif (ilForumPostDraft::isSavePostDraftAllowed() && $this->requestAction == 'editdraft') {
1860            $this->replyEditForm->addCommandButton('publishDraft', $this->lng->txt('publish'));
1861        } else {
1862            $this->replyEditForm->addCommandButton('savePost', $this->lng->txt('save'));
1863        }
1864        $hidden_draft_id = new ilHiddenInputGUI('draft_id');
1865        if (isset($_GET['draft_id']) && (int) $_GET['draft_id'] > 0) {
1866            $auto_save_draft_id = (int) $_GET['draft_id'];
1867        }
1868        $hidden_draft_id->setValue($auto_save_draft_id);
1869        $this->replyEditForm->addItem($hidden_draft_id);
1870
1871        if (in_array($this->requestAction, ['showreply', 'ready_showreply', 'editdraft'])) {
1872            $rtestring = ilRTE::_getRTEClassname();
1873
1874            if (array_key_exists('show_rte', $_POST)) {
1875                ilObjAdvancedEditing::_setRichTextEditorUserState($_POST['show_rte']);
1876            }
1877
1878            if (strtolower($rtestring) != 'iltinymce' || !ilObjAdvancedEditing::_getRichTextEditorUserState()) {
1879                if ($quotingAllowed) {
1880                    $this->replyEditForm->addCommandButton('quotePost', $this->lng->txt('forum_add_quote'));
1881                }
1882            }
1883
1884            if (
1885                !$this->user->isAnonymous() &&
1886                in_array($this->requestAction, ['editdraft', 'showreply', 'ready_showreply']) &&
1887                ilForumPostDraft::isSavePostDraftAllowed()
1888            ) {
1889                if (ilForumPostDraft::isAutoSavePostDraftAllowed()) {
1890                    $this->decorateWithAutosave($this->replyEditForm);
1891                }
1892
1893                if ($this->requestAction == 'editdraft') {
1894                    $this->replyEditForm->addCommandButton('updateDraft', $this->lng->txt('save_message'));
1895                } elseif ($this->isTopLevelReplyCommand()) {
1896                    $this->replyEditForm->addCommandButton('saveTopLevelDraft', $this->lng->txt('save_message'));
1897                } else {
1898                    $this->replyEditForm->addCommandButton('saveAsDraft', $this->lng->txt('save_message'));
1899                }
1900
1901                $cancel_cmd = 'cancelDraft';
1902            }
1903        }
1904        $this->replyEditForm->addCommandButton($cancel_cmd, $this->lng->txt('cancel'));
1905    }
1906
1907    /**
1908     * @return ilPropertyFormGUI
1909     */
1910    private function getReplyEditForm()
1911    {
1912        if (null === $this->replyEditForm) {
1913            $this->initReplyEditForm();
1914        }
1915
1916        return $this->replyEditForm;
1917    }
1918
1919    /**
1920     *
1921     */
1922    public function createTopLevelPostObject()
1923    {
1924        if (isset($_GET['draft_id']) && (int) $_GET['draft_id'] > 0 && !$this->user->isAnonymous()
1925            && ilForumPostDraft::isSavePostDraftAllowed()) {
1926            $draft_obj = new ilForumPostDraft($this->user->getId(), $this->objCurrentPost->getId(), (int) $_GET['draft_id']);
1927        }
1928
1929        if ($draft_obj instanceof ilForumPostDraft && $draft_obj->getDraftId() > 0) {
1930            $this->ctrl->setParameter($this, 'action', 'editdraft');
1931            $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
1932            $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
1933            $this->ctrl->setParameter($this, 'draft_id', $draft_obj->getDraftId());
1934            $this->ctrl->setParameter($this, 'offset', 0);
1935            $this->ctrl->setParameter($this, 'orderby', $_GET['orderby']);
1936            $this->ctrl->redirect($this, 'editDraft');
1937        } else {
1938            $this->viewThreadObject();
1939        }
1940        return;
1941    }
1942
1943    /**
1944     *
1945     */
1946    public function saveTopLevelPostObject()
1947    {
1948        $this->savePostObject();
1949        return;
1950    }
1951
1952    public function publishSelectedDraftObject()
1953    {
1954        if (isset($_GET['draft_id']) && (int) $_GET['draft_id'] > 0) {
1955            $this->publishDraftObject(false);
1956        }
1957    }
1958
1959    public function publishDraftObject($use_replyform = true)
1960    {
1961        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
1962            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1963        }
1964
1965        if (!$this->access->checkAccess('add_reply', '', $this->object->getRefId())) {
1966            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
1967        }
1968
1969        if (!$this->objCurrentTopic->getId()) {
1970            \ilUtil::sendFailure($this->lng->txt('frm_action_not_possible_thr_deleted'), true);
1971            $this->ctrl->redirect($this);
1972        }
1973
1974        if ($this->objCurrentTopic->isClosed()) {
1975            \ilUtil::sendFailure($this->lng->txt('frm_action_not_possible_thr_closed'), true);
1976            $this->ctrl->redirect($this);
1977        }
1978
1979        if (!$this->objCurrentPost->getId()) {
1980            $this->requestAction = '';
1981            \ilUtil::sendFailure($this->lng->txt('frm_action_not_possible_parent_deleted'));
1982            $this->viewThreadObject();
1983            return;
1984        }
1985
1986        $post_id = $this->objCurrentPost->getId();
1987
1988        $draft_obj = new ilForumPostDraft($this->user->getId(), $post_id, (int) $_GET['draft_id']);
1989
1990        if ($use_replyform) {
1991            $oReplyEditForm = $this->getReplyEditForm();
1992            // @Nadia: Why do we need this additional check here (with this check mandatory fields are NOT checked, so I suggest to remove it):  && !$draft_obj instanceof ilForumPostDraft
1993            if (!$oReplyEditForm->checkInput()) {
1994                $oReplyEditForm->setValuesByPost();
1995                return $this->viewThreadObject();
1996            }
1997            $post_subject = $oReplyEditForm->getInput('subject');
1998            $post_message = $oReplyEditForm->getInput('message');
1999            $mob_direction = 0;
2000        } else {
2001            $post_subject = $draft_obj->getPostSubject();
2002            $post_message = $draft_obj->getPostMessage();
2003            $mob_direction = 1;
2004        }
2005
2006        if ($draft_obj->getDraftId() > 0) {
2007            // init objects
2008            $oForumObjects = $this->getForumObjects();
2009            $frm = $oForumObjects['frm'];
2010            $frm->setMDB2WhereCondition(' top_frm_fk = %s ', array('integer'), array($frm->getForumId()));
2011
2012            // reply: new post
2013            $status = 1;
2014            $send_activation_mail = 0;
2015
2016            if ($this->objProperties->isPostActivationEnabled()) {
2017                if (!$this->is_moderator) {
2018                    $status = 0;
2019                    $send_activation_mail = 1;
2020                } elseif ($this->objCurrentPost->isAnyParentDeactivated()) {
2021                    $status = 0;
2022                }
2023            }
2024
2025            $newPost = $frm->generatePost(
2026                $draft_obj->getForumId(),
2027                $draft_obj->getThreadId(),
2028                $this->user->getId(),
2029                $draft_obj->getPostDisplayUserId(),
2030                ilRTE::_replaceMediaObjectImageSrc($post_message, $mob_direction),
2031                $draft_obj->getPostId(),
2032                (int) $draft_obj->getNotify(),
2033                $this->handleFormInput($post_subject, false),
2034                $draft_obj->getPostUserAlias(),
2035                '',
2036                $status,
2037                $send_activation_mail
2038            );
2039
2040            $this->object->markPostRead($this->user->getId(), (int) $this->objCurrentTopic->getId(), (int) $this->objCurrentPost->getId());
2041
2042            $uploadedObjects = ilObjMediaObject::_getMobsOfObject('frm~:html', $this->user->getId());
2043
2044            foreach ($uploadedObjects as $mob) {
2045                ilObjMediaObject::_removeUsage($mob, 'frm~:html', $this->user->getId());
2046                ilObjMediaObject::_saveUsage($mob, 'frm:html', $newPost);
2047            }
2048            ilForumUtil::saveMediaObjects($post_message, 'frm:html', $newPost, $mob_direction);
2049
2050            if ($this->objProperties->isFileUploadAllowed()) {
2051                $file = $_FILES['userfile'];
2052                if (is_array($file) && !empty($file)) {
2053                    $tmp_file_obj = new ilFileDataForum($this->object->getId(), $newPost);
2054                    $tmp_file_obj->storeUploadedFile($file);
2055                }
2056
2057                //move files of draft to posts directory
2058                $oFDForum = new ilFileDataForum($this->object->getId(), $newPost);
2059                $oFDForumDrafts = new ilFileDataForumDrafts($this->object->getId(), $draft_obj->getDraftId());
2060
2061                $oFDForumDrafts->moveFilesOfDraft($oFDForum->getForumPath(), $newPost);
2062                $oFDForumDrafts->delete();
2063            }
2064
2065            if (ilForumPostDraft::isSavePostDraftAllowed()) {
2066                $GLOBALS['ilAppEventHandler']->raise(
2067                    'Modules/Forum',
2068                    'publishedDraft',
2069                    array('draftObj' => $draft_obj,
2070                          'obj_id' => $this->object->getId(),
2071                          'is_file_upload_allowed' => $this->objProperties->isFileUploadAllowed())
2072                );
2073            }
2074            $draft_obj->deleteDraft();
2075
2076            $GLOBALS['ilAppEventHandler']->raise(
2077                'Modules/Forum',
2078                'createdPost',
2079                array(
2080                    'ref_id' => $this->object->getRefId(),
2081                    'post' => new ilForumPost($newPost),
2082                    'notify_moderators' => (bool) $send_activation_mail
2083                )
2084            );
2085
2086            $message = '';
2087            if (!$this->is_moderator && !$status) {
2088                $message .= $this->lng->txt('forums_post_needs_to_be_activated');
2089            } else {
2090                $message .= $this->lng->txt('forums_post_new_entry');
2091            }
2092
2093            $_SESSION['frm'][(int) $_GET['thr_pk']]['openTreeNodes'][] = (int) $this->objCurrentPost->getId();
2094
2095            $this->ctrl->clearParameters($this);
2096            ilUtil::sendSuccess($message, true);
2097            $this->ctrl->setParameter($this, 'pos_pk', $newPost);
2098            $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
2099
2100            $this->ctrl->redirect($this, 'viewThread');
2101        }
2102    }
2103
2104    /**
2105     * @return bool
2106     */
2107    public function savePostObject()
2108    {
2109        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
2110            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
2111        }
2112
2113        if (!$this->objCurrentTopic->getId()) {
2114            \ilUtil::sendFailure($this->lng->txt('frm_action_not_possible_thr_deleted'), true);
2115            $this->ctrl->redirect($this);
2116        }
2117
2118        if ($this->objCurrentTopic->isClosed()) {
2119            \ilUtil::sendFailure($this->lng->txt('frm_action_not_possible_thr_closed'), true);
2120            $this->ctrl->redirect($this);
2121        }
2122
2123        $this->ensureThreadBelongsToForum((int) $this->object->getId(), $this->objCurrentTopic);
2124
2125        if (!isset($_POST['del_file']) || !is_array($_POST['del_file'])) {
2126            $_POST['del_file'] = array();
2127        }
2128
2129        $oReplyEditForm = $this->getReplyEditForm();
2130        if ($oReplyEditForm->checkInput()) {
2131            if (!$this->objCurrentPost->getId()) {
2132                $this->requestAction = '';
2133                \ilUtil::sendFailure($this->lng->txt('frm_action_not_possible_parent_deleted'));
2134                $this->viewThreadObject();
2135                return;
2136            }
2137
2138            $this->doCaptchaCheck();
2139
2140            // init objects
2141            $oForumObjects = $this->getForumObjects();
2142            /**
2143             * @var $forumObj ilObjForum
2144             */
2145            $forumObj = $oForumObjects['forumObj'];
2146            /**
2147             * @var $frm ilForum
2148             */
2149            $frm = $oForumObjects['frm'];
2150            $frm->setMDB2WhereCondition(' top_frm_fk = %s ', array('integer'), array($frm->getForumId()));
2151            $topicData = $frm->getOneTopic();
2152
2153            // Generating new posting
2154            if ($this->requestAction == 'ready_showreply') {
2155                if (!$this->access->checkAccess('add_reply', '', (int) $_GET['ref_id'])) {
2156                    $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
2157                }
2158
2159                // reply: new post
2160                $status = 1;
2161                $send_activation_mail = 0;
2162
2163                if ($this->objProperties->isPostActivationEnabled()) {
2164                    if (!$this->is_moderator) {
2165                        $status = 0;
2166                        $send_activation_mail = 1;
2167                    } elseif ($this->objCurrentPost->isAnyParentDeactivated()) {
2168                        $status = 0;
2169                    }
2170                }
2171
2172                if ($this->isWritingWithPseudonymAllowed()) {
2173                    if (!strlen($oReplyEditForm->getInput('alias'))) {
2174                        $user_alias = $this->lng->txt('forums_anonymous');
2175                    } else {
2176                        $user_alias = $oReplyEditForm->getInput('alias');
2177                    }
2178                    $display_user_id = 0;
2179                } else {
2180                    $user_alias = $this->user->getLogin();
2181                    $display_user_id = $this->user->getId();
2182                }
2183
2184                $newPost = $frm->generatePost(
2185                    $topicData['top_pk'],
2186                    $this->objCurrentTopic->getId(),
2187                    $this->user->getId(),
2188                    $display_user_id,
2189                    ilRTE::_replaceMediaObjectImageSrc($oReplyEditForm->getInput('message'), 0),
2190                    $this->objCurrentPost->getId(),
2191                    (int) $oReplyEditForm->getInput('notify'),
2192                    $this->handleFormInput($oReplyEditForm->getInput('subject'), false),
2193                    $user_alias,
2194                    '',
2195                    $status,
2196                    $send_activation_mail
2197                );
2198
2199                if (ilForumPostDraft::isSavePostDraftAllowed()) {
2200                    $draft_id = 0;
2201                    if (ilForumPostDraft::isAutoSavePostDraftAllowed()) {
2202                        $draft_id = $_POST['draft_id']; // info aus dem autosave?
2203                    }
2204                    $draft_obj = new ilForumPostDraft($this->user->getId(), $this->objCurrentPost->getId(), $draft_id);
2205                    if ($draft_obj instanceof ilForumPostDraft) {
2206                        $draft_obj->deleteDraft();
2207                    }
2208                }
2209
2210                // mantis #8115: Mark parent as read
2211                $this->object->markPostRead($this->user->getId(), (int) $this->objCurrentTopic->getId(), (int) $this->objCurrentPost->getId());
2212
2213                // copy temporary media objects (frm~)
2214                ilForumUtil::moveMediaObjects($oReplyEditForm->getInput('message'), 'frm~:html', $this->user->getId(), 'frm:html', $newPost);
2215
2216                if ($this->objProperties->isFileUploadAllowed()) {
2217                    $oFDForum = new ilFileDataForum($forumObj->getId(), $newPost);
2218                    $file = $_FILES['userfile'];
2219                    if (is_array($file) && !empty($file)) {
2220                        $oFDForum->storeUploadedFile($file);
2221                    }
2222                }
2223
2224                $GLOBALS['ilAppEventHandler']->raise(
2225                    'Modules/Forum',
2226                    'createdPost',
2227                    array(
2228                        'ref_id' => $this->object->getRefId(),
2229                        'post' => new ilForumPost($newPost),
2230                        'notify_moderators' => (bool) $send_activation_mail
2231                    )
2232                );
2233
2234                $message = '';
2235                if (!$this->is_moderator && !$status) {
2236                    $message .= $this->lng->txt('forums_post_needs_to_be_activated');
2237                } else {
2238                    $message .= $this->lng->txt('forums_post_new_entry');
2239                }
2240
2241                ilUtil::sendSuccess($message, true);
2242                $this->ctrl->clearParameters($this);
2243                $this->ctrl->setParameter($this, 'post_created_below', $this->objCurrentPost->getId());
2244                $this->ctrl->setParameter($this, 'pos_pk', $newPost);
2245                $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
2246                $this->ctrl->redirect($this, 'viewThread');
2247            } else {
2248                if ((!$this->is_moderator &&
2249                   !$this->objCurrentPost->isOwner($this->user->getId())) || $this->objCurrentPost->isCensored() ||
2250                   $this->user->getId() == ANONYMOUS_USER_ID) {
2251                    $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
2252                }
2253
2254                $this->ensureThreadBelongsToForum((int) $this->object->getId(), $this->objCurrentPost->getThread());
2255
2256                // remove usage of deleted media objects
2257                $oldMediaObjects = ilObjMediaObject::_getMobsOfObject('frm:html', $this->objCurrentPost->getId());
2258                $curMediaObjects = ilRTE::_getMediaObjects($oReplyEditForm->getInput('message'), 0);
2259                foreach ($oldMediaObjects as $oldMob) {
2260                    $found = false;
2261                    foreach ($curMediaObjects as $curMob) {
2262                        if ($oldMob == $curMob) {
2263                            $found = true;
2264                            break;
2265                        }
2266                    }
2267                    if (!$found) {
2268                        if (ilObjMediaObject::_exists($oldMob)) {
2269                            ilObjMediaObject::_removeUsage($oldMob, 'frm:html', $this->objCurrentPost->getId());
2270                            $mob_obj = new ilObjMediaObject($oldMob);
2271                            $mob_obj->delete();
2272                        }
2273                    }
2274                }
2275
2276                // save old activation status for send_notification decision
2277                $old_status_was_active = $this->objCurrentPost->isActivated();
2278
2279                // if active post has been edited posting mus be activated again by moderator
2280                $status = 1;
2281                $send_activation_mail = 0;
2282
2283                if ($this->objProperties->isPostActivationEnabled()) {
2284                    if (!$this->is_moderator) {
2285                        $status = 0;
2286                        $send_activation_mail = 1;
2287                    } elseif ($this->objCurrentPost->isAnyParentDeactivated()) {
2288                        $status = 0;
2289                    }
2290                }
2291                $this->objCurrentPost->setStatus($status);
2292
2293                $this->objCurrentPost->setSubject($this->handleFormInput($oReplyEditForm->getInput('subject'), false));
2294                $this->objCurrentPost->setMessage(ilRTE::_replaceMediaObjectImageSrc($oReplyEditForm->getInput('message'), 0));
2295                $this->objCurrentPost->setNotification((int) $oReplyEditForm->getInput('notify'));
2296                $this->objCurrentPost->setChangeDate(date('Y-m-d H:i:s'));
2297                $this->objCurrentPost->setUpdateUserId($this->user->getId());
2298
2299                // edit: update post
2300                if ($this->objCurrentPost->update()) {
2301                    $this->objCurrentPost->reload();
2302
2303                    // Change news item accordingly
2304                    // note: $this->objCurrentPost->getForumId() does not give us the forum ID here (why?)
2305                    $news_id = ilNewsItem::getFirstNewsIdForContext(
2306                        $forumObj->getId(),
2307                        'frm',
2308                        $this->objCurrentPost->getId(),
2309                        'pos'
2310                    );
2311                    if ($news_id > 0) {
2312                        $news_item = new ilNewsItem($news_id);
2313                        $news_item->setTitle($this->objCurrentPost->getSubject());
2314                        $news_item->setContent(
2315                            ilRTE::_replaceMediaObjectImageSrc($frm->prepareText(
2316                                $this->objCurrentPost->getMessage(),
2317                                0
2318                            ), 1)
2319                        );
2320
2321                        if ($this->objCurrentPost->getMessage() != strip_tags($this->objCurrentPost->getMessage())) {
2322                            $news_item->setContentHtml(true);
2323                        } else {
2324                            $news_item->setContentHtml(false);
2325                        }
2326                        $news_item->update();
2327                    }
2328
2329                    $oFDForum = $oForumObjects['file_obj'];
2330
2331                    $file2delete = $oReplyEditForm->getInput('del_file');
2332                    if (is_array($file2delete) && count($file2delete)) {
2333                        $oFDForum->unlinkFilesByMD5Filenames($file2delete);
2334                    }
2335
2336                    if ($this->objProperties->isFileUploadAllowed()) {
2337                        $file = $_FILES['userfile'];
2338                        if (is_array($file) && !empty($file)) {
2339                            $oFDForum->storeUploadedFile($file);
2340                        }
2341                    }
2342
2343                    $GLOBALS['ilAppEventHandler']->raise(
2344                        'Modules/Forum',
2345                        'updatedPost',
2346                        array(
2347                            'ref_id' => $this->object->getRefId(),
2348                            'post' => $this->objCurrentPost,
2349                            'notify_moderators' => (bool) $send_activation_mail,
2350                            'old_status_was_active' => (bool) $old_status_was_active
2351                        )
2352                    );
2353
2354                    ilUtil::sendSuccess($this->lng->txt('forums_post_modified'), true);
2355                }
2356
2357                $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
2358                $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
2359                $this->ctrl->setParameter($this, 'viewmode', $_SESSION['viewmode']);
2360                $this->ctrl->redirect($this, 'viewThread');
2361            }
2362        } else {
2363            $this->requestAction = substr($this->requestAction, 6);
2364        }
2365        return $this->viewThreadObject();
2366    }
2367
2368    private function hideToolbar($a_flag = null)
2369    {
2370        if (null === $a_flag) {
2371            return $this->hideToolbar;
2372        }
2373
2374        $this->hideToolbar = $a_flag;
2375        return $this;
2376    }
2377
2378    public function quotePostObject()
2379    {
2380        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
2381            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
2382        }
2383
2384        if (!is_array($_POST['del_file'])) {
2385            $_POST['del_file'] = array();
2386        }
2387
2388        if ($this->objCurrentTopic->isClosed()) {
2389            $this->requestAction = '';
2390            return $this->viewThreadObject();
2391        }
2392
2393        $oReplyEditForm = $this->getReplyEditForm();
2394
2395        // remove mandatory fields
2396        $oReplyEditForm->getItemByPostVar('subject')->setRequired(false);
2397        $oReplyEditForm->getItemByPostVar('message')->setRequired(false);
2398
2399        $oReplyEditForm->checkInput();
2400
2401        // add mandatory fields
2402        $oReplyEditForm->getItemByPostVar('subject')->setRequired(true);
2403        $oReplyEditForm->getItemByPostVar('message')->setRequired(true);
2404
2405        $this->requestAction = 'showreply';
2406
2407        $this->viewThreadObject();
2408    }
2409
2410    public function getQuotationHTMLAsynchObject()
2411    {
2412        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
2413            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
2414        }
2415
2416        $this->ensureThreadBelongsToForum((int) $this->object->getId(), $this->objCurrentPost->getThread());
2417
2418        $oForumObjects = $this->getForumObjects();
2419        /**
2420         * @var $frm ilForum
2421         */
2422        $frm = $oForumObjects['frm'];
2423
2424        $authorinfo = new ilForumAuthorInformation(
2425            $this->objCurrentPost->getPosAuthorId(),
2426            $this->objCurrentPost->getDisplayUserId(),
2427            $this->objCurrentPost->getUserAlias(),
2428            $this->objCurrentPost->getImportName()
2429        );
2430
2431        $html = ilRTE::_replaceMediaObjectImageSrc($frm->prepareText($this->objCurrentPost->getMessage(), 1, $authorinfo->getAuthorName()), 1);
2432        echo $html;
2433        exit();
2434    }
2435
2436    private function getForumObjects()
2437    {
2438        if (null === $this->forumObjects) {
2439            $forumObj = $this->object;
2440            $file_obj = new ilFileDataForum($forumObj->getId(), $this->objCurrentPost->getId());
2441            $frm = $forumObj->Forum;
2442            $frm->setForumId($forumObj->getId());
2443            $frm->setForumRefId($forumObj->getRefId());
2444
2445            $this->forumObjects['forumObj'] = $forumObj;
2446            $this->forumObjects['frm'] = $frm;
2447            $this->forumObjects['file_obj'] = $file_obj;
2448        }
2449
2450        return $this->forumObjects;
2451    }
2452
2453    public function viewThreadObject()
2454    {
2455        $bottom_toolbar = clone $this->toolbar;
2456        $bottom_toolbar_split_button_items = array();
2457
2458
2459        $this->tpl->addCss('./Modules/Forum/css/forum_tree.css');
2460        if (!isset($_SESSION['viewmode'])) {
2461            $_SESSION['viewmode'] = $this->objProperties->getDefaultView();
2462        }
2463
2464        // quick and dirty: check for treeview
2465        if (!isset($_SESSION['thread_control']['old'])) {
2466            $_SESSION['thread_control']['old'] = $_GET['thr_pk'];
2467            $_SESSION['thread_control']['new'] = $_GET['thr_pk'];
2468        } elseif (isset($_SESSION['thread_control']['old']) && $_GET['thr_pk'] != $_SESSION['thread_control']['old']) {
2469            $_SESSION['thread_control']['new'] = $_GET['thr_pk'];
2470        }
2471
2472        if (isset($_GET['viewmode']) && $_GET['viewmode'] != $_SESSION['viewmode']) {
2473            $_SESSION['viewmode'] = $_GET['viewmode'];
2474        }
2475
2476        if ((strlen($this->requestAction) > 0 && $_SESSION['viewmode'] != ilForumProperties::VIEW_DATE)
2477        || ($_SESSION['viewmode'] == ilForumProperties::VIEW_TREE)) {
2478            $_SESSION['viewmode'] = ilForumProperties::VIEW_TREE;
2479        } else {
2480            $_SESSION['viewmode'] = ilForumProperties::VIEW_DATE;
2481        }
2482
2483        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
2484            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
2485        }
2486
2487        // init objects
2488        $oForumObjects = $this->getForumObjects();
2489        /**
2490         * @var $forumObj ilObjForum
2491         */
2492        $forumObj = $oForumObjects['forumObj'];
2493        /**
2494         * @var $frm ilForum
2495         */
2496        $frm = $oForumObjects['frm'];
2497        /**
2498         * @var $file_obj ilFileDataForum
2499         */
2500        $file_obj = $oForumObjects['file_obj'];
2501
2502        $selected_draft_id = (int) ($this->httpRequest->getQueryParams()['draft_id'] ?? 0);
2503
2504        if (isset($this->httpRequest->getQueryParams()['file'])) {
2505            $file_obj_for_delivery = $file_obj;
2506            if (ilForumPostDraft::isSavePostDraftAllowed() && $selected_draft_id > 0) {
2507                $file_obj_for_delivery = new ilFileDataForumDrafts($forumObj->getId(), $selected_draft_id);
2508            }
2509            $file_obj_for_delivery->deliverFile(\ilUtil::stripSlashes($this->httpRequest->getQueryParams()['file']));
2510        }
2511
2512        if (!$this->objCurrentTopic->getId()) {
2513            $this->ctrl->redirect($this, 'showThreads');
2514        }
2515
2516        $this->ensureThreadBelongsToForum((int) $this->object->getId(), $this->objCurrentTopic);
2517
2518        // Set context for login
2519        $append = '_' . $this->objCurrentTopic->getId() .
2520            ($this->objCurrentPost->getId() ? '_' . $this->objCurrentPost->getId() : '');
2521        $this->tpl->setLoginTargetPar('frm_' . $_GET['ref_id'] . $append);
2522
2523        // delete temporary media object (not in case a user adds media objects and wants to save an invalid form)
2524        if (!in_array($this->requestAction, ['showreply', 'showedit'])) {
2525            try {
2526                $mobs = ilObjMediaObject::_getMobsOfObject('frm~:html', $this->user->getId());
2527                foreach ($mobs as $mob) {
2528                    if (ilObjMediaObject::_exists($mob)) {
2529                        ilObjMediaObject::_removeUsage($mob, 'frm~:html', $this->user->getId());
2530                        $mob_obj = new ilObjMediaObject($mob);
2531                        $mob_obj->delete();
2532                    }
2533                }
2534            } catch (Exception $e) {
2535            }
2536        }
2537
2538        $firstNodeInThread = $this->objCurrentTopic->getFirstPostNode($this->is_moderator, true);
2539
2540        if ($this->isHierarchicalView() && $firstNodeInThread) {
2541            $exp = new ilForumExplorerGUI('frm_exp_' . $this->objCurrentTopic->getId(), $this, 'viewThread');
2542            $exp->setThread($this->objCurrentTopic, $firstNodeInThread);
2543            if (!$exp->handleCommand()) {
2544                $this->tpl->setLeftNavContent($exp->getHTML());
2545            }
2546        }
2547
2548        if (!$this->getCreationMode() && $this->access->checkAccess('read', '', $this->object->getRefId())) {
2549            $this->ilNavigationHistory->addItem(
2550                (int) $this->object->getRefId(),
2551                \ilLink::_getLink((int) $this->object->getRefId(), 'frm'),
2552                'frm'
2553            );
2554        }
2555
2556        // save last access
2557        $forumObj->updateLastAccess($this->user->getId(), (int) $this->objCurrentTopic->getId());
2558
2559        $this->prepareThreadScreen($forumObj);
2560
2561        $this->tpl->addBlockFile('ADM_CONTENT', 'adm_content', 'tpl.forums_threads_view.html', 'Modules/Forum');
2562
2563        if (isset($this->httpRequest->getQueryParams()['anchor'])) {
2564            $this->tpl->setVariable('JUMP2ANCHOR_ID', (int) $this->httpRequest->getQueryParams()['anchor']);
2565        }
2566        $this->tpl->setVariable('LIST_TYPE', $this->isHierarchicalView() ? 'sort_by_posts' : 'sort_by_date');
2567
2568        if ($this->isHierarchicalView()) {
2569            $orderField = 'frm_posts_tree.rgt';
2570            $this->objCurrentTopic->setOrderDirection('DESC');
2571        } else {
2572            $orderField = 'frm_posts.pos_date';
2573            $this->objCurrentTopic->setOrderDirection(
2574                in_array($this->objProperties->getDefaultView(), array(ilForumProperties::VIEW_DATE_ASC, ilForumProperties::VIEW_TREE))
2575                ? 'ASC' : 'DESC'
2576            );
2577        }
2578
2579        $posNum = 0;
2580
2581        // get forum- and thread-data
2582        $frm->setMDB2WhereCondition('top_frm_fk = %s ', array('integer'), array($frm->getForumId()));
2583
2584        if ($firstNodeInThread) {
2585            $this->objCurrentTopic->updateVisits();
2586
2587            $this->tpl->setTitle($this->lng->txt('forums_thread') . " \"" . $this->objCurrentTopic->getSubject() . "\"");
2588
2589            // build location-links
2590            $this->locator->addRepositoryItems();
2591            $this->locator->addItem($this->object->getTitle(), $this->ctrl->getLinkTarget($this, ""), "_top");
2592            $this->tpl->setLocator();
2593
2594            // set tabs
2595            // menu template (contains linkbar)
2596            /** @var $menutpl ilTemplate */
2597            $menutpl = new ilTemplate('tpl.forums_threads_menu.html', true, true, 'Modules/Forum');
2598
2599            // mark all as read
2600            if (
2601                !$this->user->isAnonymous() &&
2602                $forumObj->getCountUnread($this->user->getId(), (int) $this->objCurrentTopic->getId(), true)
2603            ) {
2604                $this->ctrl->setParameter($this, 'mark_read', '1');
2605                $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
2606
2607                $mark_thr_read_button = ilLinkButton::getInstance();
2608                $mark_thr_read_button->setCaption('forums_mark_read');
2609                $mark_thr_read_button->setUrl($this->ctrl->getLinkTarget($this, 'viewThread'));
2610                $mark_thr_read_button->setAccessKey(ilAccessKey::MARK_ALL_READ);
2611
2612                $bottom_toolbar_split_button_items[] = $mark_thr_read_button;
2613
2614                $this->ctrl->clearParameters($this);
2615            }
2616
2617            // print thread
2618            $this->ctrl->setParameterByClass('ilforumexportgui', 'print_thread', $this->objCurrentTopic->getId());
2619            $this->ctrl->setParameterByClass('ilforumexportgui', 'thr_top_fk', $this->objCurrentTopic->getForumId());
2620
2621
2622            $print_thr_button = ilLinkButton::getInstance();
2623            $print_thr_button->setCaption('forums_print_thread');
2624            $print_thr_button->setUrl($this->ctrl->getLinkTargetByClass('ilforumexportgui', 'printThread'));
2625
2626            $bottom_toolbar_split_button_items[] = $print_thr_button;
2627
2628            $this->ctrl->clearParametersByClass('ilforumexportgui');
2629
2630            $this->addHeaderAction();
2631
2632            if (isset($this->httpRequest->getQueryParams()['mark_read'])) {
2633                $forumObj->markThreadRead($this->user->getId(), (int) $this->objCurrentTopic->getId());
2634                ilUtil::sendInfo($this->lng->txt('forums_thread_marked'), true);
2635            }
2636
2637            // get complete tree of thread
2638            $this->objCurrentTopic->setOrderField($orderField);
2639            $subtree_nodes = $this->objCurrentTopic->getPostTree($firstNodeInThread);
2640
2641            if (!$this->isTopLevelReplyCommand() &&
2642                $firstNodeInThread instanceof ilForumPost &&
2643                !$this->objCurrentTopic->isClosed() &&
2644                $this->access->checkAccess('add_reply', '', (int) $_GET['ref_id'])
2645            ) {
2646                $reply_button = ilLinkButton::getInstance();
2647                $reply_button->setPrimary(true);
2648                $reply_button->setCaption('add_new_answer');
2649                $this->ctrl->setParameter($this, 'action', 'showreply');
2650                $this->ctrl->setParameter($this, 'pos_pk', $firstNodeInThread->getId());
2651                $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
2652                $this->ctrl->setParameter($this, 'offset', (int) $_GET['offset']);
2653                $this->ctrl->setParameter($this, 'orderby', $_GET['orderby']);
2654
2655                $reply_button->setUrl($this->ctrl->getLinkTarget($this, 'createTopLevelPost', 'frm_page_bottom'));
2656
2657                $this->ctrl->clearParameters($this);
2658                array_unshift($bottom_toolbar_split_button_items, $reply_button);
2659            }
2660
2661            // no posts
2662            if (!$posNum = count($subtree_nodes)) {
2663                ilUtil::sendInfo($this->lng->txt('forums_no_posts_available'));
2664            }
2665
2666            $pageHits = $frm->getPageHits();
2667
2668            $z = 0;
2669
2670            // navigation to browse
2671            if ($posNum > $pageHits) {
2672                $params = array(
2673                    'ref_id' => $_GET['ref_id'],
2674                    'thr_pk' => $this->objCurrentTopic->getId(),
2675                    'orderby' => $_GET['orderby']
2676                );
2677
2678                if (!isset($_GET['offset'])) {
2679                    $Start = 0;
2680                } else {
2681                    $Start = (int) $_GET['offset'];
2682                }
2683
2684                $linkbar = ilUtil::Linkbar($this->ctrl->getLinkTarget($this, 'viewThread'), $posNum, $pageHits, $Start, $params);
2685
2686                if ($linkbar != '') {
2687                    $menutpl->setCurrentBlock('linkbar');
2688                    $menutpl->setVariable('LINKBAR', $linkbar);
2689                    $menutpl->parseCurrentBlock();
2690                }
2691            }
2692
2693            $this->tpl->setVariable('THREAD_MENU', $menutpl->get());
2694
2695            // assistance val for anchor-links
2696            $jump = 0;
2697            $render_drafts = false;
2698            $draftsObjects = null;
2699
2700            if (ilForumPostDraft::isSavePostDraftAllowed() && !$this->user->isAnonymous()) {
2701                $draftsObjects = ilForumPostDraft::getInstancesByUserIdAndThreadId($this->user->getId(), $this->objCurrentTopic->getId());
2702                if (count($draftsObjects) > 0) {
2703                    $render_drafts = true;
2704                }
2705            }
2706
2707            foreach ($subtree_nodes as $node) {
2708                /** @var $node ilForumPost */
2709                $this->ctrl->clearParameters($this);
2710
2711                if ($this->objCurrentPost->getId() && $this->objCurrentPost->getId() == $node->getId()) {
2712                    $jump++;
2713                }
2714
2715                if ($firstNodeInThread->getId() != $this->objCurrentPost->getId() && $posNum > $pageHits && $z >= ($Start + $pageHits)) {
2716                    // if anchor-link was not found ...
2717                    if ($this->objCurrentPost->getId() && $jump < 1) {
2718                        $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
2719                        $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
2720                        $this->ctrl->setParameter($this, 'offset', ($Start + $pageHits));
2721                        $this->ctrl->setParameter($this, 'orderby', $_GET['orderby']);
2722                        $this->ctrl->redirect($this, 'viewThread', $this->objCurrentPost->getId());
2723                    } else {
2724                        break;
2725                    }
2726                }
2727
2728                if (($posNum > $pageHits && $z >= $Start) || $posNum <= $pageHits) {
2729                    if (!$this->isTopLevelReplyCommand() && $this->objCurrentPost->getId() == $node->getId()) {
2730                        # actions for "active" post
2731                        if ($this->is_moderator || $node->isActivated() || $node->isOwner($this->user->getId())) {
2732                            if (!$this->objCurrentTopic->isClosed() && in_array($this->requestAction, [
2733                                'showreply', 'showedit', 'showdraft', 'editdraft'
2734                            ])) {
2735                                $this->renderPostingForm($frm, $node, $this->requestAction);
2736                            } elseif (!$this->objCurrentTopic->isClosed() && $this->requestAction === 'delete') {
2737                                if (
2738                                    $this->is_moderator ||
2739                                    ($node->isOwner($this->user->getId()) && !$node->hasReplies()) &&
2740                                    $this->user->getId() != ANONYMOUS_USER_ID
2741                                ) {
2742                                    $this->tpl->setVariable('FORM', $this->getDeleteFormHTML());
2743                                }
2744                            } elseif (!$this->objCurrentTopic->isClosed() && $this->requestAction === 'censor') {
2745                                if ($this->is_moderator) {
2746                                    $this->tpl->setVariable('FORM', $this->getCensorshipFormHTML());
2747                                }
2748                            } elseif (!$this->objCurrentTopic->isClosed() && $this->displayConfirmPostActivation()) {
2749                                if ($this->is_moderator) {
2750                                    $this->tpl->setVariable('FORM', $this->getActivationFormHTML());
2751                                }
2752                            }
2753                        }
2754                    }
2755                    $this->renderPostContent($node, $this->requestAction, $Start, $z);
2756                    $this->renderDraftContent($this->requestAction, $render_drafts, $node, $selected_draft_id);
2757                }
2758                $z++;
2759            }
2760
2761            if ($firstNodeInThread instanceof \ilForumPost) {
2762                if (!$this->objCurrentTopic->isClosed() && in_array($this->requestAction, ['showdraft', 'editdraft'])) {
2763                    $this->renderPostingForm($frm, $firstNodeInThread, $this->requestAction);
2764                }
2765                $this->renderDraftContent($this->requestAction, $render_drafts, $firstNodeInThread, $selected_draft_id);
2766            }
2767
2768            if (
2769                $firstNodeInThread instanceof ilForumPost &&
2770                in_array($this->ctrl->getCmd(), array('createTopLevelPost', 'saveTopLevelPost')) &&
2771                !$this->objCurrentTopic->isClosed() &&
2772                $this->access->checkAccess('add_reply', '', (int) $_GET['ref_id'])) {
2773                // Important: Don't separate the following two lines (very fragile code ...)
2774                $this->objCurrentPost->setId($firstNodeInThread->getId());
2775                $form = $this->getReplyEditForm();
2776
2777                if ($this->ctrl->getCmd() == 'saveTopLevelPost') {
2778                    $form->setValuesByPost();
2779                }
2780                $this->tpl->setVariable('BOTTOM_FORM', $form->getHTML());
2781            }
2782        } else {
2783            $this->tpl->setCurrentBlock('posts_no');
2784            $this->tpl->setVariable('TXT_MSG_NO_POSTS_AVAILABLE', $this->lng->txt('forums_posts_not_available'));
2785            $this->tpl->parseCurrentBlock();
2786        }
2787
2788        if ($bottom_toolbar_split_button_items) {
2789            $bottom_split_button = ilSplitButtonGUI::getInstance();
2790            $i = 0;
2791            foreach ($bottom_toolbar_split_button_items as $item) {
2792                if ($i == 0) {
2793                    $bottom_split_button->setDefaultButton($item);
2794                } else {
2795                    $bottom_split_button->addMenuItem(new ilButtonToSplitButtonMenuItemAdapter($item));
2796                }
2797
2798                ++$i;
2799            }
2800            $bottom_toolbar->addStickyItem($bottom_split_button);
2801            $this->toolbar->addStickyItem($bottom_split_button);
2802        }
2803
2804        if ($bottom_toolbar_split_button_items) {
2805            $bottom_toolbar->addSeparator();
2806        }
2807
2808        $to_top_button = ilLinkButton::getInstance();
2809        $to_top_button->setCaption('top_of_page');
2810        $to_top_button->setUrl('#frm_page_top');
2811        $bottom_toolbar->addButtonInstance($to_top_button);
2812        if ($posNum > 0) {
2813            $this->tpl->setVariable('TOOLBAR_BOTTOM', $bottom_toolbar->getHTML());
2814        }
2815
2816        $permalink = new ilPermanentLinkGUI('frm', $this->object->getRefId(), '_' . $this->objCurrentTopic->getId());
2817        $this->tpl->setVariable('PRMLINK', $permalink->getHTML());
2818
2819        $this->tpl->addOnLoadCode('$(".ilFrmPostContent img").each(function() {
2820			var $elm = $(this);
2821			$elm.css({
2822				maxWidth: $elm.attr("width") + "px",
2823				maxHeight: $elm.attr("height")  + "px"
2824			});
2825			$elm.removeAttr("width");
2826			$elm.removeAttr("height");
2827		});');
2828
2829        return true;
2830    }
2831
2832    private function getModifiedReOnSubject($on_reply = false)
2833    {
2834        $subject = $this->objCurrentPost->getSubject();
2835        $re_txt = $this->lng->txt('post_reply');
2836
2837        $re_txt_with_num = str_replace(':', '(', $re_txt);
2838        $search_length = strlen($re_txt_with_num);
2839        $comp = substr_compare($re_txt_with_num, substr($subject, 0, $search_length), 0, $search_length);
2840
2841        if ($comp == 0) {
2842            $modified_subject = $subject;
2843            if ($on_reply == true) {
2844                // i.e. $subject = "Re(12):"
2845                $str_pos_start = strpos($subject, '(');
2846                $str_pos_end = strpos($subject, ')');
2847
2848                $length = ((int) $str_pos_end - (int) $str_pos_start);
2849                $str_pos_start++;
2850                $txt_number = substr($subject, $str_pos_start, $length - 1);
2851
2852                if (is_numeric($txt_number)) {
2853                    $re_count = (int) $txt_number + 1;
2854                    $modified_subject = substr($subject, 0, $str_pos_start) . $re_count . substr($subject, $str_pos_end);
2855                }
2856            }
2857        } else {
2858            $re_count = substr_count($subject, $re_txt);
2859            if ($re_count >= 1 && $on_reply == true) {
2860                $subject = str_replace($re_txt, '', $subject);
2861
2862                // i.e. $subject = "Re: Re: Re: ... " -> "Re(4):"
2863                $re_count++;
2864                $modified_subject = sprintf($this->lng->txt('post_reply_count'), $re_count) . ' ' . trim($subject);
2865            } elseif ($re_count >= 1 && $on_reply == false) {
2866                // possibility to modify the subject only for output
2867                // i.e. $subject = "Re: Re: Re: ... " -> "Re(3):"
2868                $modified_subject = sprintf($this->lng->txt('post_reply_count'), $re_count) . ' ' . trim($subject);
2869            } elseif ($re_count == 0) {
2870                // the first reply to a thread
2871                $modified_subject = $this->lng->txt('post_reply') . ' ' . $this->objCurrentPost->getSubject();
2872            }
2873        }
2874        return $modified_subject;
2875    }
2876
2877    public function showUserObject()
2878    {
2879        $profile_gui = new ilPublicUserProfileGUI((int) $_GET['user']);
2880        $add = $this->getUserProfileAdditional((int) $_GET['ref_id'], (int) $_GET['user']);
2881        $profile_gui->setAdditional($add);
2882        $profile_gui->setBackUrl(\ilUtil::stripSlashes($_GET['backurl']));
2883        $this->tpl->setContent($this->ctrl->getHTML($profile_gui));
2884    }
2885
2886    protected function getUserProfileAdditional($a_forum_ref_id, $a_user_id)
2887    {
2888        if (!$this->access->checkAccess('read', '', $a_forum_ref_id)) {
2889            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
2890        }
2891
2892        /**
2893         * @var $ref_obj ilObjForum
2894         */
2895        $ref_obj = ilObjectFactory::getInstanceByRefId($a_forum_ref_id);
2896        if ($ref_obj->getType() == 'frm') {
2897            $forumObj = new ilObjForum($a_forum_ref_id);
2898            $frm = $forumObj->Forum;
2899            $frm->setForumId($forumObj->getId());
2900            $frm->setForumRefId($forumObj->getRefId());
2901        } else {
2902            $frm = new ilForum();
2903        }
2904
2905        // count articles of user
2906        if ($this->access->checkAccess('moderate_frm', '', $a_forum_ref_id)) {
2907            $numPosts = $frm->countUserArticles(addslashes($a_user_id));
2908        } else {
2909            $numPosts = $frm->countActiveUserArticles(addslashes($a_user_id));
2910        }
2911
2912        return array($this->lng->txt('forums_posts') => $numPosts);
2913    }
2914
2915    public function performThreadsActionObject()
2916    {
2917        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
2918            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
2919        }
2920
2921        unset($_SESSION['threads2move']);
2922
2923        if (isset($_POST['thread_ids']) && is_array($_POST['thread_ids'])) {
2924            if (isset($_POST['selected_cmd']) && $_POST['selected_cmd'] == 'move') {
2925                if ($this->is_moderator) {
2926                    $_SESSION['threads2move'] = $_POST['thread_ids'];
2927                    $this->moveThreadsObject();
2928                }
2929            } elseif ($_POST['selected_cmd'] == 'enable_notifications' && $this->settings->get('forum_notification') != 0) {
2930                for ($i = 0; $i < count($_POST['thread_ids']); $i++) {
2931                    $tmp_obj = new ilForumTopic($_POST['thread_ids'][$i]);
2932                    $this->ensureThreadBelongsToForum((int) $this->object->getId(), $tmp_obj);
2933                    $tmp_obj->enableNotification($this->user->getId());
2934                }
2935
2936                $this->ctrl->redirect($this, 'showThreads');
2937            } elseif ($_POST['selected_cmd'] == 'disable_notifications' && $this->settings->get('forum_notification') != 0) {
2938                for ($i = 0; $i < count($_POST['thread_ids']); $i++) {
2939                    $tmp_obj = new ilForumTopic($_POST['thread_ids'][$i]);
2940                    $this->ensureThreadBelongsToForum((int) $this->object->getId(), $tmp_obj);
2941                    $tmp_obj->disableNotification($this->user->getId());
2942                }
2943
2944                $this->ctrl->redirect($this, 'showThreads');
2945            } elseif ($_POST['selected_cmd'] == 'close') {
2946                if ($this->is_moderator) {
2947                    for ($i = 0; $i < count($_POST['thread_ids']); $i++) {
2948                        $tmp_obj = new ilForumTopic($_POST['thread_ids'][$i]);
2949                        $this->ensureThreadBelongsToForum((int) $this->object->getId(), $tmp_obj);
2950                        $tmp_obj->close();
2951                    }
2952                }
2953                ilUtil::sendSuccess($this->lng->txt('selected_threads_closed'), true);
2954                $this->ctrl->redirect($this, 'showThreads');
2955            } elseif ($_POST['selected_cmd'] == 'reopen') {
2956                if ($this->is_moderator) {
2957                    for ($i = 0; $i < count($_POST['thread_ids']); $i++) {
2958                        $tmp_obj = new ilForumTopic($_POST['thread_ids'][$i]);
2959                        $this->ensureThreadBelongsToForum((int) $this->object->getId(), $tmp_obj);
2960                        $tmp_obj->reopen();
2961                    }
2962                }
2963
2964                ilUtil::sendSuccess($this->lng->txt('selected_threads_reopened'), true);
2965                $this->ctrl->redirect($this, 'showThreads');
2966            } elseif ($_POST['selected_cmd'] == 'makesticky') {
2967                if ($this->is_moderator) {
2968                    $message = $this->lng->txt('sel_threads_make_sticky');
2969
2970                    for ($i = 0; $i < count($_POST['thread_ids']); $i++) {
2971                        $tmp_obj = new ilForumTopic($_POST['thread_ids'][$i]);
2972                        $this->ensureThreadBelongsToForum((int) $this->object->getId(), $tmp_obj);
2973                        $makeSticky = $tmp_obj->makeSticky();
2974
2975                        if (!$makeSticky) {
2976                            $message = $this->lng->txt('sel_threads_already_sticky');
2977                        }
2978                    }
2979                }
2980                if ($message != null) {
2981                    ilUtil::sendInfo($message, true);
2982                }
2983                $this->ctrl->redirect($this, 'showThreads');
2984            } elseif ($_POST['selected_cmd'] == 'unmakesticky') {
2985                if ($this->is_moderator) {
2986                    $message = $this->lng->txt('sel_threads_make_unsticky');
2987                    for ($i = 0; $i < count($_POST['thread_ids']); $i++) {
2988                        $tmp_obj = new ilForumTopic($_POST['thread_ids'][$i]);
2989                        $this->ensureThreadBelongsToForum((int) $this->object->getId(), $tmp_obj);
2990                        $unmakeSticky = $tmp_obj->unmakeSticky();
2991                        if (!$unmakeSticky) {
2992                            $message = $this->lng->txt('sel_threads_already_unsticky');
2993                        }
2994                    }
2995                }
2996
2997                if ($message != null) {
2998                    ilUtil::sendInfo($message, true);
2999                }
3000                $this->ctrl->redirect($this, 'showThreads');
3001            } elseif ($_POST['selected_cmd'] == 'editThread') {
3002                if ($this->is_moderator) {
3003                    $count = count($_POST['thread_ids']);
3004                    if ($count != 1) {
3005                        ilUtil::sendInfo($this->lng->txt('select_max_one_thread'), true);
3006                        $this->ctrl->redirect($this, 'showThreads');
3007                    } else {
3008                        foreach ($_POST['thread_ids'] as $thread_id) {
3009                            return $this->editThreadObject($thread_id, null);
3010                        }
3011                    }
3012                }
3013
3014                $this->ctrl->redirect($this, 'showThreads');
3015            } elseif ($_POST['selected_cmd'] == 'html') {
3016                $this->ctrl->setCmd('exportHTML');
3017                $this->ctrl->setCmdClass('ilForumExportGUI');
3018                $this->executeCommand();
3019            } elseif ($_POST['selected_cmd'] == 'confirmDeleteThreads') {
3020                $this->confirmDeleteThreads();
3021            } elseif ($_POST['selected_cmd'] == 'merge') {
3022                $this->mergeThreadsObject();
3023            } else {
3024                ilUtil::sendInfo($this->lng->txt('topics_please_select_one_action'), true);
3025                $this->ctrl->redirect($this, 'showThreads');
3026            }
3027        } else {
3028            ilUtil::sendInfo($this->lng->txt('select_at_least_one_thread'), true);
3029            $this->ctrl->redirect($this, 'showThreads');
3030        }
3031    }
3032
3033    public function performMoveThreadsObject()
3034    {
3035        if (!$this->is_moderator) {
3036            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3037        }
3038
3039        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
3040            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3041        }
3042
3043        $threads2move = $_SESSION['threads2move'];
3044        if (!is_array($threads2move) || !count($threads2move)) {
3045            ilUtil::sendInfo($this->lng->txt('select_at_least_one_thread'), true);
3046            $this->ctrl->redirect($this, 'showThreads');
3047        }
3048
3049        if (!$this->access->checkAccess('read', '', (int) $_POST['frm_ref_id'])) {
3050            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3051        }
3052
3053        $threads = [];
3054        array_walk($threads2move, function ($threadId) use (&$threads) {
3055            $thread = new \ilForumTopic($threadId);
3056            $this->ensureThreadBelongsToForum((int) $this->object->getId(), $thread);
3057
3058            $threads[] = $threadId;
3059        });
3060
3061        if (isset($_POST['frm_ref_id']) && (int) $_POST['frm_ref_id']) {
3062            $errorMessages = $this->object->Forum->moveThreads(
3063                (array) $_SESSION['threads2move'],
3064                $this->object->getRefId(),
3065                $this->ilObjDataCache->lookupObjId($_POST['frm_ref_id'])
3066            );
3067
3068            if (array() !== $errorMessages) {
3069                \ilUtil::sendFailure(
3070                    implode("<br><br>", $errorMessages),
3071                    true
3072                );
3073                return $this->ctrl->redirectByClass('ilObjForumGUI', 'showThreads');
3074            }
3075
3076            unset($_SESSION['threads2move']);
3077            ilUtil::sendInfo($this->lng->txt('threads_moved_successfully'), true);
3078            $this->ctrl->redirect($this, 'showThreads');
3079        } else {
3080            ilUtil::sendInfo($this->lng->txt('no_forum_selected'));
3081            $this->moveThreadsObject();
3082        }
3083    }
3084
3085    public function cancelMoveThreadsObject()
3086    {
3087        unset($_SESSION['threads2move']);
3088        $this->ctrl->redirect($this, 'showThreads');
3089    }
3090
3091    public function moveThreadsObject()
3092    {
3093        if (!$this->is_moderator) {
3094            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3095        }
3096
3097        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
3098            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3099        }
3100
3101        $threads2move = $_SESSION['threads2move'];
3102        if (!is_array($threads2move) || !count($threads2move)) {
3103            ilUtil::sendInfo($this->lng->txt('select_at_least_one_thread'), true);
3104            $this->ctrl->redirect($this, 'showThreads');
3105        }
3106
3107        $threads = [];
3108        $isModerator = $this->is_moderator;
3109        array_walk($threads2move, function ($threadId) use (&$threads, $isModerator) {
3110            $thread = new \ilForumTopic($threadId, $isModerator);
3111            $this->ensureThreadBelongsToForum((int) $this->object->getId(), $thread);
3112
3113            $threads[] = $thread;
3114        });
3115
3116        $exp = new ilForumMoveTopicsExplorer($this, 'moveThreads');
3117        $exp->setPathOpen($this->object->getRefId());
3118        $exp->setNodeSelected(isset($_POST['frm_ref_id']) && (int) $_POST['frm_ref_id'] ? (int) $_POST['frm_ref_id'] : 0);
3119        $exp->setCurrentFrmRefId($this->object->getRefId());
3120        $exp->setHighlightedNode($this->object->getRefId());
3121        if (!$exp->handleCommand()) {
3122            $this->tpl->addBlockFile('ADM_CONTENT', 'adm_content', 'tpl.forums_threads_move.html', 'Modules/Forum');
3123
3124            if (!$this->hideToolbar()) {
3125                $this->toolbar->addButton($this->lng->txt('back'), $this->ctrl->getLinkTarget($this));
3126            }
3127
3128            $tblThr = new ilTable2GUI($this);
3129            $tblThr->setId('il_frm_thread_move_table_' . $this->object->getRefId());
3130            $tblThr->setTitle($this->lng->txt('move_chosen_topics'));
3131            $tblThr->addColumn($this->lng->txt('subject'), 'top_name', '100%');
3132            $tblThr->disable('header');
3133            $tblThr->disable('footer');
3134            $tblThr->disable('linkbar');
3135            $tblThr->disable('sort');
3136            $tblThr->disable('linkbar');
3137            $tblThr->setLimit(PHP_INT_MAX);
3138            $tblThr->setRowTemplate('tpl.forums_threads_move_thr_row.html', 'Modules/Forum');
3139            $tblThr->setDefaultOrderField('is_sticky');
3140            $counter = 0;
3141            $result = array();
3142            foreach ($threads as $thread) {
3143                $result[$counter]['num'] = $counter + 1;
3144                $result[$counter]['thr_subject'] = $thread->getSubject();
3145                ++$counter;
3146            }
3147            $tblThr->setData($result);
3148            $this->tpl->setVariable('THREADS_TABLE', $tblThr->getHTML());
3149
3150            $this->tpl->setVariable('FRM_SELECTION_TREE', $exp->getHTML());
3151            $this->tpl->setVariable('CMD_SUBMIT', 'performMoveThreads');
3152            $this->tpl->setVariable('TXT_SUBMIT', $this->lng->txt('move'));
3153            $this->tpl->setVariable('FORMACTION', $this->ctrl->getFormAction($this, 'performMoveThreads'));
3154        }
3155
3156        return true;
3157    }
3158
3159    private function isWritingWithPseudonymAllowed() : bool
3160    {
3161        if ($this->objProperties->isAnonymized() && (!$this->is_moderator || !$this->objProperties->getMarkModeratorPosts())) {
3162            return true;
3163        }
3164        return false;
3165    }
3166
3167    protected function deleteThreadDraftsObject()
3168    {
3169        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
3170            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3171        }
3172
3173        $draftIds = array_filter((array) ($this->httpRequest->getParsedBody()['draft_ids'] ?? []));
3174        if (0 === count($draftIds)) {
3175            $draftIds = array_filter([(int) ($this->httpRequest->getQueryParams()['draft_id'] ?? 0)]);
3176        }
3177
3178        $instances = \ilForumPostDraft::getDraftInstancesByUserId($this->user->getId());
3179        $checkedDraftIds = [];
3180        foreach ($draftIds as $draftId) {
3181            if (array_key_exists($draftId, $instances)) {
3182                $checkedDraftIds[] = $draftId;
3183                $draft = $instances[$draftId];
3184
3185                $this->deleteMobsOfDraft($draft->getDraftId(), $draft->getPostMessage());
3186
3187                $draftFileData = new \ilFileDataForumDrafts(0, $draft->getDraftId());
3188                $draftFileData->delete();
3189
3190                $GLOBALS['ilAppEventHandler']->raise(
3191                    'Modules/Forum',
3192                    'deletedDraft',
3193                    [
3194                    'draftObj' => $draft,
3195                    'obj_id' => $this->object->getId(),
3196                    'is_file_upload_allowed' => $this->objProperties->isFileUploadAllowed(),
3197                ]
3198                );
3199
3200                $draft->deleteDraft();
3201            }
3202        }
3203
3204        if (count($checkedDraftIds) > 1) {
3205            \ilUtil::sendInfo($this->lng->txt('delete_drafts_successfully'), true);
3206        } else {
3207            \ilUtil::sendInfo($this->lng->txt('delete_draft_successfully'), true);
3208        }
3209        $this->ctrl->redirect($this, 'showThreads');
3210    }
3211
3212    /**
3213     * @param bool $isDraft
3214     * @return \ilPropertyFormGUI
3215     */
3216    private function buildThreadForm($isDraft = false) : \ilPropertyFormGUI
3217    {
3218        $draftId = (int) ($this->httpRequest->getQueryParams()['draft_id'] ?? 0);
3219        $allowNotification = !$this->objProperties->isAnonymized();
3220
3221        $mail = new \ilMail($this->user->getId());
3222        if (!$this->rbac->system()->checkAccess('internal_mail', $mail->getMailObjectReferenceId())) {
3223            $allowNotification = false;
3224        }
3225
3226        $form = new \ilForumThreadFormGUI(
3227            $this,
3228            $this->objProperties,
3229            $this->isWritingWithPseudonymAllowed(),
3230            $allowNotification,
3231            $isDraft,
3232            $draftId
3233        );
3234
3235        $this->decorateWithAutosave($form);
3236
3237        return $form;
3238    }
3239
3240    protected function createThreadObject()
3241    {
3242        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
3243            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3244        }
3245
3246        if (!$this->access->checkAccess('add_thread', '', $this->object->getRefId())) {
3247            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3248        }
3249
3250        $templateForWidthHandling = new \ilTemplate('tpl.create_thread_form.html', true, true, 'Modules/Forum');
3251        $templateForWidthHandling->setVariable('CREATE_FORM', $this->buildThreadForm()->getHTML());
3252        $templateForWidthHandling->parseCurrentBlock();
3253
3254        $this->tpl->setContent($templateForWidthHandling->get());
3255    }
3256
3257    /**
3258     * Refactored thread creation to method, refactoring to a separate class should be done in next refactoring steps
3259     * @param ilForumPostDraft $draft
3260     * @param bool $createFromDraft
3261     */
3262    private function createThread(\ilForumPostDraft $draft, bool $createFromDraft = false)
3263    {
3264        if (
3265            !$this->access->checkAccess('add_thread', '', $this->object->getRefId()) ||
3266            !$this->access->checkAccess('read', '', $this->object->getRefId())
3267        ) {
3268            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3269        }
3270
3271        $frm = $this->object->Forum;
3272        $frm->setForumId($this->object->getId());
3273        $frm->setForumRefId($this->object->getRefId());
3274        $frm->setMDB2WhereCondition('top_frm_fk = %s ', array('integer'), array($frm->getForumId()));
3275        $topicData = $frm->getOneTopic();
3276
3277        $form = $this->buildThreadForm($createFromDraft);
3278        if ($form->checkInput()) {
3279            $this->doCaptchaCheck();
3280
3281            $userIdForDisplayPurposes = $this->user->getId();
3282            if ($this->isWritingWithPseudonymAllowed()) {
3283                $userIdForDisplayPurposes = 0;
3284            }
3285
3286            $status = 1;
3287            if (
3288                ($this->objProperties->isPostActivationEnabled() && !$this->is_moderator) ||
3289                $this->objCurrentPost->isAnyParentDeactivated()
3290            ) {
3291                $status = 0;
3292            }
3293
3294            if ($createFromDraft) {
3295                $newThread = new \ilForumTopic(0, true, true);
3296                $newThread->setForumId($topicData['top_pk']);
3297                $newThread->setThrAuthorId($draft->getPostAuthorId());
3298                $newThread->setDisplayUserId($draft->getPostDisplayUserId());
3299                $newThread->setSubject($this->handleFormInput($form->getInput('subject'), false));
3300                $newThread->setUserAlias($draft->getPostUserAlias());
3301
3302                $newPost = $frm->generateThread(
3303                    $newThread,
3304                    \ilRTE::_replaceMediaObjectImageSrc($form->getInput('message'), 0),
3305                    $draft->getNotify(),
3306                    $draft->getPostNotify(),
3307                    $status
3308                );
3309            } else {
3310                $userAlias = \ilForumUtil::getPublicUserAlias($form->getInput('alias'), $this->objProperties->isAnonymized());
3311                $newThread = new \ilForumTopic(0, true, true);
3312                $newThread->setForumId($topicData['top_pk']);
3313                $newThread->setThrAuthorId($this->user->getId());
3314                $newThread->setDisplayUserId($userIdForDisplayPurposes);
3315                $newThread->setSubject($this->handleFormInput($form->getInput('subject'), false));
3316                $newThread->setUserAlias($userAlias);
3317
3318                $newPost = $frm->generateThread(
3319                    $newThread,
3320                    \ilRTE::_replaceMediaObjectImageSrc($form->getInput('message'), 0),
3321                    $form->getItemByPostVar('notify') ? (int) $form->getInput('notify') : 0,
3322                    0, // #19980
3323                    $status
3324                );
3325            }
3326
3327            if ($this->objProperties->isFileUploadAllowed()) {
3328                $file = $_FILES['userfile'];
3329                if (is_array($file) && !empty($file)) {
3330                    $fileData = new \ilFileDataForum($this->object->getId(), $newPost);
3331                    $fileData->storeUploadedFile($file);
3332                }
3333            }
3334
3335            $frm->setDbTable('frm_data');
3336            $frm->setMDB2WhereCondition('top_pk = %s ', array('integer'), array($topicData['top_pk']));
3337            $frm->updateVisits($topicData['top_pk']);
3338
3339            if ($createFromDraft) {
3340                $mediaObjects = \ilObjMediaObject::_getMobsOfObject('frm~:html', $this->user->getId());
3341            } else {
3342                $mediaObjects = \ilRTE::_getMediaObjects($form->getInput('message'), 0);
3343            }
3344            foreach ($mediaObjects as $mob) {
3345                if (\ilObjMediaObject::_exists($mob)) {
3346                    \ilObjMediaObject::_removeUsage($mob, 'frm~:html', $this->user->getId());
3347                    \ilObjMediaObject::_saveUsage($mob, 'frm:html', $newPost);
3348                }
3349            }
3350
3351            if ($draft->getDraftId() > 0) {
3352                $draftHistory = new \ilForumDraftsHistory();
3353                $draftHistory->deleteHistoryByDraftIds([$draft->getDraftId()]);
3354                if ($this->objProperties->isFileUploadAllowed()) {
3355                    $forumFileData = new \ilFileDataForum($this->object->getId(), $newPost);
3356                    $draftFileData = new \ilFileDataForumDrafts($this->object->getId(), $draft->getDraftId());
3357                    $draftFileData->moveFilesOfDraft($forumFileData->getForumPath(), $newPost);
3358                }
3359                $draft->deleteDraft();
3360            }
3361
3362            $GLOBALS['ilAppEventHandler']->raise(
3363                'Modules/Forum',
3364                'createdPost',
3365                [
3366                    'ref_id' => $this->object->getRefId(),
3367                    'post' => new \ilForumPost($newPost),
3368                    'notify_moderators' => !$status
3369            ]
3370            );
3371
3372            \ilUtil::sendSuccess($this->lng->txt('forums_thread_new_entry'), true);
3373            $this->ctrl->redirect($this);
3374        }
3375
3376        $form->setValuesByPost();
3377        if (!$this->objProperties->isAnonymized()) {
3378            $form->getItemByPostVar('alias')->setValue($this->user->getLogin());
3379        }
3380
3381        $this->tpl->setContent($form->getHTML());
3382    }
3383
3384    protected function publishThreadDraftObject()
3385    {
3386        if (!ilForumPostDraft::isSavePostDraftAllowed()) {
3387            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3388        }
3389
3390        $draftId = (int) ($this->httpRequest->getQueryParams()['draft_id'] ?? 0);
3391        $draft = \ilForumPostDraft::newInstanceByDraftId($draftId);
3392
3393        if ((int) $draft->getDraftId() <= 0) {
3394            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3395        }
3396
3397        $this->createThread($draft, true);
3398    }
3399
3400    protected function addThreadObject()
3401    {
3402        $draft = new \ilForumPostDraft();
3403        if (\ilForumPostDraft::isSavePostDraftAllowed()) {
3404            $draftId = (int) ($this->httpRequest->getParsedBody()['draft_id'] ?? 0);
3405            if ($draftId > 0) {
3406                $draft = \ilForumPostDraft::newInstanceByDraftId($draftId);
3407            }
3408        }
3409
3410        $this->createThread($draft, false);
3411    }
3412
3413    protected function enableForumNotificationObject()
3414    {
3415        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
3416            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3417        }
3418
3419        $frm = $this->object->Forum;
3420        $frm->setForumId($this->object->getId());
3421        $frm->enableForumNotification($this->user->getId());
3422
3423        if ((int) $this->objCurrentTopic->getId() > 0) {
3424            $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
3425            \ilUtil::sendInfo($this->lng->txt('forums_forum_notification_enabled'), true);
3426            $this->ctrl->redirect($this, 'viewThread');
3427        }
3428
3429        \ilUtil::sendInfo($this->lng->txt('forums_forum_notification_enabled'));
3430        $this->showThreadsObject();
3431    }
3432
3433    protected function disableForumNotificationObject()
3434    {
3435        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
3436            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3437        }
3438
3439        $frm = $this->object->Forum;
3440        $frm->setForumId($this->object->getId());
3441        $frm->disableForumNotification($this->user->getId());
3442
3443        if ((int) $this->objCurrentTopic->getId() > 0) {
3444            $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
3445            \ilUtil::sendInfo($this->lng->txt('forums_forum_notification_disabled'), true);
3446            $this->ctrl->redirect($this, 'viewThread');
3447        }
3448
3449        \ilUtil::sendInfo($this->lng->txt('forums_forum_notification_disabled'));
3450        $this->showThreadsObject();
3451    }
3452
3453    /**
3454     * @inheritdoc
3455     */
3456    protected function setColumnSettings(ilColumnGUI $column_gui)
3457    {
3458        $column_gui->setBlockProperty('news', 'title', $this->lng->txt('frm_latest_postings'));
3459        $column_gui->setBlockProperty('news', 'prevent_aggregation', true);
3460        $column_gui->setRepositoryMode(true);
3461
3462        if ($this->access->checkAccess('write', '', $this->object->getRefId())) {
3463            $news_set = new \ilSetting('news');
3464            if ($news_set->get('enable_rss_for_internal')) {
3465                $column_gui->setBlockProperty('news', 'settings', true);
3466                $column_gui->setBlockProperty('news', 'public_notifications_option', true);
3467            }
3468        }
3469    }
3470
3471    /**
3472     * @inheritdoc
3473     */
3474    protected function addLocatorItems()
3475    {
3476        if ($this->object instanceof \ilObjForum) {
3477            $this->locator->addItem($this->object->getTitle(), $this->ctrl->getLinkTarget($this), '', $this->object->getRefId());
3478        }
3479    }
3480
3481    public function handleFormInput($a_text, $a_stripslashes = true)
3482    {
3483        $a_text = str_replace("<", "&lt;", $a_text);
3484        $a_text = str_replace(">", "&gt;", $a_text);
3485        if ($a_stripslashes) {
3486            $a_text = ilUtil::stripSlashes($a_text);
3487        }
3488
3489        return $a_text;
3490    }
3491
3492    public function prepareFormOutput($a_text)
3493    {
3494        $a_text = str_replace("&lt;", "<", $a_text);
3495        $a_text = str_replace("&gt;", ">", $a_text);
3496        $a_text = ilUtil::prepareFormOutput($a_text);
3497        return $a_text;
3498    }
3499
3500    protected function infoScreen()
3501    {
3502        if (
3503            !$this->access->checkAccess('visible', '', $this->object->getRefId()) &&
3504            !$this->access->checkAccess('read', '', $this->object->getRefId())
3505        ) {
3506            $this->error->raiseError($this->lng->txt('msg_no_perm_read'), $this->error->MESSAGE);
3507        }
3508
3509        $info = new \ilInfoScreenGUI($this);
3510        $info->enablePrivateNotes();
3511        $info->addMetaDataSections($this->object->getId(), 0, $this->object->getType());
3512        $this->ctrl->forwardCommand($info);
3513    }
3514
3515    /**
3516     *
3517     */
3518    protected function markPostUnreadObject()
3519    {
3520        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
3521            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3522        }
3523
3524        if ((int) $this->objCurrentPost->getId() > 0) {
3525            $this->ensureThreadBelongsToForum((int) $this->object->getId(), $this->objCurrentPost->getThread());
3526
3527            $this->object->markPostUnread($this->user->getId(), (int) $this->objCurrentPost->getId());
3528        }
3529        $this->viewThreadObject();
3530    }
3531
3532    /**
3533     *
3534     */
3535    protected function markPostReadObject()
3536    {
3537        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
3538            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3539        }
3540
3541        if ((int) $this->objCurrentTopic->getId() > 0 && (int) $this->objCurrentPost->getId() > 0) {
3542            $this->ensureThreadBelongsToForum((int) $this->object->getId(), $this->objCurrentPost->getThread());
3543
3544            $this->object->markPostRead(
3545                $this->user->getId(),
3546                (int) $this->objCurrentTopic->getId(),
3547                (int) $this->objCurrentPost->getId()
3548            );
3549        }
3550        $this->viewThreadObject();
3551    }
3552
3553    /**
3554     * @inheritdoc
3555     */
3556    protected function initHeaderAction($a_sub_type = null, $a_sub_id = null)
3557    {
3558        $lg = parent::initHeaderAction();
3559
3560        if ((int) $this->objCurrentTopic->getId() > 0) {
3561            $container_obj = null; // Workaround: Do not show "desktop actions" in thread view
3562            $lg->setContainerObject($container_obj);
3563        }
3564
3565        if (!($lg instanceof \ilObjForumListGUI) || !$this->settings->get('forum_notification')) {
3566            return $lg;
3567        }
3568
3569        if ($this->user->isAnonymous() || !$this->access->checkAccess('read', '', $this->object->getRefId())) {
3570            return $lg;
3571        }
3572
3573        $frm = $this->object->Forum;
3574        $frm->setForumId($this->object->getId());
3575        $frm->setForumRefId($this->object->getRefId());
3576        $frm->setMDB2Wherecondition('top_frm_fk = %s ', array('integer'), array($frm->getForumId()));
3577
3578        $isForumNotificationEnabled = $frm->isForumNotificationEnabled($this->user->getId());
3579        $userMayDisableNotifications = $this->isUserAllowedToDeactivateNotification();
3580
3581        if ((int) $this->objCurrentTopic->getId() > 0) {
3582            $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
3583        }
3584
3585        if ($this->isParentObjectCrsOrGrp()) {
3586            // special behaviour for CRS/GRP-Forum notification!!
3587            if ($isForumNotificationEnabled && $userMayDisableNotifications) {
3588                $lg->addCustomCommand(
3589                    $this->ctrl->getLinkTarget($this, 'disableForumNotification'),
3590                    'forums_disable_forum_notification'
3591                );
3592            } elseif (!$isForumNotificationEnabled) {
3593                $lg->addCustomCommand(
3594                    $this->ctrl->getLinkTarget($this, 'enableForumNotification'),
3595                    'forums_enable_forum_notification'
3596                );
3597            }
3598        } elseif ($isForumNotificationEnabled) {
3599            $lg->addCustomCommand(
3600                $this->ctrl->getLinkTarget($this, 'disableForumNotification'),
3601                'forums_disable_forum_notification'
3602            );
3603        } else {
3604            $lg->addCustomCommand(
3605                $this->ctrl->getLinkTarget($this, 'enableForumNotification'),
3606                'forums_enable_forum_notification'
3607            );
3608        }
3609
3610        $isThreadNotificationEnabled = false;
3611        if ((int) $this->objCurrentTopic->getId() > 0) {
3612            $isThreadNotificationEnabled = $this->objCurrentTopic->isNotificationEnabled($this->user->getId());
3613            if ($isThreadNotificationEnabled) {
3614                $lg->addCustomCommand(
3615                    $this->ctrl->getLinkTarget($this, 'toggleThreadNotification'),
3616                    'forums_disable_notification'
3617                );
3618            } else {
3619                $lg->addCustomCommand(
3620                    $this->ctrl->getLinkTarget($this, 'toggleThreadNotification'),
3621                    'forums_enable_notification'
3622                );
3623            }
3624        }
3625        $this->ctrl->setParameter($this, 'thr_pk', '');
3626
3627        if ($isForumNotificationEnabled || $isThreadNotificationEnabled) {
3628            $lg->addHeaderIcon(
3629                'not_icon',
3630                ilUtil::getImagePath('notification_on.svg'),
3631                $this->lng->txt('frm_notification_activated')
3632            );
3633        } else {
3634            $lg->addHeaderIcon(
3635                'not_icon',
3636                ilUtil::getImagePath('notification_off.svg'),
3637                $this->lng->txt('frm_notification_deactivated')
3638            );
3639        }
3640
3641        return $lg;
3642    }
3643
3644    public function isUserAllowedToDeactivateNotification()
3645    {
3646        if ($this->objProperties->getNotificationType() == 'default') {
3647            return true;
3648        }
3649
3650        if ($this->objProperties->isUserToggleNoti() == 0) {
3651            return true;
3652        }
3653
3654        if ($this->isParentObjectCrsOrGrp()) {
3655            $frm_noti = new ilForumNotification((int) $_GET['ref_id']);
3656            $frm_noti->setUserId($this->user->getId());
3657
3658            $user_toggle = (int) $frm_noti->isUserToggleNotification();
3659            if ($user_toggle == 0 && $this->objProperties->isUserToggleNoti() == 0) {
3660                return true;
3661            }
3662        }
3663
3664        return false;
3665    }
3666
3667    public function isParentObjectCrsOrGrp() : bool
3668    {
3669        $grpRefId = $this->repositoryTree->checkForParentType($this->object->getRefId(), 'grp');
3670        $crsRefId = $this->repositoryTree->checkForParentType($this->object->getRefId(), 'crs');
3671
3672        return ($grpRefId > 0 || $crsRefId > 0);
3673    }
3674
3675    /**
3676     * @inheritdoc
3677     */
3678    public function addToDeskObject()
3679    {
3680        if (!(int) $this->settings->get('disable_my_offers')) {
3681            \ilDesktopItemGUI::addToDesktop();
3682            \ilUtil::sendSuccess($this->lng->txt('added_to_desktop'));
3683        }
3684
3685        $this->showThreadsObject();
3686    }
3687
3688    /**
3689     * @inheritdoc
3690     */
3691    public function removeFromDeskObject()
3692    {
3693        if (!(int) $this->settings->get('disable_my_offers')) {
3694            \ilDesktopItemGUI::removeFromDesktop();
3695            \ilUtil::sendSuccess($this->lng->txt('removed_from_desktop'));
3696        }
3697
3698        $this->showThreadsObject();
3699    }
3700
3701    protected function saveThreadSortingObject()
3702    {
3703        if (!$this->is_moderator) {
3704            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3705        }
3706
3707        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
3708            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3709        }
3710
3711        $threadIdToSortValueMap = (array) ($this->httpRequest->getParsedBody()['thread_sorting'] ?? []);
3712
3713        array_walk($threadIdToSortValueMap, function ($sortValue, $threadId) {
3714            $this->ensureThreadBelongsToForum((int) $this->object->getId(), new \ilForumTopic($threadId));
3715        });
3716
3717        foreach ($threadIdToSortValueMap as $threadId => $sortValue) {
3718            $sortValue = str_replace(',', '.', $sortValue);
3719            $sortValue = (float) $sortValue * 100;
3720            $this->object->setThreadSorting((int) $threadId, $sortValue);
3721        }
3722
3723        \ilUtil::sendSuccess($this->lng->txt('saved_successfully'), true);
3724        $this->ctrl->redirect($this, 'showThreads');
3725    }
3726
3727    /**
3728     *
3729     */
3730    public function mergeThreadsObject()
3731    {
3732        if (!$this->is_moderator) {
3733            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3734        }
3735
3736        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
3737            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3738        }
3739
3740        $threadIdToMerge = (int) ($this->httpRequest->getQueryParams()['merge_thread_id'] ?? 0);
3741        if (!($threadIdToMerge > 0)) {
3742            $threadIds = array_values(
3743                array_filter(array_map('intval', (array) $this->httpRequest->getParsedBody()['thread_ids'] ?? []))
3744            );
3745            if (1 === count($threadIds)) {
3746                $threadIdToMerge = current($threadIds);
3747            } else {
3748                \ilUtil::sendInfo($this->lng->txt('select_one'));
3749                $this->showThreadsObject();
3750                return;
3751            }
3752        }
3753
3754        $frm = $this->object->Forum;
3755        $frm->setForumId($this->object->getId());
3756        $frm->setForumRefId($this->object->getRefId());
3757
3758        $threadToMerge = new ilForumTopic($threadIdToMerge);
3759
3760        if (\ilForum::_lookupObjIdForForumId($threadToMerge->getForumId()) != $frm->getForumId()) {
3761            \ilUtil::sendFailure($this->lng->txt('not_allowed_to_merge_into_another_forum'));
3762            $this->showThreadsObject();
3763            return;
3764        }
3765
3766        $frm->setMDB2Wherecondition('top_frm_fk = %s ', array('integer'), array($frm->getForumId()));
3767
3768        $this->tpl->addBlockFile('ADM_CONTENT', 'adm_content', 'tpl.forums_threads_liste.html', 'Modules/Forum');
3769
3770        $topicData = $frm->getOneTopic();
3771        if ($topicData) {
3772            $this->ctrl->setParameter($this, 'merge_thread_id', $threadIdToMerge);
3773            $tbl = new \ilForumTopicTableGUI(
3774                $this,
3775                'mergeThreads',
3776                '',
3777                (int) $this->httpRequest->getQueryParams()['ref_id'],
3778                $topicData,
3779                $this->is_moderator,
3780                $this->settings->get('forum_overview')
3781            );
3782            $tbl->setSelectedThread($threadToMerge);
3783            $tbl->setMapper($frm)->fetchData();
3784            $tbl->init();
3785            $this->tpl->setVariable('THREADS_TABLE', $tbl->getHTML());
3786        } else {
3787            \ilUtil::sendFailure($this->lng->txt('select_one'));
3788            $this->showThreadsObject();
3789        }
3790    }
3791
3792    /**
3793     *
3794     */
3795    public function confirmMergeThreadsObject()
3796    {
3797        if (!$this->is_moderator) {
3798            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3799        }
3800
3801        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
3802            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3803        }
3804
3805        $sourceThreadId = (int) ($this->httpRequest->getQueryParams()['merge_thread_id'] ?? 0);
3806        $targetThreadIds = array_values(
3807            array_filter(array_map('intval', (array) $this->httpRequest->getParsedBody()['thread_ids'] ?? []))
3808        );
3809
3810        if (!($sourceThreadId > 0) || 1 !== count($targetThreadIds)) {
3811            \ilUtil::sendFailure($this->lng->txt('select_one'));
3812            $this->mergeThreadsObject();
3813            return;
3814        }
3815
3816        $targetThreadId = current($targetThreadIds);
3817        if ($sourceThreadId == $targetThreadId) {
3818            \ilUtil::sendFailure($this->lng->txt('error_same_thread_ids'));
3819            $this->showThreadsObject();
3820            return;
3821        }
3822
3823        if (ilForumTopic::lookupForumIdByTopicId($sourceThreadId) != ilForumTopic::lookupForumIdByTopicId($targetThreadId)) {
3824            \ilUtil::sendFailure($this->lng->txt('not_allowed_to_merge_into_another_forum'));
3825            $this->ctrl->clearParameters($this);
3826            $this->showThreadsObject();
3827            return;
3828        }
3829
3830        if (\ilForumTopic::_lookupDate($sourceThreadId) < ilForumTopic::_lookupDate($targetThreadId)) {
3831            \ilUtil::sendInfo($this->lng->txt('switch_threads_for_merge'));
3832        }
3833
3834        $this->ensureThreadBelongsToForum((int) $this->object->getId(), new \ilForumTopic((int) $sourceThreadId));
3835        $this->ensureThreadBelongsToForum((int) $this->object->getId(), new \ilForumTopic((int) $targetThreadId));
3836
3837        $c_gui = new ilConfirmationGUI();
3838
3839        $c_gui->setFormAction($this->ctrl->getFormAction($this, 'performMergeThreads'));
3840        $c_gui->setHeaderText($this->lng->txt('frm_sure_merge_threads'));
3841        $c_gui->setCancel($this->lng->txt('cancel'), 'showThreads');
3842        $c_gui->setConfirm($this->lng->txt('confirm'), 'performMergeThreads');
3843
3844        $c_gui->addItem(
3845            'thread_ids[]',
3846            $sourceThreadId,
3847            sprintf($this->lng->txt('frm_merge_src'), ilForumTopic::_lookupTitle($sourceThreadId))
3848        );
3849        $c_gui->addItem(
3850            'thread_ids[]',
3851            $targetThreadId,
3852            sprintf($this->lng->txt('frm_merge_target'), ilForumTopic::_lookupTitle($targetThreadId))
3853        );
3854        $this->tpl->setContent($c_gui->getHTML());
3855    }
3856
3857    /**
3858     *
3859     */
3860    public function performMergeThreadsObject()
3861    {
3862        if (!$this->is_moderator) {
3863            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3864        }
3865
3866        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
3867            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3868        }
3869
3870        $threadIds = array_values(
3871            array_filter(array_map('intval', (array) $this->httpRequest->getParsedBody()['thread_ids'] ?? []))
3872        );
3873        if (2 !== count($threadIds)) {
3874            ilUtil::sendFailure($this->lng->txt('select_one'));
3875            $this->showThreadsObject();
3876            return;
3877        }
3878
3879        if ((int) $threadIds[0] === (int) $threadIds[1]) {
3880            ilUtil::sendFailure($this->lng->txt('error_same_thread_ids'));
3881            $this->showThreadsObject();
3882            return;
3883        }
3884
3885        try {
3886            $frm = new \ilForum();
3887            $frm->setForumId($this->object->getId());
3888            $frm->setForumRefId($this->object->getRefId());
3889
3890            $this->ensureThreadBelongsToForum((int) $this->object->getId(), new \ilForumTopic((int) $threadIds[0]));
3891            $this->ensureThreadBelongsToForum((int) $this->object->getId(), new \ilForumTopic((int) $threadIds[1]));
3892
3893            $frm->mergeThreads((int) $threadIds[0], (int) $threadIds[1]);
3894            \ilUtil::sendSuccess($this->lng->txt('merged_threads_successfully'));
3895        } catch (\ilException $e) {
3896            \ilUtil::sendFailure($this->lng->txt($e->getMessage()));
3897        }
3898
3899        $this->showThreadsObject();
3900    }
3901
3902    /**
3903     *
3904     */
3905    protected function setSideBlocks()
3906    {
3907        $content = $this->getRightColumnHTML();
3908        if (!$this->ctrl->isAsynch()) {
3909            $content = implode('', [
3910                \ilRepositoryObjectSearchGUI::getSearchBlockHTML($this->lng->txt('frm_search')),
3911                $content,
3912            ]);
3913        }
3914        $this->tpl->setRightContent($content);
3915    }
3916
3917    /**
3918     *
3919     */
3920    protected function deliverDraftZipFileObject()
3921    {
3922        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
3923            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3924        }
3925
3926        $draftId = $this->httpRequest->getQueryParams()['draft_id'] ?? 0;
3927        $draft = \ilForumPostDraft::newInstanceByDraftId((int) $draftId);
3928        if ($draft->getPostAuthorId() == $this->user->getId()) {
3929            $fileData = new \ilFileDataForumDrafts(0, $draft->getDraftId());
3930            if (!$fileData->deliverZipFile()) {
3931                $this->ctrl->redirect($this);
3932            }
3933        }
3934    }
3935
3936    /**
3937     *
3938     */
3939    protected function deliverZipFileObject()
3940    {
3941        if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
3942            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3943        }
3944
3945        $this->ensureThreadBelongsToForum((int) $this->object->getId(), $this->objCurrentPost->getThread());
3946
3947        $fileData = new \ilFileDataForum($this->object->getId(), $this->objCurrentPost->getId());
3948        if (!$fileData->deliverZipFile()) {
3949            $this->ctrl->redirect($this);
3950        }
3951    }
3952
3953    /**
3954     * @param ilPropertyFormGUI|null $form
3955     */
3956    protected function editThreadDraftObject(\ilPropertyFormGUI $form = null)
3957    {
3958        if (
3959            !$this->access->checkAccess('add_thread', '', $this->object->getRefId()) ||
3960            !$this->access->checkAccess('read', '', $this->object->getRefId()) ||
3961            !\ilForumPostDraft::isSavePostDraftAllowed()
3962        ) {
3963            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
3964        }
3965
3966        $frm = $this->object->Forum;
3967        $frm->setForumId($this->object->getId());
3968        $frm->setForumRefId($this->object->getRefId());
3969
3970        $draft = new \ilForumPostDraft();
3971        $draftId = (int) ($this->httpRequest->getQueryParams()['draft_id'] ?? 0);
3972        if ($draftId > 0) {
3973            $draft = $draft->newInstanceByDraftId($draftId);
3974        }
3975
3976        $historyCheck = (int) ($this->httpRequest->getQueryParams()['hist_check'] ?? 1);
3977        if (!($form instanceof \ilPropertyFormGUI) && $historyCheck > 0) {
3978            $this->doHistoryCheck($draft->getDraftId());
3979        }
3980
3981        if (!$form instanceof \ilPropertyFormGUI) {
3982            $form = $this->buildThreadForm(true);
3983            $form->setValuesByArray([
3984                'alias' => $draft->getPostUserAlias(),
3985                'subject' => $draft->getPostSubject(),
3986                'message' => \ilRTE::_replaceMediaObjectImageSrc($frm->prepareText($draft->getPostMessage(), 2), 1),
3987                'notify' => $draft->getNotify() ? true : false,
3988                'userfile' => '',
3989                'del_file' => []
3990            ]);
3991        } else {
3992            $this->ctrl->setParameter($this, 'draft_id', $draftId);
3993        }
3994
3995        $this->tpl->setContent($form->getHTML() . $this->modal_history);
3996    }
3997
3998    protected function restoreFromHistoryObject()
3999    {
4000        $historyId = (int) ($this->httpRequest->getQueryParams()['history_id'] ?? 0);
4001        $history = new \ilForumDraftsHistory($historyId);
4002
4003        $draft = $history->rollbackAutosave();
4004        if ($draft->getThreadId() == 0 && $draft->getPostId() == 0) {
4005            $this->ctrl->setParameter($this, 'draft_id', $history->getDraftId());
4006            $this->ctrl->redirect($this, 'editThreadDraft');
4007        }
4008
4009        $this->ctrl->clearParameters($this);
4010        $this->ctrl->setParameter($this, 'pos_pk', $draft->getPostId());
4011        $this->ctrl->setParameter($this, 'thr_pk', $draft->getThreadId());
4012        $this->ctrl->setParameter($this, 'draft_id', $draft->getDraftId());
4013        $this->ctrl->setParameter($this, 'action', 'editdraft');
4014
4015        // create draft backup before redirect!
4016        \ilForumPostDraft::createDraftBackup((int) $draft->getDraftId());
4017
4018        $this->ctrl->redirect($this, 'viewThread');
4019    }
4020
4021    protected function saveThreadAsDraftObject()
4022    {
4023        if (
4024            !$this->access->checkAccess('add_thread', '', $this->object->getRefId()) ||
4025            !$this->access->checkAccess('read', '', $this->object->getRefId()) ||
4026            !\ilForumPostDraft::isSavePostDraftAllowed()
4027        ) {
4028            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4029        }
4030
4031        $autoSavedDraftId = (int) ($this->httpRequest->getParsedBody()['draft_id'] ?? 0);
4032        if ($autoSavedDraftId <= 0) {
4033            $autoSavedDraftId = (int) ($this->httpRequest->getQueryParams()['draft_id'] ?? 0);
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 ', array('integer'), array($frm->getForumId()));
4040        $topicData = $frm->getOneTopic();
4041
4042        $form = $this->buildThreadForm();
4043        if ($form->checkInput()) {
4044            $this->doCaptchaCheck();
4045
4046            if (0 === $autoSavedDraftId) {
4047                $draft = new \ilForumPostDraft();
4048            } else {
4049                $draft = \ilForumPostDraft::newInstanceByDraftId($autoSavedDraftId);
4050            }
4051
4052            $draft->setForumId($topicData['top_pk']);
4053            $draft->setThreadId(0);
4054            $draft->setPostId(0);
4055            $draft->setPostSubject($this->handleFormInput($form->getInput('subject'), false));
4056            $draft->setPostMessage(\ilRTE::_replaceMediaObjectImageSrc($form->getInput('message'), 0));
4057            $userAlias = \ilForumUtil::getPublicUserAlias($form->getInput('alias'), $this->objProperties->isAnonymized());
4058            $draft->setPostUserAlias($userAlias);
4059            $draft->setNotify((int) $form->getInput('notify'));
4060            $draft->setPostAuthorId($this->user->getId());
4061            $draft->setPostDisplayUserId(($this->objProperties->isAnonymized() ? 0 : $this->user->getId()));
4062
4063            if (0 === $autoSavedDraftId) {
4064                $draftId = $draft->saveDraft();
4065            } else {
4066                $draft->updateDraft();
4067                $draftId = $draft->getDraftId();
4068            }
4069
4070            $GLOBALS['ilAppEventHandler']->raise(
4071                'Modules/Forum',
4072                'savedAsDraft',
4073                [
4074                'draftObj' => $draft,
4075                'obj_id' => $this->object->getId(),
4076                'is_file_upload_allowed' => $this->objProperties->isFileUploadAllowed(),
4077            ]
4078            );
4079
4080            \ilForumUtil::moveMediaObjects($form->getInput('message'), 'frm~d:html', $draftId, 'frm~d:html', $draftId);
4081
4082            $draftFileData = new \ilFileDataForumDrafts($this->object->getId(), $draftId);
4083
4084            $files2delete = $form->getInput('del_file');
4085            if (is_array($files2delete) && count($files2delete) > 0) {
4086                $draftFileData->unlinkFilesByMD5Filenames($files2delete);
4087            }
4088
4089            if ($this->objProperties->isFileUploadAllowed()) {
4090                $file = $_FILES['userfile'];
4091                if (is_array($file) && !empty($file)) {
4092                    $draftFileData->storeUploadedFile($file);
4093                }
4094            }
4095
4096            \ilUtil::sendSuccess($this->lng->txt('save_draft_successfully'), true);
4097            $this->ctrl->clearParameters($this);
4098            $this->ctrl->redirect($this, 'showThreads');
4099        }
4100
4101        $this->requestAction = substr($this->requestAction, 6); // @nmatuschek: Why this, I don't get it???
4102        $form->setValuesByPost();
4103        $this->ctrl->setParameter($this, 'draft_id', $autoSavedDraftId);
4104        $this->tpl->setContent($form->getHTML());
4105    }
4106
4107    protected function updateThreadDraftObject()
4108    {
4109        if (
4110            !$this->access->checkAccess('add_thread', '', $this->object->getRefId()) ||
4111            !$this->access->checkAccess('read', '', $this->object->getRefId()) ||
4112            !\ilForumPostDraft::isSavePostDraftAllowed()
4113        ) {
4114            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4115        }
4116
4117        $draftId = (int) ($this->httpRequest->getQueryParams()['draft_id'] ?? 0);
4118        if ($draftId <= 0) {
4119            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4120        }
4121
4122        $form = $this->buildThreadForm(true);
4123        if ($form->checkInput()) {
4124            $this->doCaptchaCheck();
4125
4126            $userAlias = \ilForumUtil::getPublicUserAlias($form->getInput('alias'), $this->objProperties->isAnonymized());
4127
4128            $draft = \ilForumPostDraft::newInstanceByDraftId($draftId);
4129            $draft->setPostSubject($this->handleFormInput($form->getInput('subject'), false));
4130            $draft->setPostMessage(\ilRTE::_replaceMediaObjectImageSrc($form->getInput('message'), 0));
4131            $draft->setPostUserAlias($userAlias);
4132            $draft->setNotify((int) $form->getInput('notify'));
4133            $draft->setPostAuthorId($this->user->getId());
4134            $draft->setPostDisplayUserId(($this->objProperties->isAnonymized() ? 0 : $this->user->getId()));
4135            $draft->updateDraft();
4136
4137            $GLOBALS['ilAppEventHandler']->raise(
4138                'Modules/Forum',
4139                'updatedDraft',
4140                [
4141                    'draftObj' => $draft,
4142                    'obj_id' => $this->object->getId(),
4143                    'is_file_upload_allowed' => $this->objProperties->isFileUploadAllowed(),
4144            ]
4145            );
4146
4147            \ilForumUtil::moveMediaObjects(
4148                $form->getInput('message'),
4149                'frm~d:html',
4150                $draft->getDraftId(),
4151                'frm~d:html',
4152                $draft->getDraftId()
4153            );
4154
4155            $draftFileData = new \ilFileDataForumDrafts($this->object->getId(), $draft->getDraftId());
4156
4157            $files2delete = $form->getInput('del_file');
4158            if (is_array($files2delete) && count($files2delete) > 0) {
4159                $draftFileData->unlinkFilesByMD5Filenames($files2delete);
4160            }
4161
4162            if ($this->objProperties->isFileUploadAllowed()) {
4163                $file = $_FILES['userfile'];
4164                if (is_array($file) && !empty($file)) {
4165                    $draftFileData->storeUploadedFile($file);
4166                }
4167            }
4168
4169            \ilUtil::sendSuccess($this->lng->txt('save_draft_successfully'), true);
4170            $this->ctrl->clearParameters($this);
4171            $this->ctrl->redirect($this, 'showThreads');
4172        }
4173
4174        $form->setValuesByPost();
4175        $this->ctrl->setParameter($this, 'hist_check', 0);
4176        $this->ctrl->setParameter($this, 'draft_id', $draftId);
4177        $this->editThreadDraftObject($form);
4178    }
4179
4180    public function saveAsDraftObject()
4181    {
4182        if (!$this->objCurrentTopic->getId()) {
4183            \ilUtil::sendFailure($this->lng->txt('frm_action_not_possible_thr_deleted'), true);
4184            $this->ctrl->redirect($this);
4185        }
4186
4187        if ($this->objCurrentTopic->isClosed()) {
4188            \ilUtil::sendFailure($this->lng->txt('frm_action_not_possible_thr_closed'), true);
4189            $this->ctrl->redirect($this);
4190        }
4191
4192        if (!isset($_POST['del_file']) || !is_array($_POST['del_file'])) {
4193            $_POST['del_file'] = array();
4194        }
4195
4196        $autosave_draft_id = 0;
4197        if (ilForumPostDraft::isAutoSavePostDraftAllowed() && isset($_POST['draft_id'])) {
4198            $autosave_draft_id = (int) $_POST['draft_id'];
4199        }
4200        $oReplyEditForm = $this->getReplyEditForm();
4201        if ($oReplyEditForm->checkInput()) {
4202            if (!$this->objCurrentPost->getId()) {
4203                $this->requestAction = '';
4204                \ilUtil::sendFailure($this->lng->txt('frm_action_not_possible_parent_deleted'));
4205                $this->viewThreadObject();
4206                return;
4207            }
4208
4209            $this->doCaptchaCheck();
4210
4211            // init objects
4212            $oForumObjects = $this->getForumObjects();
4213            /**
4214             * @var $forumObj ilObjForum
4215             */
4216            $forumObj = $oForumObjects['forumObj'];
4217            /**
4218             * @var $frm ilForum
4219             */
4220            $frm = $oForumObjects['frm'];
4221            $frm->setMDB2WhereCondition(' top_frm_fk = %s ', array('integer'), array($frm->getForumId()));
4222            $topicData = $frm->getOneTopic();
4223
4224            // Generating new posting
4225            if ($this->requestAction == 'ready_showreply') {
4226                if (!$this->access->checkAccess('add_reply', '', (int) $_GET['ref_id'])) {
4227                    $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4228                }
4229
4230                $user_alias = ilForumUtil::getPublicUserAlias($oReplyEditForm->getInput('alias'), $this->objProperties->isAnonymized());
4231
4232                if ($autosave_draft_id == 0) {
4233                    $draftObj = new ilForumPostDraft();
4234                } else {
4235                    $draftObj = ilForumPostDraft::newInstanceByDraftId($autosave_draft_id);
4236                }
4237                $draftObj->setForumId($topicData['top_pk']);
4238                $draftObj->setThreadId($this->objCurrentTopic->getId());
4239                $draftObj->setPostId($this->objCurrentPost->getId());
4240
4241                $draftObj->setPostSubject($this->handleFormInput($oReplyEditForm->getInput('subject'), false));
4242                $draftObj->setPostMessage(ilRTE::_replaceMediaObjectImageSrc($oReplyEditForm->getInput('message'), 0));
4243                $draftObj->setPostUserAlias($user_alias);
4244                $draftObj->setNotify((int) $oReplyEditForm->getInput('notify'));
4245                $draftObj->setPostNotify((int) $oReplyEditForm->getInput('notify_post'));
4246
4247                $draftObj->setPostAuthorId($this->user->getId());
4248                $draftObj->setPostDisplayUserId(($this->objProperties->isAnonymized() ? 0 : $this->user->getId()));
4249
4250                if ($autosave_draft_id == 0) {
4251                    $draft_id = $draftObj->saveDraft();
4252                } else {
4253                    $draftObj->updateDraft();
4254                    $draft_id = $draftObj->getDraftId();
4255                }
4256
4257
4258                if (ilForumPostDraft::isSavePostDraftAllowed()) {
4259                    $GLOBALS['ilAppEventHandler']->raise(
4260                        'Modules/Forum',
4261                        'savedAsDraft',
4262                        array('draftObj' => $draftObj,
4263                                  'obj_id' => $this->object->getId(),
4264                                  'is_file_upload_allowed' => $this->objProperties->isFileUploadAllowed())
4265                    );
4266                }
4267
4268                if ($this->objProperties->isFileUploadAllowed()) {
4269                    $file = $_FILES['userfile'];
4270                    if (is_array($file) && !empty($file)) {
4271                        $oFDForumDrafts = new ilFileDataForumDrafts($this->object->getId(), $draftObj->getDraftId());
4272                        $oFDForumDrafts->storeUploadedFile($file);
4273                    }
4274                }
4275
4276                // copy temporary media objects (frm~)
4277                ilForumUtil::moveMediaObjects($oReplyEditForm->getInput('message'), 'frm~d:html', $draft_id, 'frm~d:html', $draft_id);
4278
4279                $_SESSION['frm'][(int) $_GET['thr_pk']]['openTreeNodes'][] = (int) $this->objCurrentPost->getId();
4280
4281                ilUtil::sendSuccess($this->lng->txt('save_draft_successfully'), true);
4282                $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
4283                $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
4284                $this->ctrl->redirect($this, 'viewThread');
4285            }
4286        } else {
4287            $oReplyEditForm->setValuesByPost();
4288            $this->requestAction = substr($this->requestAction, 6);
4289        }
4290        return $this->viewThreadObject();
4291    }
4292
4293    protected function editDraftObject()
4294    {
4295        if (\ilForumPostDraft::isAutoSavePostDraftAllowed()) {
4296            $draftId = (int) ($this->httpRequest->getQueryParams()['draft_id'] ?? 0);
4297            if ($this->checkDraftAccess($draftId)) {
4298                $this->doHistoryCheck($draftId);
4299            }
4300        }
4301
4302        $this->viewThreadObject();
4303    }
4304
4305    /**
4306     *
4307     */
4308    public function updateDraftObject()
4309    {
4310        if (!$this->objCurrentTopic->getId()) {
4311            \ilUtil::sendFailure($this->lng->txt('frm_action_not_possible_thr_deleted'), true);
4312            $this->ctrl->redirect($this);
4313        }
4314
4315        if ($this->objCurrentTopic->isClosed()) {
4316            \ilUtil::sendFailure($this->lng->txt('frm_action_not_possible_thr_closed'), true);
4317            $this->ctrl->redirect($this);
4318        }
4319
4320        if (!$this->objCurrentPost->getId()) {
4321            $this->requestAction = '';
4322            \ilUtil::sendFailure($this->lng->txt('frm_action_not_possible_parent_deleted'));
4323            $this->viewThreadObject();
4324            return;
4325        }
4326
4327        if (!isset($_POST['del_file']) || !is_array($_POST['del_file'])) {
4328            $_POST['del_file'] = array();
4329        }
4330
4331        $oReplyEditForm = $this->getReplyEditForm();
4332        if ($oReplyEditForm->checkInput()) {
4333            $this->doCaptchaCheck();
4334
4335            // init objects
4336            $oForumObjects = $this->getForumObjects();
4337            /**
4338             * @var $forumObj ilObjForum
4339             */
4340            $forumObj = $oForumObjects['forumObj'];
4341
4342            if (!$this->user->isAnonymous() && in_array($this->requestAction, ['showdraft', 'editdraft'])) {
4343                if (!$this->access->checkAccess('add_reply', '', (int) $_GET['ref_id'])) {
4344                    $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4345                }
4346
4347                $user_alias = ilForumUtil::getPublicUserAlias($oReplyEditForm->getInput('alias'), $this->objProperties->isAnonymized());
4348
4349                // generateDraft
4350                $update_draft = new ilForumPostDraft($this->user->getId(), $this->objCurrentPost->getId(), (int) $_GET['draft_id']);
4351
4352                $update_draft->setPostSubject($this->handleFormInput($oReplyEditForm->getInput('subject'), false));
4353                $update_draft->setPostMessage(ilRTE::_replaceMediaObjectImageSrc($oReplyEditForm->getInput('message'), 0));
4354                $update_draft->setPostUserAlias($user_alias);
4355                $update_draft->setNotify((int) $oReplyEditForm->getInput('notify'));
4356                $update_draft->setUpdateUserId($this->user->getId());
4357                $update_draft->setPostAuthorId($this->user->getId());
4358                $update_draft->setPostDisplayUserId(($this->objProperties->isAnonymized() ? 0 : $this->user->getId()));
4359
4360                $update_draft->updateDraft();
4361
4362                if (ilForumPostDraft::isSavePostDraftAllowed()) {
4363                    $GLOBALS['ilAppEventHandler']->raise(
4364                        'Modules/Forum',
4365                        'updatedDraft',
4366                        array('draftObj' => $update_draft,
4367                              'obj_id' => $this->object->getId(),
4368                              'is_file_upload_allowed' => $this->objProperties->isFileUploadAllowed())
4369                    );
4370                }
4371
4372                $uploadedObjects = ilObjMediaObject::_getMobsOfObject('frm~:html', $this->user->getId());
4373
4374                foreach ($uploadedObjects as $mob) {
4375                    ilObjMediaObject::_removeUsage($mob, 'frm~:html', $this->user->getId());
4376                    ilObjMediaObject::_saveUsage($mob, 'frm~d:html', $update_draft->getDraftId());
4377                }
4378                ilForumUtil::saveMediaObjects($oReplyEditForm->getInput('message'), 'frm~d:html', $update_draft->getDraftId());
4379
4380                $oFDForumDrafts = new ilFileDataForumDrafts($forumObj->getId(), $update_draft->getDraftId());
4381
4382                $file2delete = $oReplyEditForm->getInput('del_file');
4383                if (is_array($file2delete) && count($file2delete)) {
4384                    $oFDForumDrafts->unlinkFilesByMD5Filenames($file2delete);
4385                }
4386
4387                if ($this->objProperties->isFileUploadAllowed()) {
4388                    $file = $_FILES['userfile'];
4389                    if (is_array($file) && !empty($file)) {
4390                        $oFDForumDrafts->storeUploadedFile($file);
4391                    }
4392                }
4393
4394                $_SESSION['frm'][(int) $_GET['thr_pk']]['openTreeNodes'][] = (int) $this->objCurrentPost->getId();
4395                ilUtil::sendSuccess($this->lng->txt('save_draft_successfully'), true);
4396            }
4397            $this->ctrl->clearParameters($this);
4398            $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
4399            $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
4400            $this->ctrl->setParameter($this, 'draft_id', $update_draft->getDraftId());
4401        } else {
4402            $this->ctrl->clearParameters($this);
4403            $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
4404            $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
4405            $this->ctrl->setParameter($this, 'draft_id', (int) $_GET['draft_id']);
4406            $this->ctrl->setParameter($this, 'action', 'editdraft');
4407            $oReplyEditForm->setValuesByPost();
4408            return $this->viewThreadObject();
4409        }
4410        $this->ctrl->clearParameters($this);
4411        $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
4412        $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
4413        $this->ctrl->redirect($this, 'viewThread');
4414    }
4415
4416    /**
4417     * todo: move to ilForumUtil
4418     * @param $draft_id
4419     * @param $message
4420     */
4421    protected function deleteMobsOfDraft($draft_id, $message)
4422    {
4423        // remove usage of deleted media objects
4424        $oldMediaObjects = ilObjMediaObject::_getMobsOfObject('frm~d:html', $draft_id);
4425        $curMediaObjects = ilRTE::_getMediaObjects($message, 0);
4426        foreach ($oldMediaObjects as $oldMob) {
4427            $found = false;
4428            foreach ($curMediaObjects as $curMob) {
4429                if ($oldMob == $curMob) {
4430                    $found = true;
4431                    break;
4432                }
4433            }
4434            if (!$found) {
4435                if (ilObjMediaObject::_exists($oldMob)) {
4436                    ilObjMediaObject::_removeUsage($oldMob, 'frm~d:html', $draft_id);
4437                    $mob_obj = new ilObjMediaObject($oldMob);
4438                    $mob_obj->delete();
4439                }
4440            }
4441        }
4442    }
4443
4444    /**
4445     * @param ilForumPostDraft|null $draft_obj
4446     */
4447    protected function deleteSelectedDraft(ilForumPostDraft $draft_obj = null)
4448    {
4449        if (
4450            !$this->access->checkAccess('add_reply', '', (int) $_GET['ref_id']) ||
4451            $this->user->isAnonymous() ||
4452            ($draft_obj instanceof ilForumPostDraft && $this->user->getId() != $draft_obj->getPostAuthorId())) {
4453            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4454        }
4455
4456        $post_id = $this->objCurrentPost->getId();
4457        if (!($draft_obj instanceof ilForumPostDraft)) {
4458            $draft_id_to_delete = (int) $_GET['draft_id'];
4459            $draft_obj = new ilForumPostDraft($this->user->getId(), $post_id, $draft_id_to_delete);
4460
4461            if (!$draft_obj->getDraftId() || ($draft_obj->getDraftId() != $draft_id_to_delete)) {
4462                $this->ctrl->clearParameters($this);
4463                $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
4464                $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
4465                $this->ctrl->redirect($this, 'viewThread');
4466            }
4467        }
4468
4469        $this->deleteMobsOfDraft($draft_obj->getDraftId(), $draft_obj->getPostMessage());
4470
4471        $objFileDataForumDrafts = new ilFileDataForumDrafts(0, $draft_obj->getDraftId());
4472        $objFileDataForumDrafts->delete();
4473
4474        if (ilForumPostDraft::isSavePostDraftAllowed()) {
4475            $GLOBALS['ilAppEventHandler']->raise(
4476                'Modules/Forum',
4477                'deletedDraft',
4478                array('draftObj' => $draft_obj,
4479                      'obj_id' => $this->object->getId(),
4480                      'is_file_upload_allowed' => $this->objProperties->isFileUploadAllowed())
4481            );
4482        }
4483        $draft_obj->deleteDraft();
4484
4485        ilUtil::sendSuccess($this->lng->txt('delete_draft_successfully'), true);
4486        $this->ctrl->clearParameters($this);
4487        $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
4488        $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
4489        $this->ctrl->redirect($this, 'viewThread');
4490    }
4491
4492    protected function autosaveDraftAsyncObject()
4493    {
4494        $draftId = (int) ($this->httpRequest->getQueryParams()['draft_id'] ?? 0);
4495        if (
4496            $this->requestAction !== 'ready_showreply' &&
4497            $this->access->checkAccess('read', '', $this->object->getRefId()) &&
4498            $this->access->checkAccess('add_reply', '', $this->object->getRefId())
4499        ) {
4500            $action = new \ilForumAutoSaveAsyncDraftAction(
4501                $this->user,
4502                $this->getReplyEditForm(),
4503                $this->objProperties,
4504                $this->objCurrentTopic,
4505                $this->objCurrentPost,
4506                function (string $message) : string {
4507                    return $this->handleFormInput($message);
4508                },
4509                $draftId,
4510                (int) \ilObjForum::lookupForumIdByRefId($this->ref_id),
4511                \ilUtil::stripSlashes($this->requestAction)
4512            );
4513
4514            echo json_encode($action->executeAndGetResponseObject());
4515        }
4516
4517        exit();
4518    }
4519
4520    protected function autosaveThreadDraftAsyncObject()
4521    {
4522        $draftId = (int) ($this->httpRequest->getQueryParams()['draft_id'] ?? 0);
4523        if (
4524            $this->requestAction !== 'ready_showreply' &&
4525            $this->access->checkAccess('read', '', $this->object->getRefId()) &&
4526            $this->access->checkAccess('add_thread', '', $this->object->getRefId())
4527        ) {
4528            $action = new \ilForumAutoSaveAsyncDraftAction(
4529                $this->user,
4530                $this->buildThreadForm(),
4531                $this->objProperties,
4532                $this->objCurrentTopic,
4533                $this->objCurrentPost,
4534                function (string $message) : string {
4535                    return $this->handleFormInput($message, false);
4536                },
4537                $draftId,
4538                (int) \ilObjForum::lookupForumIdByRefId($this->ref_id),
4539                \ilUtil::stripSlashes($this->requestAction)
4540            );
4541
4542            echo json_encode($action->executeAndGetResponseObject());
4543        }
4544
4545        exit();
4546    }
4547
4548    /**
4549     * @param string $action
4550     * @param bool $is_post
4551     * @param ilForumPost $node
4552     * @param int $Start
4553     * @param ilForumPostDraft|NULL $draft
4554     * @throws ilSplitButtonException
4555     */
4556    private function renderSplitButton(string $action, $is_post = true, ilForumPost $node, $Start = 0, ilForumPostDraft $draft = null)
4557    {
4558        $actions = array();
4559        if ($is_post) {
4560            if ($this->objCurrentPost->getId() != $node->getId() || (
4561                !in_array($action, ['showreply', 'showedit', 'censor', 'delete']) && !$this->displayConfirmPostActivation()
4562            )) {
4563                if ($this->is_moderator || $node->isActivated() || $node->isOwner($this->user->getId())) {
4564                    // button: reply
4565                    if (!$this->objCurrentTopic->isClosed() && $node->isActivated() &&
4566                        $this->access->checkAccess('add_reply', '', (int) $_GET['ref_id']) &&
4567                        !$node->isCensored()
4568                    ) {
4569                        $this->ctrl->setParameter($this, 'action', 'showreply');
4570                        $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
4571                        $this->ctrl->setParameter($this, 'offset', $Start);
4572                        $this->ctrl->setParameter($this, 'orderby', $_GET['orderby']);
4573                        $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
4574
4575                        if (!isset($draftsObjects[$node->getId()])) {
4576                            $actions['reply_to_postings'] = $this->ctrl->getLinkTarget(
4577                                $this, 'viewThread',
4578                                'reply_' . $node->getId()
4579                            );
4580                        }
4581
4582                        $this->ctrl->clearParameters($this);
4583                    }
4584
4585                    // button: edit article
4586                    if (!$this->objCurrentTopic->isClosed() &&
4587                        ($node->isOwner($this->user->getId()) || $this->is_moderator) &&
4588                        !$node->isCensored() &&
4589                        $this->user->getId() != ANONYMOUS_USER_ID
4590                    ) {
4591                        $this->ctrl->setParameter($this, 'action', 'showedit');
4592                        $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
4593                        $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
4594                        $this->ctrl->setParameter($this, 'offset', $Start);
4595                        $this->ctrl->setParameter($this, 'orderby', $_GET['orderby']);
4596
4597                        $actions['edit'] = $this->ctrl->getLinkTarget($this, 'viewThread', $node->getId());
4598
4599                        $this->ctrl->clearParameters($this);
4600                    }
4601
4602                    // button: mark read
4603                    if ($this->user->getId() != ANONYMOUS_USER_ID && !$node->isPostRead()) {
4604                        $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
4605                        $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
4606                        $this->ctrl->setParameter($this, 'offset', $Start);
4607                        $this->ctrl->setParameter($this, 'orderby', $_GET['orderby']);
4608                        $this->ctrl->setParameter($this, 'viewmode', $_SESSION['viewmode']);
4609
4610                        $actions['frm_mark_as_read'] = $this->ctrl->getLinkTarget($this, 'markPostRead', $node->getId());
4611
4612                        $this->ctrl->clearParameters($this);
4613                    }
4614
4615                    // button: mark unread
4616                    if ($this->user->getId() != ANONYMOUS_USER_ID &&
4617                        $node->isPostRead()
4618                    ) {
4619                        $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
4620                        $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
4621                        $this->ctrl->setParameter($this, 'offset', $Start);
4622                        $this->ctrl->setParameter($this, 'orderby', $_GET['orderby']);
4623                        $this->ctrl->setParameter($this, 'viewmode', $_SESSION['viewmode']);
4624
4625                        $actions['frm_mark_as_unread'] = $this->ctrl->getLinkTarget($this, 'markPostUnread', $node->getId());
4626
4627                        $this->ctrl->clearParameters($this);
4628                    }
4629
4630                    // button: print
4631                    if (!$node->isCensored()) {
4632                        $this->ctrl->setParameterByClass('ilforumexportgui', 'print_post', $node->getId());
4633                        $this->ctrl->setParameterByClass('ilforumexportgui', 'top_pk', $node->getForumId());
4634                        $this->ctrl->setParameterByClass('ilforumexportgui', 'thr_pk', $node->getThreadId());
4635
4636                        $actions['print'] = $this->ctrl->getLinkTargetByClass('ilforumexportgui', 'printPost');
4637
4638                        $this->ctrl->clearParameters($this);
4639                    }
4640
4641                    # buttons for every post except the "active"
4642                    if (!$this->objCurrentTopic->isClosed() &&
4643                        ($this->is_moderator ||
4644                            ($node->isOwner($this->user->getId()) && !$node->hasReplies())) &&
4645                        $this->user->getId() != ANONYMOUS_USER_ID
4646                    ) {
4647                        // button: delete
4648                        $this->ctrl->setParameter($this, 'action', 'delete');
4649                        $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
4650                        $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
4651                        $this->ctrl->setParameter($this, 'offset', $Start);
4652                        $this->ctrl->setParameter($this, 'orderby', $_GET['orderby']);
4653
4654                        $actions['delete'] = $this->ctrl->getLinkTarget($this, 'viewThread', $node->getId());
4655
4656                        $this->ctrl->clearParameters($this);
4657                    }
4658
4659                    if (!$this->objCurrentTopic->isClosed() && $this->is_moderator) {
4660                        // button: censor
4661                        $this->ctrl->setParameter($this, 'action', 'censor');
4662                        $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
4663                        $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
4664                        $this->ctrl->setParameter($this, 'offset', $Start);
4665                        $this->ctrl->setParameter($this, 'orderby', $_GET['orderby']);
4666                        if ($node->isCensored()) {
4667                            $actions['frm_revoke_censorship'] = $this->ctrl->getLinkTarget($this, 'viewThread', $node->getId());
4668                        } else {
4669                            $actions['frm_censorship'] = $this->ctrl->getLinkTarget($this, 'viewThread', $node->getId());
4670                        }
4671
4672                        $this->ctrl->clearParameters($this);
4673
4674                        // button: activation/deactivation
4675                        $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
4676                        $this->ctrl->setParameter($this, 'thr_pk', $node->getThreadId());
4677                        $this->ctrl->setParameter($this, 'offset', $Start);
4678                        $this->ctrl->setParameter($this, 'orderby', $_GET['orderby']);
4679
4680                        if (!$node->isActivated()) {
4681                            $actions['activate_post'] = $this->ctrl->getLinkTarget($this, 'askForPostActivation', $node->getId());
4682                        }
4683
4684                        $this->ctrl->clearParameters($this);
4685                    }
4686                }
4687            }
4688        } else {
4689            if (!isset($draft)) {
4690                $draftsObjects = ilForumPostDraft::getInstancesByUserIdAndThreadId($this->user->getId(), $this->objCurrentTopic->getId());
4691                $draft = $draftsObjects[$node->getId()];
4692            }
4693            // get actions for drafts
4694            $this->ctrl->setParameter($this, 'action', 'publishdraft');
4695            $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
4696            $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
4697            $this->ctrl->setParameter($this, 'offset', (int) $_GET['offset']);
4698            $this->ctrl->setParameter($this, 'draft_id', $draft->getDraftId());
4699            $this->ctrl->setParameter($this, 'orderby', $_GET['orderby']);
4700            $actions['publish'] = $this->ctrl->getLinkTarget($this, 'publishSelectedDraft', $node->getId());
4701            $this->ctrl->clearParameters($this);
4702
4703            $this->ctrl->setParameter($this, 'action', 'editdraft');
4704            $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
4705            $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
4706            $this->ctrl->setParameter($this, 'draft_id', $draft->getDraftId());
4707            $this->ctrl->setParameter($this, 'offset', (int) $_GET['offset']);
4708            $this->ctrl->setParameter($this, 'orderby', $_GET['orderby']);
4709            $actions['edit'] = $this->ctrl->getLinkTarget($this, 'editDraft', 'draft_edit_' . $draft->getDraftId());
4710            $this->ctrl->clearParameters($this);
4711
4712            $this->ctrl->setParameter($this, 'action', 'deletedraft');
4713            $this->ctrl->setParameter($this, 'pos_pk', $node->getId());
4714            $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentTopic->getId());
4715            $this->ctrl->setParameter($this, 'draft_id', $draft->getDraftId());
4716            $this->ctrl->setParameter($this, 'offset', (int) $_GET['offset']);
4717            $this->ctrl->setParameter($this, 'orderby', $_GET['orderby']);
4718            $actions['delete'] = $this->ctrl->getLinkTarget($this, 'viewThread', $node->getId());
4719            $this->ctrl->clearParameters($this);
4720
4721            if (isset($_GET['draft_id']) && $action === 'editdraft') {
4722                $actions = array();
4723            }
4724        }
4725
4726        $this->tpl->setCurrentBlock('posts_row');
4727        if (count($actions) > 0) {
4728            $action_button = ilSplitButtonGUI::getInstance();
4729
4730            $i = 0;
4731            foreach ($actions as $lng_id => $url) {
4732                if ($i == 0) {
4733                    $sb_item = ilLinkButton::getInstance();
4734                    $sb_item->setCaption($lng_id);
4735                    $sb_item->setUrl($url);
4736
4737                    $action_button->setDefaultButton($sb_item);
4738                    ++$i;
4739                } else {
4740                    $sb_item = ilLinkButton::getInstance();
4741                    $sb_item->setCaption($lng_id);
4742                    $sb_item->setUrl($url);
4743
4744                    $action_button->addMenuItem(new ilButtonToSplitButtonMenuItemAdapter($sb_item));
4745                }
4746            }
4747
4748            if ($is_post) {
4749                $this->tpl->setVariable('COMMANDS', $action_button->render());
4750            } elseif (!in_array($action, ['deletedraft', 'editdraft']) && !$this->objCurrentTopic->isClosed()) {
4751                $this->tpl->setVariable('COMMANDS', $action_button->render());
4752            }
4753        }
4754    }
4755
4756    /**
4757     * @param int $draftId
4758     * @return bool
4759     */
4760    public function checkDraftAccess(int $draftId) : bool
4761    {
4762        $draft = \ilForumPostDraft::newInstanceByDraftId($draftId);
4763        if (
4764            !$this->access->checkAccess('add_reply', '', $this->object->getRefId()) || $this->user->isAnonymous() ||
4765            ($draft instanceof \ilForumPostDraft && $this->user->getId() != $draft->getPostAuthorId())
4766        ) {
4767            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
4768        }
4769
4770        return true;
4771    }
4772
4773    /**
4774     * @param $draftId
4775     */
4776    private function doHistoryCheck($draftId)
4777    {
4778        if (!\ilForumPostDraft::isAutoSavePostDraftAllowed()) {
4779            return;
4780        }
4781
4782        \iljQueryUtil::initjQuery();
4783        $draftsFromHistory = \ilForumDraftsHistory::getInstancesByDraftId($draftId);
4784        if (is_array($draftsFromHistory) && sizeof($draftsFromHistory) > 0) {
4785            $modal = \ilModalGUI::getInstance();
4786            $modal->setHeading($this->lng->txt('restore_draft_from_autosave'));
4787            $modal->setId('frm_autosave_restore');
4788            $form_tpl = new \ilTemplate('tpl.restore_thread_draft.html', true, true, 'Modules/Forum');
4789
4790            foreach ($draftsFromHistory as $key => $history_instance) {
4791                $accordion = new ilAccordionGUI();
4792                $accordion->setId('acc_' . $history_instance->getHistoryId());
4793
4794                $form_tpl->setCurrentBlock('list_item');
4795                $message = \ilRTE::_replaceMediaObjectImageSrc($history_instance->getPostMessage(), 1);
4796
4797                $history_date = ilDatePresentation::formatDate(new ilDateTime($history_instance->getDraftDate(), IL_CAL_DATETIME));
4798                $this->ctrl->setParameter($this, 'history_id', $history_instance->getHistoryId());
4799                $header = $history_date . ' - ' . $history_instance->getPostSubject();
4800                $accordion->addItem($header, $message . $this->uiRenderer->render(
4801                    $this->uiFactory->button()->standard(
4802                        $this->lng->txt('restore'),
4803                        $this->ctrl->getLinkTarget($this, 'restoreFromHistory')
4804                    )
4805                ));
4806
4807                $form_tpl->setVariable('ACC_AUTO_SAVE', $accordion->getHtml());
4808                $form_tpl->parseCurrentBlock();
4809            }
4810
4811            $form_tpl->setVariable('RESTORE_DATA_EXISTS', 'found_threat_history_to_restore');
4812            $modal->setBody($form_tpl->get());
4813            $modal->initJS();
4814            $this->modal_history = $modal->getHTML();
4815        } else {
4816            ilForumPostDraft::createDraftBackup($draftId);
4817        }
4818    }
4819
4820    /**
4821     * Performs a CAPTCHA check for anonymous users if the CAPTCHA should be used for forums in the public area
4822     */
4823    protected function doCaptchaCheck()
4824    {
4825        if ($this->user->isAnonymous() && !$this->user->isCaptchaVerified() && \ilCaptchaUtil::isActiveForForum()) {
4826            $this->user->setCaptchaVerified(true);
4827        }
4828    }
4829
4830    /**
4831     * @param ilForum $frm
4832     * @param ilForumPost $node
4833     * @param string $action
4834     * @throws ilTemplateException
4835     */
4836    private function renderPostingForm(ilForum $frm, ilForumPost $node, string $action)
4837    {
4838        if (
4839            $action == 'showedit' && (
4840                (!$this->is_moderator && !$node->isOwner($this->user->getId()) || $this->user->isAnonymous()) || $node->isCensored()
4841            )
4842        ) {
4843            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->getMessage());
4844        } elseif ($action == 'showreply' && !$this->access->checkAccess('add_reply', '', (int) $_GET['ref_id'])) {
4845            $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->getMessage());
4846        }
4847
4848        $this->tpl->setVariable('REPLY_ANKER', 'reply_' . $this->objCurrentPost->getId());
4849        $oEditReplyForm = $this->getReplyEditForm();
4850        if ($action !== 'editdraft') {
4851            switch ($this->objProperties->getSubjectSetting()) {
4852                case 'add_re_to_subject':
4853                    $subject = $this->getModifiedReOnSubject(true);
4854                    break;
4855
4856                case 'preset_subject':
4857                    $subject = $this->objCurrentPost->getSubject();
4858                    break;
4859
4860                case 'empty_subject':
4861                default:
4862                    $subject = null;
4863                    break;
4864            }
4865        }
4866
4867        switch ($action) {
4868            case 'showreply':
4869                if ($this->ctrl->getCmd() == 'savePost' || $this->ctrl->getCmd() == 'saveAsDraft') {
4870                    $oEditReplyForm->setValuesByPost();
4871                } else {
4872                    if ($this->ctrl->getCmd() == 'quotePost') {
4873                        $authorinfo = new ilForumAuthorInformation(
4874                            $node->getPosAuthorId(),
4875                            $node->getDisplayUserId(),
4876                            $node->getUserAlias(),
4877                            $node->getImportName()
4878                        );
4879
4880                        $oEditReplyForm->setValuesByPost();
4881                        $oEditReplyForm->getItemByPostVar('message')->setValue(
4882                            ilRTE::_replaceMediaObjectImageSrc(
4883                                $frm->prepareText(
4884                                    $node->getMessage(),
4885                                    1,
4886                                    $authorinfo->getAuthorName()
4887                                ) . "\n" . $oEditReplyForm->getInput('message'),
4888                                1
4889                            )
4890                        );
4891                    } else {
4892                        $oEditReplyForm->setValuesByArray(array(
4893                            'alias' => '',
4894                            'subject' => $subject,
4895                            'message' => '',
4896                            'notify' => 0,
4897                            'userfile' => '',
4898                            'del_file' => array()
4899                        ));
4900                    }
4901                }
4902
4903                $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
4904                $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
4905
4906                $jsTpl = new ilTemplate('tpl.forum_post_quoation_ajax_handler.html', true, true, 'Modules/Forum');
4907                $jsTpl->setVariable(
4908                    'IL_FRM_QUOTE_CALLBACK_SRC',
4909                    $this->ctrl->getLinkTarget($this, 'getQuotationHTMLAsynch', '', true)
4910                );
4911                $this->ctrl->clearParameters($this);
4912                $this->tpl->setVariable('FORM_ADDITIONAL_JS', $jsTpl->get());
4913                break;
4914
4915            case 'showedit':
4916                if ($this->ctrl->getCmd() == 'savePost') {
4917                    $oEditReplyForm->setValuesByPost();
4918                } else {
4919                    $oEditReplyForm->setValuesByArray(array(
4920                        'alias' => '',
4921                        'subject' => $this->objCurrentPost->getSubject(),
4922                        'message' => ilRTE::_replaceMediaObjectImageSrc($frm->prepareText(
4923                            $this->objCurrentPost->getMessage(),
4924                            2
4925                        ), 1),
4926                        'notify' => $this->objCurrentPost->isNotificationEnabled() ? true : false,
4927                        'userfile' => '',
4928                        'del_file' => array()
4929                    ));
4930                }
4931
4932                $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getParentId());
4933                $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
4934                $jsTpl = new ilTemplate('tpl.forum_post_quoation_ajax_handler.html', true, true, 'Modules/Forum');
4935                $jsTpl->setVariable(
4936                    'IL_FRM_QUOTE_CALLBACK_SRC',
4937                    $this->ctrl->getLinkTarget($this, 'getQuotationHTMLAsynch', '', true)
4938                );
4939                $this->ctrl->clearParameters($this);
4940                $this->tpl->setVariable('FORM_ADDITIONAL_JS', $jsTpl->get());
4941                break;
4942
4943            case 'editdraft':
4944                if (in_array($this->ctrl->getCmd(), array('saveDraft', 'updateDraft', 'publishDraft'))) {
4945                    $oEditReplyForm->setValuesByPost();
4946                } else {
4947                    if (isset($_GET['draft_id']) && (int) $_GET['draft_id'] > 0) {
4948                        /**
4949                         * @var object $draftObjects ilForumPost
4950                         */
4951                        $draftObject = new ilForumPostDraft(
4952                            $this->user->getId(),
4953                            $this->objCurrentPost->getId(),
4954                            (int) $_GET['draft_id']
4955                        );
4956                        $oEditReplyForm->setValuesByArray(array(
4957                            'alias' => $draftObject->getPostUserAlias(),
4958                            'subject' => $draftObject->getPostSubject(),
4959                            'message' => ilRTE::_replaceMediaObjectImageSrc($frm->prepareText(
4960                                $draftObject->getPostMessage(),
4961                                2
4962                            ), 1),
4963                            'notify' => $draftObject->getNotify() ? true : false,
4964                            'userfile' => '',
4965                            'del_file' => array()
4966                        ));
4967                    }
4968                }
4969
4970                $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
4971                $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
4972
4973                $jsTpl = new ilTemplate('tpl.forum_post_quoation_ajax_handler.html', true, true, 'Modules/Forum');
4974                $jsTpl->setVariable(
4975                    'IL_FRM_QUOTE_CALLBACK_SRC',
4976                    $this->ctrl->getLinkTarget($this, 'getQuotationHTMLAsynch', '', true)
4977                );
4978                $this->ctrl->clearParameters($this);
4979                $this->tpl->setVariable('FORM_ADDITIONAL_JS', $jsTpl->get());
4980                break;
4981        }
4982        $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
4983        $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
4984        $this->ctrl->setParameter($this, 'offset', (int) $_GET['offset']);
4985        $this->ctrl->setParameter($this, 'orderby', $_GET['orderby']);
4986        $this->ctrl->setParameter($this, 'action', $_GET['action']);
4987        if ($action !== 'editdraft') {
4988            $this->tpl->setVariable('FORM', $oEditReplyForm->getHTML());
4989        }
4990        $this->ctrl->clearParameters($this);
4991    }
4992}
4993