]> git.vanrenterghem.biz Git - www.vanrenterghem.biz.git/blob - phpBB2/includes/functions_post.php
Baseline
[www.vanrenterghem.biz.git] / phpBB2 / includes / functions_post.php
1 <?php
2 /***************************************************************************
3  *                            functions_post.php
4  *                            -------------------
5  *   begin                : Saturday, Feb 13, 2001
6  *   copyright            : (C) 2001 The phpBB Group
7  *   email                : support@phpbb.com
8  *
9  *   $Id: functions_post.php,v 1.9.2.52 2006/05/06 13:38:55 grahamje Exp $
10  *
11  *
12  ***************************************************************************/
14 /***************************************************************************
15  *
16  *   This program is free software; you can redistribute it and/or modify
17  *   it under the terms of the GNU General Public License as published by
18  *   the Free Software Foundation; either version 2 of the License, or
19  *   (at your option) any later version.
20  *
21  ***************************************************************************/
23 if (!defined('IN_PHPBB'))
24 {
25         die('Hacking attempt');
26 }
28 $html_entities_match = array('#&(?!(\#[0-9]+;))#', '#<#', '#>#', '#"#');
29 $html_entities_replace = array('&amp;', '&lt;', '&gt;', '&quot;');
31 $unhtml_specialchars_match = array('#&gt;#', '#&lt;#', '#&quot;#', '#&amp;#');
32 $unhtml_specialchars_replace = array('>', '<', '"', '&');
34 //
35 // This function will prepare a posted message for
36 // entry into the database.
37 //
38 function prepare_message($message, $html_on, $bbcode_on, $smile_on, $bbcode_uid = 0)
39 {
40         global $board_config, $html_entities_match, $html_entities_replace;
42         //
43         // Clean up the message
44         //
45         $message = trim($message);
47         if ($html_on)
48         {
49                 // If HTML is on, we try to make it safe
50                 // This approach is quite agressive and anything that does not look like a valid tag
51                 // is going to get converted to HTML entities
52                 $message = stripslashes($message);
53                 $html_match = '#<[^\w<]*(\w+)((?:"[^"]*"|\'[^\']*\'|[^<>\'"])+)?>#';
54                 $matches = array();
56                 $message_split = preg_split($html_match, $message);
57                 preg_match_all($html_match, $message, $matches);
59                 $message = '';
61                 foreach ($message_split as $part)
62                 {
63                         $tag = array(array_shift($matches[0]), array_shift($matches[1]), array_shift($matches[2]));
64                         $message .= preg_replace($html_entities_match, $html_entities_replace, $part) . clean_html($tag);
65                 }
67                 $message = addslashes($message);
68                 $message = str_replace('&quot;', '\&quot;', $message);
69         }
70         else
71         {
72                 $message = preg_replace($html_entities_match, $html_entities_replace, $message);
73         }
75         if($bbcode_on && $bbcode_uid != '')
76         {
77                 $message = bbencode_first_pass($message, $bbcode_uid);
78         }
80         return $message;
81 }
83 function unprepare_message($message)
84 {
85         global $unhtml_specialchars_match, $unhtml_specialchars_replace;
87         return preg_replace($unhtml_specialchars_match, $unhtml_specialchars_replace, $message);
88 }
90 //
91 // Prepare a message for posting
92 // 
93 function prepare_post(&$mode, &$post_data, &$bbcode_on, &$html_on, &$smilies_on, &$error_msg, &$username, &$bbcode_uid, &$subject, &$message, &$poll_title, &$poll_options, &$poll_length)
94 {
95         global $board_config, $userdata, $lang, $phpEx, $phpbb_root_path;
97         // Check username
98         if (!empty($username))
99         {
100                 $username = phpbb_clean_username($username);
102                 if (!$userdata['session_logged_in'] || ($userdata['session_logged_in'] && $username != $userdata['username']))
103                 {
104                         include($phpbb_root_path . 'includes/functions_validate.'.$phpEx);
106                         $result = validate_username($username);
107                         if ($result['error'])
108                         {
109                                 $error_msg .= (!empty($error_msg)) ? '<br />' . $result['error_msg'] : $result['error_msg'];
110                         }
111                 }
112                 else
113                 {
114                         $username = '';
115                 }
116         }
118         // Check subject
119         if (!empty($subject))
120         {
121                 $subject = htmlspecialchars(trim($subject));
122         }
123         else if ($mode == 'newtopic' || ($mode == 'editpost' && $post_data['first_post']))
124         {
125                 $error_msg .= (!empty($error_msg)) ? '<br />' . $lang['Empty_subject'] : $lang['Empty_subject'];
126         }
128         // Check message
129         if (!empty($message))
130         {
131                 $bbcode_uid = ($bbcode_on) ? make_bbcode_uid() : '';
132                 $message = prepare_message(trim($message), $html_on, $bbcode_on, $smilies_on, $bbcode_uid);
133         }
134         else if ($mode != 'delete' && $mode != 'poll_delete') 
135         {
136                 $error_msg .= (!empty($error_msg)) ? '<br />' . $lang['Empty_message'] : $lang['Empty_message'];
137         }
139         //
140         // Handle poll stuff
141         //
142         if ($mode == 'newtopic' || ($mode == 'editpost' && $post_data['first_post']))
143         {
144                 $poll_length = (isset($poll_length)) ? max(0, intval($poll_length)) : 0;
146                 if (!empty($poll_title))
147                 {
148                         $poll_title = htmlspecialchars(trim($poll_title));
149                 }
151                 if(!empty($poll_options))
152                 {
153                         $temp_option_text = array();
154                         while(list($option_id, $option_text) = @each($poll_options))
155                         {
156                                 $option_text = trim($option_text);
157                                 if (!empty($option_text))
158                                 {
159                                         $temp_option_text[intval($option_id)] = htmlspecialchars($option_text);
160                                 }
161                         }
162                         $option_text = $temp_option_text;
164                         if (count($poll_options) < 2)
165                         {
166                                 $error_msg .= (!empty($error_msg)) ? '<br />' . $lang['To_few_poll_options'] : $lang['To_few_poll_options'];
167                         }
168                         else if (count($poll_options) > $board_config['max_poll_options']) 
169                         {
170                                 $error_msg .= (!empty($error_msg)) ? '<br />' . $lang['To_many_poll_options'] : $lang['To_many_poll_options'];
171                         }
172                         else if ($poll_title == '')
173                         {
174                                 $error_msg .= (!empty($error_msg)) ? '<br />' . $lang['Empty_poll_title'] : $lang['Empty_poll_title'];
175                         }
176                 }
177         }
179         return;
182 //
183 // Post a new topic/reply/poll or edit existing post/poll
184 //
185 function submit_post($mode, &$post_data, &$message, &$meta, &$forum_id, &$topic_id, &$post_id, &$poll_id, &$topic_type, &$bbcode_on, &$html_on, &$smilies_on, &$attach_sig, &$bbcode_uid, $post_username, $post_subject, $post_message, $poll_title, &$poll_options, &$poll_length)
187         global $board_config, $lang, $db, $phpbb_root_path, $phpEx;
188         global $userdata, $user_ip;
190         include($phpbb_root_path . 'includes/functions_search.'.$phpEx);
192         $current_time = time();
194         if ($mode == 'newtopic' || $mode == 'reply' || $mode == 'editpost') 
195         {
196                 //
197                 // Flood control
198                 //
199                 $where_sql = ($userdata['user_id'] == ANONYMOUS) ? "poster_ip = '$user_ip'" : 'poster_id = ' . $userdata['user_id'];
200                 $sql = "SELECT MAX(post_time) AS last_post_time
201                         FROM " . POSTS_TABLE . "
202                         WHERE $where_sql";
203                 if ($result = $db->sql_query($sql))
204                 {
205                         if ($row = $db->sql_fetchrow($result))
206                         {
207                                 if (intval($row['last_post_time']) > 0 && ($current_time - intval($row['last_post_time'])) < intval($board_config['flood_interval']))
208                                 {
209                                         message_die(GENERAL_MESSAGE, $lang['Flood_Error']);
210                                 }
211                         }
212                 }
213         }
215         if ($mode == 'editpost')
216         {
217                 remove_search_post($post_id);
218         }
220         if ($mode == 'newtopic' || ($mode == 'editpost' && $post_data['first_post']))
221         {
222                 $topic_vote = (!empty($poll_title) && count($poll_options) >= 2) ? 1 : 0;
224                 $sql  = ($mode != "editpost") ? "INSERT INTO " . TOPICS_TABLE . " (topic_title, topic_poster, topic_time, forum_id, topic_status, topic_type, topic_vote) VALUES ('$post_subject', " . $userdata['user_id'] . ", $current_time, $forum_id, " . TOPIC_UNLOCKED . ", $topic_type, $topic_vote)" : "UPDATE " . TOPICS_TABLE . " SET topic_title = '$post_subject', topic_type = $topic_type " . (($post_data['edit_vote'] || !empty($poll_title)) ? ", topic_vote = " . $topic_vote : "") . " WHERE topic_id = $topic_id";
225                 if (!$db->sql_query($sql))
226                 {
227                         message_die(GENERAL_ERROR, 'Error in posting', '', __LINE__, __FILE__, $sql);
228                 }
230                 if ($mode == 'newtopic')
231                 {
232                         $topic_id = $db->sql_nextid();
233                 }
234         }
236         $edited_sql = ($mode == 'editpost' && !$post_data['last_post'] && $post_data['poster_post']) ? ", post_edit_time = $current_time, post_edit_count = post_edit_count + 1 " : "";
237         $sql = ($mode != "editpost") ? "INSERT INTO " . POSTS_TABLE . " (topic_id, forum_id, poster_id, post_username, post_time, poster_ip, enable_bbcode, enable_html, enable_smilies, enable_sig) VALUES ($topic_id, $forum_id, " . $userdata['user_id'] . ", '$post_username', $current_time, '$user_ip', $bbcode_on, $html_on, $smilies_on, $attach_sig)" : "UPDATE " . POSTS_TABLE . " SET post_username = '$post_username', enable_bbcode = $bbcode_on, enable_html = $html_on, enable_smilies = $smilies_on, enable_sig = $attach_sig" . $edited_sql . " WHERE post_id = $post_id";
238         if (!$db->sql_query($sql, BEGIN_TRANSACTION))
239         {
240                 message_die(GENERAL_ERROR, 'Error in posting', '', __LINE__, __FILE__, $sql);
241         }
243         if ($mode != 'editpost')
244         {
245                 $post_id = $db->sql_nextid();
246         }
248         $sql = ($mode != 'editpost') ? "INSERT INTO " . POSTS_TEXT_TABLE . " (post_id, post_subject, bbcode_uid, post_text) VALUES ($post_id, '$post_subject', '$bbcode_uid', '$post_message')" : "UPDATE " . POSTS_TEXT_TABLE . " SET post_text = '$post_message',  bbcode_uid = '$bbcode_uid', post_subject = '$post_subject' WHERE post_id = $post_id";
249         if (!$db->sql_query($sql))
250         {
251                 message_die(GENERAL_ERROR, 'Error in posting', '', __LINE__, __FILE__, $sql);
252         }
254         add_search_words('single', $post_id, stripslashes($post_message), stripslashes($post_subject));
256         //
257         // Add poll
258         // 
259         if (($mode == 'newtopic' || ($mode == 'editpost' && $post_data['edit_poll'])) && !empty($poll_title) && count($poll_options) >= 2)
260         {
261                 $sql = (!$post_data['has_poll']) ? "INSERT INTO " . VOTE_DESC_TABLE . " (topic_id, vote_text, vote_start, vote_length) VALUES ($topic_id, '$poll_title', $current_time, " . ($poll_length * 86400) . ")" : "UPDATE " . VOTE_DESC_TABLE . " SET vote_text = '$poll_title', vote_length = " . ($poll_length * 86400) . " WHERE topic_id = $topic_id";
262                 if (!$db->sql_query($sql))
263                 {
264                         message_die(GENERAL_ERROR, 'Error in posting', '', __LINE__, __FILE__, $sql);
265                 }
267                 $delete_option_sql = '';
268                 $old_poll_result = array();
269                 if ($mode == 'editpost' && $post_data['has_poll'])
270                 {
271                         $sql = "SELECT vote_option_id, vote_result  
272                                 FROM " . VOTE_RESULTS_TABLE . " 
273                                 WHERE vote_id = $poll_id 
274                                 ORDER BY vote_option_id ASC";
275                         if (!($result = $db->sql_query($sql)))
276                         {
277                                 message_die(GENERAL_ERROR, 'Could not obtain vote data results for this topic', '', __LINE__, __FILE__, $sql);
278                         }
280                         while ($row = $db->sql_fetchrow($result))
281                         {
282                                 $old_poll_result[$row['vote_option_id']] = $row['vote_result'];
284                                 if (!isset($poll_options[$row['vote_option_id']]))
285                                 {
286                                         $delete_option_sql .= ($delete_option_sql != '') ? ', ' . $row['vote_option_id'] : $row['vote_option_id'];
287                                 }
288                         }
289                 }
290                 else
291                 {
292                         $poll_id = $db->sql_nextid();
293                 }
295                 @reset($poll_options);
297                 $poll_option_id = 1;
298                 while (list($option_id, $option_text) = each($poll_options))
299                 {
300                         if (!empty($option_text))
301                         {
302                                 $option_text = str_replace("\'", "''", htmlspecialchars($option_text));
303                                 $poll_result = ($mode == "editpost" && isset($old_poll_result[$option_id])) ? $old_poll_result[$option_id] : 0;
305                                 $sql = ($mode != "editpost" || !isset($old_poll_result[$option_id])) ? "INSERT INTO " . VOTE_RESULTS_TABLE . " (vote_id, vote_option_id, vote_option_text, vote_result) VALUES ($poll_id, $poll_option_id, '$option_text', $poll_result)" : "UPDATE " . VOTE_RESULTS_TABLE . " SET vote_option_text = '$option_text', vote_result = $poll_result WHERE vote_option_id = $option_id AND vote_id = $poll_id";
306                                 if (!$db->sql_query($sql))
307                                 {
308                                         message_die(GENERAL_ERROR, 'Error in posting', '', __LINE__, __FILE__, $sql);
309                                 }
310                                 $poll_option_id++;
311                         }
312                 }
314                 if ($delete_option_sql != '')
315                 {
316                         $sql = "DELETE FROM " . VOTE_RESULTS_TABLE . " 
317                                 WHERE vote_option_id IN ($delete_option_sql) 
318                                         AND vote_id = $poll_id";
319                         if (!$db->sql_query($sql))
320                         {
321                                 message_die(GENERAL_ERROR, 'Error deleting pruned poll options', '', __LINE__, __FILE__, $sql);
322                         }
323                 }
324         }
326         $meta = '<meta http-equiv="refresh" content="3;url=' . append_sid("viewtopic.$phpEx?" . POST_POST_URL . "=" . $post_id) . '#' . $post_id . '">';
327         $message = $lang['Stored'] . '<br /><br />' . sprintf($lang['Click_view_message'], '<a href="' . append_sid("viewtopic.$phpEx?" . POST_POST_URL . "=" . $post_id) . '#' . $post_id . '">', '</a>') . '<br /><br />' . sprintf($lang['Click_return_forum'], '<a href="' . append_sid("viewforum.$phpEx?" . POST_FORUM_URL . "=$forum_id") . '">', '</a>');
329         return false;
332 //
333 // Update post stats and details
334 //
335 function update_post_stats(&$mode, &$post_data, &$forum_id, &$topic_id, &$post_id, &$user_id)
337         global $db;
339         $sign = ($mode == 'delete') ? '- 1' : '+ 1';
340         $forum_update_sql = "forum_posts = forum_posts $sign";
341         $topic_update_sql = '';
343         if ($mode == 'delete')
344         {
345                 if ($post_data['last_post'])
346                 {
347                         if ($post_data['first_post'])
348                         {
349                                 $forum_update_sql .= ', forum_topics = forum_topics - 1';
350                         }
351                         else
352                         {
354                                 $topic_update_sql .= 'topic_replies = topic_replies - 1';
356                                 $sql = "SELECT MAX(post_id) AS last_post_id
357                                         FROM " . POSTS_TABLE . " 
358                                         WHERE topic_id = $topic_id";
359                                 if (!($result = $db->sql_query($sql)))
360                                 {
361                                         message_die(GENERAL_ERROR, 'Error in deleting post', '', __LINE__, __FILE__, $sql);
362                                 }
364                                 if ($row = $db->sql_fetchrow($result))
365                                 {
366                                         $topic_update_sql .= ', topic_last_post_id = ' . $row['last_post_id'];
367                                 }
368                         }
370                         if ($post_data['last_topic'])
371                         {
372                                 $sql = "SELECT MAX(post_id) AS last_post_id
373                                         FROM " . POSTS_TABLE . " 
374                                         WHERE forum_id = $forum_id"; 
375                                 if (!($result = $db->sql_query($sql)))
376                                 {
377                                         message_die(GENERAL_ERROR, 'Error in deleting post', '', __LINE__, __FILE__, $sql);
378                                 }
380                                 if ($row = $db->sql_fetchrow($result))
381                                 {
382                                         $forum_update_sql .= ($row['last_post_id']) ? ', forum_last_post_id = ' . $row['last_post_id'] : ', forum_last_post_id = 0';
383                                 }
384                         }
385                 }
386                 else if ($post_data['first_post']) 
387                 {
388                         $sql = "SELECT MIN(post_id) AS first_post_id
389                                 FROM " . POSTS_TABLE . " 
390                                 WHERE topic_id = $topic_id";
391                         if (!($result = $db->sql_query($sql)))
392                         {
393                                 message_die(GENERAL_ERROR, 'Error in deleting post', '', __LINE__, __FILE__, $sql);
394                         }
396                         if ($row = $db->sql_fetchrow($result))
397                         {
398                                 $topic_update_sql .= 'topic_replies = topic_replies - 1, topic_first_post_id = ' . $row['first_post_id'];
399                         }
400                 }
401                 else
402                 {
403                         $topic_update_sql .= 'topic_replies = topic_replies - 1';
404                 }
405         }
406         else if ($mode != 'poll_delete')
407         {
408                 $forum_update_sql .= ", forum_last_post_id = $post_id" . (($mode == 'newtopic') ? ", forum_topics = forum_topics $sign" : ""); 
409                 $topic_update_sql = "topic_last_post_id = $post_id" . (($mode == 'reply') ? ", topic_replies = topic_replies $sign" : ", topic_first_post_id = $post_id");
410         }
411         else 
412         {
413                 $topic_update_sql .= 'topic_vote = 0';
414         }
416         if ($mode != 'poll_delete')
417         {
418                 $sql = "UPDATE " . FORUMS_TABLE . " SET 
419                         $forum_update_sql 
420                         WHERE forum_id = $forum_id";
421                 if (!$db->sql_query($sql))
422                 {
423                         message_die(GENERAL_ERROR, 'Error in posting', '', __LINE__, __FILE__, $sql);
424                 }
425         }
427         if ($topic_update_sql != '')
428         {
429                 $sql = "UPDATE " . TOPICS_TABLE . " SET 
430                         $topic_update_sql 
431                         WHERE topic_id = $topic_id";
432                 if (!$db->sql_query($sql))
433                 {
434                         message_die(GENERAL_ERROR, 'Error in posting', '', __LINE__, __FILE__, $sql);
435                 }
436         }
438         if ($mode != 'poll_delete')
439         {
440                 $sql = "UPDATE " . USERS_TABLE . "
441                         SET user_posts = user_posts $sign 
442                         WHERE user_id = $user_id";
443                 if (!$db->sql_query($sql, END_TRANSACTION))
444                 {
445                         message_die(GENERAL_ERROR, 'Error in posting', '', __LINE__, __FILE__, $sql);
446                 }
447         }
449         return;
452 //
453 // Delete a post/poll
454 //
455 function delete_post($mode, &$post_data, &$message, &$meta, &$forum_id, &$topic_id, &$post_id, &$poll_id)
457         global $board_config, $lang, $db, $phpbb_root_path, $phpEx;
458         global $userdata, $user_ip;
460         if ($mode != 'poll_delete')
461         {
462                 include($phpbb_root_path . 'includes/functions_search.'.$phpEx);
464                 $sql = "DELETE FROM " . POSTS_TABLE . " 
465                         WHERE post_id = $post_id";
466                 if (!$db->sql_query($sql))
467                 {
468                         message_die(GENERAL_ERROR, 'Error in deleting post', '', __LINE__, __FILE__, $sql);
469                 }
471                 $sql = "DELETE FROM " . POSTS_TEXT_TABLE . " 
472                         WHERE post_id = $post_id";
473                 if (!$db->sql_query($sql))
474                 {
475                         message_die(GENERAL_ERROR, 'Error in deleting post', '', __LINE__, __FILE__, $sql);
476                 }
478                 if ($post_data['last_post'])
479                 {
480                         if ($post_data['first_post'])
481                         {
482                                 $forum_update_sql .= ', forum_topics = forum_topics - 1';
483                                 $sql = "DELETE FROM " . TOPICS_TABLE . " 
484                                         WHERE topic_id = $topic_id 
485                                                 OR topic_moved_id = $topic_id";
486                                 if (!$db->sql_query($sql))
487                                 {
488                                         message_die(GENERAL_ERROR, 'Error in deleting post', '', __LINE__, __FILE__, $sql);
489                                 }
491                                 $sql = "DELETE FROM " . TOPICS_WATCH_TABLE . "
492                                         WHERE topic_id = $topic_id";
493                                 if (!$db->sql_query($sql))
494                                 {
495                                         message_die(GENERAL_ERROR, 'Error in deleting post', '', __LINE__, __FILE__, $sql);
496                                 }
497                         }
498                 }
500                 remove_search_post($post_id);
501         }
503         if ($mode == 'poll_delete' || ($mode == 'delete' && $post_data['first_post'] && $post_data['last_post']) && $post_data['has_poll'] && $post_data['edit_poll'])
504         {
505                 $sql = "DELETE FROM " . VOTE_DESC_TABLE . " 
506                         WHERE topic_id = $topic_id";
507                 if (!$db->sql_query($sql))
508                 {
509                         message_die(GENERAL_ERROR, 'Error in deleting poll', '', __LINE__, __FILE__, $sql);
510                 }
512                 $sql = "DELETE FROM " . VOTE_RESULTS_TABLE . " 
513                         WHERE vote_id = $poll_id";
514                 if (!$db->sql_query($sql))
515                 {
516                         message_die(GENERAL_ERROR, 'Error in deleting poll', '', __LINE__, __FILE__, $sql);
517                 }
519                 $sql = "DELETE FROM " . VOTE_USERS_TABLE . " 
520                         WHERE vote_id = $poll_id";
521                 if (!$db->sql_query($sql))
522                 {
523                         message_die(GENERAL_ERROR, 'Error in deleting poll', '', __LINE__, __FILE__, $sql);
524                 }
525         }
527         if ($mode == 'delete' && $post_data['first_post'] && $post_data['last_post'])
528         {
529                 $meta = '<meta http-equiv="refresh" content="3;url=' . append_sid("viewforum.$phpEx?" . POST_FORUM_URL . '=' . $forum_id) . '">';
530                 $message = $lang['Deleted'];
531         }
532         else
533         {
534                 $meta = '<meta http-equiv="refresh" content="3;url=' . append_sid("viewtopic.$phpEx?" . POST_TOPIC_URL . '=' . $topic_id) . '">';
535                 $message = (($mode == 'poll_delete') ? $lang['Poll_delete'] : $lang['Deleted']) . '<br /><br />' . sprintf($lang['Click_return_topic'], '<a href="' . append_sid("viewtopic.$phpEx?" . POST_TOPIC_URL . "=$topic_id") . '">', '</a>');
536         }
538         $message .=  '<br /><br />' . sprintf($lang['Click_return_forum'], '<a href="' . append_sid("viewforum.$phpEx?" . POST_FORUM_URL . "=$forum_id") . '">', '</a>');
540         return;
543 //
544 // Handle user notification on new post
545 //
546 function user_notification($mode, &$post_data, &$topic_title, &$forum_id, &$topic_id, &$post_id, &$notify_user)
548         global $board_config, $lang, $db, $phpbb_root_path, $phpEx;
549         global $userdata, $user_ip;
551         $current_time = time();
553         if ($mode != 'delete')
554         {
555                 if ($mode == 'reply')
556                 {
557                         $sql = "SELECT ban_userid 
558                                 FROM " . BANLIST_TABLE;
559                         if (!($result = $db->sql_query($sql)))
560                         {
561                                 message_die(GENERAL_ERROR, 'Could not obtain banlist', '', __LINE__, __FILE__, $sql);
562                         }
564                         $user_id_sql = '';
565                         while ($row = $db->sql_fetchrow($result))
566                         {
567                                 if (isset($row['ban_userid']) && !empty($row['ban_userid']))
568                                 {
569                                         $user_id_sql .= ', ' . $row['ban_userid'];
570                                 }
571                         }
573                         $sql = "SELECT u.user_id, u.user_email, u.user_lang 
574                                 FROM " . TOPICS_WATCH_TABLE . " tw, " . USERS_TABLE . " u 
575                                 WHERE tw.topic_id = $topic_id 
576                                         AND tw.user_id NOT IN (" . $userdata['user_id'] . ", " . ANONYMOUS . $user_id_sql . ") 
577                                         AND tw.notify_status = " . TOPIC_WATCH_UN_NOTIFIED . " 
578                                         AND u.user_id = tw.user_id";
579                         if (!($result = $db->sql_query($sql)))
580                         {
581                                 message_die(GENERAL_ERROR, 'Could not obtain list of topic watchers', '', __LINE__, __FILE__, $sql);
582                         }
584                         $update_watched_sql = '';
585                         $bcc_list_ary = array();
586                         
587                         if ($row = $db->sql_fetchrow($result))
588                         {
589                                 // Sixty second limit
590                                 @set_time_limit(60);
592                                 do
593                                 {
594                                         if ($row['user_email'] != '')
595                                         {
596                                                 $bcc_list_ary[$row['user_lang']][] = $row['user_email'];
597                                         }
598                                         $update_watched_sql .= ($update_watched_sql != '') ? ', ' . $row['user_id'] : $row['user_id'];
599                                 }
600                                 while ($row = $db->sql_fetchrow($result));
602                                 //
603                                 // Let's do some checking to make sure that mass mail functions
604                                 // are working in win32 versions of php.
605                                 //
606                                 if (preg_match('/[c-z]:\\\.*/i', getenv('PATH')) && !$board_config['smtp_delivery'])
607                                 {
608                                         $ini_val = (@phpversion() >= '4.0.0') ? 'ini_get' : 'get_cfg_var';
610                                         // We are running on windows, force delivery to use our smtp functions
611                                         // since php's are broken by default
612                                         $board_config['smtp_delivery'] = 1;
613                                         $board_config['smtp_host'] = @$ini_val('SMTP');
614                                 }
616                                 if (sizeof($bcc_list_ary))
617                                 {
618                                         include($phpbb_root_path . 'includes/emailer.'.$phpEx);
619                                         $emailer = new emailer($board_config['smtp_delivery']);
621                                         $script_name = preg_replace('/^\/?(.*?)\/?$/', '\1', trim($board_config['script_path']));
622                                         $script_name = ($script_name != '') ? $script_name . '/viewtopic.'.$phpEx : 'viewtopic.'.$phpEx;
623                                         $server_name = trim($board_config['server_name']);
624                                         $server_protocol = ($board_config['cookie_secure']) ? 'https://' : 'http://';
625                                         $server_port = ($board_config['server_port'] <> 80) ? ':' . trim($board_config['server_port']) . '/' : '/';
627                                         $orig_word = array();
628                                         $replacement_word = array();
629                                         obtain_word_list($orig_word, $replacement_word);
631                                         $emailer->from($board_config['board_email']);
632                                         $emailer->replyto($board_config['board_email']);
634                                         $topic_title = (count($orig_word)) ? preg_replace($orig_word, $replacement_word, unprepare_message($topic_title)) : unprepare_message($topic_title);
636                                         @reset($bcc_list_ary);
637                                         while (list($user_lang, $bcc_list) = each($bcc_list_ary))
638                                         {
639                                                 $emailer->use_template('topic_notify', $user_lang);
640                 
641                                                 for ($i = 0; $i < count($bcc_list); $i++)
642                                                 {
643                                                         $emailer->bcc($bcc_list[$i]);
644                                                 }
646                                                 // The Topic_reply_notification lang string below will be used
647                                                 // if for some reason the mail template subject cannot be read 
648                                                 // ... note it will not necessarily be in the posters own language!
649                                                 $emailer->set_subject($lang['Topic_reply_notification']); 
650                                                 
651                                                 // This is a nasty kludge to remove the username var ... till (if?)
652                                                 // translators update their templates
653                                                 $emailer->msg = preg_replace('#[ ]?{USERNAME}#', '', $emailer->msg);
655                                                 $emailer->assign_vars(array(
656                                                         'EMAIL_SIG' => (!empty($board_config['board_email_sig'])) ? str_replace('<br />', "\n", "-- \n" . $board_config['board_email_sig']) : '',
657                                                         'SITENAME' => $board_config['sitename'],
658                                                         'TOPIC_TITLE' => $topic_title, 
660                                                         'U_TOPIC' => $server_protocol . $server_name . $server_port . $script_name . '?' . POST_POST_URL . "=$post_id#$post_id",
661                                                         'U_STOP_WATCHING_TOPIC' => $server_protocol . $server_name . $server_port . $script_name . '?' . POST_TOPIC_URL . "=$topic_id&unwatch=topic")
662                                                 );
664                                                 $emailer->send();
665                                                 $emailer->reset();
666                                         }
667                                 }
668                         }
669                         $db->sql_freeresult($result);
671                         if ($update_watched_sql != '')
672                         {
673                                 $sql = "UPDATE " . TOPICS_WATCH_TABLE . "
674                                         SET notify_status = " . TOPIC_WATCH_NOTIFIED . "
675                                         WHERE topic_id = $topic_id
676                                                 AND user_id IN ($update_watched_sql)";
677                                 $db->sql_query($sql);
678                         }
679                 }
681                 $sql = "SELECT topic_id 
682                         FROM " . TOPICS_WATCH_TABLE . "
683                         WHERE topic_id = $topic_id
684                                 AND user_id = " . $userdata['user_id'];
685                 if (!($result = $db->sql_query($sql)))
686                 {
687                         message_die(GENERAL_ERROR, 'Could not obtain topic watch information', '', __LINE__, __FILE__, $sql);
688                 }
690                 $row = $db->sql_fetchrow($result);
692                 if (!$notify_user && !empty($row['topic_id']))
693                 {
694                         $sql = "DELETE FROM " . TOPICS_WATCH_TABLE . "
695                                 WHERE topic_id = $topic_id
696                                         AND user_id = " . $userdata['user_id'];
697                         if (!$db->sql_query($sql))
698                         {
699                                 message_die(GENERAL_ERROR, 'Could not delete topic watch information', '', __LINE__, __FILE__, $sql);
700                         }
701                 }
702                 else if ($notify_user && empty($row['topic_id']))
703                 {
704                         $sql = "INSERT INTO " . TOPICS_WATCH_TABLE . " (user_id, topic_id, notify_status)
705                                 VALUES (" . $userdata['user_id'] . ", $topic_id, 0)";
706                         if (!$db->sql_query($sql))
707                         {
708                                 message_die(GENERAL_ERROR, 'Could not insert topic watch information', '', __LINE__, __FILE__, $sql);
709                         }
710                 }
711         }
714 //
715 // Fill smiley templates (or just the variables) with smileys
716 // Either in a window or inline
717 //
718 function generate_smilies($mode, $page_id)
720         global $db, $board_config, $template, $lang, $images, $theme, $phpEx, $phpbb_root_path;
721         global $user_ip, $session_length, $starttime;
722         global $userdata;
724         $inline_columns = 4;
725         $inline_rows = 5;
726         $window_columns = 8;
728         if ($mode == 'window')
729         {
730                 $userdata = session_pagestart($user_ip, $page_id);
731                 init_userprefs($userdata);
733                 $gen_simple_header = TRUE;
735                 $page_title = $lang['Emoticons'];
736                 include($phpbb_root_path . 'includes/page_header.'.$phpEx);
738                 $template->set_filenames(array(
739                         'smiliesbody' => 'posting_smilies.tpl')
740                 );
741         }
743         $sql = "SELECT emoticon, code, smile_url   
744                 FROM " . SMILIES_TABLE . " 
745                 ORDER BY smilies_id";
746         if ($result = $db->sql_query($sql))
747         {
748                 $num_smilies = 0;
749                 $rowset = array();
750                 while ($row = $db->sql_fetchrow($result))
751                 {
752                         if (empty($rowset[$row['smile_url']]))
753                         {
754                                 $rowset[$row['smile_url']]['code'] = str_replace("'", "\\'", str_replace('\\', '\\\\', $row['code']));
755                                 $rowset[$row['smile_url']]['emoticon'] = $row['emoticon'];
756                                 $num_smilies++;
757                         }
758                 }
760                 if ($num_smilies)
761                 {
762                         $smilies_count = ($mode == 'inline') ? min(19, $num_smilies) : $num_smilies;
763                         $smilies_split_row = ($mode == 'inline') ? $inline_columns - 1 : $window_columns - 1;
765                         $s_colspan = 0;
766                         $row = 0;
767                         $col = 0;
769                         while (list($smile_url, $data) = @each($rowset))
770                         {
771                                 if (!$col)
772                                 {
773                                         $template->assign_block_vars('smilies_row', array());
774                                 }
776                                 $template->assign_block_vars('smilies_row.smilies_col', array(
777                                         'SMILEY_CODE' => $data['code'],
778                                         'SMILEY_IMG' => $board_config['smilies_path'] . '/' . $smile_url,
779                                         'SMILEY_DESC' => $data['emoticon'])
780                                 );
782                                 $s_colspan = max($s_colspan, $col + 1);
784                                 if ($col == $smilies_split_row)
785                                 {
786                                         if ($mode == 'inline' && $row == $inline_rows - 1)
787                                         {
788                                                 break;
789                                         }
790                                         $col = 0;
791                                         $row++;
792                                 }
793                                 else
794                                 {
795                                         $col++;
796                                 }
797                         }
799                         if ($mode == 'inline' && $num_smilies > $inline_rows * $inline_columns)
800                         {
801                                 $template->assign_block_vars('switch_smilies_extra', array());
803                                 $template->assign_vars(array(
804                                         'L_MORE_SMILIES' => $lang['More_emoticons'], 
805                                         'U_MORE_SMILIES' => append_sid("posting.$phpEx?mode=smilies"))
806                                 );
807                         }
809                         $template->assign_vars(array(
810                                 'L_EMOTICONS' => $lang['Emoticons'], 
811                                 'L_CLOSE_WINDOW' => $lang['Close_window'], 
812                                 'S_SMILIES_COLSPAN' => $s_colspan)
813                         );
814                 }
815         }
817         if ($mode == 'window')
818         {
819                 $template->pparse('smiliesbody');
821                 include($phpbb_root_path . 'includes/page_tail.'.$phpEx);
822         }
825 /**
826 * Called from within prepare_message to clean included HTML tags if HTML is
827 * turned on for that post
828 * @param array $tag Matching text from the message to parse
829 */
830 function clean_html($tag)
832         global $board_config;
834         if (empty($tag[0]))
835         {
836                 return '';
837         }
839         $allowed_html_tags = preg_split('/, */', strtolower($board_config['allow_html_tags']));
840         $disallowed_attributes = '/^(?:style|on)/i';
842         // Check if this is an end tag
843         preg_match('/<[^\w\/]*\/[\W]*(\w+)/', $tag[0], $matches);
844         if (sizeof($matches))
845         {
846                 if (in_array(strtolower($matches[1]), $allowed_html_tags))
847                 {
848                         return  '</' . $matches[1] . '>';
849                 }
850                 else
851                 {
852                         return  htmlspecialchars('</' . $matches[1] . '>');
853                 }
854         }
856         // Check if this is an allowed tag
857         if (in_array(strtolower($tag[1]), $allowed_html_tags))
858         {
859                 $attributes = '';
860                 if (!empty($tag[2]))
861                 {
862                         preg_match_all('/[\W]*?(\w+)[\W]*?=[\W]*?(["\'])((?:(?!\2).)*)\2/', $tag[2], $test);
863                         for ($i = 0; $i < sizeof($test[0]); $i++)
864                         {
865                                 if (preg_match($disallowed_attributes, $test[1][$i]))
866                                 {
867                                         continue;
868                                 }
869                                 $attributes .= ' ' . $test[1][$i] . '=' . $test[2][$i] . str_replace(array('[', ']'), array('&#91;', '&#93;'), htmlspecialchars($test[3][$i])) . $test[2][$i];
870                         }
871                 }
872                 if (in_array(strtolower($tag[1]), $allowed_html_tags))
873                 {
874                         return '<' . $tag[1] . $attributes . '>';
875                 }
876                 else
877                 {
878                         return htmlspecialchars('<' . $tag[1] . $attributes . '>');
879                 }
880         }
881         // Finally, this is not an allowed tag so strip all the attibutes and escape it
882         else
883         {
884                 return htmlspecialchars('<' .   $tag[1] . '>');
885         }
887 ?>