index.php 26 KB

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