PageRenderTime 73ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/inc/classes/board-post.class.php

https://github.com/Laurelai/tsukiboards
PHP | 979 lines | 692 code | 106 blank | 181 comment | 267 complexity | eae7147bc21910839f24a5c650a29e4d MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. /*
  3. * This file is part of kusaba.
  4. *
  5. * kusaba is free software; you can redistribute it and/or modify it under the
  6. * terms of the GNU General Public License as published by the Free Software
  7. * Foundation; either version 2 of the License, or (at your option) any later
  8. * version.
  9. *
  10. * kusaba is distributed in the hope that it will be useful, but WITHOUT ANY
  11. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along with
  15. * kusaba; if not, write to the Free Software Foundation, Inc.,
  16. * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. /**
  19. * Board and Post classes
  20. *
  21. * @package kusaba
  22. */
  23. /**
  24. * Board class
  25. *
  26. * Contains all board configurations. This class handles all board page
  27. * rendering, using the templates
  28. *
  29. * @package kusaba
  30. *
  31. * TODO: replace repetitive code blocks with functions.
  32. */
  33. class Board {
  34. /* Declare the public variables */
  35. /**
  36. * Array to hold the boards settings
  37. */
  38. var $board = array();
  39. /**
  40. * Archive directory, set when archiving is enabled
  41. *
  42. * @var string Archive directory
  43. */
  44. var $archive_dir;
  45. /**
  46. * Dwoo class
  47. *
  48. * @var class Dwoo
  49. */
  50. var $dwoo;
  51. /**
  52. * Dwoo data class
  53. *
  54. * @var class Dwoo
  55. */
  56. var $dwoo_data;
  57. /**
  58. * Load balancer class
  59. *
  60. * @var class Load balancer
  61. */
  62. var $loadbalancer;
  63. /**
  64. * Initialization function for the Board class, which is called when a new
  65. * instance of this class is created. Takes a board directory as an
  66. * argument
  67. *
  68. * @param string $board Board name/directory
  69. * @param boolean $extra grab additional data for page generation purposes. Only false if all that's needed is the board info.
  70. * @return class
  71. */
  72. function Board($board, $extra = true) {
  73. global $tc_db, $CURRENTLOCALE;
  74. // If the instance was created with the board argument present, get all of the board info and configuration values and save it inside of the class
  75. if ($board!='') {
  76. $query = "SELECT * FROM `".KU_DBPREFIX."boards` WHERE `name` = ".$tc_db->qstr($board)." LIMIT 1";
  77. $results = $tc_db->GetAll($query);
  78. foreach ($results[0] as $key=>$line) {
  79. if (!is_numeric($key)) {
  80. $this->board[$key] = $line;
  81. }
  82. }
  83. // Type
  84. $types = array('img', 'txt', 'oek', 'upl');
  85. $this->board['text_readable'] = $types[$this->board['type']];
  86. if ($extra) {
  87. // Boardlist
  88. $this->board['boardlist'] = $this->DisplayBoardList();
  89. // Get the unique posts for this board
  90. $this->board['uniqueposts'] = $tc_db->GetOne("SELECT COUNT(DISTINCT `ipmd5`) FROM `" . KU_DBPREFIX . "posts` WHERE `boardid` = " . $this->board['id']. " AND `IS_DELETED` = 0");
  91. if($this->board['type'] != 1) {
  92. $this->board['filetypes_allowed'] = $tc_db->GetAll("SELECT ".KU_DBPREFIX."filetypes.filetype FROM ".KU_DBPREFIX."boards, ".KU_DBPREFIX."filetypes, ".KU_DBPREFIX."board_filetypes WHERE ".KU_DBPREFIX."boards.id = " . $this->board['id'] . " AND ".KU_DBPREFIX."board_filetypes.boardid = " . $this->board['id'] . " AND ".KU_DBPREFIX."board_filetypes.typeid = ".KU_DBPREFIX."filetypes.id ORDER BY ".KU_DBPREFIX."filetypes.filetype ASC;");
  93. }
  94. if ($this->board['locale'] && $this->board['locale'] != KU_LOCALE) {
  95. changeLocale($this->board['locale']);
  96. }
  97. }
  98. $this->board['loadbalanceurl_formatted'] = ($this->board['loadbalanceurl'] != '') ? substr($this->board['loadbalanceurl'], 0, strrpos($this->board['loadbalanceurl'], '/')) : '';
  99. if ($this->board['loadbalanceurl'] != '' && $this->board['loadbalancepassword'] != '') {
  100. require_once KU_ROOTDIR . 'inc/classes/loadbalancer.class.php';
  101. $this->loadbalancer = new Load_Balancer;
  102. $this->loadbalancer->url = $this->board['loadbalanceurl'];
  103. $this->loadbalancer->password = $this->board['loadbalancepassword'];
  104. }
  105. }
  106. }
  107. function __destruct() {
  108. changeLocale(KU_LOCALE);
  109. }
  110. /**
  111. * Regenerate all board and thread pages
  112. */
  113. function RegenerateAll() {
  114. $this->RegeneratePages();
  115. $this->RegenerateThreads();
  116. }
  117. /**
  118. * Regenerate all pages
  119. */
  120. function RegeneratePages() {
  121. global $tc_db, $CURRENTLOCALE;
  122. $this->InitializeDwoo();
  123. $results = $tc_db->GetAll("SELECT `filetype` FROM `" . KU_DBPREFIX . "embeds`");
  124. foreach ($results as $line) {
  125. $this->board['filetypes'][] .= $line[0];
  126. }
  127. $this->dwoo_data->assign('filetypes', $this->board['filetypes']);
  128. $maxpages = $this->board['maxpages'];
  129. $numposts = $tc_db->GetAll("SELECT COUNT(*) FROM `" . KU_DBPREFIX . "posts` WHERE `boardid` = " . $this->board['id'] . " AND `parentid` = 0 AND `IS_DELETED` = 0");
  130. if ($this->board['type'] == 1) {
  131. $postsperpage = KU_THREADSTXT;
  132. } elseif ($this->board['type'] == 3) {
  133. $postsperpage = 30;
  134. } else {
  135. $postsperpage = KU_THREADS;
  136. }
  137. $i = 0;
  138. $liststooutput = 0;
  139. $totalpages = calculatenumpages($this->board['type'], ($numposts[0][0]-1));
  140. if ($totalpages == '-1') {
  141. $totalpages = 0;
  142. }
  143. $this->dwoo_data->assign('numpages', $totalpages);
  144. while ($i <= $totalpages) {
  145. $newposts = Array();
  146. $this->dwoo_data->assign('thispage', $i);
  147. $threads = $tc_db->GetAll("SELECT * FROM `" . KU_DBPREFIX . "posts` WHERE `boardid` = " . $this->board['id'] . " AND `parentid` = 0 AND `IS_DELETED` = 0 ORDER BY `stickied` DESC, `bumped` DESC LIMIT ". ($postsperpage)." OFFSET ". $postsperpage * $i);
  148. $executiontime_start_page = microtime_float();
  149. foreach ($threads as $k=>$thread) {
  150. // If the thread is on the page set to mark, && hasn't been marked yet, mark it
  151. if ($thread['deleted_timestamp'] == 0 && $this->board['markpage'] > 0 && $i >= $this->board['markpage']) {
  152. $tc_db->Execute("UPDATE `".KU_DBPREFIX."posts` SET `deleted_timestamp` = '" . (time() + 7200) . "' WHERE `boardid` = " . $tc_db->qstr($this->board['id'])." AND `id` = '" . $thread['id'] . "'");
  153. clearPostCache($thread['id'], $this->board['name']);
  154. $this->RegenerateThreads($thread['id']);
  155. $this->dwoo_data->assign('replythread', 0);
  156. }
  157. $thread = $this->BuildPost($thread, true);
  158. if ($this->board['type'] != 3) {
  159. $omitids = '';
  160. $posts = $tc_db->GetAll("SELECT * FROM `" . KU_DBPREFIX . "posts` WHERE `boardid` = " . $this->board['id']." AND `parentid` = ".$thread['id']." " . (($this->board['type'] != 1) ? ("AND `IS_DELETED` = 0") : ("")) . " ORDER BY `id` DESC LIMIT ".(($thread['stickied'] == 1) ? (KU_REPLIESSTICKY) : (KU_REPLIES)));
  161. foreach ($posts as $key=>$post) {
  162. $omitids .= $post['id'].",";
  163. $posts[$key] = $this->BuildPost($post, true);
  164. }
  165. $posts = array_reverse($posts);
  166. $omitids = substr($omitids, 0, -1);
  167. array_unshift($posts, $thread);
  168. $newposts[] = $posts;
  169. } else {
  170. if (!$thread['tag']) $thread['tag'] = '*';
  171. $newposts[] = $thread;
  172. }
  173. $replycount = Array();
  174. if ($this->board['type'] == 1 || $this->board['type'] == 3 ) {
  175. $replycount = $tc_db->GetAll("SELECT COUNT(`id`) FROM `" . KU_DBPREFIX . "posts` WHERE `boardid` = " . $tc_db->qstr($this->board['id'])." AND `parentid` = " . $thread['id']);
  176. } else {
  177. $replycount = $tc_db->GetAll("SELECT COUNT(`id`) AS replies, SUM(CASE WHEN `file_md5` = '' THEN 0 ELSE 1 END) AS files FROM `" . KU_DBPREFIX . "posts` WHERE `boardid` = " . $this->board['id']." AND `parentid` = ".$thread['id']." AND `is_deleted` = 0 AND `id` NOT IN (" . $omitids . ")");
  178. }
  179. // Workaround for upload boards
  180. if ($this->board['type'] == 3) {
  181. $newposts[$k]['replies'] = $replycount[0][0];
  182. } else {
  183. $newposts[$k][0]['replies'] = $replycount[0][0];
  184. $newposts[$k][0]['images'] = (isset($replycount[0][1]) ? $replycount[0][1] : '');
  185. }
  186. }
  187. if ($this->board['type'] == 0 && !isset($embeds)) {
  188. $embeds = $tc_db->GetAll("SELECT * FROM `" . KU_DBPREFIX . "embeds`");
  189. $this->dwoo_data->assign('embeds', $embeds);
  190. }
  191. if (!isset($header)){
  192. $header = $this->PageHeader();
  193. $header = str_replace("<!sm_threadid>", 0, $header);
  194. }
  195. if (!isset($postbox)) {
  196. $postbox = $this->Postbox();
  197. $postbox = str_replace("<!sm_threadid>", 0, $postbox);
  198. }
  199. $this->dwoo_data->assign('posts', $newposts);
  200. $this->dwoo_data->assign('file_path', getCLBoardPath($this->board['name'], $this->board['loadbalanceurl_formatted'], ''));
  201. $content = $this->dwoo->get(KU_TEMPLATEDIR . '/' . $this->board['text_readable'] . '_board_page.tpl', $this->dwoo_data);
  202. $footer = $this->Footer(false, (microtime_float() - $executiontime_start_page), (($this->board['type'] == 1) ? (true) : (false)));
  203. $content = $header.$postbox.$content.$footer;
  204. $content = str_replace("\t", '',$content);
  205. $content = str_replace("&nbsp;\r\n", '&nbsp;',$content);
  206. if ($i == 0) {
  207. $page = KU_BOARDSDIR.$this->board['name'].'/'.KU_FIRSTPAGE;
  208. $this->PrintPage($page, $content, $this->board['name']);
  209. } else {
  210. $page = KU_BOARDSDIR.$this->board['name'].'/'.$i.'.html';
  211. $this->PrintPage($page, $content, $this->board['name']);
  212. }
  213. $i++;
  214. }
  215. // If text board, rebuild thread list html files
  216. if ($this->board['type'] == 1) {
  217. $numpostsleft = $tc_db->GetOne("SELECT COUNT(*) FROM `" . KU_DBPREFIX . "posts` WHERE `boardid` = " . $this->board['id'] . " AND `IS_DELETED` = 0 AND `parentid` = 0");
  218. $liststooutput = floor(($numpostsleft-1) / 40);
  219. $this->dwoo_data->assign('numpages', $liststooutput+1);
  220. $listpage = 0;
  221. $currentpostwave = 0;
  222. while ($numpostsleft>0) {
  223. $this->dwoo_data->assign('thispage', $listpage+1);
  224. $executiontime_start_list = microtime_float();
  225. $page = $this->PageHeader(0, $currentpostwave, $liststooutput);
  226. $this->Footer(false, (microtime_float()-$executiontime_start_list), true);
  227. if ($listpage==0) {
  228. $this->PrintPage(KU_BOARDSDIR.$this->board['name'].'/list.html', $page, $this->board['name']);
  229. } else {
  230. $this->PrintPage(KU_BOARDSDIR.$this->board['name'].'/list'.($listpage+1).'.html', $page, $this->board['name']);
  231. }
  232. $currentpostwave += 40;
  233. $numpostsleft -= 40;
  234. $listpage++;
  235. }
  236. }
  237. // If the board has catalog mode enabled, build it
  238. if ($this->board['enablecatalog'] == 1 && ($this->board['type'] == 0 || $this->board['type'] == 2)) {
  239. $executiontime_start_catalog = microtime_float();
  240. $catalog_head = $this->PageHeader().
  241. '&#91;<a href="' . KU_BOARDSFOLDER . $this->board['name'] . '/">'._gettext('Return').'</a>&#93; <div class="catalogmode">'._gettext('Catalog Mode').'</div>' . "\n" .
  242. '<table border="1" align="center">' . "\n" . '<tr>' . "\n";
  243. $catalog_page = '';
  244. $results = $tc_db->GetAll("SELECT `id` , `subject` , `file` , `file_type` FROM `" . KU_DBPREFIX . "posts` WHERE `boardid` = " . $this->board['id'] . " AND `IS_DELETED` = 0 AND `parentid` = 0 ORDER BY `stickied` DESC, `bumped` DESC");
  245. $numresults = count($results);
  246. if ($numresults > 0) {
  247. $celnum = 0;
  248. $trbreak = 0;
  249. $row = 1;
  250. // Calculate the number of rows we will actually output
  251. $maxrows = max(1, (($numresults - ($numresults % 12)) / 12));
  252. foreach ($results as $line) {
  253. $celnum++;
  254. $trbreak++;
  255. if ($trbreak == 13 && $celnum != $numresults) {
  256. $catalog_page .= '</tr>' . "\n" . '<tr>' . "\n";
  257. $row++;
  258. $trbreak = 1;
  259. }
  260. if ($row <= $maxrows) {
  261. $replies = $tc_db->GetOne("SELECT COUNT(*) FROM `".KU_DBPREFIX."posts` WHERE `boardid` = " . $this->board['id'] . " AND `IS_DELETED` = 0 AND `parentid` = " . $line['id']);
  262. $catalog_page .= '<td valign="middle">' . "\n" .
  263. '<a href="' . KU_BOARDSFOLDER . $this->board['name'] . '/res/' . $line['id'] . '.html"';
  264. if ($line['subject'] != '') {
  265. $catalog_page .= ' title="' . $line['subject'] . '"';
  266. }
  267. $catalog_page .= '>';
  268. if ($line['file'] != '' && $line['file'] != 'removed') {
  269. if ($line['file_type'] == 'jpg' || $line['file_type'] == 'png' || $line['file_type'] == 'gif') {
  270. $file_path = getCLBoardPath($this->board['name'], $this->board['loadbalanceurl_formatted'], $this->archive_dir);
  271. $catalog_page .= '<img src="' . $file_path . '/thumb/' . $line['file'] . 'c.' . $line['file_type'] . '" alt="' . $line['id'] . '" border="0" />';
  272. } else {
  273. $catalog_page .= _gettext('File');
  274. }
  275. } elseif ($line['file'] == 'removed') {
  276. $catalog_page .= 'Rem.';
  277. } else {
  278. $catalog_page .= _gettext('None');
  279. }
  280. $catalog_page .= '</a><br />' . "\n" . '<small>' . $replies . '</small>' . "\n" . '</td>' . "\n";
  281. }
  282. }
  283. } else {
  284. $catalog_page .= '<td>' . "\n" .
  285. _gettext('No threads.') . "\n" .
  286. '</td>' . "\n";
  287. }
  288. $catalog_page .= '</tr>' . "\n" . '</table><br /><hr />' .
  289. $this->Footer(false, (microtime_float()-$executiontime_start_catalog));
  290. $this->PrintPage(KU_BOARDSDIR . $this->board['name'] . '/catalog.html', $catalog_head.$catalog_page, $this->board['name']);
  291. }
  292. // Delete old pages
  293. $dir = KU_BOARDSDIR.$this->board['name'];
  294. $files = glob ("$dir/*.html");
  295. if (is_array($files)) {
  296. foreach ($files as $htmlfile) {
  297. if (preg_match("/[0-9+].html/", $htmlfile)) {
  298. if (substr(basename($htmlfile), 0, strpos(basename($htmlfile), '.html'))>$totalpages) {
  299. unlink($htmlfile);
  300. }
  301. }
  302. if (preg_match("/list[0-9+].html/", $htmlfile)) {
  303. if (substr(basename($htmlfile), 4, strpos(basename($htmlfile), '.html'))>($liststooutput+1)) {
  304. unlink($htmlfile);
  305. }
  306. }
  307. if (preg_match("/catalog.html/", $htmlfile)) {
  308. if (!($this->board['enablecatalog'] == 1 && ($this->board['type'] == 0 || $this->board['type'] == 2))) {
  309. unlink($htmlfile);
  310. }
  311. }
  312. }
  313. }
  314. }
  315. /**
  316. * Regenerate each thread's corresponding html file, starting with the most recently bumped
  317. */
  318. function RegenerateThreads($id = 0) {
  319. global $tc_db, $CURRENTLOCALE;
  320. require_once(KU_ROOTDIR."lib/dwoo.php");
  321. if (!isset($this->dwoo)) { $this->dwoo = New Dwoo; $this->dwoo_data = new Dwoo_Data(); $this->InitializeDwoo(); }
  322. $embeds = Array();
  323. $numimages = 0;
  324. if ($this->board['type'] != 1 && !$embeds) {
  325. $embeds = $tc_db->GetAll("SELECT * FROM `" . KU_DBPREFIX . "embeds`");
  326. $this->dwoo_data->assign('embeds', $embeds);
  327. foreach ($embeds as $embed) {
  328. $this->board['filetypes'][] .= $embed['filetype'];
  329. }
  330. $this->dwoo_data->assign('filetypes', $this->board['filetypes']);
  331. }
  332. if ($id == 0) {
  333. // Build every thread
  334. $header = $this->PageHeader(1);
  335. if ($this->board['type'] != 2){
  336. $postbox = $this->Postbox(1);
  337. }
  338. $threads = $tc_db->GetAll("SELECT * FROM `" . KU_DBPREFIX . "posts` WHERE `boardid` = " . $this->board['id'] . " AND `parentid` = 0 AND `IS_DELETED` = 0 ORDER BY `id` DESC");
  339. if (count($threads) > 0) {
  340. foreach($threads as $thread) {
  341. $numimages = 0;
  342. $executiontime_start_thread = microtime_float();
  343. $posts = $tc_db->GetAll("SELECT * FROM `" . KU_DBPREFIX . "posts` WHERE `boardid` = " . $this->board['id'] . " AND (`id` = " . $thread['id'] . " OR `parentid` = " . $thread['id'] . ") " . (($this->board['type'] != 1) ? ("AND `IS_DELETED` = 0") : ("")) . " ORDER BY `id` ASC");
  344. if ($this->board['type'] != 1 || ((isset($posts[0]['IS_DELETED']) && $posts[0]['IS_DELETED'] == 0) || (isset($posts[0]['is_deleted']) && $posts[0]['is_deleted'] == 0))) {
  345. // There might be a chance that the post was deleted during another RegenerateThreads() session, if there are no posts, move on to the next thread.
  346. if(count($posts) > 0){
  347. foreach ($posts as $key=>$post) {
  348. if (($post['file_type'] == 'jpg' || $post['file_type'] == 'gif' || $post['file_type'] == 'png') && $post['parentid'] != 0) {
  349. $numimages++;
  350. }
  351. $posts[$key] = $this->BuildPost($post, false);
  352. }
  353. $header_replaced = str_replace("<!sm_threadid>", $thread['id'], $header);
  354. $this->dwoo_data->assign('numimages', $numimages);
  355. $this->dwoo_data->assign('replythread', $thread['id']);
  356. $this->dwoo_data->assign('posts', $posts);
  357. $this->dwoo_data->assign('file_path', getCLBoardPath($this->board['name'], $this->board['loadbalanceurl_formatted'], ''));
  358. if ($this->board['type'] != 2){
  359. $postbox_replaced = str_replace("<!sm_threadid>", $thread['id'], $postbox);
  360. }
  361. else {
  362. $postbox_replaced = $this->Postbox($thread['id']);
  363. }
  364. $reply = $this->dwoo->get(KU_TEMPLATEDIR . '/' . $this->board['text_readable'] . '_reply_header.tpl', $this->dwoo_data);
  365. $content = $this->dwoo->get(KU_TEMPLATEDIR . '/' . $this->board['text_readable'] . '_thread.tpl', $this->dwoo_data);
  366. if (!isset($footer)) $footer = $this->Footer(false, (microtime_float() - $executiontime_start_thread), (($this->board['type'] == 1) ? (true) : (false)));
  367. $content = $header_replaced.$reply.$postbox_replaced.$content.$footer;
  368. $content = str_replace("\t", '',$content);
  369. $content = str_replace("&nbsp;\r\n", '&nbsp;',$content);
  370. $this->PrintPage(KU_BOARDSDIR . $this->board['name'] . $this->archive_dir . '/res/' . $thread['id'] . '.html', $content, $this->board['name']);
  371. if (KU_FIRSTLAST) {
  372. $replycount = (count($posts)-1);
  373. if ($replycount > 50) {
  374. $this->dwoo_data->assign('replycount', $replycount);
  375. $this->dwoo_data->assign('modifier', "last50");
  376. // Grab the last 50 replies
  377. $posts50 = array_slice($posts, -50, 50);
  378. // Add on the OP
  379. array_unshift($posts50, $posts[0]);
  380. $this->dwoo_data->assign('posts', $posts50);
  381. $content = $this->dwoo->get(KU_TEMPLATEDIR . '/img_thread.tpl', $this->dwoo_data);
  382. $content = $header_replaced.$reply.$postbox_replaced.$content.$footer;
  383. $content = str_replace("\t", '',$content);
  384. $content = str_replace("&nbsp;\r\n", '&nbsp;',$content);
  385. unset($posts50);
  386. $this->PrintPage(KU_BOARDSDIR . $this->board['name'] . $this->archive_dir . '/res/' . $thread['id'] . '+50.html', $content, $this->board['name']);
  387. if ($replycount > 100) {
  388. $this->dwoo_data->assign('modifier', "first100");
  389. // Grab the first 100 posts
  390. $posts100 = array_slice($posts, 0, 100);
  391. $this->dwoo_data->assign('posts', $posts100);
  392. $content = $this->dwoo->get(KU_TEMPLATEDIR . '/img_thread.tpl', $this->dwoo_data);
  393. $content = $header_replaced.$reply.$postbox_replaced.$content.$footer;
  394. $content = str_replace("\t", '',$content);
  395. $content = str_replace("&nbsp;\r\n", '&nbsp;',$content);
  396. unset($posts100);
  397. $this->PrintPage(KU_BOARDSDIR . $this->board['name'] . $this->archive_dir . '/res/' . $thread['id'] . '-100.html', $content, $this->board['name']);
  398. }
  399. $this->dwoo_data->assign('modifier', "");
  400. }
  401. }
  402. }
  403. }
  404. }
  405. }
  406. } else {
  407. $executiontime_start_thread = microtime_float();
  408. // Build only that thread
  409. $thread = $tc_db->GetAll("SELECT * FROM `" . KU_DBPREFIX . "posts` WHERE `boardid` = " . $this->board['id'] . " AND (`id` = " . $id . " OR `parentid` = " . $id . ") " . (($this->board['type'] != 1) ? ("AND `IS_DELETED` = 0") : ("")) . " ORDER BY `id` ASC");
  410. if ($this->board['type'] != 1 || ((isset($thread[0]['IS_DELETED']) && $thread[0]['IS_DELETED'] == 0) || (isset($thread[0]['is_deleted']) && $thread[0]['is_deleted'] == 0))) {
  411. foreach ($thread as $key=>$post) {
  412. if (($post['file_type'] == 'jpg' || $post['file_type'] == 'gif' || $post['file_type'] == 'png') && $post['parentid'] != 0) {
  413. $numimages++;
  414. }
  415. $thread[$key] = $this->BuildPost($post, false);
  416. }
  417. $header = $this->PageHeader($id);
  418. $postbox = $this->Postbox($id);
  419. $this->dwoo_data->assign('numimages', $numimages);
  420. $header = str_replace("<!sm_threadid>", $id, $header);
  421. $this->dwoo_data->assign('replythread', $id);
  422. if ($this->board['type'] != 2){
  423. $postbox = str_replace("<!sm_threadid>", $id, $postbox);
  424. }
  425. $this->dwoo_data->assign('threadid', $thread[0]['id']);
  426. $this->dwoo_data->assign('posts', $thread);
  427. $this->dwoo_data->assign('file_path', getCLBoardPath($this->board['name'], $this->board['loadbalanceurl_formatted'], ''));
  428. $postbox = $this->dwoo->get(KU_TEMPLATEDIR . '/' . $this->board['text_readable'] . '_reply_header.tpl', $this->dwoo_data).$postbox;
  429. $content = $this->dwoo->get(KU_TEMPLATEDIR . '/' . $this->board['text_readable'] . '_thread.tpl', $this->dwoo_data);
  430. if (!isset($footer)) $footer = $this->Footer(false, (microtime_float() - $executiontime_start_thread), (($this->board['type'] == 1) ? (true) : (false)));
  431. $content = $header.$postbox.$content.$footer;
  432. $content = str_replace("\t", '',$content);
  433. $content = str_replace("&nbsp;\r\n", '&nbsp;',$content);
  434. $this->PrintPage(KU_BOARDSDIR . $this->board['name'] . $this->archive_dir . '/res/' . $id . '.html', $content, $this->board['name']);
  435. if (KU_FIRSTLAST) {
  436. $replycount = $tc_db->GetOne("SELECT COUNT(`id`) FROM `" . KU_DBPREFIX . "posts` WHERE `boardid` = " . $this->board['id'] . " AND `parentid` = " . $id . " AND `IS_DELETED` = 0");
  437. if ($replycount > 50) {
  438. $this->dwoo_data->assign('replycount', $replycount);
  439. $this->dwoo_data->assign('modifier', "last50");
  440. // Grab the last 50 replies
  441. $posts50 = array_slice($thread, -50, 50);
  442. // Add the thread to the top of this, since it wont be included in the result
  443. array_unshift($posts50, $thread[0]);
  444. $this->dwoo_data->assign('posts', $posts50);
  445. $content = $this->dwoo->get(KU_TEMPLATEDIR . '/img_thread.tpl', $this->dwoo_data);
  446. $content = $header.$reply.$postbox.$content.$footer;
  447. $content = str_replace("\t", '',$content);
  448. $content = str_replace("&nbsp;\r\n", '&nbsp;',$content);
  449. unset($posts50);
  450. $this->PrintPage(KU_BOARDSDIR . $this->board['name'] . $this->archive_dir . '/res/' . $id . '+50.html', $content, $this->board['name']);
  451. if ($replycount > 100) {
  452. $this->dwoo_data->assign('modifier', "first100");
  453. // Grab the first 100 posts
  454. $posts100 = array_slice($thread, 0, 100);
  455. $this->dwoo_data->assign('posts', $posts100);
  456. $this->dwoo_data->assign('posts', $posts);
  457. $content = $this->dwoo->get(KU_TEMPLATEDIR . '/img_thread.tpl', $this->dwoo_data);
  458. $content = $header.$reply.$postbox.$content.$footer;
  459. $content = str_replace("\t", '',$content);
  460. $content = str_replace("&nbsp;\r\n", '&nbsp;',$content);
  461. unset($posts100);
  462. $this->PrintPage(KU_BOARDSDIR . $this->board['name'] . $this->archive_dir . '/res/' . $id . '-100.html', $content, $this->board['name']);
  463. }
  464. $this->dwoo_data->assign('modifier', "");
  465. }
  466. }
  467. }
  468. }
  469. }
  470. function BuildPost($post, $page) {
  471. global $CURRENTLOCALE;
  472. if ($this->board['type'] == 1 && ((isset($post['IS_DELETED']) && $post['IS_DELETED'] == 1) || (isset($post['is_deleted']) && $post['is_deleted'] == 1))) {
  473. $post['name'] = '';
  474. $post['email'] = '';
  475. $post['tripcode'] = _gettext('Deleted');
  476. $post['message'] = '<font color="gray">'._gettext('This post has been deleted.').'</font>';
  477. }
  478. $dateEmail = (empty($this->board['anonymous'])) ? $post['email'] : 0;
  479. $post['message'] = stripslashes(formatLongMessage($post['message'], $this->board['name'], (($post['parentid'] == 0) ? ($post['id']) : ($post['parentid'])), $page));
  480. $post['timestamp_formatted'] = formatDate($post['timestamp'], 'post', $CURRENTLOCALE, $dateEmail);
  481. $post['reflink'] = formatReflink($this->board['name'], (($post['parentid'] == 0) ? ($post['id']) : ($post['parentid'])), $post['id'], $CURRENTLOCALE);
  482. if (isset($this->board['filetypes']) && in_array($post['file_type'], $this->board['filetypes'])) {
  483. $post['videobox'] = embeddedVideoBox($post);
  484. }
  485. if ($post['file_type'] == 'mp3' && $this->board['loadbalanceurl'] == '') {
  486. //Grab the ID3 info. TODO: Make this work for load-balanced boards.
  487. // include getID3() library
  488. require_once(KU_ROOTDIR . 'lib/getid3/getid3.php');
  489. // Initialize getID3 engine
  490. $getID3 = new getID3;
  491. $post['id3'] = $getID3->analyze(KU_BOARDSDIR.$this->board['name'].'/src/'.$post['file'].'.mp3');
  492. getid3_lib::CopyTagsToComments($post['id3']);
  493. }
  494. if ($post['file_type']!='jpg'&&$post['file_type']!='gif'&&$post['file_type']!='png'&&$post['file_type']!=''&&!in_array($post['file_type'], $this->board['filetypes'])) {
  495. if(!isset($filetype_info[$post['file_type']])) $filetype_info[$post['file_type']] = getfiletypeinfo($post['file_type']);
  496. $post['nonstandard_file'] = KU_WEBPATH . '/inc/filetypes/' . $filetype_info[$post['file_type']][0];
  497. if($post['thumb_w']!=0&&$post['thumb_h']!=0) {
  498. if(file_exists(KU_BOARDSDIR.$this->board['name'].'/thumb/'.$post['file'].'s.jpg'))
  499. $post['nonstandard_file'] = KU_WEBPATH . '/' .$this->board['name'].'/thumb/'.$post['file'].'s.jpg';
  500. elseif(file_exists(KU_BOARDSDIR.$this->board['name'].'/thumb/'.$post['file'].'s.png'))
  501. $post['nonstandard_file'] = KU_WEBPATH . '/' .$this->board['name'].'/thumb/'.$post['file'].'s.png';
  502. elseif(file_exists(KU_BOARDSDIR.$this->board['name'].'/thumb/'.$post['file'].'s.gif'))
  503. $post['nonstandard_file'] = KU_WEBPATH . '/' .$this->board['name'].'/thumb/'.$post['file'].'s.gif';
  504. else {
  505. $post['thumb_w'] = $filetype_info[$post['file_type']][1];
  506. $post['thumb_h'] = $filetype_info[$post['file_type']][2];
  507. }
  508. }
  509. else {
  510. $post['thumb_w'] = $filetype_info[$post['file_type']][1];
  511. $post['thumb_h'] = $filetype_info[$post['file_type']][2];
  512. }
  513. }
  514. return $post;
  515. }
  516. /**
  517. * Build the page header
  518. *
  519. * @param integer $replythread The ID of the thread the header is being build for. 0 if it is for a board page
  520. * @param integer $liststart The number which the thread list starts on (text boards only)
  521. * @param integer $liststooutput The number of list pages which will be generated (text boards only)
  522. * @return string The built header
  523. */
  524. function PageHeader($replythread = '0', $liststart = '0', $liststooutput = '-1') {
  525. global $tc_db, $CURRENTLOCALE;
  526. $tpl = Array();
  527. $tpl['htmloptions'] = ((KU_LOCALE == 'he' && empty($this->board['locale'])) || $this->board['locale'] == 'he') ? ' dir="rtl"' : '' ;
  528. $tpl['title'] = '';
  529. if (KU_DIRTITLE) {
  530. $tpl['title'] .= '/' . $this->board['name'] . '/ - ';
  531. }
  532. $tpl['title'] .= $this->board['desc'];
  533. $ad_top = 185;
  534. $ad_right = 25;
  535. if ($this->board['type']==1) {
  536. $ad_top -= 50;
  537. } else {
  538. if ($replythread!=0) {
  539. $ad_top += 50;
  540. }
  541. }
  542. if ($this->board['type']==2) {
  543. $ad_top += 40;
  544. }
  545. $this->dwoo_data->assign('title', $tpl['title']);
  546. $this->dwoo_data->assign('htmloptions', $tpl['htmloptions']);
  547. $this->dwoo_data->assign('locale', $CURRENTLOCALE);
  548. $this->dwoo_data->assign('ad_top', $ad_top);
  549. $this->dwoo_data->assign('ad_right', $ad_right);
  550. $this->dwoo_data->assign('board', $this->board);
  551. $this->dwoo_data->assign('replythread', $replythread);
  552. if ($this->board['type'] != 1) {
  553. $topads = $tc_db->GetOne("SELECT code FROM `" . KU_DBPREFIX . "ads` WHERE `position` = 'top' AND `disp` = '1'");
  554. $this->dwoo_data->assign('topads', $topads);
  555. $this->dwoo_data->assign('ku_styles', explode(':', KU_STYLES));
  556. $this->dwoo_data->assign('ku_defaultstyle', (!empty($this->board['defaultstyle']) ? ($this->board['defaultstyle']) : (KU_DEFAULTSTYLE)));
  557. } else {
  558. $this->dwoo_data->assign('ku_styles', explode(':', KU_TXTSTYLES));
  559. $this->dwoo_data->assign('ku_defaultstyle', (!empty($this->board['defaultstyle']) ? ($this->board['defaultstyle']) : (KU_DEFAULTTXTSTYLE)));
  560. }
  561. $this->dwoo_data->assign('boardlist', $this->board['boardlist']);
  562. $global_header = $this->dwoo->get(KU_TEMPLATEDIR . '/global_board_header.tpl', $this->dwoo_data);
  563. if ($this->board['type'] != 1) {
  564. $header = $this->dwoo->get(KU_TEMPLATEDIR . '/' . $this->board['text_readable'] . '_header.tpl', $this->dwoo_data);
  565. } else {
  566. if ($liststooutput == -1) {
  567. $this->dwoo_data->assign('isindex', true);
  568. } else {
  569. $this->dwoo_data->assign('isindex', false);
  570. }
  571. if ($replythread != 0) $this->dwoo_data->assign('isthread', true);
  572. $header = $this->dwoo->get(KU_TEMPLATEDIR . '/txt_header.tpl', $this->dwoo_data);
  573. if ($replythread == 0) {
  574. $startrecord = ($liststooutput >= 0 || $this->board['compactlist']) ? 40 : KU_THREADSTXT ;
  575. $threads = $tc_db->GetAll("SELECT * FROM `" . KU_DBPREFIX . "posts` WHERE `boardid` = " . $tc_db->qstr($this->board['id']) . " AND `parentid` = 0 AND `IS_DELETED` = 0 ORDER BY `stickied` DESC, `bumped` DESC LIMIT " . $startrecord . " OFFSET " . $liststart);
  576. foreach($threads AS $key=>$thread) {
  577. $replycount = $tc_db->GetOne("SELECT COUNT(`id`) FROM `" . KU_DBPREFIX . "posts` WHERE `boardid` = " . $tc_db->qstr($this->board['id']) . " AND `parentid` = " . $thread['id']);
  578. $threads[$key]['replies'] = $replycount;
  579. }
  580. $this->dwoo_data->assign('threads', $threads);
  581. $header .= $this->dwoo->get(KU_TEMPLATEDIR . '/txt_threadlist.tpl', $this->dwoo_data);
  582. }
  583. }
  584. return $global_header.$header;
  585. }
  586. /**
  587. * Build the page header for an oekaki posting
  588. *
  589. * @param integer $replyto The ID of the thread being replied to. 0 for a new thread
  590. */
  591. function OekakiHeader($replyto, $postoek) {
  592. $executiontime_start = microtime_float();
  593. $this->InitializeDwoo();
  594. $page = $this->PageHeader();
  595. $this->dwoo_data->assign('replythread', $replyto);
  596. $page .= $this->Postbox();
  597. $executiontime_stop = microtime_float();
  598. $page .= $this->Footer(false, ($executiontime_stop - $executiontime_start));
  599. $this->PrintPage('', $page, true);
  600. }
  601. /**
  602. * Generate the postbox area
  603. *
  604. * @param integer $replythread The ID of the thread being replied to. 0 if not replying
  605. * @param string $postboxnotice The postbox notice
  606. * @return string The generated postbox
  607. */
  608. function Postbox($replythread = 0) {
  609. global $tc_db;
  610. if (KU_BLOTTER && $this->board['type'] != 1) {
  611. $this->dwoo_data->assign('blotter', getBlotter());
  612. $this->dwoo_data->assign('blotter_updated', getBlotterLastUpdated());
  613. }
  614. $postbox = '';
  615. if ($this->board['type'] == 2 && $replythread > 0) {
  616. $oekposts = $tc_db->GetAll("SELECT `id` FROM `" . KU_DBPREFIX."posts` WHERE `boardid` = " . $this->board['id']." AND (`id` = ".$replythread." OR `parentid` = ".$replythread.") AND `file` != '' AND `file` != 'removed' AND `file_type` IN ('jpg', 'gif', 'png') AND `IS_DELETED` = 0 ORDER BY `parentid` ASC, `timestamp` ASC");
  617. $this->dwoo_data->assign('oekposts', $oekposts);
  618. }
  619. if ($this->board['enablecaptcha'] == 1)
  620. {
  621. if( KU_CAPTCHA_TYPE == 'recaptcha' )
  622. {
  623. // RH - use reCAPTCHA challenge instead of the faptcha
  624. require_once(KU_ROOTDIR.'recaptchalib.php');
  625. $publickey = "6LdVg8YSAAAAAOhqx0eFT1Pi49fOavnYgy7e-lTO";
  626. $this->dwoo_data->assign('faptcha_input', recaptcha_get_html($publickey)); // Originally assigned to 'recaptcha', bit lazy doing this, maybe template can have both?
  627. }
  628. else if( KU_CAPTCHA_TYPE == 'faptcha' )
  629. {
  630. // RH - Textbox to type the faptcha answer into = "captcha", calling it this reuses existing validation JS
  631. // Likewise we call the image 'captchaimage' as before
  632. // 06/01/2012 SRC now also appends random querystring in case of caching issues
  633. // 15/01/2012 blank answer textbox on refresh to avoid accidental wrong answers
  634. $faptcha_image = '<a href="#" onclick="javascript:document.getElementById(\'captchaimage\').src = \''. KU_CGIPATH . '/faptcha.php?\' + Math.random();javascript:document.getElementById(\'captcha\').value=\'\';return false;"> <IMG ID="captchaimage" SRC="'. KU_WEBFOLDER .'faptcha.php?'.mt_rand().'" border="0" alt="Click for a new faptcha" title="Click for a new faptcha"> </A>';
  635. $faptcha_input = '<BR><input type="text" name="captcha" id="captcha" title="Enter character\'s name (common nicknames accepted ... probably)" size="28" maxlength="75" accesskey="c" />';
  636. $this->dwoo_data->assign('faptcha_image', $faptcha_image); // the faptcha image
  637. $this->dwoo_data->assign('faptcha_input', $faptcha_input); // faptcha answer input textbox
  638. }
  639. else
  640. {
  641. die("ERROR: Unrecognised captcha type set in config.php! (KU_CAPTCHA_TYPE)");
  642. }
  643. }
  644. if(($this->board['type'] == 1 && $replythread == 0) || $this->board['type'] != 1) {
  645. $postbox .= $this->dwoo->get(KU_TEMPLATEDIR . '/' . $this->board['text_readable'] . '_post_box.tpl', $this->dwoo_data);
  646. }
  647. return $postbox;
  648. }
  649. /**
  650. * Display the user-defined list of boards found in boards.html
  651. *
  652. * @param boolean $is_textboard If the board this is being displayed for is a text board
  653. * @return string The board list
  654. */
  655. function DisplayBoardList($is_textboard = false) {
  656. if (KU_GENERATEBOARDLIST) {
  657. global $tc_db;
  658. $output = '';
  659. $results = $tc_db->GetAll("SELECT `id` FROM `" . KU_DBPREFIX . "sections` ORDER BY `order` ASC");
  660. $boards = array();
  661. foreach($results AS $line) {
  662. $results2 = $tc_db->GetAll("SELECT * FROM `" . KU_DBPREFIX . "boards` WHERE `section` = '" . $line['id'] . "' ORDER BY `order` ASC, `name` ASC");
  663. foreach($results2 AS $line2) {
  664. $boards[$line['id']][$line2['id']]['name'] = htmlspecialchars($line2['name']);
  665. $boards[$line['id']][$line2['id']]['desc'] = htmlspecialchars($line2['desc']);
  666. }
  667. }
  668. } else {
  669. $boards = KU_ROOTDIR . 'boards.html';
  670. }
  671. return $boards;
  672. }
  673. /**
  674. * Display the page footer
  675. *
  676. * @param boolean $noboardlist Force the board list to not be displayed
  677. * @param string $executiontime The time it took the page to be created
  678. * @param boolean $hide_extra Hide extra footer information, and display the manage link
  679. * @return string The generated footer
  680. */
  681. function Footer($noboardlist = false, $executiontime = '', $hide_extra = false) {
  682. global $tc_db, $dwoo, $dwoo_data;
  683. $footer = '';
  684. if ($hide_extra || $noboardlist) $this->dwoo_data->assign('boardlist', '');
  685. if ($executiontime != '') $this->dwoo_data->assign('executiontime', round($executiontime, 2));
  686. $botads = $tc_db->GetOne("SELECT code FROM `" . KU_DBPREFIX . "ads` WHERE `position` = 'bot' AND `disp` = '1'");
  687. $this->dwoo_data->assign('botads', $botads);
  688. $footer = $this->dwoo->get(KU_TEMPLATEDIR . '/' . $this->board['text_readable'] . '_footer.tpl', $this->dwoo_data);
  689. $footer .= $this->dwoo->get(KU_TEMPLATEDIR . '/global_board_footer.tpl', $this->dwoo_data);
  690. return $footer;
  691. }
  692. /**
  693. * Finalize the page and print it to the specified filename
  694. *
  695. * @param string $filename File to print the page to
  696. * @param string $contents Page contents
  697. * @param string $board Board which the file is being generated for
  698. * @return string The page contents, if requested
  699. */
  700. function PrintPage($filename, $contents, $board) {
  701. if ($board !== true) {
  702. print_page($filename, $contents, $board);
  703. } else {
  704. echo $contents;
  705. }
  706. }
  707. /**
  708. * Initialize the instance of smary which will be used for generating pages
  709. */
  710. function InitializeDwoo() {
  711. require_once KU_ROOTDIR . 'lib/dwoo.php';
  712. $this->dwoo = new Dwoo();
  713. $this->dwoo_data = new Dwoo_Data();
  714. $this->dwoo_data->assign('cwebpath', getCWebpath());
  715. $this->dwoo_data->assign('boardpath', getCLBoardPath());
  716. }
  717. /**
  718. * Enable/disable archive mode
  719. *
  720. * @param boolean $mode True/false for enabling/disabling archive mode
  721. */
  722. function ArchiveMode($mode) {
  723. $this->archive_dir = ($mode && $this->board['enablearchiving'] == 1) ? '/arch' : '';
  724. }
  725. }
  726. /**
  727. * Post class
  728. *
  729. * Used for post insertion, deletion, and reporting.
  730. *
  731. * @package kusaba
  732. */
  733. class Post extends Board {
  734. // Declare the public variables
  735. var $post = Array();
  736. function Post($postid, $board, $boardid, $is_inserting = false) {
  737. global $tc_db;
  738. $results = $tc_db->GetAll("SELECT * FROM `".KU_DBPREFIX."posts` WHERE `boardid` = '" . $boardid . "' AND `id` = ".$tc_db->qstr($postid)." LIMIT 1");
  739. if (count($results)==0&&!$is_inserting) {
  740. exitWithErrorPage('Invalid post ID.');
  741. } elseif ($is_inserting) {
  742. $this->Board($board, false);
  743. } else {
  744. foreach ($results[0] as $key=>$line) {
  745. if (!is_numeric($key)) $this->post[$key] = $line;
  746. }
  747. $results = $tc_db->GetAll("SELECT `cleared` FROM `".KU_DBPREFIX."reports` WHERE `postid` = ".$tc_db->qstr($this->post['id'])." LIMIT 1");
  748. if (count($results)>0) {
  749. foreach($results AS $line) {
  750. $this->post['isreported'] = ($line['cleared'] == 0) ? true : 'cleared';
  751. }
  752. } else {
  753. $this->post['isreported'] = false;
  754. }
  755. $this->post['isthread'] = ($this->post['parentid'] == 0) ? true : false;
  756. if (empty($this->board) || $this->board['name'] != $board) {
  757. $this->Board($board, false);
  758. }
  759. }
  760. }
  761. function Delete($allow_archive = false) {
  762. global $tc_db;
  763. $i = 0;
  764. if ($this->post['isthread'] == true) {
  765. if ($allow_archive && $this->board['enablearchiving'] == 1 && $this->board['loadbalanceurl'] == '') {
  766. $this->ArchiveMode(true);
  767. $this->RegenerateThreads($this->post['id']);
  768. @copy(KU_BOARDSDIR . $this->board['name'] . '/src/' . $this->post['file'] . '.' . $this->post['filetype'], KU_BOARDSDIR . $this->board['name'] . $this->archive_dir . '/src/' . $this->post['file'] . '.' . $this->post['filetype']);
  769. @copy(KU_BOARDSDIR . $this->board['name'] . '/thumb/' . $this->post['file'] . 's.' . $this->post['filetype'], KU_BOARDSDIR . $this->board['name'] . $this->archive_dir . '/thumb/' . $this->post['file'] . 's.' . $this->post['filetype']);
  770. }
  771. $results = $tc_db->GetAll("SELECT `id`, `file`, `file_type` FROM `".KU_DBPREFIX."posts` WHERE `boardid` = '" . $this->board['id'] . "' AND `IS_DELETED` = 0 AND `parentid` = ".$tc_db->qstr($this->post['id']));
  772. foreach($results AS $line) {
  773. $i++;
  774. if ($allow_archive && $this->board['enablearchiving'] == 1) {
  775. @copy(KU_BOARDSDIR . $this->board['name'] . '/src/' . $line['file'] . '.' . $line['file_type'], KU_BOARDSDIR . $this->board['name'] . $this->archive_dir . '/src/' . $line['file'] . '.' . $line['file_type']);
  776. @copy(KU_BOARDSDIR . $this->board['name'] . '/thumb/' . $line['file'] . 's.' . $line['file_type'], KU_BOARDSDIR . $this->board['name'] . $this->archive_dir . '/thumb/' . $line['file'] . 's.' . $line['file_type']);
  777. }
  778. }
  779. if ($allow_archive && $this->board['enablearchiving'] == 1) {
  780. $this->ArchiveMode(false);
  781. }
  782. @unlink(KU_BOARDSDIR.$this->board['name'].'/res/'.$this->post['id'].'.html');
  783. @unlink(KU_BOARDSDIR.$this->board['name'].'/res/'.$this->post['id'].'-100.html');
  784. @unlink(KU_BOARDSDIR.$this->board['name'].'/res/'.$this->post['id'].'+50.html');
  785. $this->DeleteFile(false, true);
  786. foreach($results AS $line) {
  787. $tc_db->Execute("UPDATE `".KU_DBPREFIX."posts` SET `IS_DELETED` = 1 , `deleted_timestamp` = '" . time() . "' WHERE `boardid` = '" . $this->board['id'] . "' AND `id` = '".$line['id']."' AND `parentid` = ".$tc_db->qstr($this->post['id']));
  788. clearPostCache($line['id'], $this->board['name']);
  789. }
  790. $tc_db->Execute("DELETE FROM `".KU_DBPREFIX."watchedthreads` WHERE `threadid` = ".$tc_db->qstr($this->post['id'])." AND `board` = '".$this->board['name']."'");
  791. $tc_db->Execute("UPDATE `".KU_DBPREFIX."posts` SET `IS_DELETED` = 1 , `deleted_timestamp` = '" . time() . "' WHERE `boardid` = '" . $this->board['id'] . "' AND `id` = ".$tc_db->qstr($this->post['id']));
  792. clearPostCache($this->post['id'], $this->board['name']);
  793. return $i.' ';
  794. } else {
  795. $this->DeleteFile(false);
  796. $tc_db->Execute("UPDATE `".KU_DBPREFIX."posts` SET `IS_DELETED` = 1 , `deleted_timestamp` = '" . time() . "' WHERE `boardid` = '" . $this->board['id'] . "' AND `id` = ".$tc_db->qstr($this->post['id']));
  797. clearPostCache($this->post['id'], $this->board['name']);
  798. return true;
  799. }
  800. }
  801. function DeleteFile($update_to_removed = true, $whole_thread = false) {
  802. global $tc_db;
  803. if ($whole_thread && $this->post['isthread']) {
  804. $results = $tc_db->GetAll("SELECT `id`, `file`, `file_type` FROM `".KU_DBPREFIX."posts` WHERE `boardid` = " . $this->board['id'] . " AND `IS_DELETED` = 0 AND `parentid` = ".$tc_db->qstr($this->post['id']));
  805. if (count($results)>0) {
  806. foreach($results AS $line) {
  807. if ($line['file'] != '' && $line['file'] != 'removed') {
  808. if ($this->board['loadbalanceurl'] != '') {
  809. $this->loadbalancer->Delete($line['file'], $line['file_type']);
  810. } else {
  811. @unlink(KU_BOARDSDIR.$this->board['name'].'/src/'.$line['file'].'.'.$line['file_type']);
  812. @unlink(KU_BOARDSDIR.$this->board['name'].'/src/'.$line['file'].'.pch');
  813. @unlink(KU_BOARDSDIR.$this->board['name'].'/thumb/'.$line['file'].'s.'.$line['file_type']);
  814. @unlink(KU_BOARDSDIR.$this->board['name'].'/thumb/'.$line['file'].'c.'.$line['file_type']);
  815. if ($line['file_type'] == 'mp3') {
  816. @unlink(KU_BOARDSDIR.$this->board['name'].'/thumb/'.$line['file'].'s.jpg');
  817. @unlink(KU_BOARDSDIR.$this->board['name'].'/thumb/'.$line['file'].'s.png');
  818. @unlink(KU_BOARDSDIR.$this->board['name'].'/thumb/'.$line['file'].'s.gif');
  819. }
  820. }
  821. if ($update_to_removed) {
  822. $tc_db->Execute("UPDATE `".KU_DBPREFIX."posts` SET `file` = 'removed', `file_md5` = '' WHERE `boardid` = '" . $this->board['id'] . "' AND `id` = ".$line['id']);
  823. clearPostCache($line['id'], $this->board['name']);
  824. }
  825. }
  826. }
  827. }
  828. $this->DeleteFile($update_to_removed);
  829. } else {
  830. if ($this->post['file']!=''&&$this->post['file']!='removed') {
  831. if ($this->board['loadbalanceurl'] != '') {
  832. $this->loadbalancer->Delete($this->post['file'], $this->post['filetype']);
  833. } else {
  834. @unlink(KU_BOARDSDIR.$this->board['name'].'/src/'.$this->post['file'].'.'.$this->post['file_type']);
  835. @unlink(KU_BOARDSDIR.$this->board['name'].'/src/'.$this->post['file'].'.pch');
  836. @unlink(KU_BOARDSDIR.$this->board['name'].'/thumb/'.$this->post['file'].'s.'.$this->post['file_type']);
  837. @unlink(KU_BOARDSDIR.$this->board['name'].'/thumb/'.$this->post['file'].'c.'.$this->post['file_type']);
  838. if ($this->post['file_type'] == 'mp3') {
  839. @unlink(KU_BOARDSDIR.$this->board['name'].'/thumb/'.$this->post['file'].'s.jpg');
  840. @unlink(KU_BOARDSDIR.$this->board['name'].'/thumb/'.$this->post['file'].'s.png');
  841. @unlink(KU_BOARDSDIR.$this->board['name'].'/thumb/'.$this->post['file'].'s.gif');
  842. }
  843. }
  844. if ($update_to_removed) {
  845. $tc_db->Execute("UPDATE `".KU_DBPREFIX."posts` SET `file` = 'removed', `file_md5` = '' WHERE `boardid` = '" . $this->board['id'] . "' AND `id` = ".$tc_db->qstr($this->post['id']));
  846. clearPostCache($this->post['id'], $this->board['name']);
  847. }
  848. }
  849. }
  850. }
  851. function Insert($parentid, $name, $tripcode, $email, $subject, $message, $filename, $file_original, $filetype, $file_md5, $image_w, $image_h, $filesize, $thumb_w, $thumb_h, $password, $timestamp, $bumped, $ip, $posterauthority, $tag, $stickied, $locked, $boardid) {
  852. global $tc_db;
  853. // RH - ipmd5 now salted (insecure poster ID issue)
  854. $query = "INSERT INTO `".KU_DBPREFIX."posts` ( `parentid` , `boardid`, `name` , `tripcode` , `email` , `subject` , `message` , `file` , `file_original`, `file_type` , `file_md5` , `image_w` , `image_h` , `file_size` , `file_size_formatted` , `thumb_w` , `thumb_h` , `password` , `timestamp` , `bumped` , `ip` , `ipmd5` , `posterauthority` , `tag` , `stickied` , `locked` ) VALUES ( ".$tc_db->qstr($parentid).", ".$tc_db->qstr($boardid).", ".$tc_db->qstr($name).", ".$tc_db->qstr($tripcode).", ".$tc_db->qstr($email).", ".$tc_db->qstr($subject).", ".$tc_db->qstr($message).", ".$tc_db->qstr($filename).", ".$tc_db->qstr($file_original).", ".$tc_db->qstr($filetype).", ".$tc_db->qstr($file_md5).", ".$tc_db->qstr(intval($image_w)).", ".$tc_db->qstr(intval($image_h)).", ".$tc_db->qstr($filesize).", ".$tc_db->qstr(ConvertBytes($filesize)).", ".$tc_db->qstr($thumb_w).", ".$tc_db->qstr($thumb_h).", ".$tc_db->qstr($password).", ".$tc_db->qstr($timestamp).", ".$tc_db->qstr($bumped).", ".$tc_db->qstr(md5_encrypt($ip, KU_RANDOMSEED)).", '".md5(KU_SALT.$ip)."', ".$tc_db->qstr($posterauthority).", ".$tc_db->qstr($tag).", ".$tc_db->qstr($stickied).", ".$tc_db->qstr($locked)." )";
  855. $tc_db->Execute($query);
  856. $id = $tc_db->Insert_Id();
  857. if(!$id || KU_DBTYPE == 'sqlite') {
  858. // Non-mysql installs don't return the insert ID after insertion, we need to manually get it.
  859. $id = $tc_db->GetOne("SELECT `id` FROM `".KU_DBPREFIX."posts` WHERE `boardid` = ".$tc_db->qstr($boardid)." AND timestamp = ".$tc_db->qstr($timestamp)." AND `ipmd5` = '".md5(KU_SALT.$ip)."' LIMIT 1");
  860. }
  861. if ($id == 1 && $this->board['start'] > 1) {
  862. $tc_db->Execute("UPDATE `".KU_DBPREFIX."posts` SET `id` = '".$this->board['start']."' WHERE `boardid` = ".$boardid);
  863. return $this->board['start'];
  864. }
  865. return $id;
  866. }
  867. function Report() {
  868. global $tc_db;
  869. return $tc_db->Execute("INSERT INTO `".KU_DBPREFIX."reports` ( `board` , `postid` , `when` , `ip`, `reason` ) VALUES ( " . $tc_db->qstr($this->board['name']) . " , " . $tc_db->qstr($this->post['id']) . " , ".time()." , '" . md5_encrypt($_SERVER['REMOTE_ADDR'], KU_RANDOMSEED) . "', " . $tc_db->qstr($_POST['reportreason']) . " )");
  870. }
  871. }
  872. ?>