viewthread.php 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. use Chamilo\CourseBundle\Entity\CForumPost;
  4. /**
  5. * @author Julio Montoya <gugli100@gmail.com> UI Improvements + lots of bugfixes
  6. *
  7. * @package chamilo.forum
  8. */
  9. require_once __DIR__.'/../inc/global.inc.php';
  10. $current_course_tool = TOOL_FORUM;
  11. $this_section = SECTION_COURSES;
  12. // Notification for unauthorized people.
  13. api_protect_course_script(true);
  14. require_once 'forumfunction.inc.php';
  15. $nameTools = get_lang('Forum');
  16. $forumUrl = api_get_path(WEB_CODE_PATH).'forum/';
  17. // Are we in a lp ?
  18. $origin = api_get_origin();
  19. $_user = api_get_user_info();
  20. $my_search = null;
  21. $forumId = isset($_GET['forum']) ? (int) $_GET['forum'] : 0;
  22. $threadId = isset($_GET['thread']) ? (int) $_GET['thread'] : 0;
  23. /* MAIN DISPLAY SECTION */
  24. /* Retrieving forum and forum category information */
  25. // We are getting all the information about the current forum and forum category.
  26. // Note pcool: I tried to use only one sql statement (and function) for this,
  27. // but the problem is that the visibility of the forum AND forum category are stored in the item_property table.
  28. // Note: This has to be validated that it is an existing thread
  29. $current_thread = get_thread_information($forumId, $threadId);
  30. // Note: This has to be validated that it is an existing forum.
  31. $current_forum = get_forum_information($current_thread['forum_id']);
  32. $current_forum_category = get_forumcategory_information($current_forum['forum_category']);
  33. $whatsnew_post_info = isset($_SESSION['whatsnew_post_info']) ? $_SESSION['whatsnew_post_info'] : null;
  34. if (api_is_in_gradebook()) {
  35. $interbreadcrumb[] = [
  36. 'url' => Category::getUrl(),
  37. 'name' => get_lang('ToolGradebook'),
  38. ];
  39. }
  40. $groupId = api_get_group_id();
  41. $group_properties = GroupManager::get_group_properties($groupId);
  42. $sessionId = api_get_session_id();
  43. $ajaxURL = api_get_path(WEB_AJAX_PATH).'forum.ajax.php?'.api_get_cidreq().'&a=change_post_status';
  44. $htmlHeadXtra[] = '<script>
  45. $(function() {
  46. $("span").on("click", ".change_post_status", function() {
  47. var updateDiv = $(this).parent();
  48. var postId = updateDiv.attr("id");
  49. $.ajax({
  50. url: "'.$ajaxURL.'&post_id="+postId,
  51. type: "GET",
  52. success: function(data) {
  53. updateDiv.html(data);
  54. }
  55. });
  56. });
  57. });
  58. </script>';
  59. /* Actions */
  60. $my_action = isset($_GET['action']) ? $_GET['action'] : '';
  61. $logInfo = [
  62. 'tool' => TOOL_FORUM,
  63. 'tool_id' => $forumId,
  64. 'tool_id_detail' => $threadId,
  65. 'action' => !empty($my_action) ? $my_action : 'view-thread',
  66. 'action_details' => isset($_GET['content']) ? $_GET['content'] : '',
  67. ];
  68. Event::registerLog($logInfo);
  69. $currentUrl = api_get_path(WEB_CODE_PATH).'forum/viewthread.php?forum='.$forumId.'&'.api_get_cidreq().'&thread='.$threadId;
  70. switch ($my_action) {
  71. case 'delete':
  72. if (
  73. isset($_GET['content']) &&
  74. isset($_GET['id']) &&
  75. (api_is_allowed_to_edit(false, true) ||
  76. (isset($group_properties['iid']) && GroupManager::is_tutor_of_group(api_get_user_id(), $group_properties)))
  77. ) {
  78. $message = delete_post($_GET['id']);
  79. Display::addFlash(Display::return_message(get_lang($message)));
  80. }
  81. header('Location: '.$currentUrl);
  82. exit;
  83. break;
  84. case 'invisible':
  85. case 'visible':
  86. if (isset($_GET['id']) &&
  87. (api_is_allowed_to_edit(false, true) ||
  88. (isset($group_properties['iid']) && GroupManager::is_tutor_of_group(api_get_user_id(), $group_properties)))
  89. ) {
  90. $message = approve_post($_GET['id'], $_GET['action']);
  91. Display::addFlash(Display::return_message(get_lang($message)));
  92. }
  93. header('Location: '.$currentUrl);
  94. exit;
  95. break;
  96. case 'move':
  97. if (isset($_GET['post'])) {
  98. $message = move_post_form();
  99. Display::addFlash(Display::return_message(get_lang($message)));
  100. }
  101. header('Location: '.$currentUrl);
  102. exit;
  103. break;
  104. case 'report':
  105. $postId = isset($_GET['post_id']) ? $_GET['post_id'] : 0;
  106. $result = reportPost($postId, $current_forum, $current_thread);
  107. Display::addFlash(Display::return_message(get_lang('Reported')));
  108. header('Location: '.$currentUrl);
  109. exit;
  110. break;
  111. case 'ask_revision':
  112. if (api_get_configuration_value('allow_forum_post_revisions')) {
  113. $postId = isset($_GET['post_id']) ? $_GET['post_id'] : 0;
  114. $result = savePostRevision($postId);
  115. Display::addFlash(Display::return_message(get_lang('Saved')));
  116. }
  117. header('Location: '.$currentUrl);
  118. exit;
  119. break;
  120. }
  121. if (!empty($groupId)) {
  122. $interbreadcrumb[] = [
  123. 'url' => api_get_path(WEB_CODE_PATH).'group/group.php?'.api_get_cidreq(),
  124. 'name' => get_lang('Groups'),
  125. ];
  126. $interbreadcrumb[] = [
  127. 'url' => api_get_path(WEB_CODE_PATH).'group/group_space.php?'.api_get_cidreq(),
  128. 'name' => get_lang('GroupSpace').' '.$group_properties['name'],
  129. ];
  130. $interbreadcrumb[] = [
  131. 'url' => api_get_path(WEB_CODE_PATH).'forum/viewforum.php?forum='.$forumId.'&'.api_get_cidreq()."&search=".Security::remove_XSS(urlencode($my_search)),
  132. 'name' => Security::remove_XSS($current_forum['forum_title']),
  133. ];
  134. $interbreadcrumb[] = [
  135. 'url' => api_get_path(WEB_CODE_PATH).'forum/viewthread.php?forum='.$forumId.'&'.api_get_cidreq().'&thread='.$threadId,
  136. 'name' => Security::remove_XSS($current_thread['thread_title']),
  137. ];
  138. } else {
  139. $my_search = isset($_GET['search']) ? $_GET['search'] : '';
  140. if ($origin != 'learnpath') {
  141. $interbreadcrumb[] = [
  142. 'url' => api_get_path(WEB_CODE_PATH).'forum/index.php?'.api_get_cidreq().'&search='.Security::remove_XSS(
  143. urlencode($my_search)
  144. ),
  145. 'name' => $nameTools,
  146. ];
  147. $interbreadcrumb[] = [
  148. 'url' => api_get_path(
  149. WEB_CODE_PATH
  150. ).'forum/viewforumcategory.php?forumcategory='.$current_forum_category['cat_id']."&search=".Security::remove_XSS(
  151. urlencode($my_search)
  152. ),
  153. 'name' => Security::remove_XSS($current_forum_category['cat_title']),
  154. ];
  155. $interbreadcrumb[] = [
  156. 'url' => api_get_path(WEB_CODE_PATH).'forum/viewforum.php?'.api_get_cidreq().'&forum='.$forumId."&search=".Security::remove_XSS(urlencode($my_search)),
  157. 'name' => Security::remove_XSS($current_forum['forum_title']),
  158. ];
  159. $interbreadcrumb[] = [
  160. 'url' => '#',
  161. 'name' => Security::remove_XSS($current_thread['thread_title']),
  162. ];
  163. }
  164. }
  165. // If the user is not a course administrator and the forum is hidden
  166. // then the user is not allowed here.
  167. if (!api_is_allowed_to_edit(false, true) &&
  168. ($current_forum['visibility'] == 0 || $current_thread['visibility'] == 0)
  169. ) {
  170. api_not_allowed();
  171. }
  172. // this increases the number of times the thread has been viewed
  173. increase_thread_view($threadId);
  174. if ($origin == 'learnpath') {
  175. $template = new Template('', false, false, true, true, false);
  176. } else {
  177. $template = new Template();
  178. }
  179. $actions = '<span style="float:right;">'.search_link().'</span>';
  180. if ($origin != 'learnpath') {
  181. $actions .= '<a href="'.$forumUrl.'viewforum.php?forum='.$forumId.'&'.api_get_cidreq().'">'
  182. .Display::return_icon('back.png', get_lang('BackToForum'), '', ICON_SIZE_MEDIUM).'</a>';
  183. }
  184. // The reply to thread link should only appear when the forum_category is
  185. // not locked AND the forum is not locked AND the thread is not locked.
  186. // If one of the three levels is locked then the link should not be displayed.
  187. if (($current_forum_category &&
  188. $current_forum_category['locked'] == 0) &&
  189. $current_forum['locked'] == 0 &&
  190. $current_thread['locked'] == 0 ||
  191. api_is_allowed_to_edit(false, true)
  192. ) {
  193. // The link should only appear when the user is logged in or when anonymous posts are allowed.
  194. if ($_user['user_id'] || ($current_forum['allow_anonymous'] == 1 && !$_user['user_id'])) {
  195. // reply link
  196. if (!api_is_anonymous() && api_is_allowed_to_session_edit(false, true)) {
  197. $actions .= '<a href="'.$forumUrl.'reply.php?'.api_get_cidreq().'&forum='.$forumId.'&thread='
  198. .$threadId.'&action=replythread">'
  199. .Display::return_icon('reply_thread.png', get_lang('ReplyToThread'), '', ICON_SIZE_MEDIUM)
  200. .'</a>';
  201. }
  202. // new thread link
  203. if ((
  204. api_is_allowed_to_edit(false, true) &&
  205. !(api_is_session_general_coach() && $current_forum['session_id'] != $sessionId)) ||
  206. ($current_forum['allow_new_threads'] == 1 && isset($_user['user_id'])) ||
  207. ($current_forum['allow_new_threads'] == 1 && !isset($_user['user_id']) && $current_forum['allow_anonymous'] == 1)
  208. ) {
  209. if ($current_forum['locked'] != 1 && $current_forum['locked'] != 1) {
  210. $actions .= '&nbsp;&nbsp;';
  211. } else {
  212. $actions .= get_lang('ForumLocked');
  213. }
  214. }
  215. }
  216. }
  217. $template->assign('forum_actions', $actions);
  218. $template->assign('origin', api_get_origin());
  219. /* Display Forum Category and the Forum information */
  220. if (!isset($_SESSION['view'])) {
  221. $viewMode = $current_forum['default_view'];
  222. } else {
  223. $viewMode = $_SESSION['view'];
  224. }
  225. $whiteList = ['flat', 'threaded', 'nested'];
  226. if (isset($_GET['view']) && in_array($_GET['view'], $whiteList)) {
  227. $viewMode = $_GET['view'];
  228. $_SESSION['view'] = $viewMode;
  229. }
  230. if (empty($viewMode)) {
  231. $viewMode = 'flat';
  232. }
  233. if ($current_thread['thread_peer_qualify'] == 1) {
  234. Display::addFlash(Display::return_message(get_lang('ForumThreadPeerScoringStudentComment'), 'info'));
  235. }
  236. $allowReport = reportAvailable();
  237. // Are we in a lp ?
  238. $origin = api_get_origin();
  239. //delete attachment file
  240. if (isset($_GET['action']) &&
  241. $_GET['action'] == 'delete_attach' &&
  242. isset($_GET['id_attach'])
  243. ) {
  244. delete_attachment(0, $_GET['id_attach']);
  245. }
  246. $origin = api_get_origin();
  247. $sessionId = api_get_session_id();
  248. $_user = api_get_user_info();
  249. $userId = api_get_user_id();
  250. $groupId = api_get_group_id();
  251. // Decide whether we show the latest post first
  252. $sortDirection = isset($_GET['posts_order']) && $_GET['posts_order'] === 'desc' ? 'DESC' : ($origin != 'learnpath' ? 'ASC' : 'DESC');
  253. $posts = getPosts($current_forum, $threadId, $sortDirection, true);
  254. $count = 0;
  255. $group_id = api_get_group_id();
  256. $locked = api_resource_is_locked_by_gradebook($threadId, LINK_FORUM_THREAD);
  257. $sessionId = api_get_session_id();
  258. $currentThread = get_thread_information($forumId, $threadId);
  259. $userId = api_get_user_id();
  260. $groupInfo = GroupManager::get_group_properties($group_id);
  261. $postCount = 1;
  262. $allowUserImageForum = api_get_course_setting('allow_user_image_forum');
  263. // The user who posted it can edit his thread only if the course admin allowed this in the properties
  264. // of the forum
  265. // The course admin him/herself can do this off course always
  266. $tutorGroup = GroupManager::is_tutor_of_group(api_get_user_id(), $groupInfo);
  267. $postList = [];
  268. foreach ($posts as $post) {
  269. $posterId = isset($post['user_id']) ? $post['user_id'] : 0;
  270. $username = '';
  271. if (isset($post['username'])) {
  272. $username = sprintf(get_lang('LoginX'), $post['username']);
  273. }
  274. $name = $post['complete_name'];
  275. if (empty($posterId)) {
  276. $name = $post['poster_name'];
  277. }
  278. $post['user_data'] = '';
  279. if ($origin != 'learnpath') {
  280. if ($allowUserImageForum) {
  281. $post['user_data'] = '<div class="thumbnail">'.
  282. display_user_image($posterId, $name, $origin).'</div>';
  283. }
  284. $post['user_data'] .= Display::tag(
  285. 'h4',
  286. display_user_link($posterId, $name, $origin, $username),
  287. ['class' => 'title-username']
  288. );
  289. $_user = api_get_user_info($posterId);
  290. $iconStatus = $_user['icon_status'];
  291. $post['user_data'] .= '<div class="user-type text-center">'.$iconStatus.'</div>';
  292. } else {
  293. if ($allowUserImageForum) {
  294. $post['user_data'] .= '<div class="thumbnail">'.
  295. display_user_image($posterId, $name, $origin).'</div>';
  296. }
  297. $post['user_data'] .= Display::tag(
  298. 'p',
  299. $name,
  300. [
  301. 'title' => api_htmlentities($username, ENT_QUOTES),
  302. 'class' => 'lead',
  303. ]
  304. );
  305. }
  306. if ($origin != 'learnpath') {
  307. $post['user_data'] .= Display::tag(
  308. 'p',
  309. Display::dateToStringAgoAndLongDate($post['post_date']),
  310. ['class' => 'post-date']
  311. );
  312. } else {
  313. $post['user_data'] .= Display::tag(
  314. 'p',
  315. Display::dateToStringAgoAndLongDate($post['post_date']),
  316. ['class' => 'text-muted']
  317. );
  318. }
  319. // get attach id
  320. $attachment_list = get_attachment($post['post_id']);
  321. $id_attach = !empty($attachment_list) ? $attachment_list['iid'] : '';
  322. $iconEdit = '';
  323. $editButton = '';
  324. $askForRevision = '';
  325. if ((isset($groupInfo['iid']) && $tutorGroup) ||
  326. ($current_forum['allow_edit'] == 1 && $posterId == $userId) ||
  327. (api_is_allowed_to_edit(false, true) &&
  328. !(api_is_session_general_coach() && $current_forum['session_id'] != $sessionId))
  329. ) {
  330. if ($locked == false && postIsEditableByStudent($current_forum, $post)) {
  331. $editUrl = api_get_path(WEB_CODE_PATH).'forum/editpost.php?'.api_get_cidreq();
  332. $editUrl .= "&forum=$forumId&thread=$threadId&post={$post['post_id']}&id_attach=$id_attach";
  333. $iconEdit .= "<a href='".$editUrl."'>"
  334. .Display::return_icon('edit.png', get_lang('Edit'), [], ICON_SIZE_SMALL)
  335. ."</a>";
  336. $editButton = Display::toolbarButton(
  337. get_lang('Edit'),
  338. $editUrl,
  339. 'pencil',
  340. 'default'
  341. );
  342. }
  343. }
  344. if ((isset($groupInfo['iid']) && $tutorGroup) ||
  345. api_is_allowed_to_edit(false, true) &&
  346. !(api_is_session_general_coach() && $current_forum['session_id'] != $sessionId)
  347. ) {
  348. if ($locked == false) {
  349. $deleteUrl = api_get_self().'?'.api_get_cidreq().'&'.http_build_query(
  350. [
  351. 'forum' => $forumId,
  352. 'thread' => $threadId,
  353. 'action' => 'delete',
  354. 'content' => 'post',
  355. 'id' => $post['post_id'],
  356. ]
  357. );
  358. $iconEdit .= Display::url(
  359. Display::return_icon('delete.png', get_lang('Delete'), [], ICON_SIZE_SMALL),
  360. $deleteUrl,
  361. [
  362. 'onclick' => "javascript:if(!confirm('"
  363. .addslashes(api_htmlentities(get_lang('DeletePost'), ENT_QUOTES))
  364. ."')) return false;",
  365. 'id' => "delete-post-{$post['post_id']}",
  366. ]
  367. );
  368. }
  369. }
  370. if (api_is_allowed_to_edit(false, true) &&
  371. !(
  372. api_is_session_general_coach() &&
  373. $current_forum['session_id'] != $sessionId
  374. )
  375. ) {
  376. $iconEdit .= return_visible_invisible_icon(
  377. 'post',
  378. $post['post_id'],
  379. $post['visible'],
  380. [
  381. 'forum' => $forumId,
  382. 'thread' => $threadId,
  383. ]
  384. );
  385. if ($count > 0) {
  386. $iconEdit .= "<a href=\"viewthread.php?".api_get_cidreq()
  387. ."&forum=$forumId&thread=$threadId&action=move&post={$post['post_id']}"
  388. ."\">".Display::return_icon('move.png', get_lang('MovePost'), [], ICON_SIZE_SMALL)."</a>";
  389. }
  390. }
  391. $userCanQualify = $currentThread['thread_peer_qualify'] == 1 && $post['poster_id'] != $userId;
  392. if (api_is_allowed_to_edit(null, true)) {
  393. $userCanQualify = true;
  394. }
  395. $postIsARevision = false;
  396. $flagRevision = '';
  397. if ($post['poster_id'] == $userId) {
  398. $revision = getPostRevision($post['post_id']);
  399. if (empty($revision)) {
  400. $askForRevision = getAskRevisionButton($post['post_id'], $current_thread);
  401. } else {
  402. $postIsARevision = true;
  403. $languageId = api_get_language_id(strtolower($revision));
  404. $languageInfo = api_get_language_info($languageId);
  405. if ($languageInfo) {
  406. $languages = api_get_language_list_for_flag();
  407. $flagRevision = '<span class="flag-icon flag-icon-'.$languages[$languageInfo['english_name']].'"></span> ';
  408. }
  409. }
  410. } else {
  411. if (postNeedsRevision($post['post_id'])) {
  412. $askForRevision = giveRevisionButton($post['post_id'], $current_thread);
  413. } else {
  414. $revision = getPostRevision($post['post_id']);
  415. if (!empty($revision)) {
  416. $postIsARevision = true;
  417. $languageId = api_get_language_id(strtolower($revision));
  418. $languageInfo = api_get_language_info($languageId);
  419. if ($languageInfo) {
  420. $languages = api_get_language_list_for_flag();
  421. $flagRevision = '<span class="flag-icon flag-icon-'.$languages[$languageInfo['english_name']].'"></span> ';
  422. }
  423. }
  424. }
  425. }
  426. $post['is_a_revision'] = $postIsARevision;
  427. $post['flag_revision'] = $flagRevision;
  428. if (empty($currentThread['thread_qualify_max'])) {
  429. $userCanQualify = false;
  430. }
  431. if ($userCanQualify) {
  432. if ($count > 0) {
  433. $current_qualify_thread = showQualify(
  434. '1',
  435. $posterId,
  436. $threadId
  437. );
  438. if ($locked == false) {
  439. $iconEdit .= "<a href=\"forumqualify.php?".api_get_cidreq()
  440. ."&forum=$forumId&thread=$threadId&action=list&post={$post['post_id']}"
  441. ."&user={$post['user_id']}&user_id={$post['user_id']}"
  442. ."&idtextqualify=$current_qualify_thread"
  443. ."\" >".Display::return_icon('quiz.png', get_lang('Qualify'))."</a>";
  444. }
  445. }
  446. }
  447. $reportButton = '';
  448. if ($allowReport) {
  449. $reportButton = getReportButton($post['post_id'], $current_thread);
  450. }
  451. $statusIcon = getPostStatus($current_forum, $post);
  452. if (!empty($iconEdit)) {
  453. $post['user_data'] .= "<div class='tools-icons'> $iconEdit $statusIcon </div>";
  454. } else {
  455. if (!empty(strip_tags($statusIcon))) {
  456. $post['user_data'] .= "<div class='tools-icons'> $statusIcon </div>";
  457. }
  458. }
  459. $buttonReply = '';
  460. $buttonQuote = '';
  461. $waitingValidation = '';
  462. if (($current_forum_category && $current_forum_category['locked'] == 0) &&
  463. $current_forum['locked'] == 0 && $current_thread['locked'] == 0 || api_is_allowed_to_edit(false, true)
  464. ) {
  465. if ($userId || ($current_forum['allow_anonymous'] == 1 && !$userId)) {
  466. if (!api_is_anonymous() && api_is_allowed_to_session_edit(false, true)) {
  467. $buttonReply = Display::toolbarButton(
  468. get_lang('ReplyToMessage'),
  469. 'reply.php?'.api_get_cidreq().'&'.http_build_query([
  470. 'forum' => $forumId,
  471. 'thread' => $threadId,
  472. 'post' => $post['post_id'],
  473. 'action' => 'replymessage',
  474. ]),
  475. 'reply',
  476. 'primary',
  477. ['id' => "reply-to-post-{$post['post_id']}"]
  478. );
  479. $buttonQuote = Display::toolbarButton(
  480. get_lang('QuoteMessage'),
  481. 'reply.php?'.api_get_cidreq().'&'.http_build_query([
  482. 'forum' => $forumId,
  483. 'thread' => $threadId,
  484. 'post' => $post['post_id'],
  485. 'action' => 'quote',
  486. ]),
  487. 'quote-left',
  488. 'success',
  489. ['id' => "quote-post-{$post['post_id']}"]
  490. );
  491. if ($current_forum['moderated'] && !api_is_allowed_to_edit(false, true)) {
  492. if (empty($post['status']) || $post['status'] == CForumPost::STATUS_WAITING_MODERATION) {
  493. $buttonReply = '';
  494. $buttonQuote = '';
  495. }
  496. }
  497. }
  498. }
  499. } else {
  500. $closedPost = '';
  501. if ($current_forum_category && $current_forum_category['locked'] == 1) {
  502. $closedPost = Display::tag(
  503. 'div',
  504. '<em class="fa fa-exclamation-triangle"></em> '.get_lang('ForumcategoryLocked'),
  505. ['class' => 'alert alert-warning post-closed']
  506. );
  507. }
  508. if ($current_forum['locked'] == 1) {
  509. $closedPost = Display::tag(
  510. 'div',
  511. '<em class="fa fa-exclamation-triangle"></em> '.get_lang('ForumLocked'),
  512. ['class' => 'alert alert-warning post-closed']
  513. );
  514. }
  515. if ($current_thread['locked'] == 1) {
  516. $closedPost = Display::tag(
  517. 'div',
  518. '<em class="fa fa-exclamation-triangle"></em> '.get_lang('ThreadLocked'),
  519. ['class' => 'alert alert-warning post-closed']
  520. );
  521. }
  522. $post['user_data'] .= $closedPost;
  523. }
  524. // note: this can be removed here because it will be displayed in the tree
  525. if (isset($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$post['post_id']]) &&
  526. !empty($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$post['post_id']]) &&
  527. !empty($whatsnew_post_info[$forumId][$post['thread_id']])
  528. ) {
  529. $post_image = Display::return_icon('forumpostnew.gif');
  530. } else {
  531. $post_image = Display::return_icon('forumpost.gif');
  532. }
  533. if ($post['post_notification'] == '1' && $post['poster_id'] == $userId) {
  534. $post_image .= Display::return_icon(
  535. 'forumnotification.gif',
  536. get_lang('YouWillBeNotified')
  537. );
  538. }
  539. $post['current'] = false;
  540. if (isset($_GET['post_id']) && $_GET['post_id'] == $post['post_id']) {
  541. $post['current'] = true;
  542. }
  543. // Replace Re: with an icon
  544. $search = [
  545. get_lang('ReplyShort'),
  546. 'Re:',
  547. 'RE:',
  548. 'AW:',
  549. 'Aw:',
  550. ];
  551. $replace = '<span>'.Display::returnFontAwesomeIcon('mail-reply').'</span>';
  552. $post['post_title'] = str_replace($search, $replace, Security::remove_XSS($post['post_title']));
  553. // The post title
  554. $titlePost = Display::tag('h3', $post['post_title'], ['class' => 'forum_post_title']);
  555. $post['post_title'] = '<a name="post_id_'.$post['post_id'].'"></a>';
  556. $post['post_title'] .= Display::tag('div', $titlePost, ['class' => 'post-header']);
  557. // the post body
  558. $post['post_data'] = Display::tag('div', $post['post_text'], ['class' => 'post-body']);
  559. // The check if there is an attachment
  560. $post['post_attachments'] = '';
  561. $attachment_list = getAllAttachment($post['post_id']);
  562. if (!empty($attachment_list) && is_array($attachment_list)) {
  563. foreach ($attachment_list as $attachment) {
  564. $user_filename = $attachment['filename'];
  565. $post['post_attachments'] .= Display::return_icon('attachment.gif', get_lang('Attachment'));
  566. $post['post_attachments'] .= '<a href="download.php?file=';
  567. $post['post_attachments'] .= $attachment['path'];
  568. $post['post_attachments'] .= ' "> '.$user_filename.' </a>';
  569. $post['post_attachments'] .= '<span class="forum_attach_comment" >'.$attachment['comment'].'</span>';
  570. if (($current_forum['allow_edit'] == 1 && $post['user_id'] == $userId) ||
  571. (api_is_allowed_to_edit(false, true) && !(api_is_session_general_coach() && $current_forum['session_id'] != $sessionId))
  572. ) {
  573. $post['post_attachments'] .= '&nbsp;&nbsp;<a href="'.api_get_self().'?'.api_get_cidreq().'&action=delete_attach&id_attach='
  574. .$attachment['iid'].'&forum='.$forumId.'&thread='.$threadId
  575. .'" onclick="javascript:if(!confirm(\''
  576. .addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES)).'\')) return false;">'
  577. .Display::return_icon('delete.png', get_lang('Delete')).'</a><br />';
  578. }
  579. }
  580. }
  581. $post['post_buttons'] = "$askForRevision $editButton $reportButton $buttonReply $buttonQuote $waitingValidation";
  582. $postList[] = $post;
  583. // The post has been displayed => it can be removed from the what's new array
  584. unset($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$post['post_id']]);
  585. unset($_SESSION['whatsnew_post_info'][$current_forum['forum_id']][$current_thread['thread_id']][$post['post_id']]);
  586. $count++;
  587. }
  588. $template->assign('posts', $postList);
  589. $formToString = '';
  590. $showForm = true;
  591. if (!api_is_allowed_to_edit(false, true) &&
  592. (($current_forum_category && $current_forum_category['visibility'] == 0) || $current_forum['visibility'] == 0)
  593. ) {
  594. $showForm = false;
  595. }
  596. if (!api_is_allowed_to_edit(false, true) &&
  597. (
  598. ($current_forum_category && $current_forum_category['locked'] != 0) ||
  599. $current_forum['locked'] != 0 || $current_thread['locked'] != 0
  600. )
  601. ) {
  602. $showForm = false;
  603. }
  604. if (!$_user['user_id'] && $current_forum['allow_anonymous'] == 0) {
  605. $showForm = false;
  606. }
  607. if ($current_forum['forum_of_group'] != 0) {
  608. $show_forum = GroupManager::user_has_access(
  609. api_get_user_id(),
  610. $current_forum['forum_of_group'],
  611. GroupManager::GROUP_TOOL_FORUM
  612. );
  613. if (!$show_forum) {
  614. $showForm = false;
  615. }
  616. }
  617. if ($showForm) {
  618. $form = show_add_post_form(
  619. $current_forum,
  620. 'replythread',
  621. null,
  622. false
  623. );
  624. $formToString = $form->returnForm();
  625. }
  626. $template->assign('form', $formToString);
  627. $layout = $template->get_template('forum/posts.tpl');
  628. $template->display($layout);