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('Assessments'),
  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('Group area').' '.$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('Back to forum'), '', 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('Reply to this thread'), '', 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('Forum blocked');
  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('To get the expected score in this forum, your contribution will have to be scored by another student, and you will have to score at least 2 other student\'s contributions. Until you reach this objective, even if scored, your contribution will show as a 0 score in the global grades for this course.'), '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('Login: %s'), $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('Are you sure you want to delete this post? Deleting this post will also delete the replies on this post. Please check the threaded view to see which posts will also be deleted'), 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('Move post'), [], 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('Grade activity'))."</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('Reply to this message'),
  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('Quote this message'),
  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('Forum category Locked'),
  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('Forum blocked'),
  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('Thread is locked.'),
  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('You will be notified')
  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('Re:'),
  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('Please confirm your choice'), 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);