viewthread_nested.inc.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. use Chamilo\CourseBundle\Entity\CForumPost;
  4. /**
  5. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  6. * @author Julio Montoya <gugli100@gmail.com> UI Improvements + lots of bugfixes
  7. * @copyright Ghent University
  8. * @package chamilo.forum
  9. */
  10. // Are we in a lp ?
  11. $origin = api_get_origin();
  12. //delete attachment file
  13. if (isset($_GET['action']) &&
  14. $_GET['action'] == 'delete_attach' &&
  15. isset($_GET['id_attach'])
  16. ) {
  17. delete_attachment(0, $_GET['id_attach']);
  18. }
  19. // Decide whether we show the latest post first
  20. $sortDirection = isset($_GET['posts_order']) && $_GET['posts_order'] === 'desc' ? 'DESC' : ($origin != 'learnpath' ? 'ASC' : 'DESC');
  21. $posts = getPosts($current_forum, $_GET['thread'], $sortDirection, true);
  22. $count = 0;
  23. $clean_forum_id = intval($_GET['forum']);
  24. $clean_thread_id = intval($_GET['thread']);
  25. $group_id = api_get_group_id();
  26. $locked = api_resource_is_locked_by_gradebook($clean_thread_id, LINK_FORUM_THREAD);
  27. $sessionId = api_get_session_id();
  28. $currentThread = get_thread_information($clean_forum_id, $_GET['thread']);
  29. $userId = api_get_user_id();
  30. $groupInfo = GroupManager::get_group_properties($group_id);
  31. $postCount = 1;
  32. $allowUserImageForum = api_get_course_setting('allow_user_image_forum');
  33. foreach ($posts as $post) {
  34. // The style depends on the status of the message: approved or not.
  35. if ($post['visible'] == '0') {
  36. $titleclass = 'forum_message_post_title_2_be_approved';
  37. $messageclass = 'forum_message_post_text_2_be_approved';
  38. $leftclass = 'forum_message_left_2_be_approved';
  39. } else {
  40. $titleclass = 'forum_message_post_title';
  41. $messageclass = 'forum_message_post_text';
  42. $leftclass = 'forum_message_left';
  43. }
  44. $indent = $post['indent_cnt'];
  45. $html = '';
  46. $html .= '<div class="col-md-offset-'.$indent.'" >';
  47. $html .= '<div class="panel panel-default forum-post">';
  48. $html .= '<div class="panel-body">';
  49. $html .= '<div class="row">';
  50. $html .= '<div class="col-md-2">';
  51. $username = sprintf(get_lang('LoginX'), $post['username']);
  52. if ($post['user_id'] == '0') {
  53. $name = $post['poster_name'];
  54. } else {
  55. $name = api_get_person_name($post['firstname'], $post['lastname']);
  56. }
  57. if ($origin != 'learnpath') {
  58. if ($allowUserImageForum) {
  59. $html .= '<div class="thumbnail">'.display_user_image($post['user_id'], $name, $origin).'</div>';
  60. }
  61. $html .= Display::tag(
  62. 'h4',
  63. display_user_link($post['user_id'], $name, $origin, $username),
  64. array('class' => 'title-username')
  65. );
  66. } else {
  67. if ($allowUserImageForum) {
  68. $html .= '<div class="thumbnail">'.display_user_image($post['user_id'], $name, $origin).'</div>';
  69. }
  70. $html .= Display::tag(
  71. 'p',
  72. $name,
  73. array(
  74. 'title' => api_htmlentities($username, ENT_QUOTES),
  75. 'class' => 'lead'
  76. )
  77. );
  78. }
  79. if ($origin != 'learnpath') {
  80. $html .= Display::tag(
  81. 'p',
  82. Display::dateToStringAgoAndLongDate($post['post_date']),
  83. array('class' => 'post-date')
  84. );
  85. } else {
  86. $html .= Display::tag(
  87. 'p',
  88. Display::dateToStringAgoAndLongDate($post['post_date']),
  89. array('class' => 'text-muted')
  90. );
  91. }
  92. // get attach id
  93. $attachment_list = get_attachment($post['post_id']);
  94. $id_attach = !empty($attachment_list) ? $attachment_list['iid'] : '';
  95. $iconEdit = '';
  96. $editButton = '';
  97. // The user who posted it can edit his thread only if the course admin allowed this in the properties of the forum
  98. // The course admin him/herself can do this off course always
  99. $tutorGroup = GroupManager::is_tutor_of_group(api_get_user_id(), $groupInfo);
  100. if ((isset($groupInfo['iid']) && $tutorGroup) ||
  101. ($current_forum['allow_edit'] == 1 && $post['user_id'] == $userId) ||
  102. (api_is_allowed_to_edit(false, true) &&
  103. !(api_is_course_coach() && $current_forum['session_id'] != $sessionId))
  104. ) {
  105. if ($locked == false && postIsEditableByStudent($current_forum, $post)) {
  106. $editUrl = api_get_path(WEB_CODE_PATH).'forum/editpost.php?'.api_get_cidreq();
  107. $editUrl .= "&forum=$clean_forum_id&thread=$clean_thread_id&post={$post['post_id']}&id_attach=$id_attach";
  108. $iconEdit .= "<a href='".$editUrl."'>"
  109. . Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL)
  110. . "</a>";
  111. $editButton = Display::toolbarButton(
  112. get_lang('Edit'),
  113. $editUrl,
  114. 'pencil',
  115. 'default'
  116. );
  117. }
  118. }
  119. if ((isset($groupInfo['iid']) && $tutorGroup) ||
  120. api_is_allowed_to_edit(false, true) &&
  121. !(api_is_course_coach() && $current_forum['session_id'] != $sessionId)
  122. ) {
  123. if ($locked == false) {
  124. $deleteUrl = api_get_self().'?'.api_get_cidreq().'&'.http_build_query([
  125. 'forum' => $clean_forum_id,
  126. 'thread' => $clean_thread_id,
  127. 'action' => 'delete',
  128. 'content' => 'post',
  129. 'id' => $post['post_id']
  130. ]);
  131. $iconEdit .= Display::url(
  132. Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL),
  133. $deleteUrl,
  134. [
  135. 'onclick' => "javascript:if(!confirm('"
  136. . addslashes(api_htmlentities(get_lang('DeletePost'), ENT_QUOTES))
  137. . "')) return false;",
  138. 'id' => "delete-post-{$post['post_id']}"
  139. ]
  140. );
  141. }
  142. }
  143. if (api_is_allowed_to_edit(false, true) &&
  144. !(
  145. api_is_course_coach() &&
  146. $current_forum['session_id'] != $sessionId
  147. )
  148. ) {
  149. $iconEdit .= return_visible_invisible_icon(
  150. 'post',
  151. $post['post_id'],
  152. $post['visible'],
  153. array(
  154. 'forum' => $clean_forum_id,
  155. 'thread' => $clean_thread_id
  156. )
  157. );
  158. if ($count > 0) {
  159. $iconEdit .= "<a href=\"viewthread.php?".api_get_cidreq()
  160. . "&forum=$clean_forum_id&thread=$clean_thread_id&action=move&post={$post['post_id']}"
  161. . "\">".Display::return_icon('move.png', get_lang('MovePost'), array(), ICON_SIZE_SMALL)."</a>";
  162. }
  163. }
  164. $userCanQualify = $currentThread['thread_peer_qualify'] == 1 && $post['poster_id'] != $userId;
  165. if (api_is_allowed_to_edit(null, true)) {
  166. $userCanQualify = true;
  167. }
  168. if (empty($currentThread['thread_qualify_max'])) {
  169. $userCanQualify = false;
  170. }
  171. if ($userCanQualify) {
  172. if ($count > 0) {
  173. $current_qualify_thread = showQualify(
  174. '1',
  175. $post['user_id'],
  176. $_GET['thread']
  177. );
  178. if ($locked == false) {
  179. $iconEdit .= "<a href=\"forumqualify.php?".api_get_cidreq()
  180. . "&forum=$clean_forum_id&thread=$clean_thread_id&action=list&post={$post['post_id']}"
  181. . "&user={$post['user_id']}&user_id={$post['user_id']}"
  182. . "&idtextqualify=$current_qualify_thread"
  183. . "\" >".Display::return_icon('quiz.png', get_lang('Qualify'))."</a>";
  184. }
  185. }
  186. }
  187. $statusIcon = getPostStatus($current_forum, $post);
  188. if (!empty($iconEdit)) {
  189. $html .= '<div class="tools-icons">'.$iconEdit.' '.$statusIcon.'</div>';
  190. } else {
  191. if (!empty(strip_tags($statusIcon))) {
  192. $html .= '<div class="tools-icons">'.$statusIcon.'</div>';
  193. }
  194. }
  195. $buttonReply = '';
  196. $buttonQuote = '';
  197. $waitingValidation = '';
  198. if (($current_forum_category && $current_forum_category['locked'] == 0) &&
  199. $current_forum['locked'] == 0 && $current_thread['locked'] == 0 || api_is_allowed_to_edit(false, true)
  200. ) {
  201. if ($userId || ($current_forum['allow_anonymous'] == 1 && !$userId)) {
  202. if (!api_is_anonymous() && api_is_allowed_to_session_edit(false, true)) {
  203. $buttonReply = Display::toolbarButton(
  204. get_lang('ReplyToMessage'),
  205. 'reply.php?'.api_get_cidreq().'&'.http_build_query([
  206. 'forum' => $clean_forum_id,
  207. 'thread' => $clean_thread_id,
  208. 'post' => $post['post_id'],
  209. 'action' => 'replymessage'
  210. ]),
  211. 'reply',
  212. 'primary',
  213. ['id' => "reply-to-post-{$post['post_id']}"]
  214. );
  215. $buttonQuote = Display::toolbarButton(
  216. get_lang('QuoteMessage'),
  217. 'reply.php?'.api_get_cidreq().'&'.http_build_query([
  218. 'forum' => $clean_forum_id,
  219. 'thread' => $clean_thread_id,
  220. 'post' => $post['post_id'],
  221. 'action' => 'quote'
  222. ]),
  223. 'quote-left',
  224. 'success',
  225. ['id' => "quote-post-{$post['post_id']}"]
  226. );
  227. if ($current_forum['moderated'] && !api_is_allowed_to_edit(false, true)) {
  228. if (empty($post['status']) || $post['status'] == CForumPost::STATUS_WAITING_MODERATION) {
  229. $buttonReply = '';
  230. $buttonQuote = '';
  231. }
  232. }
  233. }
  234. }
  235. } else {
  236. $closedPost = '';
  237. if ($current_forum_category && $current_forum_category['locked'] == 1) {
  238. $closedPost = Display::tag(
  239. 'div',
  240. '<em class="fa fa-exclamation-triangle"></em> '.get_lang('ForumcategoryLocked'),
  241. array('class' => 'alert alert-warning post-closed')
  242. );
  243. }
  244. if ($current_forum['locked'] == 1) {
  245. $closedPost = Display::tag(
  246. 'div',
  247. '<em class="fa fa-exclamation-triangle"></em> '.get_lang('ForumLocked'),
  248. array('class' => 'alert alert-warning post-closed')
  249. );
  250. }
  251. if ($current_thread['locked'] == 1) {
  252. $closedPost = Display::tag(
  253. 'div',
  254. '<em class="fa fa-exclamation-triangle"></em> '.get_lang('ThreadLocked'),
  255. array('class' => 'alert alert-warning post-closed')
  256. );
  257. }
  258. $html .= $closedPost;
  259. }
  260. $html .= '</div>';
  261. // note: this can be removed here because it will be displayed in the tree
  262. if (
  263. isset($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$post['post_id']]) &&
  264. !empty($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$post['post_id']]) &&
  265. !empty($whatsnew_post_info[$_GET['forum']][$post['thread_id']])
  266. ) {
  267. $post_image = Display::return_icon('forumpostnew.gif');
  268. } else {
  269. $post_image = Display::return_icon('forumpost.gif');
  270. }
  271. if ($post['post_notification'] == '1' && $post['poster_id'] == $userId) {
  272. $post_image .= Display::return_icon(
  273. 'forumnotification.gif',
  274. get_lang('YouWillBeNotified')
  275. );
  276. }
  277. $html .= '<div class="col-md-10">';
  278. // The post title
  279. $titlePost = Display::tag('h3', $post['post_title'], array('class' => 'forum_post_title'));
  280. $html .= Display::tag('div', $titlePost, array('class' => 'post-header'));
  281. // the post body
  282. $html .= Display::tag('div', $post['post_text'], array('class' => 'post-body'));
  283. $html .= '</div>';
  284. $html .= '</div>';
  285. $html .= '<div class="row">';
  286. $html .= '<div class="col-md-6">';
  287. // The check if there is an attachment
  288. $attachment_list = getAllAttachment($post['post_id']);
  289. if (!empty($attachment_list) && is_array($attachment_list)) {
  290. foreach ($attachment_list as $attachment) {
  291. $user_filename = $attachment['filename'];
  292. $html .= Display::return_icon('attachment.gif', get_lang('Attachment'));
  293. $html .= '<a href="download.php?file=';
  294. $html .= $attachment['path'];
  295. $html .= ' "> '.$user_filename.' </a>';
  296. $html .= '<span class="forum_attach_comment" >'.$attachment['comment'].'</span>';
  297. if (($current_forum['allow_edit'] == 1 && $post['user_id'] == $userId) ||
  298. (api_is_allowed_to_edit(false, true) && !(api_is_course_coach() && $current_forum['session_id'] != $sessionId))
  299. ) {
  300. $html .= '&nbsp;&nbsp;<a href="'.api_get_self().'?'.api_get_cidreq().'&action=delete_attach&id_attach='
  301. . $attachment['iid'].'&forum='.$clean_forum_id.'&thread='.$clean_thread_id
  302. . '" onclick="javascript:if(!confirm(\''
  303. . addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES)).'\')) return false;">'
  304. . Display::return_icon('delete.gif', get_lang('Delete')).'</a><br />';
  305. }
  306. }
  307. }
  308. $html .= '</div>';
  309. $html .= '<div class="col-md-6 text-right">';
  310. $html .= "$editButton $buttonReply $buttonQuote $waitingValidation";
  311. $html .= '</div>';
  312. $html .= '</div>';
  313. // The post has been displayed => it can be removed from the what's new array
  314. unset($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$post['post_id']]);
  315. unset($_SESSION['whatsnew_post_info'][$current_forum['forum_id']][$current_thread['thread_id']][$post['post_id']]);
  316. $html .= '</div>';
  317. $html .= '</div>';
  318. $html .= '</div>';
  319. echo $html;
  320. $count++;
  321. }