PageRenderTime 72ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 1ms

/root/includes/functions_post_oo.php

https://github.com/phpbb-de/phpbb3-mod-hookup
PHP | 1957 lines | 1433 code | 267 blank | 257 comment | 198 complexity | 54221ee3c058cc68b7de39362f5c852a MD5 | raw file
Possible License(s): GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. *
  4. * @package functions_post_oo (object-oriented posting api)
  5. * @copyright (c) 2006-2007 Pyramide (Frank Dreyer)
  6. * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  7. *
  8. */
  9. if (!defined('IN_PHPBB'))
  10. {
  11. exit;
  12. }
  13. if (!function_exists('generate_smilies'))
  14. {
  15. include($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
  16. }
  17. if (!function_exists('display_forums'))
  18. {
  19. include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
  20. }
  21. if (!function_exists('make_forum_select'))
  22. {
  23. include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
  24. }
  25. if (!function_exists('get_folder'))
  26. {
  27. include($phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx);
  28. }
  29. //This file might be included inside a function where $user is not set locally:
  30. global $user;
  31. if (isset($user))
  32. {
  33. $user->add_lang('posting');
  34. }
  35. class topic
  36. {
  37. var $topic_id;
  38. var $forum_id;
  39. var $posts = array();
  40. var $icon_id = 0;
  41. var $topic_attachment = 0;
  42. var $topic_approved = 1;
  43. var $topic_reported = 0;
  44. var $topic_views = 0;
  45. var $topic_replies = 0;
  46. var $topic_replies_real = 0;
  47. var $topic_status = ITEM_UNLOCKED;
  48. var $topic_moved_id = 0;
  49. var $topic_type = POST_NORMAL;
  50. var $topic_time_limit = 0;
  51. var $topic_title = '';
  52. var $topic_time;
  53. var $topic_poster;
  54. var $topic_first_post_id;
  55. var $topic_first_poster_name;
  56. var $topic_first_poster_colour;
  57. var $topic_last_post_id;
  58. var $topic_last_poster_name;
  59. var $topic_last_poster_colour;
  60. var $topic_last_post_subject;
  61. var $topic_last_post_time;
  62. var $topic_last_view_time;
  63. var $topic_bumped = 0;
  64. var $topic_bumper = 0;
  65. var $poll_title = '';
  66. var $poll_start = 0;
  67. var $poll_length = 0;
  68. var $poll_max_options = 1;
  69. var $poll_last_vote = 0;
  70. var $poll_vote_change = 0;
  71. var $poll_options = array();
  72. function topic($forum_id = 0)
  73. {
  74. $this->forum_id = $forum_id;
  75. }
  76. function get($topic_id, $load_posts = false)
  77. {
  78. global $db;
  79. $sql = 'SELECT *
  80. FROM ' . TOPICS_TABLE . '
  81. WHERE topic_id = ' . intval($topic_id);
  82. $result = $db->sql_query($sql);
  83. $topic_data = $db->sql_fetchrow($result);
  84. $db->sql_freeresult($result);
  85. if (!$topic_data)
  86. {
  87. //topic does not exist, return false
  88. return false;
  89. }
  90. //create object and fill in data
  91. $topic = new topic();
  92. $topic->topic_id = $topic_data['topic_id'];
  93. $topic->forum_id = $topic_data['forum_id'];
  94. $topic->icon_id = $topic_data['icon_id'];
  95. $topic->topic_attachment = $topic_data['topic_attachment'];
  96. $topic->topic_approved = $topic_data['topic_approved'];
  97. $topic->topic_reported = $topic_data['topic_reported'];
  98. $topic->topic_views = $topic_data['topic_views'];
  99. $topic->topic_replies = $topic_data['topic_replies'];
  100. $topic->topic_replies_real = $topic_data['topic_replies_real'];
  101. $topic->topic_status = $topic_data['topic_status'];
  102. $topic->topic_moved_id = $topic_data['topic_moved_id'];
  103. $topic->topic_type = $topic_data['topic_type'];
  104. $topic->topic_time_limit = $topic_data['topic_time_limit'];
  105. $topic->topic_title = $topic_data['topic_title'];
  106. $topic->topic_time = $topic_data['topic_time'];
  107. $topic->topic_poster = $topic_data['topic_poster'];
  108. $topic->topic_first_post_id = $topic_data['topic_first_post_id'];
  109. $topic->topic_first_poster_name = $topic_data['topic_first_poster_name'];
  110. $topic->topic_first_poster_colour = $topic_data['topic_first_poster_colour'];
  111. $topic->topic_last_post_id = $topic_data['topic_last_post_id'];
  112. $topic->topic_last_poster_name = $topic_data['topic_last_poster_name'];
  113. $topic->topic_last_poster_colour = $topic_data['topic_last_poster_colour'];
  114. $topic->topic_last_post_subject = $topic_data['topic_last_post_subject'];
  115. $topic->topic_last_post_time = $topic_data['topic_last_post_time'];
  116. $topic->topic_last_view_time = $topic_data['topic_last_view_time'];
  117. $topic->topic_bumped = $topic_data['topic_bumped'];
  118. $topic->topic_bumper = $topic_data['topic_bumper'];
  119. $topic->poll_title = $topic_data['poll_title'];
  120. $topic->poll_start = $topic_data['poll_start'];
  121. $topic->poll_length = $topic_data['poll_length'];
  122. $topic->poll_max_options = $topic_data['poll_max_options'];
  123. $topic->poll_last_vote = $topic_data['poll_last_vote'];
  124. $topic->poll_vote_change = $topic_data['poll_vote_change'];
  125. if ($load_posts)
  126. {
  127. $sql = 'SELECT *
  128. FROM ' . POSTS_TABLE . '
  129. WHERE topic_id = ' . intval($topic_id) . '
  130. ORDER BY post_time ASC';
  131. $result = $db->sql_query($sql);
  132. while ($post_data = $db->sql_fetchrow($result))
  133. {
  134. $topic->posts[] = post::from_array($post_data);
  135. }
  136. $db->sql_freeresult($result);
  137. }
  138. return $topic;
  139. }
  140. function from_post($post)
  141. {
  142. $topic = new topic();
  143. $topic->topic_id = $post->topic_id;
  144. $topic->forum_id = $post->forum_id;
  145. $topic->topic_title = $post->post_subject;
  146. $topic->topic_poster = $post->poster_id;
  147. $topic->topic_time = $post->post_time;
  148. $topic->icon_id = $post->icon_id;
  149. $topic->topic_attachment = $post->post_attachment;
  150. $topic->topic_approved = $post->post_approved;
  151. $topic->topic_reported = $post->post_reported;
  152. $topic->posts[] = &$post;
  153. return $topic;
  154. }
  155. function submit($submit_posts = true)
  156. {
  157. global $config, $db, $auth, $user;
  158. if (!$this->topic_id && count($this->posts) == 0)
  159. {
  160. trigger_error('cannot create a topic without posts', E_USER_ERROR);
  161. }
  162. if (!$this->topic_id)
  163. {
  164. //new post, set some default values if not set yet
  165. if(!$this->topic_poster) $this->topic_poster = $user->data['user_id'];
  166. if(!$this->topic_time) $this->topic_time = time();
  167. $this->posts[0]->post_subject = $this->topic_title;
  168. }
  169. if ($this->forum_id == 0)
  170. {
  171. //no forum id known, can only insert as global announcement
  172. $this->topic_type = POST_GLOBAL;
  173. }
  174. $this->topic_title = truncate_string($this->topic_title);
  175. $sql_data = array(
  176. 'icon_id' => $this->icon_id,
  177. 'topic_attachment' => $this->topic_attachment ? 1 : 0,
  178. 'topic_approved' => $this->topic_approved ? 1 : 0,
  179. 'topic_reported' => $this->topic_reported ? 1 : 0,
  180. //'topic_views' => $this->topic_views,
  181. 'topic_replies' => $this->topic_replies,
  182. 'topic_replies_real'=> $this->topic_replies_real,
  183. 'topic_status' => $this->topic_status,
  184. 'topic_moved_id' => $this->topic_moved_id,
  185. 'topic_type' => $this->topic_type,
  186. 'topic_time_limit' => $this->topic_time_limit,
  187. 'topic_title' => $this->topic_title,
  188. 'topic_time' => $this->topic_time,
  189. 'topic_poster' => $this->topic_poster,
  190. 'topic_bumped' => $this->topic_bumped ? 1 : 0,
  191. 'topic_bumper' => $this->topic_bumper,
  192. 'poll_title' => $this->poll_title,
  193. 'poll_start' => $this->poll_start,
  194. 'poll_length' => $this->poll_length,
  195. 'poll_max_options' => $this->poll_max_options,
  196. //'poll_last_vote' => $this->poll_last_vote,
  197. 'poll_vote_change' => $this->poll_vote_change ? 1 : 0
  198. );
  199. $sync = new syncer();
  200. if ($this->topic_id)
  201. {
  202. //edit
  203. $sql = 'SELECT *
  204. FROM ' . TOPICS_TABLE . '
  205. WHERE topic_id = ' . intval($this->topic_id);
  206. $result = $db->sql_query($sql);
  207. $topic_data = $db->sql_fetchrow($result);
  208. $db->sql_freeresult($result);
  209. if (!$topic_data)
  210. {
  211. trigger_error("topic_id={$this->topic_id}, but that topic does not exist", E_USER_ERROR);
  212. }
  213. $db->sql_transaction('begin');
  214. $sql = 'UPDATE ' . TOPICS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_data) . ' WHERE topic_id = ' . $this->topic_id;
  215. $db->sql_query($sql);
  216. //move to another forum -> also move posts and update statistics
  217. if ($this->forum_id != $topic_data['forum_id'])
  218. {
  219. $sql = 'UPDATE ' . POSTS_TABLE . '
  220. SET forum_id = ' . $this->forum_id . '
  221. WHERE topic_id = ' . $this->topic_id;
  222. $db->sql_query($sql);
  223. //old forum
  224. if ($topic_data['forum_id'] != 0)
  225. {
  226. $sync->add('forum', $topic_data['forum_id'], 'forum_topics', $topic_data['topic_approved'] ? -1 : 0);
  227. $sync->add('forum', $topic_data['forum_id'], 'forum_topics_real', -1);
  228. $sync->add('forum', $topic_data['forum_id'], 'forum_posts', -($topic_data['topic_replies'] + 1));
  229. $sync->forum_last_post($topic_data['forum_id']);
  230. }
  231. //new forum
  232. if ($this->forum_id != 0)
  233. {
  234. $sync->add('forum', $this->forum_id, 'forum_topics', $this->topic_approved ? 1 : 0);
  235. $sync->add('forum', $this->forum_id, 'forum_topics_real', 1);
  236. $sync->add('forum', $this->forum_id, 'forum_posts', ($this->topic_replies + 1));
  237. }
  238. }
  239. if ($this->topic_approved != $topic_data['topic_approved'])
  240. {
  241. //if forum_id was changed, we've already updated forum_topics above
  242. if (($this->forum_id == $topic_data['forum_id']) && ($this->forum_id != 0))
  243. {
  244. $sync->add('forum', $this->forum_id, 'forum_topics', $this->topic_approved ? 1 : -1);
  245. $sync->add('forum', $this->forum_id, 'forum_posts', $this->topic_approved ? (1 + $this->topic_replies) : -(1 + $this->topic_replies));
  246. $sync->forum_last_post($this->forum_id);
  247. }
  248. //same with total topics+posts
  249. set_config('num_topics', $this->topic_approved ? $config['num_topics'] + 1 : $config['num_topics'] - 1, true);
  250. set_config('num_posts', $this->topic_approved ? $config['num_posts'] + (1 + $this->topic_replies) : $config['num_posts'] - (1 + $this->topic_replies), true);
  251. }
  252. $db->sql_transaction('commit');
  253. }
  254. else
  255. {
  256. //new topic
  257. $sql_data['forum_id'] = $this->forum_id;
  258. $sql = 'INSERT INTO ' . TOPICS_TABLE . ' ' .
  259. $db->sql_build_array('INSERT', $sql_data);
  260. $db->sql_query($sql);
  261. $this->topic_id = $db->sql_nextid();
  262. if ($this->forum_id != 0)
  263. {
  264. $sync->add('forum', $this->forum_id, 'forum_topics', $this->topic_approved ? 1 : 0);
  265. $sync->add('forum', $this->forum_id, 'forum_topics_real', 1);
  266. }
  267. //total topics
  268. if ($this->topic_approved)
  269. {
  270. set_config('num_topics', $config['num_topics'] + 1, true);
  271. }
  272. $sync->new_topic_flag = true;
  273. }
  274. // insert or update poll
  275. if (isset($this->poll_options) && !empty($this->poll_options))
  276. {
  277. $cur_poll_options = array();
  278. if ($this->poll_start && isset($topic_data))
  279. {
  280. $sql = 'SELECT * FROM ' . POLL_OPTIONS_TABLE . '
  281. WHERE topic_id = ' . $this->topic_id . '
  282. ORDER BY poll_option_id';
  283. $result = $db->sql_query($sql);
  284. $cur_poll_options = array();
  285. while ($row = $db->sql_fetchrow($result))
  286. {
  287. $cur_poll_options[] = $row;
  288. }
  289. $db->sql_freeresult($result);
  290. }
  291. $sql_insert_ary = array();
  292. for ($i = 0, $size = sizeof($this->poll_options); $i < $size; $i++)
  293. {
  294. if (trim($this->poll_options[$i]))
  295. {
  296. if (empty($cur_poll_options[$i]))
  297. {
  298. $sql_insert_ary[] = array(
  299. 'poll_option_id' => (int) $i,
  300. 'topic_id' => (int) $this->topic_id,
  301. 'poll_option_text' => (string) $this->poll_options[$i]
  302. );
  303. }
  304. else if ($this->poll_options[$i] != $cur_poll_options[$i])
  305. {
  306. $sql = 'UPDATE ' . POLL_OPTIONS_TABLE . "
  307. SET poll_option_text = '" . $db->sql_escape($this->poll_options[$i]) . "'
  308. WHERE poll_option_id = " . $cur_poll_options[$i]['poll_option_id'] . '
  309. AND topic_id = ' . $this->topic_id;
  310. $db->sql_query($sql);
  311. }
  312. }
  313. }
  314. $db->sql_multi_insert(POLL_OPTIONS_TABLE, $sql_insert_ary);
  315. if (sizeof($this->poll_options) < sizeof($cur_poll_options))
  316. {
  317. $sql = 'DELETE FROM ' . POLL_OPTIONS_TABLE . '
  318. WHERE poll_option_id >= ' . sizeof($this->poll_options) . '
  319. AND topic_id = ' . $this->topic_id;
  320. $db->sql_query($sql);
  321. }
  322. }
  323. //delete poll if we had one and poll_start is 0 now
  324. if (isset($topic_data) && $topic_data['poll_start'] && $this->poll_start == 0)
  325. {
  326. $sql = 'DELETE FROM ' . POLL_OPTIONS_TABLE . '
  327. WHERE topic_id = ' . $this->topic_id;
  328. $db->sql_query($sql);
  329. $sql = 'DELETE FROM ' . POLL_VOTES_TABLE . '
  330. WHERE topic_id = ' . $this->topic_id;
  331. $db->sql_query($sql);
  332. }
  333. //End poll
  334. if ($submit_posts && count($this->posts))
  335. {
  336. //find and sync first post
  337. if ($sync->new_topic_flag)
  338. {
  339. //test if var was not set in post
  340. $first_post = $this->posts[0];
  341. if ($first_post->post_subject == '')
  342. {
  343. $first_post->post_subject = $this->topic_title;
  344. }
  345. if (!$first_post->poster_id)
  346. {
  347. $first_post->poster_id = $this->topic_poster;
  348. }
  349. if (!$this->topic_approved)
  350. {
  351. $first_post->post_approved = 0;
  352. }
  353. }
  354. elseif ($topic_data && $this->topic_first_post_id != 0)
  355. {
  356. foreach ($this->posts as $post)
  357. {
  358. if ($post->post_id == $this->topic_first_post_id)
  359. {
  360. //test if var has been changed in topic. this is like the
  361. //else($submit_posts) below, but the user might have changed the
  362. //post object but not the topic, so we can't just overwrite them
  363. $first_post = $post;
  364. if ($this->topic_title != $topic_data['topic_title'])
  365. {
  366. $first_post->post_subject = $this->topic_title;
  367. }
  368. if ($this->topic_time != $topic_data['topic_time'])
  369. {
  370. $first_post->post_time = $this->topic_time;
  371. }
  372. if ($this->topic_poster != $topic_data['topic_poster'])
  373. {
  374. $first_post->poster_id = $this->topic_poster;
  375. $first_post->post_username = ($this->topic_poster == ANONYMOUS) ? $this->topic_first_poster_name : '';
  376. }
  377. if ($this->topic_approved != $topic_data['topic_approved'])
  378. {
  379. $first_post->post_approved = $this->topic_approved;
  380. }
  381. break;
  382. }
  383. }
  384. }
  385. //TODO sort by post_time in case user messed with it
  386. foreach ($this->posts as $post)
  387. {
  388. $post->_topic = $this;
  389. $post->topic_id = $this->topic_id;
  390. $post->forum_id = $this->forum_id;
  391. //if(!$post->poster_id) $post->poster_id = $this->topic_poster;
  392. $post->_submit($sync);
  393. }
  394. }
  395. else
  396. {
  397. //sync first post if user edited topic only
  398. $sync->set('post', $this->topic_first_post_id, array(
  399. 'post_subject' => $this->topic_title,
  400. 'post_time' => $this->topic_time,
  401. 'poster_id' => $this->topic_poster,
  402. 'post_username' => ($this->topic_poster == ANONYMOUS) ? $this->topic_first_poster_name : '',
  403. 'post_approved' => $this->topic_approved,
  404. 'post_reported' => $this->topic_reported
  405. ));
  406. }
  407. $sync->execute();
  408. //refresh $this->topic_foo variables...
  409. $this->refresh_statvars();
  410. }
  411. /**
  412. * synchronizes topic and forum via sync() and updates member variables
  413. * ($this->topic_last_post_id etc.)
  414. */
  415. function sync()
  416. {
  417. global $db;
  418. if (!$this->topic_id)
  419. {
  420. //topic does not exist yet
  421. return;
  422. }
  423. sync('topic', 'topic_id', $this->topic_id, false, true);
  424. if ($this->forum_id > 0)
  425. {
  426. sync('forum', 'forum_id', $this->forum_id);
  427. }
  428. $this->refresh_statvars();
  429. }
  430. function refresh_statvars()
  431. {
  432. global $db;
  433. $sql = 'SELECT *
  434. FROM ' . TOPICS_TABLE . '
  435. WHERE topic_id = ' . $this->topic_id;
  436. $result = $db->sql_query($sql);
  437. $topic_data = $db->sql_fetchrow($result);
  438. $db->sql_freeresult($result);
  439. if (!$topic_data)
  440. {
  441. //topic does not exist although we have a topic_id?
  442. trigger_error("topic id set ({$this->topic_id}) but topic does not exist?", E_USER_ERROR);
  443. }
  444. $this->topic_attachment = $topic_data['topic_attachment'];
  445. $this->topic_approved = $topic_data['topic_approved'];
  446. $this->topic_reported = $topic_data['topic_reported'];
  447. $this->topic_views = $topic_data['topic_views'];
  448. $this->topic_replies = $topic_data['topic_replies'];
  449. $this->topic_replies_real = $topic_data['topic_replies_real'];
  450. $this->topic_first_post_id = $topic_data['topic_first_post_id'];
  451. $this->topic_first_poster_name = $topic_data['topic_first_poster_name'];
  452. $this->topic_first_poster_colour = $topic_data['topic_first_poster_colour'];
  453. $this->topic_last_post_id = $topic_data['topic_last_post_id'];
  454. $this->topic_last_poster_name = $topic_data['topic_last_poster_name'];
  455. $this->topic_last_poster_colour = $topic_data['topic_last_poster_colour'];
  456. $this->topic_last_post_subject = $topic_data['topic_last_post_subject'];
  457. $this->topic_last_post_time = $topic_data['topic_last_post_time'];
  458. $this->topic_last_view_time = $topic_data['topic_last_view_time'];
  459. }
  460. /***/
  461. function add_poll($title, $poll_options, $max_options = 1)
  462. {
  463. $this->poll_start = time();
  464. $this->poll_title = $title;
  465. $this->poll_options = $poll_options;
  466. $this->poll_max_options = $max_options;
  467. }
  468. /***/
  469. function delete_poll()
  470. {
  471. $this->poll_title = '';
  472. $this->poll_start = 0;
  473. $this->poll_length = 0;
  474. $this->poll_last_vote = 0;
  475. $this->poll_max_options = 0;
  476. $this->poll_vote_change = 0;
  477. //POLL_OPTIONS_TABLE and POLL_VOTES_TABLE will be cleared in submit()
  478. }
  479. /**
  480. * clears all votes (restarts poll)
  481. */
  482. function reset_poll()
  483. {
  484. global $db;
  485. $db->sql_transaction('begin');
  486. $sql = 'UPDATE ' . POLL_OPTIONS_TABLE . '
  487. SET poll_option_total = 0
  488. WHERE topic_id = ' . $this->topic_id;
  489. $db->sql_query($sql);
  490. $sql = 'DELETE FROM ' . POLL_VOTES_TABLE . '
  491. WHERE topic_id = ' . $this->topic_id;
  492. $db->sql_query($sql);
  493. $this->poll_start = time();
  494. $this->poll_last_vote = 0;
  495. $sql = 'UPDATE ' . TOPICS_TABLE . '
  496. SET poll_start = ' . $this->poll_start . ',
  497. poll_last_vote = 0
  498. WHERE topic_id = ' . $this->topic_id;
  499. $db->sql_query($sql);
  500. $db->sql_transaction('commit');
  501. }
  502. /**
  503. * bumps the topic
  504. * @param
  505. */
  506. function bump($user_id = 0)
  507. {
  508. global $db, $user;
  509. $current_time = time();
  510. if($user_id == 0) $user_id = $user->data['user_id'];
  511. $db->sql_transaction('begin');
  512. $sql = 'UPDATE ' . POSTS_TABLE . "
  513. SET post_time = $current_time
  514. WHERE post_id = {$this->topic_last_post_id}
  515. AND topic_id = {$this->topic_id}";
  516. $db->sql_query($sql);
  517. $this->topic_bumped = 1;
  518. $this->topic_bumper = $user_id;
  519. $this->topic_last_post_time = $current_time;
  520. $sql = 'UPDATE ' . TOPICS_TABLE . "
  521. SET topic_last_post_time = $current_time,
  522. topic_bumped = 1,
  523. topic_bumper = $user_id
  524. WHERE topic_id = $topic_id";
  525. $db->sql_query($sql);
  526. update_post_information('forum', $this->forum_id);
  527. $sql = 'UPDATE ' . USERS_TABLE . "
  528. SET user_lastpost_time = $current_time
  529. WHERE user_id = $user_id";
  530. $db->sql_query($sql);
  531. $db->sql_transaction('commit');
  532. markread('post', $this->forum_id, $this->topic_id, $current_time, $user_id);
  533. add_log('mod', $this->forum_id, $this->topic_id, 'LOG_BUMP_TOPIC', $this->topic_title);
  534. }
  535. function move($forum_id)
  536. {
  537. move_topics($this->topic_id, $forum_id);
  538. $this->forum_id = $forum_id;
  539. foreach ($this->posts as $post)
  540. {
  541. $post->forum_id = $forum_id;
  542. }
  543. }
  544. function delete()
  545. {
  546. if (!$this->topic_id)
  547. {
  548. trigger_error('NO_TOPIC', E_USER_ERROR);
  549. }
  550. $ret = delete_topics('topic_id', $this->topic_id);
  551. //remove references to the deleted topic so calls to submit() will create a
  552. //new topic instead of trying to update the topich which does not exist anymore
  553. $this->topic_id = NULL;
  554. foreach ($this->posts as $post)
  555. {
  556. $post->topic_id = NULL;
  557. $post->post_id = NULL;
  558. }
  559. return $ret;
  560. }
  561. }
  562. class post
  563. {
  564. var $post_id;
  565. var $topic_id;
  566. var $forum_id;
  567. var $poster_id;
  568. var $post_username = '';
  569. var $poster_ip;
  570. var $icon_id = 0;
  571. var $post_time;
  572. var $post_postcount = 1;
  573. var $post_approved = 1;
  574. var $post_reported = 0;
  575. var $enable_bbcode = 1;
  576. var $enable_smilies = 1;
  577. var $enable_magic_url = 1;
  578. var $enable_sig = 1;
  579. var $post_subject = '';
  580. var $post_text = '';
  581. var $post_edit_time = 0;
  582. var $post_edit_reason = '';
  583. var $post_edit_user = 0;
  584. var $post_edit_count = 0;
  585. var $post_edit_locked = 0;
  586. var $_topic;
  587. var $post_attachment = 0;
  588. var $attachments = array();
  589. function post($topic_id = NULL, $post_text = '')
  590. {
  591. $this->topic_id = $topic_id;
  592. $this->post_text = $post_text;
  593. }
  594. /**
  595. * static method, loads the post with a given post_id from database.
  596. * returns false if the post does not exist
  597. */
  598. function get($post_id)
  599. {
  600. global $db;
  601. //$sql = "SELECT p.*, t.topic_first_post_id, t.topic_last_post_id
  602. // FROM " . POSTS_TABLE . " p, " . TOPICS_TABLE . " t
  603. // WHERE p.post_id=" . intval($this->post_id) . " AND t.topic_id = p.topic_id";
  604. $sql = 'SELECT *
  605. FROM ' . POSTS_TABLE . '
  606. WHERE post_id = ' . intval($post_id);
  607. $result = $db->sql_query($sql);
  608. $post_data = $db->sql_fetchrow($result);
  609. $db->sql_freeresult($result);
  610. if (!$post_data)
  611. {
  612. //post does not exist, return false
  613. return false;
  614. }
  615. return post::from_array($post_data);
  616. }
  617. function from_array($post_data)
  618. {
  619. global $db;
  620. if (!is_array($post_data))
  621. {
  622. trigger_error('post::from_array - $post_data not an array');
  623. }
  624. //create object and fill in data
  625. $post = new post();
  626. $post->post_id = $post_data['post_id'];
  627. $post->topic_id = $post_data['topic_id'];
  628. $post->forum_id = $post_data['forum_id'];
  629. $post->poster_id = $post_data['poster_id'];
  630. $post->post_username = $post_data['post_username'];
  631. $post->poster_ip = $post_data['poster_ip'];
  632. $post->icon_id = $post_data['icon_id'];
  633. $post->post_time = $post_data['post_time'];
  634. $post->post_postcount = $post_data['post_postcount'];
  635. $post->post_approved = $post_data['post_approved'];
  636. $post->post_reported = $post_data['post_reported'];
  637. $post->enable_bbcode = $post_data['enable_bbcode'];
  638. $post->enable_smilies = $post_data['enable_smilies'];
  639. $post->enable_magic_url = $post_data['enable_magic_url'];
  640. $post->enable_sig = $post_data['enable_sig'];
  641. $post->post_subject = $post_data['post_subject'];
  642. $post->post_attachment = $post_data['post_attachment'];
  643. $post->post_edit_time = $post_data['post_edit_time'];
  644. $post->post_edit_reason = $post_data['post_edit_reason'];
  645. $post->post_edit_user = $post_data['post_edit_user'];
  646. $post->post_edit_count = $post_data['post_edit_count'];
  647. //check first/last post
  648. //$this->_is_first_post = ($post_data['post_id'] == $post_data['topic_first_post_id']);
  649. //$this->_is_last_post = ($post_data['post_id'] == $post_data['topic_last_post_id']);
  650. //parse message
  651. decode_message($post_data['post_text'], $post_data['bbcode_uid']);
  652. $post_data['post_text'] = str_replace(array('&#58;', '&#46;'), array(':', '.'), $post_data['post_text']);
  653. $post->post_text = $post_data['post_text'];
  654. //attachments
  655. if ($post->post_attachment)
  656. {
  657. $sql = 'SELECT *
  658. FROM ' . ATTACHMENTS_TABLE . '
  659. WHERE post_msg_id = ' . $post->post_id;
  660. $result = $db->sql_query($sql);
  661. while ($attach_row = $db->sql_fetchrow($result))
  662. {
  663. $post->attachments[] = attachment::from_array($attach_row);
  664. }
  665. }
  666. return $post;
  667. }
  668. /**
  669. *loads and returns the topic for this post
  670. * @param all_posts whether to load all other posts of the topic into topic->posts
  671. */
  672. function get_topic($all_posts = false)
  673. {
  674. if (!$this->_topic)
  675. {
  676. if ($this->post_id)
  677. {
  678. //existing post, load existing topic
  679. $this->_topic = topic::get($this->topic_id, $all_posts);
  680. //insert $this into topic->posts array
  681. if ($all_posts)
  682. {
  683. //this post was also loaded from database, replace it with $this
  684. for ($i=0; $i<sizeof($this->_topic->posts); $i++)
  685. {
  686. if ($this->_topic->posts[$i]->post_id == $this->post_id)
  687. {
  688. //found it
  689. $this->_topic->posts[$i] = &$this;
  690. break;
  691. }
  692. }
  693. }
  694. else
  695. {
  696. //no posts were loaded in topic::get(), add our post to topic->posts
  697. $this->_topic->posts[] = &$this;
  698. }
  699. }
  700. else
  701. {
  702. //new post, generate topic
  703. $this->_topic = topic::from_post($this);
  704. }
  705. }
  706. return $this->_topic;
  707. }
  708. /**
  709. * sets the following variables based on the permissions of $this->poster_id:
  710. * post_postcount, post_approved
  711. * enable_bbcode, enable_smilies, enable_magic_url, enable_sig
  712. * img_status, flash_status, quote_status
  713. * by default (if you never call this function) all variables are set to 1 (allowed)
  714. * note that this does not check whether the user can post at all - use validate() for that.
  715. * @todo
  716. */
  717. function apply_permissions()
  718. {
  719. //TODO
  720. }
  721. /**
  722. * checks if $this->poster_id has the permissions required to submit this post.
  723. * note that calling this does not change the behaviour of submit()
  724. */
  725. function validate()
  726. {
  727. // ?? $this->apply_permissions();
  728. //TODO
  729. }
  730. /**
  731. * returns the html representation of this post
  732. */
  733. function display_format()
  734. {
  735. //TODO
  736. }
  737. /**
  738. * moves this post to a different topic. If you want to merge multiple post
  739. * into one topic, calling move_posts() directly is recommended.
  740. */
  741. function merge_into($topic_id)
  742. {
  743. move_posts($this->post_id, $topic_id);
  744. $this->topic_id = $topic_id;
  745. $this->_topic = null;
  746. }
  747. /**
  748. * Submit dummy function for PHP4 compatibility
  749. */
  750. function submit()
  751. {
  752. $dummy_var = false;
  753. $this->_submit($dummy_var);
  754. }
  755. /**
  756. * create/update this post in the database
  757. * @param $sync used internally by topic->submit()
  758. */
  759. function _submit(&$sync)
  760. {
  761. global $config, $db, $auth, $user;
  762. if ($sync === false)
  763. {
  764. //submit() was called directly so we need to sync after it
  765. $sync = new syncer();
  766. $exec_sync = true;
  767. }
  768. else
  769. {
  770. //submit() was called by topic->submit(), sync there when everything is done
  771. $exec_sync = false;
  772. }
  773. if (!$this->post_id)
  774. {
  775. //new post, set some default values if not set yet
  776. if(!$this->poster_id) $this->poster_id = $user->data['user_id'];
  777. if(!$this->poster_ip) $this->poster_ip = $user->ip;
  778. if(!$this->post_time) $this->post_time = time();
  779. }
  780. $this->post_subject = truncate_string($this->post_subject);
  781. $sql_data = array(
  782. 'poster_id' => $this->poster_id,
  783. 'poster_ip' => $this->poster_ip,
  784. 'post_username' => $this->post_username,
  785. 'icon_id' => $this->icon_id,
  786. 'post_time' => $this->post_time,
  787. 'post_postcount' => $this->post_postcount ? 1 : 0,
  788. 'post_approved' => $this->post_approved ? 1 : 0,
  789. 'post_reported' => $this->post_reported ? 1 : 0,
  790. 'enable_bbcode' => $this->enable_bbcode ? 1 : 0,
  791. 'enable_smilies' => $this->enable_smilies ? 1 : 0,
  792. 'enable_magic_url' => $this->enable_magic_url ? 1 : 0,
  793. 'enable_sig' => $this->enable_sig ? 1 : 0,
  794. 'post_subject' => $this->post_subject,
  795. 'bbcode_bitfield' => 0,
  796. 'bbcode_uid' => '',
  797. 'post_text' => $this->post_text,
  798. 'post_checksum' => md5($this->post_text),
  799. //'post_attachment' => $this->post_attachment ? 1 : 0,
  800. 'post_edit_time' => $this->post_edit_time,
  801. 'post_edit_reason' => $this->post_edit_reason,
  802. 'post_edit_user' => $this->post_edit_user,
  803. 'post_edit_count' => $this->post_edit_count,
  804. 'post_edit_locked' => $this->post_edit_locked
  805. );
  806. $flags = '';
  807. generate_text_for_storage($sql_data['post_text'], $sql_data['bbcode_uid'], $sql_data['bbcode_bitfield'], $flags, $this->enable_bbcode, $this->enable_magic_url, $this->enable_smilies);
  808. if ($this->post_id && $this->topic_id)
  809. {
  810. //edit
  811. $sql = 'SELECT p.*, t.topic_first_post_id, t.topic_last_post_id, t.topic_approved, t.topic_replies
  812. FROM ' . POSTS_TABLE . ' p
  813. LEFT JOIN ' . TOPICS_TABLE . ' t
  814. ON (t.topic_id = p.topic_id)
  815. WHERE p.post_id = ' . intval($this->post_id);
  816. //$sql = "SELECT * FROM " . POSTS_TABLE . " WHERE post_id=" . intval($this->post_id);
  817. $result = $db->sql_query($sql);
  818. $post_data = $db->sql_fetchrow($result);
  819. $db->sql_freeresult($result);
  820. if (!$post_data)
  821. {
  822. trigger_error("post_id={$this->post_id}, but that post does not exist", E_USER_ERROR);
  823. }
  824. //check first/last post
  825. $is_first_post = ($post_data['post_id'] == $post_data['topic_first_post_id']);
  826. $is_last_post = ($post_data['post_id'] == $post_data['topic_last_post_id']);
  827. $db->sql_transaction('begin');
  828. $sql = 'UPDATE ' . POSTS_TABLE . '
  829. SET ' . $db->sql_build_array('UPDATE', $sql_data) . '
  830. WHERE post_id=' . $this->post_id;
  831. $db->sql_query($sql);
  832. if ($this->topic_id != $post_data['topic_id'])
  833. {
  834. //merge into new topic
  835. //get new topic's forum id and first/last post time
  836. $sql = 'SELECT forum_id, topic_time, topic_last_post_time
  837. FROM ' . TOPICS_TABLE . "
  838. WHERE topic_id = {$this->topic_id}";
  839. $result = $db->sql_query($sql);
  840. $new_topic_data = $db->sql_fetchrow($result);
  841. if (!$new_topic_data)
  842. {
  843. trigger_error("attempted to merge post {$this->post_id} into topic {$this->topic_id}, but that topic does not exist", E_USER_ERROR);
  844. }
  845. //sync forum_posts
  846. if ($new_topic_data['forum_id'] != $post_data['forum_id'])
  847. {
  848. $sync->add('forum', $post_data['forum_id'], 'forum_posts', $this->post_approved ? -1 : 0);
  849. $sync->add('forum', $new_topic_data['forum_id'], 'forum_posts', $this->post_approved ? 1 : 0);
  850. if ($this->forum_id != $new_topic_data['forum_id'])
  851. {
  852. //user changed topic_id but not forum_id, so we saved the wrong one above. correct it via sync
  853. $this->forum_id = $new_topic_data['forum_id'];
  854. $sync->set('post', $this->post_id, 'forum_id', $this->forum_id);
  855. }
  856. }
  857. //sync old topic
  858. $sync->add('topic', $post_data['topic_id'], 'topic_replies', $this->post_approved ? -1 : 0);
  859. $sync->add('topic', $post_data['topic_id'], 'topic_replies_real', -1);
  860. //sync new topic
  861. $sync->add('topic', $this->topic_id, 'topic_replies', $this->post_approved ? 1 : 0);
  862. $sync->add('topic', $this->topic_id, 'topic_replies_real', 1);
  863. if ($is_first_post)
  864. {
  865. //this was the first post in the old topic, sync it
  866. $sync->topic_first_post($post_data['topic_id']);
  867. $is_first_post = false; //unset since we dont know status for new topic yet
  868. }
  869. if ($is_last_post)
  870. {
  871. //this was the last post in the old topic, sync it
  872. $sync->topic_last_post($post_data['topic_id']);
  873. $sync->forum_last_post($post_data['forum_id']);
  874. $is_last_post = false; //unset since we dont know status for new topic yet
  875. }
  876. if ($this->post_time <= $new_topic_data['topic_time'])
  877. {
  878. //this will be the first post in the new topic, sync it
  879. $sync->topic_first_post($this->topic_id);
  880. $is_first_post = true;
  881. }
  882. if ($this->post_time >= $new_topic_data['topic_last_post_time'])
  883. {
  884. //this will be the last post in the new topic, sync it
  885. $sync->topic_last_post($this->topic_id);
  886. $sync->forum_last_post($this->topic_id);
  887. $is_last_post = true;
  888. }
  889. }
  890. elseif ($is_first_post)
  891. {
  892. $sync->set('topic', $this->topic_id, array(
  893. 'icon_id' => $this->icon_id,
  894. 'topic_approved' => $this->post_approved,
  895. 'topic_title' => $this->post_subject,
  896. 'topic_poster' => $this->poster_id,
  897. 'topic_time' => $this->post_time
  898. ));
  899. }
  900. //check if some statistics relevant flags have been changed
  901. if ($this->post_approved != $post_data['post_approved'])
  902. {
  903. //if topic_id was changed, we've already updated it above.
  904. if ($this->topic_id == $post_data['topic_id'])
  905. {
  906. if ($is_first_post)
  907. {
  908. //first post -> approve/disapprove whole topic if not yet done (should only happen when directly storing the post)
  909. if ($this->post_approved != $post_data['topic_approved'])
  910. {
  911. $sync->add('forum', $this->forum_id, 'forum_topics', $this->post_approved ? 1 : -1);
  912. $sync->add('forum', $this->forum_id, 'forum_posts', $this->post_approved ? (1+$post_data['topic_replies']) : -(1+$post_data['topic_replies']));
  913. $sync->forum_last_post($this->forum_id);
  914. //and the total topics+posts
  915. set_config('num_topics', $this->post_approved ? $config['num_topics'] + 1 : $config['num_topics'] - 1, true);
  916. set_config('num_posts', $this->post_approved ? $config['num_posts'] + (1+$post_data['topic_replies']) : $config['num_posts'] - (1+$post_data['topic_replies']), true);
  917. }
  918. }
  919. else
  920. {
  921. //reply
  922. $sync->add('topic', $this->topic_id, 'topic_replies', $this->post_approved ? 1 : -1);
  923. $sync->add('forum', $this->forum_id, 'forum_posts', $this->post_approved ? 1 : -1);
  924. }
  925. }
  926. //update total posts
  927. if (!$is_first_post)
  928. {
  929. set_config('num_posts', $this->post_approved ? $config['num_posts'] + 1 : $config['num_posts'] - 1, true);
  930. }
  931. }
  932. /*if($this->post_postcount != $post_data['post_postcount'] && $this->poster_id != ANONYMOUS)
  933. {
  934. //increase or decrease user_posts
  935. $sync->add('user', $this->poster_id, 'user_posts', $this->post_approved ? 1 : -1);
  936. }*/
  937. if ($this->poster_id != $post_data['poster_id'] || $this->post_postcount != $post_data['post_postcount'])
  938. {
  939. if ($post_data['post_postcount'] && $post_data['poster_id'] != ANONYMOUS)
  940. {
  941. $sync->add('user', $post_data['poster_id'], 'user_posts', -1);
  942. }
  943. if ($this->post_postcount && $this->poster_id != ANONYMOUS)
  944. {
  945. $sync->add('user', $this->poster_id, 'user_posts', 1);
  946. }
  947. }
  948. if ($is_first_post)
  949. {
  950. $sync->topic_first_post($this->topic_id);
  951. }
  952. if ($is_last_post)
  953. {
  954. $sync->topic_last_post($this->topic_id);
  955. $sync->forum_last_post($this->forum_id);
  956. }
  957. reindex('edit', $this->post_id, $sql_data['post_text'], $this->post_subject, $this->poster_id, $this->forum_id);
  958. $db->sql_transaction('commit');
  959. }
  960. elseif ($this->topic_id)
  961. {
  962. //reply
  963. $sql = 'SELECT t.*, f.forum_name
  964. FROM ' . TOPICS_TABLE . ' t
  965. LEFT JOIN ' . FORUMS_TABLE . ' f
  966. ON (f.forum_id = t.forum_id)
  967. WHERE t.topic_id = ' . intval($this->topic_id);
  968. $result = $db->sql_query($sql);
  969. $topic_data = $db->sql_fetchrow($result);
  970. $db->sql_freeresult($result);
  971. if (!$topic_data)
  972. {
  973. trigger_error("topic_id={$this->topic_id}, but that topic does not exist", E_USER_ERROR);
  974. }
  975. //we need topic_id and forum_id
  976. $this->forum_id = $topic_data['forum_id'];
  977. $sql_data['forum_id'] = $this->forum_id;
  978. $sql_data['topic_id'] = $this->topic_id;
  979. //make sure we have a post_subject (empty subjects are bad for e.g. approving)
  980. if ($this->post_subject == '')
  981. {
  982. $this->post_subject = 'Re: ' . $topic_data['topic_title'];
  983. }
  984. $db->sql_transaction('begin');
  985. //insert post
  986. $sql = 'INSERT INTO ' . POSTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_data);
  987. $db->sql_query($sql);
  988. $this->post_id = $db->sql_nextid();
  989. //update topic
  990. if (!$sync->new_topic_flag)
  991. {
  992. $sync->add('topic', $this->topic_id, 'topic_replies', $this->post_approved ? 1 : 0);
  993. $sync->add('topic', $this->topic_id, 'topic_replies_real', 1);
  994. $sync->set('topic', $this->topic_id, 'topic_bumped', 0);
  995. $sync->set('topic', $this->topic_id, 'topic_bumper', 0);
  996. }
  997. else
  998. {
  999. $sync->topic_first_post($this->topic_id);
  1000. $sync->new_topic_flag = false;
  1001. }
  1002. $sync->topic_last_post($this->topic_id);
  1003. //update forum
  1004. if ($this->forum_id != 0)
  1005. {
  1006. $sync->add('forum', $this->forum_id, 'forum_posts', $this->post_approved ? 1 : 0);
  1007. $sync->forum_last_post($this->forum_id);
  1008. }
  1009. if ($this->post_postcount)
  1010. {
  1011. //increase user_posts...
  1012. $sync->add('user', $this->poster_id, 'user_posts', 1);
  1013. }
  1014. if ($this->post_approved)
  1015. {
  1016. //...and total posts
  1017. set_config('num_posts', $config['num_posts'] + 1, true);
  1018. }
  1019. reindex('reply', $this->post_id, $sql_data['post_text'], $this->post_subject, $this->poster_id, $this->forum_id);
  1020. $db->sql_transaction('commit');
  1021. // Mark this topic as posted to
  1022. markread('post', $this->forum_id, $this->topic_id, $this->post_time, $this->poster_id);
  1023. // Mark this topic as read
  1024. // We do not use post_time here, this is intended (post_time can have a date in the past if editing a message)
  1025. markread('topic', $this->forum_id, $this->topic_id, time());
  1026. //
  1027. if ($config['load_db_lastread'] && $user->data['is_registered'])
  1028. {
  1029. $sql = 'SELECT mark_time
  1030. FROM ' . FORUMS_TRACK_TABLE . '
  1031. WHERE user_id = ' . $user->data['user_id'] . '
  1032. AND forum_id = ' . $this->forum_id;
  1033. $result = $db->sql_query($sql);
  1034. $f_mark_time = (int) $db->sql_fetchfield('mark_time');
  1035. $db->sql_freeresult($result);
  1036. }
  1037. else if ($config['load_anon_lastread'] || $user->data['is_registered'])
  1038. {
  1039. $f_mark_time = false;
  1040. }
  1041. if (($config['load_db_lastread'] && $user->data['is_registered']) || $config['load_anon_lastread'] || $user->data['is_registered'])
  1042. {
  1043. // Update forum info
  1044. $sql = 'SELECT forum_last_post_time
  1045. FROM ' . FORUMS_TABLE . '
  1046. WHERE forum_id = ' . $this->forum_id;
  1047. $result = $db->sql_query($sql);
  1048. $forum_last_post_time = (int) $db->sql_fetchfield('forum_last_post_time');
  1049. $db->sql_freeresult($result);
  1050. update_forum_tracking_info($this->forum_id, $forum_last_post_time, $f_mark_time, false);
  1051. }
  1052. // Send Notifications
  1053. user_notification('reply', $this->post_subject, $topic_data['topic_title'], $topic_data['forum_name'], $this->forum_id, $this->topic_id, $this->post_id);
  1054. }
  1055. else
  1056. {
  1057. //new topic
  1058. $this->_topic = topic::from_post($this);
  1059. $this->_topic->submit(true);
  1060. //PHP4 Compatibility:
  1061. if(version_compare(PHP_VERSION, '5.0.0', '<'))
  1062. {
  1063. $this->topic_id = $this->_topic->topic_id;
  1064. $this->post_id = $this->_topic->topic_first_post_id;
  1065. }
  1066. $exec_sync = false;
  1067. }
  1068. foreach ($this->attachments as $attachment)
  1069. {
  1070. $attachment->post_msg_id = $this->post_id;
  1071. $attachment->topic_id = $this->topic_id;
  1072. $attachment->poster_id = $this->poster_id;
  1073. $attachment->in_message = 0;
  1074. $attachment->is_orphan = 0;
  1075. $attachment->submit();
  1076. }
  1077. if ($exec_sync)
  1078. {
  1079. $sync->execute();
  1080. }
  1081. /*if ($sync_topic)
  1082. {
  1083. if ($this->_topic)
  1084. {
  1085. $this->_topic->sync();
  1086. }
  1087. else
  1088. {
  1089. sync('topic', 'topic_id', $this->topic_id);
  1090. }
  1091. }*/
  1092. }
  1093. /**
  1094. * delete this post (and if it was the last one in the topic, also delete the topic)
  1095. */
  1096. function delete()
  1097. {
  1098. if (!$this->post_id)
  1099. {
  1100. trigger_error('NO_POST', E_USER_ERROR);
  1101. }
  1102. $ret = delete_posts('post_id', $this->post_id);
  1103. //remove references to the deleted post so calls to submit() will create a
  1104. //new post instead of trying to update the post which does not exist anymore
  1105. $this->post_id = NULL;
  1106. return $ret;
  1107. }
  1108. /**
  1109. * mark this post as edited (modify post_edit_* fields).
  1110. * currently logged in user will be used if user_id = 0
  1111. */
  1112. function mark_edited($user_id = 0, $reason = '')
  1113. {
  1114. if ($user_id = 0)
  1115. {
  1116. global $user;
  1117. $user_id = $user->data['user_id'];
  1118. }
  1119. $this->post_edit_count++;
  1120. $this->post_edit_time = time();
  1121. $this->post_edit_user = $user_id;
  1122. $this->post_edit_reason = $reason;
  1123. }
  1124. function mark_read()
  1125. {
  1126. if ($this->post_id)
  1127. {
  1128. //only when post already stored
  1129. markread('topic', $this->forum_id, $this->topic_id, time());
  1130. }
  1131. }
  1132. }
  1133. class privmsg
  1134. {
  1135. var $msg_id;
  1136. var $root_level = 0;
  1137. var $reply_from_msg_id = 0;
  1138. var $message_time;
  1139. var $author_id;
  1140. var $author_ip;
  1141. //var $to_address;
  1142. //var $bcc_address;
  1143. /**list of recipients in the form:
  1144. * array(
  1145. * 'u' => array(
  1146. * 12 => 'to', //user_id 12 as to
  1147. * 34 => 'bcc' //user_id 34 as bcc
  1148. * ),
  1149. * 'g' => array(
  1150. * 56 => 'to', //group_id 56 as to
  1151. * 78 => 'bcc' //group_id 78 as bcc
  1152. * )
  1153. * )*/
  1154. var $address_list = array('u'=>array(), 'g'=> array());
  1155. var $icon_id;
  1156. var $enable_bbcode = 1;
  1157. var $enable_smilies = 1;
  1158. var $enable_magic_url = 1;
  1159. var $enable_sig = 1;
  1160. var $message_subject = '';
  1161. var $message_text = '';
  1162. var $message_edit_reason = '';
  1163. var $message_edit_user = 0;
  1164. var $message_edit_time = 0;
  1165. var $message_edit_count = 0;
  1166. //var $message_attachment = 0;
  1167. function pm()
  1168. {
  1169. }
  1170. /**
  1171. * initializes and returns a new privmsg object as reply to the message with msg_id $msg_id
  1172. */
  1173. function reply_to($msg_id, $quote = true)
  1174. {
  1175. global $db;
  1176. $sql = 'SELECT p.msg_id, p.root_level, p.author_id, p.message_subject, p.message_text, p.bbcode_uid, p.to_address, p.bcc_address, u.username
  1177. FROM ' . PRIVMSGS_TABLE . ' p
  1178. LEFT JOIN ' . USERS_TABLE . ' u
  1179. ON (p.author_id = u.user_id)
  1180. WHERE msg_id = ' . intval($msg_id);
  1181. $result = $db->sql_query($sql);
  1182. $row = $db->sql_fetchrow($result);
  1183. if (!$row)
  1184. {
  1185. trigger_error('NO_PRIVMSG', E_USER_ERROR);
  1186. }
  1187. $privmsg = new privmsg();
  1188. $privmsg->reply_from_msg_id = $row['msg_id'];
  1189. $privmsg->root_level = ($row['root_level'] ? $row['root_level'] : $row['msg_id']);
  1190. $privmsg->message_subject = ((!preg_match('/^Re:/', $row['message_subject'])) ? 'Re: ' : '') . censor_text($row['message_subject']);
  1191. if ($quote)
  1192. {
  1193. decode_message($row['message_text'], $row['bbcode_uid']);
  1194. //for some reason we need &quot; here instead of "
  1195. $privmsg->message_text = '[quote=&quot;' . $row['username'] . '&quot;]' . censor_text(trim($row['message_text'])) . "[/quote]\n";
  1196. }
  1197. //add original sender as recipient
  1198. $privmsg->to($row['author_id']);
  1199. //if message had only a single recipient, use that as sender
  1200. if ($row['to_address'] == '' || $row['bcc_address'] == '')
  1201. {
  1202. $to = ($row['to_address'] != '') ? $row['to_address'] : $row['bcc_address'];
  1203. if (preg_match('#^u_(\\d+)$#', $to, $m))
  1204. {
  1205. $privmsg->author_id = $m[1];
  1206. }
  1207. }
  1208. return $privmsg;
  1209. }
  1210. /**
  1211. * adds a recipient. arguments can be (in any order):
  1212. * - 'to': set type to 'to' (default)
  1213. * - 'bcc': set type to 'bcc'
  1214. * - integer: a user_id or group_id
  1215. * - 'u' or 'user': the number is a user_id (default)
  1216. * - 'g' or 'group': the number is a group_id
  1217. * e.g. $pm->to('user', 'to', 123);
  1218. */
  1219. function to()
  1220. {
  1221. $type = 'to';
  1222. $ug_type = 'u';
  1223. $id = 0;
  1224. $args = func_get_args();
  1225. $args = array_map('strtolower', $args);
  1226. foreach ($args as $arg)
  1227. {
  1228. switch ($arg)
  1229. {
  1230. case 'to': $type = 'to'; break;
  1231. case 'bcc': $type = 'bcc'; break;
  1232. case 'user': case 'u': $ug_type = 'u'; break;
  1233. case 'group': case 'g': $ug_type = 'g'; break;
  1234. }
  1235. if(is_numeric($arg)) $id = intval($arg);
  1236. }
  1237. if ($id == 0)
  1238. {
  1239. trigger_error('privmsg->to(): no id given', E_USER_ERROR);
  1240. }
  1241. $this->address_list[$ug_type][$id] = $type;
  1242. }
  1243. function get($id)
  1244. {
  1245. trigger_error('not yet implemented', E_USER_ERROR);
  1246. }
  1247. function submit()
  1248. {
  1249. global $user, $db;
  1250. if (!$this->msg_id)
  1251. {
  1252. //new message, set some default values if not set yet
  1253. if(!$this->author_id) $this->author_id = $user->data['user_id'];
  1254. if(!$this->author_ip) $this->author_ip = $user->ip;
  1255. if(!$this->message_time) $this->message_time = time();
  1256. }
  1257. $this->message_subject = truncate_string($this->message_subject);
  1258. if ($user->data['user_id'] == $this->author_id)
  1259. {
  1260. $author_username = $user->data['username'];
  1261. }
  1262. else
  1263. {
  1264. $sql = 'SELECT username
  1265. FROM ' . USERS_TABLE . '
  1266. WHERE user_id=' . $this->author_id;
  1267. $result = $db->sql_query($sql);
  1268. $row = $db->sql_fetchrow($result);
  1269. if (!$row)
  1270. {
  1271. trigger_error('NO_USER', E_USER_ERROR);
  1272. }
  1273. $author_username = $row['username'];
  1274. }
  1275. $message = $this->message_text;
  1276. $bbcode_uid = $bbcode_bitfield = $options = '';
  1277. generate_text_for_storage($message, $bbcode_uid, $bbcode_bitfield, $options, $this->enable_bbcode, $this->enable_magic_url, $this->enable_smilies);
  1278. $data = array(
  1279. 'msg_id' => (int) $this->msg_id,
  1280. 'from_user_id' => (int) $this->author_id,
  1281. 'from_user_ip' => $this->author_ip,
  1282. 'from_username' => $author_username,
  1283. 'reply_from_root_level' => $this->root_level,
  1284. 'reply_from_msg_id' => $this->reply_from_msg_id,
  1285. 'icon_id' => (int) $this->icon_id,
  1286. 'enable_sig' => (bool) $this->enable_sig,
  1287. 'enable_bbcode' => (bool) $this->enable_bbcode,
  1288. 'enable_smilies' => (bool) $this->enable_smilies,
  1289. 'enable_urls' => (bool) $this->enable_magic_url,
  1290. 'bbcode_bitfield' => $bbcode_bitfield,
  1291. 'bbcode_uid' => $bbcode_uid,
  1292. 'message' => $message,
  1293. 'attachment_data' => false,
  1294. 'filename_data' => false,
  1295. 'address_list' => $this->address_list
  1296. );
  1297. $mode = ($this->msg_id) ? 'edit' : ($this->reply_from_msg_id ? 'reply' : 'post');
  1298. submit_pm($mode, $this->message_subject, $data);
  1299. $this->msg_id = $data['msg_id'];
  1300. }
  1301. function delete()
  1302. {
  1303. trigger_error('not yet implemented', E_USER_ERROR);
  1304. }
  1305. }
  1306. class attachment
  1307. {
  1308. //TODO
  1309. var $attach_id;
  1310. var $post_msg_id = 0;
  1311. var $topic_id = 0;
  1312. var $in_message = 0;
  1313. var $poster_id = 0;
  1314. var $is_orphan = 1;
  1315. var $physical_filename = '';
  1316. var $real_filename = '';
  1317. var $download_count = 0;
  1318. var $attach_comment = '';
  1319. var $extension = '';
  1320. var $mimetype = '';
  1321. var $filesize = 0;
  1322. var $filetime = 0;
  1323. var $thumbnail = 0;
  1324. function attachment()
  1325. {
  1326. //dont call new attachment(), call attachment::create() or attachment::create_checked()
  1327. }
  1328. /**
  1329. * directly creats an attachment (bypassing checks like allowed extensione etc.)
  1330. */
  1331. function create($file, $filename)
  1332. {
  1333. //TODO
  1334. /*global $user;
  1335. $attachment = new attachment();
  1336. if ($user)
  1337. {
  1338. $attachment->poster_id = $user->data['user_id'];
  1339. }
  1340. $upload = new fileupload();
  1341. $upload->local_upload($file);
  1342. $attachment->real_filename = $filename;
  1343. copy($file, $attachment->get_file());
  1344. return $attachment;*/
  1345. }
  1346. /**
  1347. * creates an attachment through the phpBB function upload_attachment. i.e.
  1348. * quota, allowed extensions etc. will be checked.
  1349. * returns an attachment object on success or an array of error messages on failure
  1350. * submit() is automatically called so that this attachment appears in the acp
  1351. * "orphaned attachments" list if you dont assign it to a post.
  1352. * WARNING: $file will be moved to the attachment storage
  1353. */
  1354. function create_checked($file, $forum_id, $mimetype = 'application/octetstream')
  1355. {
  1356. global $user;
  1357. if (!file_exists($file))
  1358. {
  1359. trigger_error('FILE_NOT_FOUND', E_USER_ERROR);
  1360. }
  1361. $filedata = array(
  1362. 'realname' => basename($file),
  1363. 'size' => filesize($file),
  1364. 'type' => $mimetype
  1365. );
  1366. $filedata = upload_attachment(false, $forum_id, true, $file, false, $filedata);
  1367. if ($filedata['post_attach'] && !sizeof($filedata['error']))
  1368. {
  1369. $attachment = new attachment();
  1370. $attachment->poster_id = $user->data['user_id'];
  1371. $attachment->physical_filename = $filedata['physical_filename'];
  1372. $attachment->real_filename = $filedata['real_filename'];
  1373. $attachment->extension = $filedata['extension'];
  1374. $attachment->mimetype = $filedata['mimetype'];
  1375. $attachment->filesize = $filedata['filesize'];
  1376. $attachment->filetime = $filedata['filetime'];
  1377. $attachment->thumbnail = $filedata['thumbnail'];
  1378. $attachment->submit();
  1379. return $attachment;
  1380. }
  1381. else
  1382. {
  1383. trigger_error(implode('<br/>', $filedata['error']), E_USER_ERROR);
  1384. }
  1385. }
  1386. function get($attach_id)
  1387. {
  1388. global $db;
  1389. $sql = "SELECT * FROM " . ATTACHMENTS_TABLE . " WHERE attach_id=" . intval($attach_id);
  1390. $result = $db->sql_query($sql);
  1391. $attach_data = $db->sql_fetchrow($result);
  1392. $db->sql_freeresult($result);
  1393. if (!$attach_data)
  1394. {
  1395. //attachment does not exist, return false
  1396. return false;
  1397. }
  1398. return attachment::from_array($attach_data);
  1399. }
  1400. function from_array($data)
  1401. {
  1402. $attachment = new attachment();
  1403. $attachment->attach_id = $data['attach_id'];
  1404. $attachment->post_msg_id = $data['post_msg_id'];
  1405. $attachment->topic_id = $data['topic_id'];
  1406. $attachment->in_message = $data['in_message'];
  1407. $attachment->poster_id = $data['poster_id'];
  1408. $attachment->is_orphan = $data['is_orphan'];
  1409. $attachment->physical_filename = $data['physical_filename'];
  1410. $attachment->real_filename = $data['real_filename'];
  1411. $attachment->download_count = $data['download_count'];
  1412. $attachment->attach_comment = $data['attach_comment'];
  1413. $attachment->extension = $data['extension'];
  1414. $attachment->mimetype = $data['mimetype'];
  1415. $attachment->filesize = $data['filesize'];
  1416. $attachment->filetime = $data['filetime'];
  1417. $attachment->thumbnail = $data['thumbnail'];
  1418. return $attachment;
  1419. }
  1420. function submit()
  1421. {
  1422. global $config, $db, $auth, $user;
  1423. if (!$this->attach_id)
  1424. {
  1425. //new attachment, set some default values if not set yet
  1426. if(!$this->poster_id) $this->poster_id = $user->data['user_id'];
  1427. if(!$this->filetime) $this->filetime = time();
  1428. }
  1429. $sql_data = array(
  1430. 'post_msg_id' => $this->post_msg_id,
  1431. 'topic_id' => $this->topic_id,
  1432. 'in_message' => $this->in_message,
  1433. 'poster_id' => $this->poster_id,
  1434. 'is_orphan' => $this->is_orphan,
  1435. 'physical_filename' => $this->physical_filename,
  1436. 'real_filename' => $this->real_filename,
  1437. //'download_count' => $this->download_count,
  1438. 'attach_comment' => $this->attach_comment,
  1439. 'extension' => $this->extension,
  1440. 'mimetype' => $this->mimetype,
  1441. 'filesize' => $this->filesize,
  1442. 'filetime' => $this->filetime,
  1443. 'thumbnail' => $this->thumbnail
  1444. );
  1445. $update_post_topic = false;
  1446. if ($this->attach_id)
  1447. {
  1448. //edit
  1449. $sql = 'SELECT *
  1450. FROM ' . ATTACHMENTS_TABLE . '
  1451. WHERE attach_id = ' . $this->attach_id;
  1452. $result = $db->sql_query($sql);
  1453. $attach_data = $db->sql_fetchrow($result);
  1454. $db->sql_freeresult($result);
  1455. if (!$attach_data)
  1456. {
  1457. trigger_error("attach_id={$this->attach_id}, but that attachment does not exist", E_USER_ERROR);
  1458. }
  1459. $sql = 'UPDATE ' . ATTACHMENTS_TABLE . '
  1460. SET ' . $db->sql_build_array('UPDATE', $sql_data) . '
  1461. WHERE attach_id = ' . $this->attach_id;
  1462. $db->sql_query($sql);
  1463. if ($attach_data['post_msg_id'] != $this->post_msg_id || $attach_data['topic_id'] != $this->topic_id)
  1464. {
  1465. $update_post_topic = true;
  1466. }
  1467. }
  1468. else
  1469. {
  1470. //insert attachment
  1471. $sql = 'INSERT INTO ' . ATTACHMENTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_data);
  1472. $db->sql_query($sql);
  1473. $this->attach_id = $db->sql_nextid();
  1474. $update_post_topic = true;
  1475. }
  1476. if ($update_post_topic)
  1477. {
  1478. //update post and topic tables
  1479. if ($this->topic_id)
  1480. {
  1481. $sql = 'UPDATE ' . TOPICS_TABLE . '
  1482. SET topic_attachment = 1
  1483. WHERE topic_id = ' . $this->topic_id;
  1484. $db->sql_query($sql);
  1485. }
  1486. if ($this->post_msg_id)
  1487. {
  1488. $sql = 'UPDATE ' . POSTS_TABLE . '
  1489. SET post_attachment = 1
  1490. WHERE post_id = ' . $this->post_msg_id;
  1491. $db->sql_query($sql);
  1492. }
  1493. }
  1494. }
  1495. function delete()
  1496. {
  1497. delete_attachments('attach', $this->id);
  1498. }
  1499. function get_file()
  1500. {
  1501. global $phpbb_root_path, $config;
  1502. return $phpbb_root_path . $config['upload_path'] . '/' . $this->physical_filename;
  1503. }
  1504. function get_thumbnail()
  1505. {
  1506. global $phpbb_root_path, $config;
  1507. return $phpbb_root_path . $config['upload_path'] . '/…

Large files files are truncated, but you can click here to view the full file