PageRenderTime 61ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/forums/inc/forums.posts.php

http://github.com/Cotonti/Cotonti
PHP | 637 lines | 499 code | 97 blank | 41 comment | 164 complexity | 4eecde4c8f1cce89497a61372b7865bd MD5 | raw file
Possible License(s): LGPL-2.1, MPL-2.0-no-copyleft-exception
  1. <?php
  2. /**
  3. * Forums posts display.
  4. *
  5. * @package Forums
  6. * @copyright (c) Cotonti Team
  7. * @license https://github.com/Cotonti/Cotonti/blob/master/License.txt
  8. */
  9. defined('COT_CODE') or die('Wrong URL');
  10. $id = cot_import('id', 'G', 'INT'); // post id
  11. $s = cot_import('s', 'G', 'TXT'); // section cat
  12. $q = cot_import('q', 'G', 'INT'); // topic id
  13. $p = cot_import('p', 'G', 'INT'); // post id
  14. list($pg, $d, $durl) = cot_import_pagenav('d', cot::$cfg['forums']['maxpostsperpage']); // page
  15. $quote = cot_import('quote', 'G', 'INT');
  16. require_once cot_langfile('countries', 'core');
  17. require_once cot_incfile('forms');
  18. /* === Hook === */
  19. foreach (cot_getextplugins('forums.posts.first') as $pl)
  20. {
  21. include $pl;
  22. }
  23. /* ===== */
  24. if ((!empty($n) && !empty($q)) || !empty($p) || !empty($id)) {
  25. if (!empty($q) && ($n == 'last' || ($n == 'unread' && cot::$usr['id'] == 0))) {
  26. $sql_forums = cot::$db->query("SELECT fp_id, fp_topicid, fp_cat, fp_posterid FROM $db_forum_posts
  27. WHERE fp_topicid = $q ORDER by fp_id DESC LIMIT 1");
  28. } elseif ($n == 'unread' && !empty($q) && cot::$usr['id'] > 0) {
  29. $sql_forums = cot::$db->query("SELECT fp_id, fp_topicid, fp_cat, fp_posterid
  30. FROM $db_forum_posts WHERE fp_topicid = $q AND fp_updated > " . cot::$usr['lastvisit'] . " ORDER by fp_id ASC LIMIT 1");
  31. if ($sql_forums->rowCount() == 0) {
  32. $sql_forums = cot::$db->query("SELECT fp_id, fp_topicid, fp_cat, fp_posterid FROM $db_forum_posts
  33. WHERE fp_topicid = $q ORDER by fp_id DESC LIMIT 1");
  34. }
  35. } elseif (!empty($p) || !empty($id)) {
  36. $p = ($p > 0) ? $p : $id;
  37. $sql_forums = cot::$db->query("SELECT fp_id, fp_topicid, fp_cat, fp_posterid, fp_creation FROM $db_forum_posts WHERE fp_id = ?", $p);
  38. }
  39. if (isset($sql_forums) && is_object($sql_forums) && $sql_forums->rowCount() > 0) {
  40. $row = $sql_forums->fetch();
  41. $p = $row['fp_id'];
  42. $q = $row['fp_topicid'];
  43. $s = $row['fp_cat'];
  44. $fp_posterid = $row['fp_posterid'];
  45. }
  46. } elseif (!empty($q)) {
  47. $sql_forums = cot::$db->query("SELECT ft_cat FROM $db_forum_topics WHERE ft_id = $q LIMIT 1");
  48. if ($row = $sql_forums->fetch()) {
  49. $s = $row['ft_cat'];
  50. }
  51. }
  52. (empty($s)) && cot_die(true, true);
  53. isset(cot::$structure['forums'][$s]) || cot_die(true, true);
  54. list(cot::$usr['auth_read'], cot::$usr['auth_write'], cot::$usr['isadmin']) = cot_auth('forums', $s);
  55. /* === Hook === */
  56. foreach (cot_getextplugins('forums.posts.rights') as $pl)
  57. {
  58. include $pl;
  59. }
  60. /* ===== */
  61. cot_block(cot::$usr['auth_read']);
  62. $sys['sublocation'] = cot::$structure['forums'][$s]['title'];
  63. if ($a == 'newpost' && !empty($s) && !empty($q))
  64. {
  65. cot_shield_protect();
  66. cot::$db->query("SELECT ft_state FROM $db_forum_topics WHERE ft_id = $q")->fetchColumn() && cot_die();
  67. $sql_forums = cot::$db->query("SELECT fp_id, fp_text, fp_posterid, fp_creation, fp_updated, fp_updater FROM $db_forum_posts
  68. WHERE fp_topicid = $q ORDER BY fp_creation DESC LIMIT 1");
  69. if ($row = $sql_forums->fetch())
  70. {
  71. if (cot::$cfg['forums']['antibumpforums'] && ( (cot::$usr['id'] == 0 && $row['fp_posterid'] == 0 &&
  72. $row['fp_posterip'] == cot::$usr['ip']) || ($row['fp_posterid'] > 0 && $row['fp_posterid'] == cot::$usr['id']) ))
  73. {
  74. cot_die();
  75. }
  76. $merge = (!cot::$cfg['forums']['antibumpforums'] && cot::$cfg['forums']['mergeforumposts'] && $row['fp_posterid'] == cot::$usr['id']) ? true : false;
  77. $merge = ($merge && cot::$cfg['forums']['mergetimeout'] > 0 && (($sys['now'] - $row['fp_updated']) > (cot::$cfg['forums']['mergetimeout'] * 3600))) ? false : $merge;
  78. }
  79. else
  80. {
  81. cot_die();
  82. }
  83. $rmsg = array();
  84. $rmsg['fp_text'] = cot_import('rmsgtext', 'P', 'HTM');
  85. $rmsg['fp_updated'] = (int)$sys['now'];
  86. $rmsg['fp_posterip'] = cot::$usr['ip'];
  87. if (mb_strlen($rmsg['fp_text']) < cot::$cfg['forums']['minpostlength'])
  88. {
  89. cot_error('forums_messagetooshort', 'rmsgtext');
  90. cot_redirect(cot_url('forums', "m=posts&q=$q&n=last", '#bottom', true));
  91. }
  92. // Extra fields
  93. if(!empty(cot::$extrafields[cot::$db->forum_posts])) {
  94. foreach (cot::$extrafields[cot::$db->forum_posts] as $exfld) {
  95. $rmsg['fp_' . $exfld['field_name']] = cot_import_extrafields('rmsg' . $exfld['field_name'], $exfld, 'P', '',
  96. 'forums_post_');
  97. }
  98. }
  99. /* === Hook === */
  100. foreach (cot_getextplugins('forums.posts.newpost.first') as $pl)
  101. {
  102. include $pl;
  103. }
  104. /* ===== */
  105. if (!cot_error_found())
  106. {
  107. if (!$merge)
  108. {
  109. $rmsg['fp_topicid'] = (int)$q;
  110. $rmsg['fp_cat'] = $s;
  111. $rmsg['fp_posterid'] = (int)cot::$usr['id'];
  112. $rmsg['fp_postername'] = cot::$usr['name'];
  113. $rmsg['fp_creation'] = (int)$sys['now'];
  114. $rmsg['fp_updater'] = 0;
  115. cot::$db->insert($db_forum_posts, $rmsg);
  116. $p = cot::$db->lastInsertId();
  117. $sql_forums = cot::$db->query("UPDATE $db_forum_topics SET
  118. ft_postcount=ft_postcount+1, ft_updated=" . $sys['now'] . ",
  119. ft_lastposterid=" . cot::$usr['id'] . ", ft_lastpostername=" . cot::$db->quote(cot::$usr['name']) . " WHERE ft_id=$q");
  120. cot_forums_sectionsetlast($s, 'fs_postcount+1');
  121. if (cot::$cfg['forums']['cat_' . $s]['countposts'])
  122. {
  123. $sql_forums = cot::$db->query("UPDATE $db_users SET user_postcount=user_postcount+1 WHERE user_id=" . cot::$usr['id']);
  124. }
  125. }
  126. else
  127. {
  128. $p = (int)$row['fp_id'];
  129. $gap_base = empty($row['fp_updated']) ? $row['fp_creation'] : $row['fp_updated'];
  130. $updated = sprintf(cot::$L['forums_mergetime'], cot_build_timegap($gap_base, $sys['now']));
  131. $rmsg['fp_text'] = $row['fp_text'] . cot_rc('forums_code_update', array('updated' => $updated)) . $rmsg['fp_text'];
  132. $rmsg['fp_updater'] = ($row['fp_posterid'] == cot::$usr['id'] && ($sys['now'] < $row['fp_updated'] + 300) && empty($row['fp_updater']) ) ? '' : cot::$usr['name'];
  133. cot::$db->update($db_forum_posts, $rmsg, 'fp_id=' . $row['fp_id']);
  134. cot::$db->update($db_forum_topics, array('ft_updated' => $sys['now']), "ft_id = $q");
  135. cot_forums_sectionsetlast($s);
  136. }
  137. cot_extrafield_movefiles();
  138. /* === Hook === */
  139. foreach (cot_getextplugins('forums.posts.newpost.done') as $pl)
  140. {
  141. include $pl;
  142. }
  143. /* ===== */
  144. if (cot::$cache)
  145. {
  146. (cot::$cfg['cache_forums']) && cot::$cache->page->clear('forums');
  147. (cot::$cfg['cache_index']) && cot::$cache->page->clear('index');
  148. }
  149. cot_shield_update(30, "New post");
  150. cot_redirect(cot_url('forums', "m=posts&q=$q&n=last", '#bottom', true));
  151. }
  152. }
  153. elseif ($a == 'delete' && cot::$usr['id'] > 0 && !empty($s) && !empty($q) && !empty($p) && (cot::$usr['isadmin'] || ($fp_posterid == cot::$usr['id'] && (cot::$cfg['forums']['edittimeout'] == '0' || $sys['now'] - $row['fp_creation'] < cot::$cfg['forums']['edittimeout'] * 3600))))
  154. {
  155. cot_check_xg();
  156. /* === Hook === */
  157. foreach (cot_getextplugins('forums.posts.delete.first') as $pl)
  158. {
  159. include $pl;
  160. }
  161. /* ===== */
  162. $row = cot::$db->query("SELECT * FROM $db_forum_posts WHERE fp_id = ? AND fp_topicid = ? AND fp_cat = ? LIMIT 1",
  163. array($p, $q, $s))->fetch();
  164. is_array($row) || cot_die();
  165. // If the post is first in the topic, then delete entire topic or show an error
  166. $first_id = cot::$db->query("SELECT fp_id FROM $db_forum_posts WHERE fp_topicid = ? LIMIT 1", array($q))->fetchColumn();
  167. if ($p == $first_id)
  168. {
  169. if (cot::$usr['isadmin'])
  170. {
  171. // Redirect to topic removal confirmation
  172. cot_redirect(str_replace('&amp;', '&', cot_confirm_url(cot_url('forums', 'm=topics&a=delete&s='.$s.'&q='.$q.'&x='.$sys['xk'], '', true), 'forums', 'forums_confirm_delete_topic')));
  173. }
  174. else
  175. {
  176. // Users can't delete topics
  177. cot_die();
  178. }
  179. }
  180. foreach($cot_extrafields[$db_forum_posts] as $exfld)
  181. {
  182. cot_extrafield_unlinkfiles($row['fp_'.$exfld['field_name']], $exfld);
  183. }
  184. $sql_forums = cot::$db->delete($db_forum_posts, 'fp_id = ? AND fp_topicid = ? AND fp_cat = ?', array($p, $q, $s));
  185. if (cot::$cfg['forums']['cat_' . $s]['countposts'])
  186. {
  187. $sql_forums = cot::$db->query("UPDATE $db_users SET user_postcount=user_postcount-1 WHERE user_id='" . $fp_posterid . "' AND user_postcount>0");
  188. }
  189. cot_log("Deleted post #" . $p, 'for');
  190. /* === Hook === */
  191. foreach (cot_getextplugins('forums.posts.delete.done') as $pl)
  192. {
  193. include $pl;
  194. }
  195. /* ===== */
  196. if (cot::$cache)
  197. {
  198. (cot::$cfg['cache_forums']) && cot::$cache->page->clear('forums');
  199. (cot::$cfg['cache_index']) && cot::$cache->page->clear('index');
  200. }
  201. if (cot::$db->query("SELECT COUNT(*) FROM $db_forum_posts WHERE fp_topicid= $q")->fetchColumn() == 0)
  202. {
  203. $sql_forums = cot::$db->query("SELECT * FROM $db_forum_topics WHERE ft_id = $q");
  204. if ($row = $sql_forums->fetch())
  205. {
  206. $sql_forums = cot::$db->delete($db_forum_topics, "ft_movedto = $q");
  207. $sql_forums = cot::$db->delete($db_forum_topics, "ft_id = $q");
  208. foreach($cot_extrafields[$db_forum_topics] as $exfld)
  209. {
  210. cot_extrafield_unlinkfiles($row['ft_'.$exfld['field_name']], $exfld);
  211. }
  212. /* === Hook === */
  213. foreach (cot_getextplugins('forums.posts.emptytopicdel') as $pl)
  214. {
  215. include $pl;
  216. }
  217. /* ===== */
  218. cot_log('Delete topic #' . $q . " (no post left)", 'for');
  219. cot_forums_sectionsetlast($s, 'fs_postcount-1', 'fs_topiccount-1');
  220. }
  221. cot_redirect(cot_url('forums', 'm=topics&s=' . $s, '', true));
  222. }
  223. else
  224. {
  225. // There's at least 1 post left, let's resync
  226. $sql_forums = cot::$db->query("SELECT fp_id, fp_posterid, fp_postername, fp_updated, fp_topicid FROM $db_forum_posts
  227. WHERE fp_topicid = ? AND fp_cat = ? ORDER BY fp_id DESC LIMIT 1",
  228. array($q, $s));
  229. if ($row = $sql_forums->fetch())
  230. {
  231. $sql_forums = cot::$db->query("UPDATE $db_forum_topics SET
  232. ft_postcount=ft_postcount-1, ft_lastposterid=" . (int)$row['fp_posterid'] . ",
  233. ft_lastpostername=" . cot::$db->quote($row['fp_postername']) . ", ft_updated=" . (int)$row['fp_updated'] . "
  234. WHERE ft_id = $q");
  235. cot_forums_sectionsetlast($s, 'fs_postcount-1');
  236. cot_redirect(cot_url('forums', 'm=posts&q=' . $row['fp_topicid'] . '&d=' . $durl , '#' . $row['fp_id'], true));
  237. }
  238. }
  239. }
  240. $sql_forums = cot::$db->query("SELECT * FROM $db_forum_topics WHERE ft_id= $q");
  241. if ($rowt = $sql_forums->fetch())
  242. {
  243. if ($rowt['ft_mode'] == 1 && !(cot::$usr['isadmin'] || $rowt['ft_firstposterid'] == cot::$usr['id']))
  244. {
  245. cot_die();
  246. }
  247. }
  248. else
  249. {
  250. cot_die(true, true);
  251. }
  252. $sql_forums = cot::$db->query("UPDATE $db_forum_topics SET ft_viewcount=ft_viewcount+1 WHERE ft_id = $q");
  253. $sql_forums = cot::$db->query("UPDATE $db_forum_stats SET fs_viewcount=fs_viewcount+1 WHERE fs_cat = " . cot::$db->quote($s));
  254. $where['topicid'] = "fp_topicid = $q";
  255. $order = 'fp_id ASC';
  256. $join_columns = '';
  257. $join_condition = '';
  258. if (!empty($p))
  259. {
  260. $p_id = $p;
  261. $postsbefore = cot::$db->query("SELECT COUNT(*) FROM $db_forum_posts AS p $join_condition WHERE " . implode(' AND ', $where) . " AND fp_id < $p_id")->fetchColumn();
  262. $d = cot::$cfg['forums']['maxpostsperpage'] * floor($postsbefore / cot::$cfg['forums']['maxpostsperpage']);
  263. $durl = cot::$cfg['easypagenav'] ? floor($d / cot::$cfg['forums']['maxpostsperpage']) + 1 : $d;
  264. }
  265. if (!empty($id))
  266. {
  267. $where['id'] = "fp_id = $id";
  268. }
  269. /* === Hook === */
  270. foreach (cot_getextplugins('forums.posts.query') as $pl)
  271. {
  272. include $pl;
  273. }
  274. /* ===== */
  275. $where = array_diff($where, array(''));
  276. $totalposts = cot::$db->query("SELECT COUNT(*) FROM $db_forum_posts AS p $join_condition WHERE " . implode(' AND ', $where))->fetchColumn();
  277. // Disallow accessing non-existent pages
  278. if (empty($id) && $totalposts > 0 && $d > $totalposts)
  279. {
  280. cot_die_message(404);
  281. }
  282. $orderlimit = empty($id) ? " ORDER BY $order LIMIT $d, " . cot::$cfg['forums']['maxpostsperpage'] : '';
  283. $sql_forums = cot::$db->query("SELECT p.*, u.* $join_columns
  284. FROM $db_forum_posts AS p LEFT JOIN $db_users AS u ON u.user_id=p.fp_posterid $join_condition
  285. WHERE " . implode(' AND ', $where) . $orderlimit);
  286. $title_params = array(
  287. 'FORUM' => cot::$L['Forums'],
  288. 'SECTION' => cot::$structure['forums'][$s]['title'],
  289. 'TITLE' => $rowt['ft_title']
  290. );
  291. $out['subtitle'] = cot_title(cot::$cfg['forums']['title_posts'], $title_params);
  292. $out['desc'] = htmlspecialchars(strip_tags($rowt['ft_desc']));
  293. $topicurl_params = array(
  294. 'm' => 'posts',
  295. 'q' => $q
  296. );
  297. if ( ($durl > 1 && cot::$cfg['easypagenav']) || ($durl > 0 && !cot::$cfg['easypagenav']) )
  298. {
  299. $topicurl_params['d'] = $durl;
  300. }
  301. $out['canonical_uri'] = cot_url('forums', $topicurl_params);
  302. /* === Hook === */
  303. foreach (cot_getextplugins('forums.posts.main') as $pl)
  304. {
  305. include $pl;
  306. }
  307. /* ===== */
  308. require_once cot::$cfg['system_dir'] . '/header.php';
  309. $mskin = cot_tplfile(array('forums', 'posts', cot::$structure['forums'][$s]['tpl']));
  310. $t = new XTemplate($mskin);
  311. /* === Hook - Part1 : Set === */
  312. $extp = cot_getextplugins('forums.posts.loop');
  313. /* ===== */
  314. $fp_num = 0;
  315. foreach ($sql_forums->fetchAll() as $row)
  316. {
  317. $row['user_text'] = (cot::$cfg['forums']['cat_' . $s]['allowusertext']) ? $row['user_text'] : '';
  318. $row['fp_updatedby'] = '';
  319. $fp_num++;
  320. $rowquote_url = (cot::$usr['id'] > 0) ? cot_url('forums', 'm=posts&s=' . $s . '&q=' . $q . '&quote=' . $row['fp_id'] . '&d=' . $durl . '&n=last', '#np') : '';
  321. $rowquote = (cot::$usr['id'] > 0) ? cot_rc('forums_rowquote', array('url' => $rowquote_url)) : '';
  322. $rowedit_url = ((cot::$usr['isadmin'] || ($row['fp_posterid'] == cot::$usr['id'] && (cot::$cfg['forums']['edittimeout'] == '0' || $sys['now'] - $row['fp_creation'] < cot::$cfg['forums']['edittimeout'] * 3600))) && cot::$usr['id'] > 0) ? cot_url('forums', 'm=editpost&s=' . $s . '&q=' . $q . '&p=' . $row['fp_id'] . '&d=' . $durl . '&' . cot_xg()) : '';
  323. $rowedit = ((cot::$usr['isadmin'] || ($row['fp_posterid'] == cot::$usr['id'] && (cot::$cfg['forums']['edittimeout'] == '0' || $sys['now'] - $row['fp_creation'] < cot::$cfg['forums']['edittimeout'] * 3600))) && cot::$usr['id'] > 0) ? cot_rc('forums_rowedit', array('url' => $rowedit_url)) : '';
  324. $rowdelete_url = (cot::$usr['id'] > 0 && (cot::$usr['isadmin'] || ($row['fp_posterid'] == cot::$usr['id'] && (cot::$cfg['forums']['edittimeout'] == '0' || $sys['now'] - $row['fp_creation'] < cot::$cfg['forums']['edittimeout'] * 3600)))) ? cot_confirm_url(cot_url('forums', 'm=posts&a=delete&' . cot_xg() . '&s=' . $s . '&q=' . $q . '&p=' . $row['fp_id'] . '&d=' . $durl), 'forums', 'forums_confirm_delete_post') : '';
  325. $rowdelete = (cot::$usr['id'] > 0 && (cot::$usr['isadmin'] || ($row['fp_posterid'] == cot::$usr['id'] && (cot::$cfg['forums']['edittimeout'] == '0' || $sys['now'] - $row['fp_creation'] < cot::$cfg['forums']['edittimeout'] * 3600)) && $fp_num > 1)) ? cot_rc('forums_rowdelete', array('url' => $rowdelete_url)) : '';
  326. if (!empty($row['fp_updater']))
  327. {
  328. $row['fp_updatedby'] = sprintf(cot::$L['forums_updatedby'], htmlspecialchars($row['fp_updater']), cot_date('datetime_medium', $row['fp_updated']), cot_build_timegap($row['fp_updated'], $sys['now']));
  329. }
  330. $t->assign(cot_generate_usertags($row, 'FORUMS_POSTS_ROW_USER'));
  331. $t->assign(array(
  332. 'FORUMS_POSTS_ROW_ID' => $row['fp_id'],
  333. 'FORUMS_POSTS_ROW_POSTID' => 'post_' . $row['fp_id'],
  334. 'FORUMS_POSTS_ROW_IDURL' => cot_url('forums', 'm=posts&id=' . $row['fp_id']),
  335. 'FORUMS_POSTS_ROW_URL' => cot_url('forums', 'm=posts&q=' . $row['fp_topicid'] . '&d=' . $durl, "#" . $row['fp_id']),
  336. 'FORUMS_POSTS_ROW_CREATION' => cot_date('datetime_medium', $row['fp_creation']),
  337. 'FORUMS_POSTS_ROW_CREATION_STAMP' => $row['fp_creation'],
  338. 'FORUMS_POSTS_ROW_UPDATED' => cot_date('datetime_medium', $row['fp_updated']),
  339. 'FORUMS_POSTS_ROW_UPDATED_STAMP' => $row['fp_updated'],
  340. 'FORUMS_POSTS_ROW_UPDATER' => htmlspecialchars($row['fp_updater']),
  341. 'FORUMS_POSTS_ROW_UPDATEDBY' => $row['fp_updatedby'],
  342. 'FORUMS_POSTS_ROW_TEXT' => cot_parse($row['fp_text'], (cot::$cfg['forums']['markup'] && cot::$cfg['forums']['cat_' . $s]['allowbbcodes'])),
  343. 'FORUMS_POSTS_ROW_ANCHORLINK' => cot_rc('forums_code_post_anchor', array('id' => $row['fp_id'])),
  344. 'FORUMS_POSTS_ROW_POSTERNAME' => cot_build_user($row['fp_posterid'], htmlspecialchars($row['fp_postername'])),
  345. 'FORUMS_POSTS_ROW_POSTERID' => $row['fp_posterid'],
  346. 'FORUMS_POSTS_ROW_POSTERIP' => (cot::$usr['isadmin']) ? cot_build_ipsearch($row['fp_posterip']) : '',
  347. 'FORUMS_POSTS_ROW_DELETE' => $rowdelete,
  348. 'FORUMS_POSTS_ROW_DELETE_URL' => $rowdelete_url,
  349. 'FORUMS_POSTS_ROW_EDIT' => $rowedit,
  350. 'FORUMS_POSTS_ROW_EDIT_URL' => $rowedit_url,
  351. 'FORUMS_POSTS_ROW_QUOTE' => $rowquote,
  352. 'FORUMS_POSTS_ROW_QUOTE_URL' => $rowquote_url,
  353. 'FORUMS_POSTS_ROW_BOTTOM' => ((empty($id) ? $d + $fp_num : $id) == $totalposts) ? cot::$R['forums_code_bottom'] :
  354. ((cot::$usr['id'] > 0 && $n == 'unread' && $row['fp_creation'] > cot::$usr['lastvisit']) ? cot::$R['forums_code_unread'] : ''),
  355. 'FORUMS_POSTS_ROW_ODDEVEN' => cot_build_oddeven($fp_num),
  356. 'FORUMS_POSTS_ROW_NUM' => $fp_num,
  357. 'FORUMS_POSTS_ROW_ORDER' => empty($id) ? $d + $fp_num : $id
  358. ));
  359. if(!empty(cot::$extrafields[cot::$db->forum_posts])) {
  360. foreach (cot::$extrafields[cot::$db->forum_posts] as $exfld) {
  361. $tag = mb_strtoupper($exfld['field_name']);
  362. $exfld_title = cot_extrafield_title($exfld, 'forums_post_');
  363. $t->assign(array(
  364. 'FORUMS_POSTS_ROW_' . $tag . '_TITLE' => $exfld_title,
  365. 'FORUMS_POSTS_ROW_' . $tag => cot_build_extrafields_data('forums', $exfld,
  366. $row['fp_' . $exfld['field_name']],
  367. (cot::$cfg['forums']['markup'] && cot::$cfg['forums']['cat_' . $s]['allowbbcodes'])),
  368. 'FORUMS_POSTS_ROW_' . $tag . '_VALUE' => $row['fp_' . $exfld['field_name']]
  369. ));
  370. }
  371. }
  372. /* === Hook - Part2 : Include === */
  373. foreach ($extp as $pl)
  374. {
  375. include $pl;
  376. }
  377. /* ===== */
  378. $t->parse('MAIN.FORUMS_POSTS_ROW');
  379. }
  380. $lastpage = (($d + cot::$cfg['forums']['maxpostsperpage']) < $totalposts) ? FALSE : TRUE;
  381. $pagenav = cot_pagenav('forums', "m=posts&q=$q", $d, $totalposts, cot::$cfg['forums']['maxpostsperpage']);
  382. $jumpbox[cot_url('forums')] = cot::$L['Forums'];
  383. foreach (cot::$structure['forums'] as $key => $val)
  384. {
  385. if (cot_auth('forums', $key, 'R') && strpos($val['path'], '.'))
  386. {
  387. ($val['tpath'] == $s) || $movebox[$key] = $val['tpath'];
  388. $jumpbox[cot_url('forums', 'm=topics&s=' . $key, '', true)] = $val['tpath'];
  389. }
  390. }
  391. if (cot::$usr['isadmin'])
  392. {
  393. $t->assign(array(
  394. 'FORUMS_POSTS_MOVE_URL' => cot_url('forums', 'm=topics&a=move&s=' . $s . '&q=' . $q . '&x=' . $sys['xk']),
  395. 'FORUMS_POSTS_BUMP_URL' => cot_url('forums', 'm=topics&a=bump&s=' . $s . '&q=' . $q . '&x=' . $sys['xk']),
  396. 'FORUMS_POSTS_LOCK_URL' => cot_url('forums', 'm=topics&a=lock&s=' . $s . '&q=' . $q . '&x=' . $sys['xk']),
  397. 'FORUMS_POSTS_STICKY_URL' => cot_url('forums', 'm=topics&a=sticky&s=' . $s . '&q=' . $q . '&x=' . $sys['xk']),
  398. 'FORUMS_POSTS_ANNOUNCE_URL' => cot_url('forums', 'm=topics&a=announcement&s=' . $s . '&q=' . $q . '&x=' . $sys['xk']),
  399. 'FORUMS_POSTS_PRIVATE_URL' => cot_url('forums', 'm=topics&a=private&s=' . $s . '&q=' . $q . '&x=' . $sys['xk']),
  400. 'FORUMS_POSTS_CLEAR_URL' => cot_url('forums', 'm=topics&a=clear&s=' . $s . '&q=' . $q . '&x=' . $sys['xk']),
  401. 'FORUMS_POSTS_DELETE_URL' => cot_confirm_url(cot_url('forums', 'm=topics&a=delete&s=' . $s . '&q=' . $q . '&x=' . $sys['xk']), 'forums', 'forums_confirm_delete_topic'),
  402. 'FORUMS_POSTS_MOVEBOX_SELECT' => cot_selectbox('', 'ns', array_keys($movebox), array_values($movebox), false),
  403. 'FORUMS_POSTS_MOVEBOX_KEEP' => cot_checkbox('0', 'ghost')
  404. ));
  405. $t->parse('MAIN.FORUMS_POSTS_ADMIN');
  406. }
  407. $allowreplybox = (cot::$cfg['forums']['antibumpforums'] && $row['fp_posterid'] > 0 && $row['fp_posterid'] == cot::$usr['id'] && cot::$usr['auth_write']) ? FALSE : TRUE;
  408. if ((cot::$cfg['forums']['enablereplyform'] || $lastpage) && !$rowt['ft_state'] && cot::$usr['id'] > 0 && $allowreplybox && cot::$usr['auth_write'])
  409. {
  410. $rmsg = null;
  411. if ($quote > 0)
  412. {
  413. $sql_forums_quote = cot::$db->query("SELECT fp_id, fp_text, fp_postername, fp_posterid, fp_creation FROM $db_forum_posts
  414. WHERE fp_topicid = ? AND fp_cat = ? AND fp_id = ? LIMIT 1",
  415. array($q, $s, $quote));
  416. if ($row4 = $sql_forums_quote->fetch())
  417. {
  418. $rmsg['fp_text'] = cot_rc('forums_code_quote', array(
  419. 'url' => cot_url('forums', 'm=posts&q=' . $q . '&d=' . $durl, '#' . $row4['fp_id'], $forums_quote_htmlspecialchars_bypass),
  420. 'id' => $row4['fp_id'],
  421. 'date' => cot_date('datetime_medium', $row4['fp_creation']),
  422. 'postername' => $row4['fp_postername'],
  423. 'text' => $row4['fp_text']
  424. ));
  425. }
  426. }
  427. // Extra fields
  428. if(!empty(cot::$extrafields[cot::$db->forum_posts])) {
  429. foreach (cot::$extrafields[cot::$db->forum_posts] as $exfld) {
  430. $uname = strtoupper($exfld['field_name']);
  431. $exfld_val = cot_build_extrafields('rmsg' . $exfld['field_name'], $exfld, $rmsg[$exfld['field_name']]);
  432. $exfld_title = cot_extrafield_title($exfld, 'forums_post_');
  433. $t->assign(array(
  434. 'FORUMS_POSTS_NEWPOST_' . $uname => $exfld_val,
  435. 'FORUMS_POSTS_NEWPOST_' . $uname . '_TITLE' => $exfld_title,
  436. 'FORUMS_POSTS_NEWPOST_EXTRAFLD' => $exfld_val,
  437. 'FORUMS_POSTS_NEWPOST_EXTRAFLD_TITLE' => $exfld_title
  438. ));
  439. $t->parse('MAIN.FORUMS_POSTS_NEWPOST.EXTRAFLD');
  440. }
  441. }
  442. $text = '';
  443. if (isset($rmsg['fp_text'])) $text = $rmsg['fp_text'];
  444. $t->assign(array(
  445. 'FORUMS_POSTS_NEWPOST_SEND' => cot_url('forums', "m=posts&a=newpost&s=" . $s . "&q=" . $q),
  446. 'FORUMS_POSTS_NEWPOST_TEXT' => cot::$R['forums_code_newpost_mark'] . cot_textarea('rmsgtext', $text,
  447. 16, 56, '', 'input_textarea_'.$minimaxieditor),
  448. 'FORUMS_POSTS_NEWPOST_EDITTIMEOUT' => cot_build_timegap(0, cot::$cfg['forums']['edittimeout'] * 3600)
  449. ));
  450. cot_display_messages($t);
  451. /* === Hook === */
  452. foreach (cot_getextplugins('forums.posts.newpost.tags') as $pl)
  453. {
  454. include $pl;
  455. }
  456. /* ===== */
  457. $t->parse('MAIN.FORUMS_POSTS_NEWPOST');
  458. } elseif ($rowt['ft_state']) {
  459. $t->assign('FORUMS_POSTS_TOPICLOCKED_BODY', cot::$L['forums_topiclocked']);
  460. $t->parse('MAIN.FORUMS_POSTS_TOPICLOCKED');
  461. } elseif (!$allowreplybox && (cot::$cfg['forums']['enablereplyform'] || $lastpage) && !$rowt['ft_state'] && cot::$usr['id'] > 0) {
  462. $t->assign('FORUMS_POSTS_ANTIBUMP_BODY', cot::$L['forums_antibump']);
  463. $t->parse('MAIN.FORUMS_POSTS_ANTIBUMP');
  464. }
  465. if ($rowt['ft_mode'] == 1) {
  466. $t->parse('MAIN.FORUMS_POSTS_TOPICPRIVATE');
  467. }
  468. $rowt['ft_title'] = (($rowt['ft_mode'] == 1) ? '# ' : '') . $rowt['ft_title'];
  469. $crumbs = cot_forums_buildpath($s);
  470. $toppath = cot_breadcrumbs($crumbs, cot::$cfg['homebreadcrumb']);
  471. $crumbs[] = $rowt['ft_title'];
  472. $toptitle = cot_breadcrumbs($crumbs, cot::$cfg['homebreadcrumb'], true);
  473. $toptitle .= ( cot::$usr['isadmin']) ? cot::$R['forums_code_admin_mark'] : '';
  474. $t->assign(array(
  475. 'FORUMS_POSTS_ID' => $q,
  476. 'FORUMS_POSTS_RSS' => cot_url('rss', "m=topics&c=$q"),
  477. 'FORUMS_POSTS_PAGETITLE' => $toptitle,
  478. 'FORUMS_POSTS_TOPICDESC' => htmlspecialchars($rowt['ft_desc']),
  479. 'FORUMS_POSTS_SHORTTITLE' => htmlspecialchars($rowt['ft_title']),
  480. 'FORUMS_POSTS_CATTITLE' => htmlspecialchars(cot::$structure['forums'][$s]['title']),
  481. 'FORUMS_POSTS_PATH' => $toppath,
  482. 'FORUMS_POSTS_PAGES' => $pagenav['main'],
  483. 'FORUMS_POSTS_PAGEPREV' => $pagenav['prev'],
  484. 'FORUMS_POSTS_PAGENEXT' => $pagenav['next'],
  485. 'FORUMS_POSTS_CURRENTPAGE' => $pagenav['current'],
  486. 'FORUMS_POSTS_TOTALPAGES' => ceil($totalposts / cot::$cfg['forums']['maxpostsperpage']),
  487. 'FORUMS_POSTS_JUMPBOX' => cot_selectbox($s, 'jumpbox', array_keys($jumpbox), array_values($jumpbox), false, 'onchange="redirect(this)"')
  488. ));
  489. // Topic icon
  490. $rowt['ft_icon'] = 'posts';
  491. $rowt['ft_postisnew'] = FALSE;
  492. if ($rowt['ft_updated'] > cot::$usr['lastvisit'] && cot::$usr['id']>0)
  493. {
  494. $rowt['ft_icon'] .= '_new';
  495. $rowt['ft_postisnew'] = TRUE;
  496. }
  497. if ($rowt['ft_postcount'] >= cot::$cfg['forums']['hottopictrigger'] && !$rowt['ft_state'] && !$rowt['ft_sticky'])
  498. {
  499. $rowt['ft_icon'] = ($rowt['ft_postisnew']) ? 'posts_new_hot' : 'posts_hot';
  500. }
  501. else
  502. {
  503. $rowt['ft_icon'] .= ($rowt['ft_sticky']) ? '_sticky' : '';
  504. $rowt['ft_icon'] .= ($rowt['ft_state']) ? '_locked' : '';
  505. }
  506. $rowt['ft_icon_type'] = $rowt['ft_icon'];
  507. $rowt['ft_icon'] = cot_rc('forums_icon_topic', array('icon' => $rowt['ft_icon']));
  508. $rowt['ft_icon_type_ex'] = $rowt['ft_icon_type'];
  509. if (cot::$usr['id'] > 0 && $rowt['ft_firstposterid'] == cot::$usr['id']) {
  510. $rowt['ft_icon_type_ex'] .= '_posted';
  511. }
  512. $t->assign(array(
  513. 'FORUMS_POSTS_ICON' => $rowt['ft_icon'],
  514. 'FORUMS_POSTS_ICON_TYPE' => $rowt['ft_icon_type'],
  515. 'FORUMS_POSTS_ICON_TYPE_EX' => $rowt['ft_icon_type_ex']
  516. ));
  517. if(!empty(cot::$extrafields[cot::$db->forum_topics])) {
  518. foreach (cot::$extrafields[cot::$db->forum_topics] as $exfld) {
  519. $tag = mb_strtoupper($exfld['field_name']);
  520. $exfld_title = cot_extrafield_title($exfld, 'forums_topic_');
  521. $t->assign(array(
  522. 'FORUMS_POSTS_TOPIC_' . $tag . '_TITLE' => $exfld_title,
  523. 'FORUMS_POSTS_TOPIC_' . $tag => cot_build_extrafields_data('forums', $exfld, $rowt['ft_' . $exfld['field_name']],
  524. (cot::$cfg['forums']['markup'] && cot::$cfg['forums']['cat_' . $s]['allowbbcodes'])),
  525. 'FORUMS_POSTS_TOPIC_' . $tag . '_VALUE' => $rowt['ft_' . $exfld['field_name']]
  526. ));
  527. }
  528. }
  529. /* === Hook === */
  530. foreach (cot_getextplugins('forums.posts.tags') as $pl)
  531. {
  532. include $pl;
  533. }
  534. /* ===== */
  535. $t->parse('MAIN');
  536. $t->out('MAIN');
  537. require_once cot::$cfg['system_dir'] . '/footer.php';
  538. if (cot::$cache && cot::$usr['id'] === 0 && cot::$cfg['cache_forums']) {
  539. cot::$cache->page->write();
  540. }