table_forum_post.php 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882
  1. <?php
  2. /**
  3. * [Discuz!] (C)2001-2099 Comsenz Inc.
  4. * This is NOT a freeware, use is subject to license terms
  5. *
  6. * $Id: table_forum_post.php 30080 2012-05-09 08:19:20Z liulanbo $
  7. */
  8. if(!defined('IN_DISCUZ')) {
  9. exit('Access Denied');
  10. }
  11. class table_forum_post extends discuz_table
  12. {
  13. private static $_tableid_tablename = array();
  14. public function __construct() {
  15. $this->_table = 'forum_post';
  16. $this->_pk = 'pid';
  17. parent::__construct();
  18. }
  19. public static function get_tablename($tableid, $primary = 0) {
  20. list($type, $tid) = explode(':', $tableid);
  21. if(!isset(self::$_tableid_tablename[$tableid])) {
  22. if($type == 'tid') {
  23. self::$_tableid_tablename[$tableid] = self::getposttablebytid($tid, $primary);
  24. } else {
  25. self::$_tableid_tablename[$tableid] = self::getposttable($type);
  26. }
  27. }
  28. return self::$_tableid_tablename[$tableid];
  29. }
  30. public function count_author_by_tid($tid) {
  31. return DB::result_first('SELECT count(DISTINCT authorid) FROM %t WHERE tid=%d', array(self::get_tablename('tid:'.$tid), $tid));
  32. }
  33. public function count_by_tid_dateline($tableid, $tid, $dateline) {
  34. return DB::result_first('SELECT COUNT(*) FROM %t WHERE tid=%d AND invisible=0 AND dateline<=%d',
  35. array(self::get_tablename($tableid), $tid, $dateline));
  36. }
  37. public function fetch_maxposition_by_tid($tableid, $tid) {
  38. return DB::result_first('SELECT position FROM %t WHERE tid=%d ORDER BY position DESC LIMIT 1',
  39. array(self::get_tablename($tableid), $tid));
  40. }
  41. public function fetch_all_by_tid_range_position($tableid, $tid, $start, $end, $maxposition, $ordertype = 0) {
  42. $storeflag = false;
  43. if($this->_allowmem) {
  44. if($ordertype != 1 && $start == 1 && $maxposition > ($end - $start)) {
  45. $data = $this->fetch_cache($tid, $this->_pre_cache_key.'tid_');
  46. if($data && count($data) == ($end - $start)) {
  47. $delauthorid = $this->fetch_cache('delauthorid');
  48. $updatefid = $this->fetch_cache('updatefid');
  49. $delpid = $this->fetch_cache('delpid');
  50. foreach($data as $k => $post) {
  51. if(in_array($post['pid'], $delpid) || $post['invisible'] < 0 || in_array($post['authorid'], $delauthorid)) {
  52. $data[$k]['invisible'] = 0;
  53. $data[$k]['authorid'] = 0;
  54. $data[$k]['useip'] = '';
  55. $data[$k]['dateline'] = 0;
  56. $data[$k]['pid'] = 0;
  57. $data[$k]['message'] = lang('forum/misc', 'post_deleted');
  58. }
  59. if(isset($updatefid[$post['fid']]) && $updatefid[$post['fid']]['dateline'] > $post['dateline']) {
  60. $data[$k]['fid'] = $updatefid[$post['fid']]['fid'];
  61. }
  62. }
  63. return $data;
  64. }
  65. $storeflag = true;
  66. }
  67. }
  68. $data = DB::fetch_all('SELECT * FROM %t WHERE tid=%d AND position>=%d AND position<%d ORDER BY position'.($ordertype == 1 ? ' DESC' : ''), array(self::get_tablename($tableid), $tid, $start, $end), 'pid');
  69. if($storeflag) {
  70. $this->store_cache($tid, $data, $this->_cache_ttl, $this->_pre_cache_key.'tid_');
  71. }
  72. return $data;
  73. }
  74. public function fetch_all_by_tid_position($tableid, $tid, $position) {
  75. return DB::fetch_all('SELECT * FROM %t WHERE tid=%d AND '.DB::field('position', $position), array(self::get_tablename($tableid), $tid));
  76. }
  77. public function count_by_tid_invisible_authorid($tid, $authorid) {
  78. return DB::result_first('SELECT COUNT(*) FROM %t WHERE tid=%d AND invisible=0 AND authorid=%d',
  79. array(self::get_tablename('tid:'.$tid), $tid, $authorid));
  80. }
  81. public function count_visiblepost_by_tid($tid) {
  82. return DB::result_first('SELECT COUNT(*) FROM %t WHERE tid=%d AND invisible=0', array(self::get_tablename('tid:'.$tid), $tid));
  83. }
  84. public function count_by_tid_pid($tid, $pid) {
  85. return DB::result_first('SELECT COUNT(*) FROM %t WHERE tid=%d AND pid<%d', array(self::get_tablename('tid:'.$tid), $tid, $pid));
  86. }
  87. public function count_by_tid_authorid($tid, $authorid) {
  88. return DB::result_first('SELECT COUNT(*) FROM %t WHERE tid=%d AND first=0 AND authorid=%d', array(self::get_tablename('tid:'.$tid), $tid, $authorid));
  89. }
  90. public function count_by_authorid($tableid, $authorid) {
  91. return DB::result_first('SELECT COUNT(*) FROM %t WHERE authorid=%d AND invisible=0', array(self::get_tablename($tableid), $authorid));
  92. }
  93. public function count_group_authorid_by_fid($tableid, $fid) {
  94. return DB::fetch_all('SELECT COUNT(*) as num, authorid FROM %t WHERE fid=%d AND first=0 GROUP BY authorid', array(self::get_tablename($tableid), $fid));
  95. }
  96. public function count_by_first($tableid, $first) {
  97. return DB::result_first('SELECT count(*) FROM %t WHERE %i', array(self::get_tablename($tableid), DB::field('first', $first)));
  98. }
  99. public function count_by_invisible($tableid, $invisible) {
  100. return DB::result_first('SELECT COUNT(*) FROM %t WHERE %i', array(self::get_tablename($tableid), DB::field('invisible', $invisible)));
  101. }
  102. public function count_table($tableid) {
  103. return DB::result_first('SELECT COUNT(*) FROM %t', array(self::get_tablename($tableid)));
  104. }
  105. public function count_by_fid_invisible($tableid, $fid, $invisible) {
  106. return DB::result_first('SELECT COUNT(*) FROM %t WHERE fid=%d AND invisible=%d', array(self::get_tablename($tableid), $fid, $invisible));
  107. }
  108. public function count_by_dateline($tableid, $dateline) {
  109. return DB::result_first('SELECT COUNT(*) FROM %t WHERE dateline>=%d AND invisible=0', array(self::get_tablename($tableid), $dateline));
  110. }
  111. public function fetch($tableid, $pid, $outmsg = true) {
  112. $post = DB::fetch_first('SELECT * FROM %t WHERE pid=%d', array(self::get_tablename($tableid), $pid));
  113. if(!$outmsg) {
  114. unset($post['message']);
  115. }
  116. return $post;
  117. }
  118. public function fetch_visiblepost_by_tid($tableid, $tid, $start = 0, $order = 0) {
  119. return DB::fetch_first('SELECT * FROM %t WHERE tid=%d AND invisible=0 ORDER BY dateline '. ($order ? 'DESC' : '').' '. DB::limit($start, 1),
  120. array(self::get_tablename($tableid), $tid));
  121. }
  122. public function fetch_threadpost_by_tid_invisible($tid, $invisible = null) {
  123. return DB::fetch_first('SELECT * FROM %t WHERE tid=%d AND first=1'.($invisible !== null ? ' AND '.DB::field('invisible', $invisible) : ''),
  124. array(self::get_tablename('tid:'.$tid), $tid));
  125. }
  126. public function fetch_pid_by_tid_authorid($tid, $authorid) {
  127. return DB::result_first('SELECT pid FROM %t WHERE tid=%d AND authorid=%d LIMIT 1', array(self::get_tablename('tid:'.$tid), $tid, $authorid));
  128. }
  129. public function fetch_pid_by_tid_clientip($tid, $clientip) {
  130. return DB::result_first('SELECT pid FROM %t WHERE tid=%d AND authorid=0 AND useip=%s LIMIT 1', array(self::get_tablename('tid:'.$tid), $tid, $clientip));
  131. }
  132. public function fetch_attachment_by_tid($tid) {
  133. return DB::result_first('SELECT attachment FROM %t WHERE tid=%d AND invisible=0 AND attachment>0 LIMIT 1', array(self::get_tablename('tid:'.$tid), $tid));
  134. }
  135. public function fetch_maxid($tableid) {
  136. return DB::result_first('SELECT MAX(pid) FROM %t', array(self::get_tablename($tableid)));
  137. }
  138. public function fetch_posts($tableid) {
  139. return DB::fetch_first('SELECT COUNT(*) AS posts, (MAX(dateline)-MIN(dateline))/86400 AS runtime FROM %t', array(self::get_tablename($tableid)));
  140. }
  141. public function fetch_by_pid_condition($tableid, $pid, $addcondiction = '', $fields = '*') {
  142. return DB::fetch_first('SELECT %i FROM %t WHERE pid=%d %i LIMIT 1',
  143. array($fields, self::get_tablename($tableid), $pid, $addcondiction));
  144. }
  145. public function fetch_all($tableid, $pids, $outmsg = true) {
  146. $postlist = array();
  147. if($pids) {
  148. $query = DB::query('SELECT * FROM %t WHERE %i', array(self::get_tablename($tableid), DB::field($this->_pk, $pids)));
  149. while($post = DB::fetch($query)) {
  150. if(!$outmsg) {
  151. unset($post['message']);
  152. }
  153. $postlist[$post[$this->_pk]] = $post;
  154. }
  155. }
  156. return $postlist;
  157. }
  158. public function fetch_all_tradepost_viewthread_by_tid($tid, $visibleallflag, $authorid, $pids, $forum_pagebydesc, $ordertype, $start, $limit) {
  159. if(empty($pids)) {
  160. return array();
  161. }
  162. $data = array();
  163. $parameter = $this->handle_viewthread_parameter($visibleallflag, $authorid, $forum_pagebydesc, $ordertype);
  164. $query = DB::query('SELECT * FROM %t WHERE tid=%d'.
  165. ($parameter['invisible'] ? ' AND '.$parameter['invisible'] : '').($parameter['authorid'] ? ' AND '.$parameter['authorid'] : '').
  166. ' AND pid NOT IN ('.dimplode($pids).')'.
  167. ' '.$parameter['orderby'].
  168. ' '.DB::limit($start, $limit),
  169. array(self::get_tablename('tid:'.$tid), $tid));
  170. while($post = DB::fetch($query)) {
  171. $data[$post['pid']] = $post;
  172. }
  173. return $data;
  174. }
  175. public function fetch_all_debatepost_viewthread_by_tid($tid, $visibleallflag, $authorid, $stand, $forum_pagebydesc, $ordertype, $start, $limit) {
  176. $data = array();
  177. $parameter = $this->handle_viewthread_parameter($visibleallflag, $authorid, $forum_pagebydesc, $ordertype, 'p.');
  178. $query = DB::query("SELECT dp.*, p.* FROM %t p LEFT JOIN %t dp ON p.pid=dp.pid WHERE p.tid=%d".
  179. ($parameter['invisible'] ? ' AND '.$parameter['invisible'] : '').($parameter['authorid'] ? ' AND '.$parameter['authorid'] : '').
  180. (isset($stand) ? ($stand ? ' AND (dp.stand='.intval($stand).' OR p.first=1)' : ' AND (dp.stand=0 OR dp.stand IS NULL OR p.first=1)') : '').
  181. ' '.$parameter['orderby'].
  182. ' '.DB::limit($start, $limit),
  183. array(self::get_tablename('tid:'.$tid), 'forum_debatepost', $tid));
  184. while($post = DB::fetch($query)) {
  185. $data[$post['pid']] = $post;
  186. }
  187. return $data;
  188. }
  189. public function fetch_all_common_viewthread_by_tid($tid, $visibleallflag, $authorid, $forum_pagebydesc, $ordertype, $count, $start, $limit) {
  190. $data = array();
  191. $storeflag = false;
  192. if($this->_allowmem) {
  193. if($ordertype != 1 && !$forum_pagebydesc && !$start && $count > $limit) {
  194. $data = $this->fetch_cache($tid, $this->_pre_cache_key.'tid_');
  195. if($data && count($data) == $limit) {
  196. $delauthorid = $this->fetch_cache('delauthorid');
  197. $updatefid = $this->fetch_cache('updatefid');
  198. $delpid = $this->fetch_cache('delpid');
  199. foreach($data as $k => $post) {
  200. if(in_array($post['pid'], $delpid) || $post['invisible'] < 0 || in_array($post['authorid'], $delauthorid)) {
  201. $data[$k]['invisible'] = 0;
  202. $data[$k]['authorid'] = 0;
  203. $data[$k]['useip'] = '';
  204. $data[$k]['dateline'] = 0;
  205. $data[$k]['pid'] = 0;
  206. $data[$k]['message'] =lang('forum/misc', 'post_deleted');
  207. }
  208. if(isset($updatefid[$post['fid']]) && $updatefid[$post['fid']]['dateline'] > $post['dateline']) {
  209. $data[$k]['fid'] = $updatefid[$post['fid']]['fid'];
  210. }
  211. }
  212. return $data;
  213. }
  214. $storeflag = true;
  215. }
  216. }
  217. $parameter = $this->handle_viewthread_parameter($visibleallflag, $authorid, $forum_pagebydesc, $ordertype);
  218. $query = DB::query('SELECT * FROM %t WHERE tid=%d'.
  219. ($parameter['invisible'] ? ' AND '.$parameter['invisible'] : '').($parameter['authorid'] ? ' AND '.$parameter['authorid'] : '').
  220. ' '.$parameter['orderby'].
  221. ' '.DB::limit($start, $limit),
  222. array(self::get_tablename('tid:'.$tid), $tid));
  223. while($post = DB::fetch($query)) {
  224. $data[$post['pid']] = $post;
  225. }
  226. if($storeflag) {
  227. $this->store_cache($tid, $data, $this->_cache_ttl, $this->_pre_cache_key.'tid_');
  228. }
  229. return $data;
  230. }
  231. private function handle_viewthread_parameter($visibleallflag, $authorid, $forum_pagebydesc, $ordertype, $alias = '') {
  232. $return = array();
  233. if(!$visibleallflag) {
  234. $return['invisible'] = $alias.DB::field('invisible', 0);
  235. }
  236. if($authorid) {
  237. $return['authorid'] = $alias.DB::field('authorid', $authorid);
  238. }
  239. if($forum_pagebydesc) {
  240. if($ordertype != 1) {
  241. $return['orderby'] = 'ORDER BY '.$alias.'dateline DESC';
  242. } else {
  243. $return['orderby'] = 'ORDER BY '.$alias.'dateline ASC';
  244. }
  245. } else {
  246. if($ordertype != 1) {
  247. $return['orderby'] = 'ORDER BY '.$alias.'dateline';
  248. } else {
  249. $return['orderby'] = 'ORDER BY '.$alias.'dateline DESC';
  250. }
  251. }
  252. return $return;
  253. }
  254. public function fetch_all_by_authorid($tableid, $authorid, $outmsg = true, $order = '', $start = 0, $limit = 0, $first = null, $invisible = null, $fid = null, $filterfid = null) {
  255. $postlist = $sql = array();
  256. if($first !== null && $invisible !== null) {
  257. if($first == 1) {
  258. $sql[] = DB::field('invisible', $invisible);
  259. $sql[] = DB::field('first', 1);
  260. } else {
  261. $sql[] = DB::field('invisible', $invisible);
  262. $sql[] = DB::field('first', 0);
  263. }
  264. } elseif($invisible !== null) {
  265. $sql[] = DB::field('invisible', $invisible);
  266. } elseif($first !== null) {
  267. $sql[] = DB::field('first', $first);
  268. }
  269. if($fid !== null) {
  270. $sql[] = DB::field('fid', $fid);
  271. }
  272. if($filterfid !== null) {
  273. $filterfid = dintval($filterfid, true);
  274. $sql[] = DB::field('fid', $filterfid, is_array($filterfid) ? 'notin' : '<>');
  275. }
  276. $query = DB::query('SELECT * FROM %t WHERE '.DB::field('authorid', $authorid).' %i '.($order ? 'ORDER BY dateline '.$order : '').' '.DB::limit($start, $limit),
  277. array(self::get_tablename($tableid), ($sql ? 'AND '.implode(' AND ', $sql) : '')));
  278. while($post = DB::fetch($query)) {
  279. if(!$outmsg) {
  280. unset($post['message']);
  281. }
  282. $postlist[$post[$this->_pk]] = $post;
  283. }
  284. return $postlist;
  285. }
  286. public function fetch_all_tid_by_first($tableid, $first, $start = 0, $limit = 0) {
  287. return DB::fetch_all('SELECT tid FROM %t WHERE first=%d '.DB::limit($start, $limit), array(self::get_tablename($tableid), $first));
  288. }
  289. public function fetch_all_by_tid($tableid, $tids, $outmsg = true, $order = '', $start = 0, $limit = 0, $first = null, $invisible = null, $authorid = null, $fid = null) {
  290. $postlist = $sql = array();
  291. if($first !== null && $invisible !== null) {
  292. if($first == 1) {
  293. $sql[] = DB::field('first', 1);
  294. $sql[] = DB::field('invisible', $invisible);
  295. } else {
  296. $sql[] = DB::field('invisible', $invisible);
  297. $sql[] = DB::field('first', 0);
  298. }
  299. } elseif($first !== null) {
  300. $sql[] = DB::field('first', $first);
  301. } elseif($invisible !== null) {
  302. $sql[] = DB::field('invisible', $invisible);
  303. }
  304. if($authorid !== null) {
  305. $sql[] = DB::field('authorid', $authorid);
  306. }
  307. if($fid !== null) {
  308. $sql[] = DB::field('fid', $fid);
  309. }
  310. $query = DB::query('SELECT * FROM %t WHERE '.DB::field('tid', $tids).' %i '.($order ? 'ORDER BY dateline '.$order : '').' '.DB::limit($start, $limit),
  311. array(self::get_tablename($tableid), ($sql ? 'AND '.implode(' AND ', $sql) : '')));
  312. while($post = DB::fetch($query)) {
  313. if(!$outmsg) {
  314. unset($post['message']);
  315. }
  316. $postlist[$post[$this->_pk]] = $post;
  317. }
  318. return $postlist;
  319. }
  320. public function fetch_all_pid_by_tid_lastpid($tid, $lastpid, $round) {
  321. return DB::fetch_all("SELECT pid FROM %t WHERE tid=%d AND pid>%d ORDER BY pid ASC %i",
  322. array(self::get_tablename('tid:'.$tid), $tid, $lastpid, DB::limit(0, $round)));
  323. }
  324. public function fetch_all_by_fid($tableid, $fid, $outmsg = true, $order = '', $start = 0, $limit = 0, $first = null, $invisible = null) {
  325. $postlist = $sql = array();
  326. if($first !== null && $invisible !== null) {
  327. if($first == 1) {
  328. $sql[] = DB::field('first', 1);
  329. $sql[] = DB::field('invisible', $invisible);
  330. } else {
  331. $sql[] = DB::field('invisible', $invisible);
  332. $sql[] = DB::field('first', 0);
  333. }
  334. } elseif($first !== null) {
  335. $sql[] = DB::field('first', $first);
  336. } elseif($invisible !== null) {
  337. $sql[] = DB::field('invisible', $invisible);
  338. }
  339. $query = DB::query('SELECT * FROM %t WHERE '.DB::field('fid', $fid).' %i '.($order ? 'ORDER BY dateline '.$order : '').' '.DB::limit($start, $limit),
  340. array(self::get_tablename($tableid), ($sql ? 'AND '.implode(' AND ', $sql) : '')));
  341. while($post = DB::fetch($query)) {
  342. if(!$outmsg) {
  343. unset($post['message']);
  344. }
  345. $postlist[$post[$this->_pk]] = $post;
  346. }
  347. return $postlist;
  348. }
  349. public function fetch_all_by_pid($tableid, $pids, $outmsg = true, $order = '', $start = 0, $limit = 0, $fid = null, $invisible = null) {
  350. $postlist = $sql = array();
  351. if($fid !== null) {
  352. $sql[] = DB::field('fid', $fid);
  353. }
  354. if($invisible !== null) {
  355. $sql[] = DB::field('invisible', $invisible);
  356. }
  357. $query = DB::query('SELECT * FROM %t WHERE '.DB::field('pid', $pids).' %i '.($order ? 'ORDER BY dateline '.$order : '').' '.DB::limit($start, $limit),
  358. array(self::get_tablename($tableid), ($sql ? 'AND '.implode(' AND ', $sql) : '')));
  359. while($post = DB::fetch($query)) {
  360. if(!$outmsg) {
  361. unset($post['message']);
  362. }
  363. $postlist[$post[$this->_pk]] = $post;
  364. }
  365. return $postlist;
  366. }
  367. public function fetch_all_debatepost_by_tid_stand($tid, $stand, $start, $limit) {
  368. return DB::fetch_all('
  369. SELECT author, authorid
  370. FROM %t p, %t dp
  371. WHERE p.tid=%d AND p.anonymous=0 AND p.invisible=0 AND dp.stand=%d AND p.pid=dp.pid
  372. ORDER BY p.dateline DESC %i',
  373. array(self::get_tablename('tid:'.$tid), 'forum_debatepost', $tid, $stand, DB::limit($start, $limit)));
  374. }
  375. public function fetch_all_visiblepost_by_tid_groupby_authorid($tableid, $tid) {
  376. return DB::fetch_all('SELECT pid, tid, authorid, subject, dateline FROM %t WHERE tid=%d AND invisible=0 GROUP BY authorid ORDER BY dateline',
  377. array(self::get_tablename($tableid), $tid));
  378. }
  379. public function fetch_all_pid_by_invisible_dateline($tableid, $invisible, $dateline, $start, $limit) {
  380. return DB::fetch_all('SELECT pid FROM %t WHERE invisible=%d AND dateline<%d %i', array(self::get_tablename($tableid), $invisible, $dateline, DB::limit($start, $limit)));
  381. }
  382. public function fetch_all_top_post_author($tableid, $timelimit, $num) {
  383. return DB::fetch_all('SELECT DISTINCT(author) AS username, authorid AS uid, COUNT(pid) AS posts
  384. FROM %t
  385. WHERE dateline>=%d AND invisible=0 AND authorid>0
  386. GROUP BY author
  387. ORDER BY posts DESC %i',
  388. array(self::get_tablename($tableid), $timelimit, DB::limit(0, $num)));
  389. }
  390. public function fetch_all_author_posts_by_dateline($tableid, $authorid, $dateline) {
  391. return DB::fetch_all('SELECT authorid, COUNT(*) AS posts FROM %t
  392. WHERE dateline>=%d AND %i AND invisible=0 GROUP BY authorid', array(self::get_tablename($tableid), $dateline, DB::field('authorid', $authorid)));
  393. }
  394. public function update($tableid, $pid, $data, $unbuffered = false, $low_priority = false, $first = null, $invisible = null, $fid = null, $status = null) {
  395. $where = array();
  396. $where[] = DB::field('pid', $pid);
  397. if($first !== null) {
  398. $where[] = DB::field('first', $first);
  399. }
  400. if($invisible !== null) {
  401. $where[] = DB::field('invisible', $invisible);
  402. }
  403. if($status !== null) {
  404. $where[] = DB::field('status', $status);
  405. }
  406. if($fid !== null) {
  407. $where[] = DB::field('fid', $fid);
  408. }
  409. $return = DB::update(self::get_tablename($tableid), $data, implode(' AND ', $where), $unbuffered, $low_priority);
  410. if($return && $this->_allowmem) {
  411. $this->update_cache($tableid, $pid, 'pid', $data, array('invisible' => $invisible, 'first' => $first, 'fid' => $fid, 'status' => $status));
  412. }
  413. return $return;
  414. }
  415. public function update_by_tid($tableid, $tid, $data, $unbuffered = false, $low_priority = false, $first = null, $invisible = null, $status = null) {
  416. $where = array();
  417. $where[] = DB::field('tid', $tid);
  418. if($first !== null) {
  419. $where[] = DB::field('first', $first);
  420. }
  421. if($invisible !== null) {
  422. $where[] = DB::field('invisible', $invisible);
  423. }
  424. if($status !== null) {
  425. $where[] = DB::field('status', $status);
  426. }
  427. $return = DB::update(self::get_tablename($tableid), $data, implode(' AND ', $where), $unbuffered, $low_priority);
  428. if($return && $this->_allowmem) {
  429. $this->update_cache(0, $tid, 'tid', $data, array('first' => $first, 'invisible' => $invisible, 'status' => $status));
  430. }
  431. return $return;
  432. }
  433. public function update_fid_by_fid($tableid, $fid, $newfid, $unbuffered = false, $low_priority = false) {
  434. $where = array();
  435. $where[] = DB::field('fid', $fid);
  436. $return = DB::update(self::get_tablename($tableid), array('fid' => $newfid), implode(' AND ', $where), $unbuffered, $low_priority);
  437. if($return && $this->_allowmem) {
  438. $updatefid = $this->fetch_cache('updatefid');
  439. $updatefid[$fid] = array('fid' => $newfid, 'dateline' => TIMESTAMP);
  440. $this->store_cache('updatefid', $updatefid);
  441. }
  442. return $return;
  443. }
  444. public function update_cache($tableid, $id, $idtype, $data, $condition = array(), $glue = 'merge') {
  445. if(!$this->_allowmem) return;
  446. if($idtype == 'tid') {
  447. $memorydata = $this->fetch_cache($id, $this->_pre_cache_key.'tid_');
  448. if(!$memorydata) {
  449. return;
  450. }
  451. if(!is_array($id)) {
  452. $memorydata = array($id => $memorydata);
  453. $id = (array)$id;
  454. }
  455. foreach($id as $v) {
  456. if(!$memorydata[$v]) {
  457. continue;
  458. }
  459. foreach($memorydata[$v] as $pid => $post) {
  460. $updateflag = true;
  461. if($condition) {
  462. foreach($condition as $ck => $cv) {
  463. if($cv !== null && !in_array($post[$ck], (array)$cv)) {
  464. $updateflag = false;
  465. break;
  466. }
  467. }
  468. }
  469. if($updateflag) {
  470. if($glue == 'merge') {
  471. $memorydata[$v][$pid] = array_merge($post, $data);
  472. } else {
  473. foreach($data as $dk => $dv) {
  474. $memorydata[$v][$pid][$dk] = helper_util::compute($memorydata[$v][$pid][$dk], $dv, $glue);
  475. }
  476. }
  477. }
  478. }
  479. $this->store_cache($v, $memorydata[$v], $this->_cache_ttl, $this->_pre_cache_key.'tid_');
  480. }
  481. } elseif($idtype == 'pid') {
  482. $memorytid = array();
  483. $query = DB::query('SELECT pid, tid FROM %t WHERE '.DB::field('pid', $id), array(self::get_tablename($tableid)));
  484. while($post = DB::fetch($query)) {
  485. $memorytid[$post['pid']] = $post['tid'];
  486. }
  487. $memorydata = $this->fetch_cache($memorytid, $this->_pre_cache_key.'tid_');
  488. if(!$memorydata) {
  489. return;
  490. }
  491. if(!is_array($id)) {
  492. $id = (array)$id;
  493. }
  494. foreach($id as $v) {
  495. if($memorydata[$memorytid[$v]][$v]) {
  496. $updateflag = true;
  497. if($condition) {
  498. foreach($condition as $ck => $cv) {
  499. if($cv !== null && !in_array($memorydata[$memorytid[$v]][$v][$ck], (array)$cv)) {
  500. $updateflag = false;
  501. break;
  502. }
  503. }
  504. }
  505. if($updateflag) {
  506. if($glue == 'merge') {
  507. $memorydata[$memorytid[$v]][$v] = array_merge($memorydata[$memorytid[$v]][$v], $data);
  508. } else {
  509. foreach($data as $dk => $dv) {
  510. $memorydata[$memorytid[$v]][$v][$dk] = helper_util::compute($memorydata[$memorytid[$v]][$v][$dk], $dv, $glue);
  511. }
  512. }
  513. }
  514. }
  515. }
  516. foreach($memorydata as $tid => $postlist) {
  517. $this->store_cache($tid, $postlist, $this->_cache_ttl, $this->_pre_cache_key.'tid_');
  518. }
  519. } elseif($idtype == 'fid') {
  520. }
  521. }
  522. public function concat_threadtags_by_tid($tid, $tags) {
  523. $return = DB::query('UPDATE %t SET tags=concat(tags, %s) WHERE tid=%d AND first=1', array(self::get_tablename('tid:'.$tid), $tags, $tid));
  524. if($return && $this->_allowmem) {
  525. $this->update_cache(0, $tid, 'tid', array('tags' => $tags), array('first' => 1), '.');
  526. }
  527. return $return;
  528. }
  529. public function increase_rate_by_pid($tableid, $pid, $rate, $ratetimes) {
  530. $return = DB::query('UPDATE %t SET rate=rate+\'%d\', ratetimes=ratetimes+\'%d\' WHERE pid=%d',
  531. array(self::get_tablename($tableid), $rate, $ratetimes, $pid));
  532. if($return && $this->_allowmem) {
  533. $this->update_cache($tableid, $pid, 'pid', array('rate' => $rate, 'ratetimes' => $ratetimes), array(), '+');
  534. }
  535. return $return;
  536. }
  537. public function increase_position_by_tid($tableid, $tid, $position) {
  538. $return = DB::query('UPDATE %t SET position=position+\'%d\' WHERE '.DB::field('tid', $tid),
  539. array(self::get_tablename($tableid), $position));
  540. return $return;
  541. }
  542. public function increase_status_by_pid($tableid, $pid, $status, $glue, $unbuffered = false) {
  543. $return = DB::query('UPDATE %t SET %i WHERE %i', array(self::get_tablename($tableid), DB::field('status', $status, $glue), DB::field('pid', $pid)), $unbuffered);
  544. if($return && $this->_allowmem) {
  545. $this->update_cache($tableid, $pid, 'pid', array('status' => $status), array(), $glue);
  546. }
  547. return $return;
  548. }
  549. public function insert($tableid, $data, $return_insert_id = false, $replace = false, $silent = false) {
  550. return DB::insert(self::get_tablename($tableid), $data, $return_insert_id, $replace, $silent);
  551. }
  552. public function delete($tableid, $pid, $unbuffered = false) {
  553. $return = DB::delete(self::get_tablename($tableid), DB::field($this->_pk, $pid), 0, $unbuffered);
  554. if($return && $this->_allowmem) {
  555. $delpid = $this->fetch_cache('delpid');
  556. $this->store_cache('delpid', array_merge((array)$pid, (array)$delpid));
  557. }
  558. return $return;
  559. }
  560. public function delete_by_tid($tableid, $tids, $unbuffered = false) {
  561. $return = DB::delete(self::get_tablename($tableid), DB::field('tid', $tids), 0, $unbuffered);
  562. if($return && $this->_allowmem) {
  563. $this->clear_cache($tids, $this->_pre_cache_key.'tid_');
  564. }
  565. return $return;
  566. }
  567. public function delete_by_authorid($tableid, $authorids, $unbuffered = false) {
  568. $return = DB::delete(self::get_tablename($tableid), DB::field('authorid', $authorids), 0, $unbuffered);
  569. if($return && $this->_allowmem) {
  570. $delauthorid = $this->fetch_cache('delauthorid');
  571. $this->store_cache('delauthorid', array_merge((array)$authorids, (array)$delauthorid));
  572. }
  573. return $return;
  574. }
  575. public function delete_by_fid($tableid, $fids, $unbuffered = false) {
  576. return DB::delete(self::get_tablename($tableid), DB::field('fid', $fids), 0, $unbuffered);
  577. }
  578. public function show_table() {
  579. return DB::fetch_all("SHOW TABLES LIKE '".DB::table('forum_post')."\_%'");
  580. }
  581. public function show_table_by_tableid($tableid) {
  582. return DB::fetch_first('SHOW CREATE TABLE %t', array(self::get_tablename($tableid)));
  583. }
  584. public function drop_table($tableid) {
  585. return ($tableid = dintval($tableid)) ? DB::query('DROP TABLE %t', array(self::get_tablename($tableid))) : false;
  586. }
  587. public function optimize_table($tableid) {
  588. return DB::query('OPTIMIZE TABLE %t', array(self::get_tablename($tableid)), true);
  589. }
  590. public function move_table($tableid, $fieldstr, $fromtable, $tid) {
  591. $tidsql = is_array($tid) ? 'tid IN(%n)' : 'tid=%d';
  592. return DB::query("INSERT INTO %t ($fieldstr) SELECT $fieldstr FROM $fromtable WHERE $tidsql", array(self::get_tablename($tableid), $tid), true);
  593. }
  594. public function count_by_search($tableid, $tid = null, $keywords = null, $invisible =null, $fid = null, $authorid = null, $author = null, $starttime = null, $endtime = null, $useip = null, $first = null) {
  595. $sql = '';
  596. $sql .= $tid ? ' AND '.DB::field('tid', $tid) : '';
  597. $sql .= $authorid !== null ? ' AND '.DB::field('authorid', $authorid) : '';
  598. $sql .= $invisible !== null ? ' AND '.DB::field('invisible', $invisible) : '';
  599. $sql .= $first !== null ? ' AND '.DB::field('first', $first) : '';
  600. $sql .= $fid ? ' AND '.DB::field('fid', $fid) : '';
  601. $sql .= $author ? ' AND '.DB::field('author', $author) : '';
  602. $sql .= $starttime ? ' AND '.DB::field('dateline', $starttime, '>=') : '';
  603. $sql .= $endtime ? ' AND '.DB::field('dateline', $endtime, '<') : '';
  604. $sql .= $useip ? ' AND '.DB::field('useip', $useip, 'like') : '';
  605. if(trim($keywords)) {
  606. $sqlkeywords = $or = '';
  607. foreach(explode(',', str_replace(' ', '', $keywords)) as $keyword) {
  608. $keyword = addslashes($keyword);
  609. $sqlkeywords .= " $or message LIKE '%$keyword%'";
  610. $or = 'OR';
  611. }
  612. $sql .= " AND ($sqlkeywords)";
  613. }
  614. if($sql) {
  615. return DB::result_first('SELECT COUNT(*) FROM %t WHERE 1 %i', array(self::get_tablename($tableid), $sql));
  616. } else {
  617. return 0;
  618. }
  619. }
  620. public function fetch_all_by_search($tableid, $tid = null, $keywords = null, $invisible = null, $fid = null, $authorid = null, $author = null, $starttime = null, $endtime = null, $useip = null, $first = null, $start = null, $limit = null) {
  621. $sql = '';
  622. $sql .= $tid ? ' AND '.DB::field('tid', $tid) : '';
  623. $sql .= $authorid ? ' AND '.DB::field('authorid', $authorid) : '';
  624. $sql .= $invisible !== null ? ' AND '.DB::field('invisible', $invisible) : '';
  625. $sql .= $first !== null ? ' AND '.DB::field('first', $first) : '';
  626. $sql .= $fid ? ' AND '.DB::field('fid', $fid) : '';
  627. $sql .= $author ? ' AND '.DB::field('author', $author) : '';
  628. $sql .= $starttime ? ' AND '.DB::field('dateline', $starttime, '>=') : '';
  629. $sql .= $endtime ? ' AND '.DB::field('dateline', $endtime, '<') : '';
  630. $sql .= $useip ? ' AND '.DB::field('useip', $useip, 'like') : '';
  631. if(trim($keywords)) {
  632. $sqlkeywords = $or = '';
  633. foreach(explode(',', str_replace(' ', '', $keywords)) as $keyword) {
  634. $keyword = addslashes($keyword);
  635. $sqlkeywords .= " $or message LIKE '%$keyword%'";
  636. $or = 'OR';
  637. }
  638. $sql .= " AND ($sqlkeywords)";
  639. }
  640. if($sql) {
  641. return DB::fetch_all('SELECT * FROM %t WHERE 1 %i ORDER BY dateline DESC %i', array(self::get_tablename($tableid), $sql, DB::limit($start, $limit)));
  642. } else {
  643. return array();
  644. }
  645. }
  646. public function count_prune_by_search($tableid, $isgroup = null, $keywords = null, $message_length = null, $fid = null, $authorid = null, $starttime = null, $endtime = null, $useip = null) {
  647. $sql = '';
  648. $sql .= $fid ? ' AND p.'.DB::field('fid', $fid) : '';
  649. $sql .= $isgroup ? ' AND t.'.DB::field('isgroup', $isgroup) : '';
  650. $sql .= $authorid !== null ? ' AND p.'.DB::field('authorid', $authorid) : '';
  651. $sql .= $starttime ? ' AND p.'.DB::field('dateline', $starttime, '>=') : '';
  652. $sql .= $endtime ? ' AND p.'.DB::field('dateline', $endtime, '<') : '';
  653. $sql .= $useip ? ' AND p.'.DB::field('useip', $useip, 'like') : '';
  654. $sql .= $message_length !== null ? ' AND LENGTH(p.message) < '.intval($message_length) : '';
  655. if(trim($keywords)) {
  656. $sqlkeywords = '';
  657. $or = '';
  658. $keywords = explode(',', str_replace(' ', '', $keywords));
  659. for($i = 0; $i < count($keywords); $i++) {
  660. if(preg_match("/\{(\d+)\}/", $keywords[$i])) {
  661. $keywords[$i] = preg_replace("/\\\{(\d+)\\\}/", ".{0,\\1}", preg_quote($keywords[$i], '/'));
  662. $sqlkeywords .= " $or p.subject REGEXP '".$keywords[$i]."' OR p.message REGEXP '".$keywords[$i]."'";
  663. } else {
  664. $keywords[$i] = addslashes($keywords[$i]);
  665. $sqlkeywords .= " $or p.subject LIKE '%".$keywords[$i]."%' OR p.message LIKE '%".$keywords[$i]."%'";
  666. }
  667. $or = 'OR';
  668. }
  669. $sql .= " AND ($sqlkeywords)";
  670. }
  671. if($sql) {
  672. if($isgroup) {
  673. return DB::result_first('SELECT COUNT(*)
  674. FROM %t p LEFT JOIN %t t USING(tid)
  675. WHERE 1 %i', array(self::get_tablename($tableid), 'forum_thread', $sql));
  676. } else {
  677. return DB::result_first('SELECT COUNT(*)
  678. FROM %t p
  679. WHERE 1 %i', array(self::get_tablename($tableid), $sql));
  680. }
  681. } else {
  682. return 0;
  683. }
  684. }
  685. public function fetch_all_new_post_by_pid($pid, $start = 0, $limit = 0, $tableid = 0, $glue = '>', $sort = 'ASC') {
  686. return $limit ? DB::fetch_all('SELECT * FROM '.DB::table($this->get_tablename($tableid)).
  687. ' WHERE '.DB::field('pid', $pid, $glue).
  688. ' ORDER BY '.DB::order('pid', $sort).
  689. DB::limit($start, $limit), $this->_pk) : array();
  690. }
  691. public function fetch_all_prune_by_search($tableid, $isgroup = null, $keywords = null, $message_length = null, $fid = null, $authorid = null, $starttime = null, $endtime = null, $useip = null, $outmsg = true, $start = null, $limit = null) {
  692. $sql = '';
  693. $sql .= $fid ? ' AND p.'.DB::field('fid', $fid) : '';
  694. $sql .= $isgroup ? ' AND t.'.DB::field('isgroup', $isgroup) : '';
  695. $sql .= $authorid !== null ? ' AND p.'.DB::field('authorid', $authorid) : '';
  696. $sql .= $starttime ? ' AND p.'.DB::field('dateline', $starttime, '>=') : '';
  697. $sql .= $endtime ? ' AND p.'.DB::field('dateline', $endtime, '<') : '';
  698. $sql .= $useip ? ' AND p.'.DB::field('useip', $useip, 'like') : '';
  699. $sql .= $message_length !== null ? ' AND LENGTH(p.message) < '.intval($message_length) : '';
  700. $postlist = array();
  701. if(trim($keywords)) {
  702. $sqlkeywords = '';
  703. $or = '';
  704. $keywords = explode(',', str_replace(' ', '', $keywords));
  705. for($i = 0; $i < count($keywords); $i++) {
  706. if(preg_match("/\{(\d+)\}/", $keywords[$i])) {
  707. $keywords[$i] = preg_replace("/\\\{(\d+)\\\}/", ".{0,\\1}", preg_quote($keywords[$i], '/'));
  708. $sqlkeywords .= " $or p.subject REGEXP '".$keywords[$i]."' OR p.message REGEXP '".$keywords[$i]."'";
  709. } else {
  710. $keywords[$i] = addslashes($keywords[$i]);
  711. $sqlkeywords .= " $or p.subject LIKE '%".$keywords[$i]."%' OR p.message LIKE '%".$keywords[$i]."%'";
  712. }
  713. $or = 'OR';
  714. }
  715. $sql .= " AND ($sqlkeywords)";
  716. }
  717. if($sql) {
  718. if($isgroup) {
  719. $query = DB::query('SELECT p.*, t.*
  720. FROM %t p LEFT JOIN %t t USING(tid)
  721. WHERE 1 %i %i', array(self::get_tablename($tableid), 'forum_thread', $sql, DB::limit($start, $limit)));
  722. } else {
  723. $query = DB::query('SELECT *
  724. FROM %t p
  725. WHERE 1 %i %i', array(self::get_tablename($tableid), $sql, DB::limit($start, $limit)));
  726. }
  727. while($post = DB::fetch($query)) {
  728. if(!$outmsg) {
  729. unset($post['message']);
  730. }
  731. $postlist[$post[$this->_pk]] = $post;
  732. }
  733. }
  734. return $postlist;
  735. }
  736. public static function getposttablebytid($tids, $primary = 0) {
  737. $isstring = false;
  738. if(!is_array($tids)) {
  739. $thread = getglobal('thread');
  740. if(!empty($thread) && isset($thread['posttableid']) && $tids == $thread['tid']) {
  741. return 'forum_post'.(empty($thread['posttableid']) ? '' : '_'.$thread['posttableid']);
  742. }
  743. $tids = array(intval($tids));
  744. $isstring = true;
  745. }
  746. $tids = array_unique($tids);
  747. $tids = array_flip($tids);
  748. if(!$primary) {
  749. loadcache('threadtableids');
  750. $threadtableids = getglobal('threadtableids', 'cache');
  751. empty($threadtableids) && $threadtableids = array();
  752. if(!in_array(0, $threadtableids)) {
  753. $threadtableids = array_merge(array(0), $threadtableids);
  754. }
  755. } else {
  756. $threadtableids = array(0);
  757. }
  758. $tables = array();
  759. $posttable = '';
  760. foreach($threadtableids as $tableid) {
  761. $threadtable = $tableid ? "forum_thread_$tableid" : 'forum_thread';
  762. $query = DB::query("SELECT tid, posttableid FROM ".DB::table($threadtable)." WHERE tid IN(".dimplode(array_keys($tids)).")");
  763. while ($value = DB::fetch($query)) {
  764. $posttable = 'forum_post'.($value['posttableid'] ? "_$value[posttableid]" : '');
  765. $tables[$posttable][$value['tid']] = $value['tid'];
  766. unset($tids[$value['tid']]);
  767. }
  768. if(!count($tids)) {
  769. break;
  770. }
  771. }
  772. if(empty($posttable)) {
  773. $posttable = 'forum_post';
  774. $tables[$posttable] = array_flip($tids);
  775. }
  776. return $isstring ? $posttable : $tables;
  777. }
  778. public function show_table_columns($table) {
  779. $data = array();
  780. $db = &DB::object();
  781. if($db->version() > '4.1') {
  782. $query = $db->query("SHOW FULL COLUMNS FROM ".DB::table($table), 'SILENT');
  783. } else {
  784. $query = $db->query("SHOW COLUMNS FROM ".DB::table($table), 'SILENT');
  785. }
  786. while($field = @DB::fetch($query)) {
  787. $data[$field['Field']] = $field;
  788. }
  789. return $data;
  790. }
  791. public static function getposttable($tableid = 0, $prefix = false) {
  792. global $_G;
  793. $tableid = intval($tableid);
  794. if($tableid) {
  795. loadcache('posttableids');
  796. $tableid = $_G['cache']['posttableids'] && in_array($tableid, $_G['cache']['posttableids']) ? $tableid : 0;
  797. $tablename = 'forum_post'.($tableid ? "_$tableid" : '');
  798. } else {
  799. $tablename = 'forum_post';
  800. }
  801. if($prefix) {
  802. $tablename = DB::table($tablename);
  803. }
  804. return $tablename;
  805. }
  806. }
  807. ?>