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