index.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. use Chamilo\CourseBundle\Entity\CForumPost;
  4. use ChamiloSession as Session;
  5. /**
  6. * These files are a complete rework of the forum. The database structure is
  7. * based on phpBB but all the code is rewritten. A lot of new functionalities
  8. * are added:
  9. * - forum categories and forums can be sorted up or down, locked or made invisible
  10. * - consistent and integrated forum administration
  11. * - forum options: are students allowed to edit their post?
  12. * moderation of posts (approval)
  13. * reply only forums (students cannot create new threads)
  14. * multiple forums per group
  15. * - sticky messages
  16. * - new view option: nested view
  17. * - quoting a message.
  18. *
  19. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  20. * @copyright Ghent University
  21. * @copyright Patrick Cool
  22. *
  23. * @package chamilo.forum
  24. */
  25. require_once __DIR__.'/../inc/global.inc.php';
  26. $current_course_tool = TOOL_FORUM;
  27. $htmlHeadXtra[] = '<script>
  28. $(document).ready(function() {
  29. $(\'.hide-me\').slideUp();
  30. });
  31. function hidecontent(content){
  32. $(content).slideToggle(\'normal\');
  33. }
  34. </script>';
  35. // The section (tabs).
  36. $this_section = SECTION_COURSES;
  37. // Notification for unauthorized people.
  38. api_protect_course_script(true);
  39. $nameTools = get_lang('Forums');
  40. $_course = api_get_course_info();
  41. $sessionId = api_get_session_id();
  42. $_user = api_get_user_info();
  43. // Including necessary files.
  44. require_once 'forumconfig.inc.php';
  45. require_once 'forumfunction.inc.php';
  46. if (api_is_in_gradebook()) {
  47. $interbreadcrumb[] = [
  48. 'url' => Category::getUrl(),
  49. 'name' => get_lang('ToolGradebook'),
  50. ];
  51. }
  52. $search_forum = isset($_GET['search']) ? Security::remove_XSS($_GET['search']) : '';
  53. /* ACTIONS */
  54. $actions = isset($_GET['action']) ? $_GET['action'] : '';
  55. if ($actions === 'add') {
  56. switch ($_GET['content']) {
  57. case 'forum':
  58. $interbreadcrumb[] = [
  59. 'url' => 'index.php?search='.$search_forum.'&'.api_get_cidreq(),
  60. 'name' => get_lang('Forum'),
  61. ];
  62. $interbreadcrumb[] = [
  63. 'url' => '#',
  64. 'name' => get_lang('AddForum'),
  65. ];
  66. break;
  67. case 'forumcategory':
  68. $interbreadcrumb[] = [
  69. 'url' => 'index.php?search='.$search_forum.'&'.api_get_cidreq(),
  70. 'name' => get_lang('Forum'),
  71. ];
  72. $interbreadcrumb[] = [
  73. 'url' => '#',
  74. 'name' => get_lang('AddForumCategory'),
  75. ];
  76. break;
  77. default:
  78. break;
  79. }
  80. } else {
  81. $interbreadcrumb[] = [
  82. 'url' => '#',
  83. 'name' => get_lang('ForumCategories'),
  84. ];
  85. }
  86. // Tool introduction
  87. $introduction = Display::return_introduction_section(TOOL_FORUM);
  88. $form_count = 0;
  89. $formContent = '';
  90. if (api_is_allowed_to_edit(false, true)) {
  91. //if is called from a learning path lp_id
  92. $lp_id = isset($_REQUEST['lp_id']) ? intval($_REQUEST['lp_id']) : null;
  93. $formContent = handle_forum_and_forumcategories($lp_id);
  94. }
  95. // Notification
  96. if ($actions == 'notify' && isset($_GET['content']) && isset($_GET['id'])) {
  97. if (api_get_session_id() != 0 &&
  98. api_is_allowed_to_session_edit(false, true) == false
  99. ) {
  100. api_not_allowed();
  101. }
  102. $return_message = set_notification($_GET['content'], $_GET['id']);
  103. Display::addFlash(Display::return_message($return_message, 'confirm', false));
  104. }
  105. get_whats_new();
  106. $whatsnew_post_info = Session::read('whatsnew_post_info');
  107. /* TRACKING */
  108. Event::event_access_tool(TOOL_FORUM);
  109. /*
  110. RETRIEVING ALL THE FORUM CATEGORIES AND FORUMS
  111. note: we do this here just after het handling of the actions to be
  112. sure that we already incorporate the latest changes
  113. */
  114. // Step 1: We store all the forum categories in an array $forum_categories.
  115. $forumCategories = get_forum_categories();
  116. // Step 2: We find all the forums (only the visible ones if it is a student).
  117. // display group forum in general forum tool depending to configuration option
  118. $setting = api_get_setting('display_groups_forum_in_general_tool');
  119. $allCourseForums = get_forums('', '', $setting === 'true');
  120. $user_id = api_get_user_id();
  121. /* RETRIEVING ALL GROUPS AND THOSE OF THE USER */
  122. // The groups of the user.
  123. $groups_of_user = [];
  124. $groups_of_user = GroupManager::get_group_ids($_course['real_id'], $user_id);
  125. // All groups in the course (and sorting them as the
  126. // id of the group = the key of the array).
  127. if (!api_is_anonymous()) {
  128. $all_groups = GroupManager::get_group_list();
  129. if (is_array($all_groups)) {
  130. foreach ($all_groups as $group) {
  131. $all_groups[$group['id']] = $group;
  132. }
  133. }
  134. }
  135. /* ACTION LINKS */
  136. $actionLeft = null;
  137. //if is called from learning path
  138. if (!empty($_GET['lp_id']) || !empty($_POST['lp_id'])) {
  139. $url = "../lp/lp_controller.php?".api_get_cidreq()
  140. ."&gradebook=&action=add_item&type=step&lp_id='.$lp_id.'#resource_tab-5";
  141. $actionLeft .= Display::url(
  142. Display::return_icon(
  143. 'back.png',
  144. get_lang("BackTo").' '.get_lang("LearningPaths"),
  145. null,
  146. ICON_SIZE_MEDIUM
  147. ),
  148. $url
  149. );
  150. }
  151. if (!empty($allCourseForums)) {
  152. $actionLeft .= search_link();
  153. }
  154. if (api_is_allowed_to_edit(false, true)) {
  155. $actionLeft .= Display::url(
  156. Display::return_icon(
  157. 'new_folder.png',
  158. get_lang('AddForumCategory'),
  159. null,
  160. ICON_SIZE_MEDIUM
  161. ),
  162. api_get_self().'?'.api_get_cidreq().'&action=add&content=forumcategory&lp_id='.$lp_id
  163. );
  164. if (is_array($forumCategories) && !empty($forumCategories)) {
  165. $actionLeft .= Display::url(
  166. Display::return_icon(
  167. 'new_forum.png',
  168. get_lang('AddForum'),
  169. null,
  170. ICON_SIZE_MEDIUM
  171. ),
  172. api_get_self().'?'.api_get_cidreq().'&action=add&content=forum&lp_id='.$lp_id
  173. );
  174. }
  175. }
  176. $actions = Display::toolbarAction('toolbar-forum', [$actionLeft]);
  177. // Fixes error if there forums with no category.
  178. $forumsInNoCategory = get_forums_in_category(0);
  179. if (!empty($forumsInNoCategory)) {
  180. $forumCategories = array_merge(
  181. $forumCategories,
  182. [
  183. [
  184. 'cat_id' => 0,
  185. 'session_id' => 0,
  186. 'visibility' => 1,
  187. 'cat_comment' => null,
  188. ],
  189. ]
  190. );
  191. }
  192. /* Display Forum Categories and the Forums in it */
  193. // Step 3: We display the forum_categories first.
  194. $listForumCategory = [];
  195. $forumCategoryInfo = [];
  196. if (is_array($forumCategories)) {
  197. foreach ($forumCategories as $forumCategory) {
  198. $forumCategoryInfo['id'] = $forumCategory['cat_id'];
  199. if (empty($forumCategory['cat_title'])) {
  200. $forumCategoryInfo['title'] = get_lang('WithoutCategory');
  201. } else {
  202. $forumCategoryInfo['title'] = $forumCategory['cat_title'];
  203. }
  204. $forumCategoryInfo['icon_session'] = api_get_session_image(
  205. $forumCategory['session_id'],
  206. $_user['status']
  207. );
  208. // Validation when belongs to a session
  209. $forumCategoryInfo['description'] = $forumCategory['cat_comment'];
  210. if (empty($sessionId) && !empty($forumCategory['session_name'])) {
  211. $forumCategory['session_display'] = ' ('.Security::remove_XSS($forumCategory['session_name']).')';
  212. } else {
  213. $forumCategory['session_display'] = null;
  214. }
  215. $tools = null;
  216. $idCategory = $forumCategory['cat_id'];
  217. $forumCategoryInfo['url'] = 'viewforumcategory.php?'.api_get_cidreq().'&forumcategory='.intval($idCategory);
  218. if (!empty($idCategory)) {
  219. if (api_is_allowed_to_edit(false, true) &&
  220. !($forumCategory['session_id'] == 0 && intval($sessionId) != 0)
  221. ) {
  222. $tools .= '<a href="'.api_get_self().'?'.api_get_cidreq()
  223. .'&action=edit&content=forumcategory&id='.intval($idCategory)
  224. .'">'.Display::return_icon(
  225. 'edit.png',
  226. get_lang('Edit'),
  227. [],
  228. ICON_SIZE_SMALL
  229. )
  230. .'</a>';
  231. $tools .= '<a href="'.api_get_self().'?'.api_get_cidreq()
  232. .'&action=delete&content=forumcategory&id='.intval($idCategory)
  233. ."\" onclick=\"javascript:if(!confirm('"
  234. .addslashes(api_htmlentities(
  235. get_lang('DeleteForumCategory'),
  236. ENT_QUOTES
  237. ))
  238. ."')) return false;\">"
  239. .Display::return_icon(
  240. 'delete.png',
  241. get_lang('Delete'),
  242. [],
  243. ICON_SIZE_SMALL
  244. )
  245. .'</a>';
  246. $tools .= return_visible_invisible_icon(
  247. 'forumcategory',
  248. $idCategory,
  249. $forumCategory['visibility']
  250. );
  251. $tools .= return_lock_unlock_icon(
  252. 'forumcategory',
  253. $idCategory,
  254. $forumCategory['locked']
  255. );
  256. $tools .= return_up_down_icon(
  257. 'forumcategory',
  258. $idCategory,
  259. $forumCategories
  260. );
  261. }
  262. }
  263. $forumCategoryInfo['tools'] = $tools;
  264. $forumCategoryInfo['forums'] = [];
  265. // The forums in this category.
  266. $forumInfo = [];
  267. $forumsInCategory = get_forums_in_category($forumCategory['cat_id']);
  268. if (!empty($forumsInCategory)) {
  269. $forumsDetailsList = null;
  270. // We display all the forums in this category.
  271. foreach ($allCourseForums as $forum) {
  272. // Here we clean the whatnew_post_info array a little bit because to display the icon we
  273. // test if $whatsnew_post_info[$forum['forum_id']] is empty or not.
  274. if (isset($forum['forum_id'])) {
  275. if (!empty($whatsnew_post_info)) {
  276. if (isset($whatsnew_post_info[$forum['forum_id']]) &&
  277. is_array($whatsnew_post_info[$forum['forum_id']])
  278. ) {
  279. foreach ($whatsnew_post_info[$forum['forum_id']] as $key_thread_id => $new_post_array) {
  280. if (empty($whatsnew_post_info[$forum['forum_id']][$key_thread_id])) {
  281. unset($whatsnew_post_info[$forum['forum_id']][$key_thread_id]);
  282. unset($_SESSION['whatsnew_post_info'][$forum['forum_id']][$key_thread_id]);
  283. }
  284. }
  285. }
  286. }
  287. }
  288. // Note: This can be speed up if we transform the $allCourseForums
  289. // to an array that uses the forum_category as the key.
  290. if (isset($forum['forum_category']) && $forum['forum_category'] == $forumCategory['cat_id']) {
  291. $show_forum = false;
  292. // SHOULD WE SHOW THIS PARTICULAR FORUM
  293. // you are teacher => show forum
  294. if (api_is_allowed_to_edit(false, true)) {
  295. $show_forum = true;
  296. } else {
  297. // you are not a teacher
  298. // it is not a group forum => show forum
  299. // (invisible forums are already left out see get_forums function)
  300. if ($forum['forum_of_group'] == '0') {
  301. $show_forum = true;
  302. } else {
  303. $show_forum = GroupManager::user_has_access(
  304. $user_id,
  305. $forum['forum_of_group'],
  306. GroupManager::GROUP_TOOL_FORUM
  307. );
  308. }
  309. }
  310. if ($show_forum) {
  311. $form_count++;
  312. $mywhatsnew_post_info = isset($whatsnew_post_info[$forum['forum_id']])
  313. ? $whatsnew_post_info[$forum['forum_id']]
  314. : null;
  315. $forumInfo['id'] = $forum['forum_id'];
  316. $forumInfo['forum_of_group'] = $forum['forum_of_group'];
  317. $forumInfo['title'] = $forum['forum_title'];
  318. $forumInfo['forum_image'] = null;
  319. // Showing the image
  320. if (!empty($forum['forum_image'])) {
  321. $image_path = api_get_path(WEB_COURSE_PATH).api_get_course_path().'/upload/forum/images/'
  322. .$forum['forum_image'];
  323. $image_size = api_getimagesize($image_path);
  324. $img_attributes = '';
  325. if (!empty($image_size)) {
  326. $forumInfo['forum_image'] = $image_path;
  327. }
  328. }
  329. // Validation when belongs to a session
  330. $forumInfo['icon_session'] = api_get_session_image(
  331. $forum['session_id'],
  332. $_user['status']
  333. );
  334. if ($forum['forum_of_group'] != '0') {
  335. $my_all_groups_forum_name = isset($all_groups[$forum['forum_of_group']]['name'])
  336. ? $all_groups[$forum['forum_of_group']]['name']
  337. : null;
  338. $my_all_groups_forum_id = isset($all_groups[$forum['forum_of_group']]['id'])
  339. ? $all_groups[$forum['forum_of_group']]['id']
  340. : null;
  341. $group_title = api_substr($my_all_groups_forum_name, 0, 30);
  342. $forumInfo['forum_group_title'] = $group_title;
  343. }
  344. $forum['forum_of_group'] == 0 ? $groupid = '' : $groupid = $forum['forum_of_group'];
  345. $forumInfo['visibility'] = $forum['visibility'];
  346. $forumInfo['number_threads'] = isset($forum['number_of_threads'])
  347. ? (int) $forum['number_of_threads']
  348. : 0;
  349. //$number_posts = isset($forum['number_of_posts']) ? $forum['number_of_posts'] : 0;
  350. $linkForum = api_get_path(WEB_CODE_PATH).'forum/viewforum.php?'.api_get_cidreq()
  351. .'&gidReq='.$groupid.'&forum='.$forum['forum_id'];
  352. $forumInfo['url'] = $linkForum;
  353. if (!empty($forum['start_time']) && !empty($forum['end_time'])) {
  354. $res = api_is_date_in_date_range($forum['start_time'], $forum['end_time']);
  355. if (!$res) {
  356. $linkForum = $forum['forum_title'];
  357. }
  358. }
  359. $forumInfo['description'] = Security::remove_XSS($forum['forum_comment']);
  360. if ($forum['moderated'] == 1 && api_is_allowed_to_edit(false, true)) {
  361. $waitingCount = getCountPostsWithStatus(
  362. CForumPost::STATUS_WAITING_MODERATION,
  363. $forum
  364. );
  365. if (!empty($waitingCount)) {
  366. $forumInfo['moderation'] = $waitingCount;
  367. }
  368. }
  369. $toolActions = null;
  370. $forumInfo['alert'] = null;
  371. // The number of topics and posts.
  372. if ($forum['forum_of_group'] !== '0') {
  373. if (is_array($mywhatsnew_post_info) && !empty($mywhatsnew_post_info)) {
  374. $forumInfo['alert'] = ' '.
  375. Display::return_icon(
  376. 'alert.png',
  377. get_lang('Forum'),
  378. null,
  379. ICON_SIZE_SMALL
  380. );
  381. }
  382. } else {
  383. if (is_array($mywhatsnew_post_info) && !empty($mywhatsnew_post_info)) {
  384. $forumInfo['alert'] = ' '.Display::return_icon(
  385. 'alert.png',
  386. get_lang('Forum'),
  387. null,
  388. ICON_SIZE_SMALL
  389. );
  390. }
  391. }
  392. $poster_id = null;
  393. // The last post in the forum.
  394. if (isset($forum['last_poster_name']) && $forum['last_poster_name'] != '') {
  395. $name = $forum['last_poster_name'];
  396. $poster_id = 0;
  397. $username = "";
  398. } else {
  399. if (isset($forum['last_poster_firstname'])) {
  400. $name = api_get_person_name(
  401. $forum['last_poster_firstname'],
  402. $forum['last_poster_lastname']
  403. );
  404. $poster_id = $forum['last_poster_id'];
  405. $userinfo = api_get_user_info($poster_id);
  406. $username = sprintf(
  407. get_lang('LoginX'),
  408. $userinfo['username']
  409. );
  410. }
  411. }
  412. $forumInfo['last_poster_id'] = $poster_id;
  413. if (!empty($forum['last_poster_id'])) {
  414. $forumInfo['last_poster_date'] = api_convert_and_format_date($forum['last_post_date']);
  415. $forumInfo['last_poster_user'] = display_user_link($poster_id, $name, null, $username);
  416. }
  417. if (api_is_allowed_to_edit(false, true)
  418. && !($forum['session_id'] == 0 && intval($sessionId) != 0)
  419. ) {
  420. $toolActions .= '<a href="'.api_get_self().'?'.api_get_cidreq()
  421. .'&action=edit&content=forum&id='.$forum['forum_id'].'">'
  422. .Display::return_icon('edit.png', get_lang('Edit'), [], ICON_SIZE_SMALL)
  423. .'</a>';
  424. $toolActions .= '<a href="'.api_get_self().'?'.api_get_cidreq()
  425. .'&action=delete&content=forum&id='.$forum['forum_id']
  426. ."\" onclick=\"javascript:if(!confirm('".addslashes(
  427. api_htmlentities(get_lang('DeleteForum'), ENT_QUOTES)
  428. )
  429. ."')) return false;\">"
  430. .Display::return_icon('delete.png', get_lang('Delete'), [], ICON_SIZE_SMALL)
  431. .'</a>';
  432. $toolActions .= return_visible_invisible_icon(
  433. 'forum',
  434. $forum['forum_id'],
  435. $forum['visibility']
  436. );
  437. $toolActions .= return_lock_unlock_icon(
  438. 'forum',
  439. $forum['forum_id'],
  440. $forum['locked']
  441. );
  442. $toolActions .= return_up_down_icon(
  443. 'forum',
  444. $forum['forum_id'],
  445. $forumsInCategory
  446. );
  447. }
  448. $iconnotify = 'notification_mail_na.png';
  449. $session_forum_notification = isset($_SESSION['forum_notification']['forum'])
  450. ? $_SESSION['forum_notification']['forum']
  451. : false;
  452. if (is_array($session_forum_notification)) {
  453. if (in_array($forum['forum_id'], $session_forum_notification)) {
  454. $iconnotify = 'notification_mail.png';
  455. }
  456. }
  457. if (!api_is_anonymous() && api_is_allowed_to_session_edit(false, true)) {
  458. $toolActions .= '<a href="'.api_get_self().'?'.api_get_cidreq()
  459. .'&action=notify&content=forum&id='.$forum['forum_id'].'">'
  460. .Display::return_icon($iconnotify, get_lang('NotifyMe'), null, ICON_SIZE_SMALL)
  461. .'</a>';
  462. }
  463. $forumInfo['tools'] = $toolActions;
  464. $forumsDetailsList[] = $forumInfo;
  465. }
  466. }
  467. }
  468. $forumCategoryInfo['forums'] = $forumsDetailsList;
  469. }
  470. $listForumCategory[] = $forumCategoryInfo;
  471. }
  472. }
  473. $tpl = new Template($nameTools);
  474. $tpl->assign('introduction_section', $introduction);
  475. $tpl->assign('actions', $actions);
  476. $tpl->assign('data', $listForumCategory);
  477. $tpl->assign('form_content', $formContent);
  478. $layout = $tpl->get_template('forum/list.tpl');
  479. $tpl->display($layout);