[ Index ] |
|
Code source de PunBB 1.2.16 |
1 <?php 2 /*********************************************************************** 3 4 Copyright (C) 2002-2005 Rickard Andersson (rickard@punbb.org) 5 6 This file is part of PunBB. 7 8 PunBB is free software; you can redistribute it and/or modify it 9 under the terms of the GNU General Public License as published 10 by the Free Software Foundation; either version 2 of the License, 11 or (at your option) any later version. 12 13 PunBB is distributed in the hope that it will be useful, but 14 WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 MA 02111-1307 USA 22 23 ************************************************************************/ 24 25 // 26 // Cookie stuff! 27 // 28 function check_cookie(&$pun_user) 29 { 30 global $db, $db_type, $pun_config, $cookie_name, $cookie_seed; 31 32 $now = time(); 33 $expire = $now + 31536000; // The cookie expires after a year 34 35 // We assume it's a guest 36 $cookie = array('user_id' => 1, 'password_hash' => 'Invité'); 37 38 // If a cookie is set, we get the user_id and password hash from it 39 if (isset($_COOKIE[$cookie_name])) 40 list($cookie['user_id'], $cookie['password_hash']) = @unserialize($_COOKIE[$cookie_name]); 41 42 if ($cookie['user_id'] > 1) 43 { 44 // Check if there's a user with the user ID and password hash from the cookie 45 $result = $db->query('SELECT u.*, g.*, o.logged, o.idle FROM '.$db->prefix.'users AS u INNER JOIN '.$db->prefix.'groups AS g ON u.group_id=g.g_id LEFT JOIN '.$db->prefix.'online AS o ON o.user_id=u.id WHERE u.id='.intval($cookie['user_id'])) or error('Unable to fetch user information', __FILE__, __LINE__, $db->error()); 46 $pun_user = $db->fetch_assoc($result); 47 48 // If user authorisation failed 49 if (!isset($pun_user['id']) || md5($cookie_seed.$pun_user['password']) !== $cookie['password_hash']) 50 { 51 pun_setcookie(0, random_pass(8), $expire); 52 set_default_user(); 53 54 return; 55 } 56 57 // Set a default language if the user selected language no longer exists 58 if (!@file_exists(PUN_ROOT.'lang/'.$pun_user['language'])) 59 $pun_user['language'] = $pun_config['o_default_lang']; 60 61 // Set a default style if the user selected style no longer exists 62 if (!@file_exists(PUN_ROOT.'style/'.$pun_user['style'].'.css')) 63 $pun_user['style'] = $pun_config['o_default_style']; 64 65 if (!$pun_user['disp_topics']) 66 $pun_user['disp_topics'] = $pun_config['o_disp_topics_default']; 67 if (!$pun_user['disp_posts']) 68 $pun_user['disp_posts'] = $pun_config['o_disp_posts_default']; 69 70 if ($pun_user['save_pass'] == '0') 71 $expire = 0; 72 73 // Define this if you want this visit to affect the online list and the users last visit data 74 if (!defined('PUN_QUIET_VISIT')) 75 { 76 // Update the online list 77 if (!$pun_user['logged']) 78 { 79 $pun_user['logged'] = $now; 80 81 // With MySQL/MySQLi, REPLACE INTO avoids a user having two rows in the online table 82 switch ($db_type) 83 { 84 case 'mysql': 85 case 'mysqli': 86 $db->query('REPLACE INTO '.$db->prefix.'online (user_id, ident, logged) VALUES('.$pun_user['id'].', \''.$db->escape($pun_user['username']).'\', '.$pun_user['logged'].')') or error('Unable to insert into online list', __FILE__, __LINE__, $db->error()); 87 break; 88 89 default: 90 $db->query('INSERT INTO '.$db->prefix.'online (user_id, ident, logged) VALUES('.$pun_user['id'].', \''.$db->escape($pun_user['username']).'\', '.$pun_user['logged'].')') or error('Unable to insert into online list', __FILE__, __LINE__, $db->error()); 91 break; 92 } 93 } 94 else 95 { 96 // Special case: We've timed out, but no other user has browsed the forums since we timed out 97 if ($pun_user['logged'] < ($now-$pun_config['o_timeout_visit'])) 98 { 99 $db->query('UPDATE '.$db->prefix.'users SET last_visit='.$pun_user['logged'].' WHERE id='.$pun_user['id']) or error('Unable to update user visit data', __FILE__, __LINE__, $db->error()); 100 $pun_user['last_visit'] = $pun_user['logged']; 101 } 102 103 $idle_sql = ($pun_user['idle'] == '1') ? ', idle=0' : ''; 104 $db->query('UPDATE '.$db->prefix.'online SET logged='.$now.$idle_sql.' WHERE user_id='.$pun_user['id']) or error('Unable to update online list', __FILE__, __LINE__, $db->error()); 105 } 106 } 107 108 $pun_user['is_guest'] = false; 109 } 110 else 111 set_default_user(); 112 } 113 114 115 // 116 // Fill $pun_user with default values (for guests) 117 // 118 function set_default_user() 119 { 120 global $db, $db_type, $pun_user, $pun_config; 121 122 $remote_addr = get_remote_address(); 123 124 // Fetch guest user 125 $result = $db->query('SELECT u.*, g.*, o.logged FROM '.$db->prefix.'users AS u INNER JOIN '.$db->prefix.'groups AS g ON u.group_id=g.g_id LEFT JOIN '.$db->prefix.'online AS o ON o.ident=\''.$remote_addr.'\' WHERE u.id=1') or error('Unable to fetch guest information', __FILE__, __LINE__, $db->error()); 126 if (!$db->num_rows($result)) 127 exit('Impossible de retrouver les informations invité. La table \''.$db->prefix.'users\' doit contenir une entrée avec un id = 1 qui représente les utilisateurs anonymes.'); 128 129 $pun_user = $db->fetch_assoc($result); 130 131 // Update online list 132 if (!$pun_user['logged']) 133 { 134 $pun_user['logged'] = time(); 135 136 // With MySQL/MySQLi, REPLACE INTO avoids a user having two rows in the online table 137 switch ($db_type) 138 { 139 case 'mysql': 140 case 'mysqli': 141 $db->query('REPLACE INTO '.$db->prefix.'online (user_id, ident, logged) VALUES(1, \''.$db->escape($remote_addr).'\', '.$pun_user['logged'].')') or error('Unable to insert into online list', __FILE__, __LINE__, $db->error()); 142 break; 143 144 default: 145 $db->query('INSERT INTO '.$db->prefix.'online (user_id, ident, logged) VALUES(1, \''.$db->escape($remote_addr).'\', '.$pun_user['logged'].')') or error('Unable to insert into online list', __FILE__, __LINE__, $db->error()); 146 break; 147 } 148 } 149 else 150 $db->query('UPDATE '.$db->prefix.'online SET logged='.time().' WHERE ident=\''.$db->escape($remote_addr).'\'') or error('Unable to update online list', __FILE__, __LINE__, $db->error()); 151 152 $pun_user['disp_topics'] = $pun_config['o_disp_topics_default']; 153 $pun_user['disp_posts'] = $pun_config['o_disp_posts_default']; 154 $pun_user['timezone'] = $pun_config['o_server_timezone']; 155 $pun_user['language'] = $pun_config['o_default_lang']; 156 $pun_user['style'] = $pun_config['o_default_style']; 157 $pun_user['is_guest'] = true; 158 } 159 160 161 // 162 // Set a cookie, PunBB style! 163 // 164 function pun_setcookie($user_id, $password_hash, $expire) 165 { 166 global $cookie_name, $cookie_path, $cookie_domain, $cookie_secure, $cookie_seed; 167 168 // Enable sending of a P3P header by removing // from the following line (try this if login is failing in IE6) 169 // @header('P3P: CP="CUR ADM"'); 170 171 if (version_compare(PHP_VERSION, '5.2.0', '>=')) 172 setcookie($cookie_name, serialize(array($user_id, md5($cookie_seed.$password_hash))), $expire, $cookie_path, $cookie_domain, $cookie_secure, true); 173 else 174 setcookie($cookie_name, serialize(array($user_id, md5($cookie_seed.$password_hash))), $expire, $cookie_path.'; HttpOnly', $cookie_domain, $cookie_secure); 175 } 176 177 178 // 179 // Check whether the connecting user is banned (and delete any expired bans while we're at it) 180 // 181 function check_bans() 182 { 183 global $db, $pun_config, $lang_common, $pun_user, $pun_bans; 184 185 // Admins aren't affected 186 if ($pun_user['g_id'] == PUN_ADMIN || !$pun_bans) 187 return; 188 189 // Add a dot at the end of the IP address to prevent banned address 192.168.0.5 from matching e.g. 192.168.0.50 190 $user_ip = get_remote_address().'.'; 191 $bans_altered = false; 192 193 foreach ($pun_bans as $cur_ban) 194 { 195 // Has this ban expired? 196 if ($cur_ban['expire'] != '' && $cur_ban['expire'] <= time()) 197 { 198 $db->query('DELETE FROM '.$db->prefix.'bans WHERE id='.$cur_ban['id']) or error('Unable to delete expired ban', __FILE__, __LINE__, $db->error()); 199 $bans_altered = true; 200 continue; 201 } 202 203 if ($cur_ban['username'] != '' && !strcasecmp($pun_user['username'], $cur_ban['username'])) 204 { 205 $db->query('DELETE FROM '.$db->prefix.'online WHERE ident=\''.$db->escape($pun_user['username']).'\'') or error('Unable to delete from online list', __FILE__, __LINE__, $db->error()); 206 message($lang_common['Ban message'].' '.(($cur_ban['expire'] != '') ? $lang_common['Ban message 2'].' '.strtolower(format_time($cur_ban['expire'], true)).'. ' : '').(($cur_ban['message'] != '') ? $lang_common['Ban message 3'].'<br /><br /><strong>'.pun_htmlspecialchars($cur_ban['message']).'</strong><br /><br />' : '<br /><br />').$lang_common['Ban message 4'].' <a href="mailto:'.$pun_config['o_admin_email'].'">'.$pun_config['o_admin_email'].'</a>.', true); 207 } 208 209 if ($cur_ban['ip'] != '') 210 { 211 $cur_ban_ips = explode(' ', $cur_ban['ip']); 212 213 for ($i = 0; $i < count($cur_ban_ips); ++$i) 214 { 215 $cur_ban_ips[$i] = $cur_ban_ips[$i].'.'; 216 217 if (substr($user_ip, 0, strlen($cur_ban_ips[$i])) == $cur_ban_ips[$i]) 218 { 219 $db->query('DELETE FROM '.$db->prefix.'online WHERE ident=\''.$db->escape($pun_user['username']).'\'') or error('Unable to delete from online list', __FILE__, __LINE__, $db->error()); 220 message($lang_common['Ban message'].' '.(($cur_ban['expire'] != '') ? $lang_common['Ban message 2'].' '.strtolower(format_time($cur_ban['expire'], true)).'. ' : '').(($cur_ban['message'] != '') ? $lang_common['Ban message 3'].'<br /><br /><strong>'.pun_htmlspecialchars($cur_ban['message']).'</strong><br /><br />' : '<br /><br />').$lang_common['Ban message 4'].' <a href="mailto:'.$pun_config['o_admin_email'].'">'.$pun_config['o_admin_email'].'</a>.', true); 221 } 222 } 223 } 224 } 225 226 // If we removed any expired bans during our run-through, we need to regenerate the bans cache 227 if ($bans_altered) 228 { 229 require_once PUN_ROOT.'include/cache.php'; 230 generate_bans_cache(); 231 } 232 } 233 234 235 // 236 // Update "Users online" 237 // 238 function update_users_online() 239 { 240 global $db, $pun_config, $pun_user; 241 242 $now = time(); 243 244 // Fetch all online list entries that are older than "o_timeout_online" 245 $result = $db->query('SELECT * FROM '.$db->prefix.'online WHERE logged<'.($now-$pun_config['o_timeout_online'])) or error('Unable to fetch old entries from online list', __FILE__, __LINE__, $db->error()); 246 while ($cur_user = $db->fetch_assoc($result)) 247 { 248 // If the entry is a guest, delete it 249 if ($cur_user['user_id'] == '1') 250 $db->query('DELETE FROM '.$db->prefix.'online WHERE ident=\''.$db->escape($cur_user['ident']).'\'') or error('Unable to delete from online list', __FILE__, __LINE__, $db->error()); 251 else 252 { 253 // If the entry is older than "o_timeout_visit", update last_visit for the user in question, then delete him/her from the online list 254 if ($cur_user['logged'] < ($now-$pun_config['o_timeout_visit'])) 255 { 256 $db->query('UPDATE '.$db->prefix.'users SET last_visit='.$cur_user['logged'].' WHERE id='.$cur_user['user_id']) or error('Unable to update user visit data', __FILE__, __LINE__, $db->error()); 257 $db->query('DELETE FROM '.$db->prefix.'online WHERE user_id='.$cur_user['user_id']) or error('Unable to delete from online list', __FILE__, __LINE__, $db->error()); 258 } 259 else if ($cur_user['idle'] == '0') 260 $db->query('UPDATE '.$db->prefix.'online SET idle=1 WHERE user_id='.$cur_user['user_id']) or error('Unable to insert into online list', __FILE__, __LINE__, $db->error()); 261 } 262 } 263 } 264 265 266 // 267 // Generate the "navigator" that appears at the top of every page 268 // 269 function generate_navlinks() 270 { 271 global $pun_config, $lang_common, $pun_user; 272 273 // Index and Userlist should always be displayed 274 $links[] = '<li id="navindex"><a href="index.php">'.$lang_common['Index'].'</a>'; 275 $links[] = '<li id="navuserlist"><a href="userlist.php">'.$lang_common['User list'].'</a>'; 276 277 if ($pun_config['o_rules'] == '1') 278 $links[] = '<li id="navrules"><a href="misc.php?action=rules">'.$lang_common['Rules'].'</a>'; 279 280 if ($pun_user['is_guest']) 281 { 282 if ($pun_user['g_search'] == '1') 283 $links[] = '<li id="navsearch"><a href="search.php">'.$lang_common['Search'].'</a>'; 284 285 $links[] = '<li id="navregister"><a href="register.php">'.$lang_common['Register'].'</a>'; 286 $links[] = '<li id="navlogin"><a href="login.php">'.$lang_common['Login'].'</a>'; 287 288 $info = $lang_common['Not logged in']; 289 } 290 else 291 { 292 if ($pun_user['g_id'] > PUN_MOD) 293 { 294 if ($pun_user['g_search'] == '1') 295 $links[] = '<li id="navsearch"><a href="search.php">'.$lang_common['Search'].'</a>'; 296 297 $links[] = '<li id="navprofile"><a href="profile.php?id='.$pun_user['id'].'">'.$lang_common['Profile'].'</a>'; 298 $links[] = '<li id="navlogout"><a href="login.php?action=out&id='.$pun_user['id'].'">'.$lang_common['Logout'].'</a>'; 299 } 300 else 301 { 302 $links[] = '<li id="navsearch"><a href="search.php">'.$lang_common['Search'].'</a>'; 303 $links[] = '<li id="navprofile"><a href="profile.php?id='.$pun_user['id'].'">'.$lang_common['Profile'].'</a>'; 304 $links[] = '<li id="navadmin"><a href="admin_index.php">'.$lang_common['Admin'].'</a>'; 305 $links[] = '<li id="navlogout"><a href="login.php?action=out&id='.$pun_user['id'].'">'.$lang_common['Logout'].'</a>'; 306 } 307 } 308 309 // Are there any additional navlinks we should insert into the array before imploding it? 310 if ($pun_config['o_additional_navlinks'] != '') 311 { 312 if (preg_match_all('#([0-9]+)\s*=\s*(.*?)\n#s', $pun_config['o_additional_navlinks']."\n", $extra_links)) 313 { 314 // Insert any additional links into the $links array (at the correct index) 315 for ($i = 0; $i < count($extra_links[1]); ++$i) 316 array_splice($links, $extra_links[1][$i], 0, array('<li id="navextra'.($i + 1).'">'.$extra_links[2][$i])); 317 } 318 } 319 320 return '<ul>'."\n\t\t\t\t".implode($lang_common['Link separator'].'</li>'."\n\t\t\t\t", $links).'</li>'."\n\t\t\t".'</ul>'; 321 } 322 323 324 // 325 // Display the profile navigation menu 326 // 327 function generate_profile_menu($page = '') 328 { 329 global $lang_profile, $pun_config, $pun_user, $id; 330 331 ?> 332 <div id="profile" class="block2col"> 333 <div class="blockmenu"> 334 <h2><span><?php echo $lang_profile['Profile menu'] ?></span></h2> 335 <div class="box"> 336 <div class="inbox"> 337 <ul> 338 <li<?php if ($page == 'essentials') echo ' class="isactive"'; ?>><a href="profile.php?section=essentials&id=<?php echo $id ?>"><?php echo $lang_profile['Section essentials'] ?></a></li> 339 <li<?php if ($page == 'personal') echo ' class="isactive"'; ?>><a href="profile.php?section=personal&id=<?php echo $id ?>"><?php echo $lang_profile['Section personal'] ?></a></li> 340 <li<?php if ($page == 'messaging') echo ' class="isactive"'; ?>><a href="profile.php?section=messaging&id=<?php echo $id ?>"><?php echo $lang_profile['Section messaging'] ?></a></li> 341 <li<?php if ($page == 'personality') echo ' class="isactive"'; ?>><a href="profile.php?section=personality&id=<?php echo $id ?>"><?php echo $lang_profile['Section personality'] ?></a></li> 342 <li<?php if ($page == 'display') echo ' class="isactive"'; ?>><a href="profile.php?section=display&id=<?php echo $id ?>"><?php echo $lang_profile['Section display'] ?></a></li> 343 <li<?php if ($page == 'privacy') echo ' class="isactive"'; ?>><a href="profile.php?section=privacy&id=<?php echo $id ?>"><?php echo $lang_profile['Section privacy'] ?></a></li> 344 <?php if ($pun_user['g_id'] == PUN_ADMIN || ($pun_user['g_id'] == PUN_MOD && $pun_config['p_mod_ban_users'] == '1')): ?> <li<?php if ($page == 'admin') echo ' class="isactive"'; ?>><a href="profile.php?section=admin&id=<?php echo $id ?>"><?php echo $lang_profile['Section admin'] ?></a></li> 345 <?php endif; ?> </ul> 346 </div> 347 </div> 348 </div> 349 <?php 350 351 } 352 353 354 // 355 // Update posts, topics, last_post, last_post_id and last_poster for a forum 356 // 357 function update_forum($forum_id) 358 { 359 global $db; 360 361 $result = $db->query('SELECT COUNT(id), SUM(num_replies) FROM '.$db->prefix.'topics WHERE forum_id='.$forum_id) or error('Unable to fetch forum topic count', __FILE__, __LINE__, $db->error()); 362 list($num_topics, $num_posts) = $db->fetch_row($result); 363 364 $num_posts = $num_posts + $num_topics; // $num_posts is only the sum of all replies (we have to add the topic posts) 365 366 $result = $db->query('SELECT last_post, last_post_id, last_poster FROM '.$db->prefix.'topics WHERE forum_id='.$forum_id.' AND moved_to IS NULL ORDER BY last_post DESC LIMIT 1') or error('Unable to fetch last_post/last_post_id/last_poster', __FILE__, __LINE__, $db->error()); 367 if ($db->num_rows($result)) // There are topics in the forum 368 { 369 list($last_post, $last_post_id, $last_poster) = $db->fetch_row($result); 370 371 $db->query('UPDATE '.$db->prefix.'forums SET num_topics='.$num_topics.', num_posts='.$num_posts.', last_post='.$last_post.', last_post_id='.$last_post_id.', last_poster=\''.$db->escape($last_poster).'\' WHERE id='.$forum_id) or error('Unable to update last_post/last_post_id/last_poster', __FILE__, __LINE__, $db->error()); 372 } 373 else // There are no topics 374 $db->query('UPDATE '.$db->prefix.'forums SET num_topics='.$num_topics.', num_posts='.$num_posts.', last_post=NULL, last_post_id=NULL, last_poster=NULL WHERE id='.$forum_id) or error('Unable to update last_post/last_post_id/last_poster', __FILE__, __LINE__, $db->error()); 375 } 376 377 378 // 379 // Delete a topic and all of it's posts 380 // 381 function delete_topic($topic_id) 382 { 383 global $db; 384 385 // Delete the topic and any redirect topics 386 $db->query('DELETE FROM '.$db->prefix.'topics WHERE id='.$topic_id.' OR moved_to='.$topic_id) or error('Unable to delete topic', __FILE__, __LINE__, $db->error()); 387 388 // Create a list of the post ID's in this topic 389 $post_ids = ''; 390 $result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE topic_id='.$topic_id) or error('Unable to fetch posts', __FILE__, __LINE__, $db->error()); 391 while ($row = $db->fetch_row($result)) 392 $post_ids .= ($post_ids != '') ? ','.$row[0] : $row[0]; 393 394 // Make sure we have a list of post ID's 395 if ($post_ids != '') 396 { 397 strip_search_index($post_ids); 398 399 // Delete posts in topic 400 $db->query('DELETE FROM '.$db->prefix.'posts WHERE topic_id='.$topic_id) or error('Unable to delete posts', __FILE__, __LINE__, $db->error()); 401 } 402 403 // Delete any subscriptions for this topic 404 $db->query('DELETE FROM '.$db->prefix.'subscriptions WHERE topic_id='.$topic_id) or error('Unable to delete subscriptions', __FILE__, __LINE__, $db->error()); 405 } 406 407 408 // 409 // Delete a single post 410 // 411 function delete_post($post_id, $topic_id) 412 { 413 global $db; 414 415 $result = $db->query('SELECT id, poster, posted FROM '.$db->prefix.'posts WHERE topic_id='.$topic_id.' ORDER BY id DESC LIMIT 2') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); 416 list($last_id, ,) = $db->fetch_row($result); 417 list($second_last_id, $second_poster, $second_posted) = $db->fetch_row($result); 418 419 // Delete the post 420 $db->query('DELETE FROM '.$db->prefix.'posts WHERE id='.$post_id) or error('Unable to delete post', __FILE__, __LINE__, $db->error()); 421 422 strip_search_index($post_id); 423 424 // Count number of replies in the topic 425 $result = $db->query('SELECT COUNT(id) FROM '.$db->prefix.'posts WHERE topic_id='.$topic_id) or error('Unable to fetch post count for topic', __FILE__, __LINE__, $db->error()); 426 $num_replies = $db->result($result, 0) - 1; 427 428 // If the message we deleted is the most recent in the topic (at the end of the topic) 429 if ($last_id == $post_id) 430 { 431 // If there is a $second_last_id there is more than 1 reply to the topic 432 if (!empty($second_last_id)) 433 $db->query('UPDATE '.$db->prefix.'topics SET last_post='.$second_posted.', last_post_id='.$second_last_id.', last_poster=\''.$db->escape($second_poster).'\', num_replies='.$num_replies.' WHERE id='.$topic_id) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); 434 else 435 // We deleted the only reply, so now last_post/last_post_id/last_poster is posted/id/poster from the topic itself 436 $db->query('UPDATE '.$db->prefix.'topics SET last_post=posted, last_post_id=id, last_poster=poster, num_replies='.$num_replies.' WHERE id='.$topic_id) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); 437 } 438 else 439 // Otherwise we just decrement the reply counter 440 $db->query('UPDATE '.$db->prefix.'topics SET num_replies='.$num_replies.' WHERE id='.$topic_id) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); 441 } 442 443 444 // 445 // Replace censored words in $text 446 // 447 function censor_words($text) 448 { 449 global $db; 450 static $search_for, $replace_with; 451 452 // If not already built in a previous call, build an array of censor words and their replacement text 453 if (!isset($search_for)) 454 { 455 $result = $db->query('SELECT search_for, replace_with FROM '.$db->prefix.'censoring') or error('Unable to fetch censor word list', __FILE__, __LINE__, $db->error()); 456 $num_words = $db->num_rows($result); 457 458 $search_for = array(); 459 for ($i = 0; $i < $num_words; ++$i) 460 { 461 list($search_for[$i], $replace_with[$i]) = $db->fetch_row($result); 462 $search_for[$i] = '/\b('.str_replace('\*', '\w*?', preg_quote($search_for[$i], '/')).')\b/i'; 463 } 464 } 465 466 if (!empty($search_for)) 467 $text = substr(preg_replace($search_for, $replace_with, ' '.$text.' '), 1, -1); 468 469 return $text; 470 } 471 472 473 // 474 // Determines the correct title for $user 475 // $user must contain the elements 'username', 'title', 'posts', 'g_id' and 'g_user_title' 476 // 477 function get_title($user) 478 { 479 global $db, $pun_config, $pun_bans, $lang_common; 480 static $ban_list, $pun_ranks; 481 482 // If not already built in a previous call, build an array of lowercase banned usernames 483 if (empty($ban_list)) 484 { 485 $ban_list = array(); 486 487 foreach ($pun_bans as $cur_ban) 488 $ban_list[] = strtolower($cur_ban['username']); 489 } 490 491 // If not already loaded in a previous call, load the cached ranks 492 if ($pun_config['o_ranks'] == '1' && empty($pun_ranks)) 493 { 494 @include PUN_ROOT.'cache/cache_ranks.php'; 495 if (!defined('PUN_RANKS_LOADED')) 496 { 497 require_once PUN_ROOT.'include/cache.php'; 498 generate_ranks_cache(); 499 require PUN_ROOT.'cache/cache_ranks.php'; 500 } 501 } 502 503 // If the user has a custom title 504 if ($user['title'] != '') 505 $user_title = pun_htmlspecialchars($user['title']); 506 // If the user is banned 507 else if (in_array(strtolower($user['username']), $ban_list)) 508 $user_title = $lang_common['Banned']; 509 // If the user group has a default user title 510 else if ($user['g_user_title'] != '') 511 $user_title = pun_htmlspecialchars($user['g_user_title']); 512 // If the user is a guest 513 else if ($user['g_id'] == PUN_GUEST) 514 $user_title = $lang_common['Guest']; 515 else 516 { 517 // Are there any ranks? 518 if ($pun_config['o_ranks'] == '1' && !empty($pun_ranks)) 519 { 520 @reset($pun_ranks); 521 while (list(, $cur_rank) = @each($pun_ranks)) 522 { 523 if (intval($user['num_posts']) >= $cur_rank['min_posts']) 524 $user_title = pun_htmlspecialchars($cur_rank['rank']); 525 } 526 } 527 528 // If the user didn't "reach" any rank (or if ranks are disabled), we assign the default 529 if (!isset($user_title)) 530 $user_title = $lang_common['Member']; 531 } 532 533 return $user_title; 534 } 535 536 537 // 538 // Generate a string with numbered links (for multipage scripts) 539 // 540 function paginate($num_pages, $cur_page, $link_to) 541 { 542 $pages = array(); 543 $link_to_all = false; 544 545 // If $cur_page == -1, we link to all pages (used in viewforum.php) 546 if ($cur_page == -1) 547 { 548 $cur_page = 1; 549 $link_to_all = true; 550 } 551 552 if ($num_pages <= 1) 553 $pages = array('<strong>1</strong>'); 554 else 555 { 556 if ($cur_page > 3) 557 { 558 $pages[] = '<a href="'.$link_to.'&p=1">1</a>'; 559 560 if ($cur_page != 4) 561 $pages[] = '…'; 562 } 563 564 // Don't ask me how the following works. It just does, OK? :-) 565 for ($current = $cur_page - 2, $stop = $cur_page + 3; $current < $stop; ++$current) 566 { 567 if ($current < 1 || $current > $num_pages) 568 continue; 569 else if ($current != $cur_page || $link_to_all) 570 $pages[] = '<a href="'.$link_to.'&p='.$current.'">'.$current.'</a>'; 571 else 572 $pages[] = '<strong>'.$current.'</strong>'; 573 } 574 575 if ($cur_page <= ($num_pages-3)) 576 { 577 if ($cur_page != ($num_pages-3)) 578 $pages[] = '…'; 579 580 $pages[] = '<a href="'.$link_to.'&p='.$num_pages.'">'.$num_pages.'</a>'; 581 } 582 } 583 584 return implode(' ', $pages); 585 } 586 587 588 // 589 // Display a message 590 // 591 function message($message, $no_back_link = false) 592 { 593 global $db, $lang_common, $pun_config, $pun_start, $tpl_main; 594 595 if (!defined('PUN_HEADER')) 596 { 597 global $pun_user; 598 599 $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Info']; 600 require PUN_ROOT.'header.php'; 601 } 602 603 ?> 604 605 <div id="msg" class="block"> 606 <h2><span><?php echo $lang_common['Info'] ?></span></h2> 607 <div class="box"> 608 <div class="inbox"> 609 <p><?php echo $message ?></p> 610 <?php if (!$no_back_link): ?> <p><a href="javascript: history.go(-1)"><?php echo $lang_common['Go back'] ?></a></p> 611 <?php endif; ?> </div> 612 </div> 613 </div> 614 <?php 615 616 require PUN_ROOT.'footer.php'; 617 } 618 619 620 // 621 // Format a time string according to $time_format and timezones 622 // 623 function format_time($timestamp, $date_only = false) 624 { 625 global $pun_config, $lang_common, $pun_user; 626 627 if ($timestamp == '') 628 return $lang_common['Never']; 629 630 $diff = ($pun_user['timezone'] - $pun_config['o_server_timezone']) * 3600; 631 $timestamp += $diff; 632 $now = time(); 633 634 $date = date($pun_config['o_date_format'], $timestamp); 635 $today = date($pun_config['o_date_format'], $now+$diff); 636 $yesterday = date($pun_config['o_date_format'], $now+$diff-86400); 637 638 if ($date == $today) 639 $date = $lang_common['Today']; 640 else if ($date == $yesterday) 641 $date = $lang_common['Yesterday']; 642 643 if (!$date_only) 644 return $date.' '.date($pun_config['o_time_format'], $timestamp); 645 else 646 return $date; 647 } 648 649 650 // 651 // If we are running pre PHP 4.3.0, we add our own implementation of file_get_contents 652 // 653 if (!function_exists('file_get_contents')) 654 { 655 function file_get_contents($filename, $use_include_path = 0) 656 { 657 $data = ''; 658 659 if ($fh = fopen($filename, 'rb', $use_include_path)) 660 { 661 $data = fread($fh, filesize($filename)); 662 fclose($fh); 663 } 664 665 return $data; 666 } 667 } 668 669 670 // 671 // Make sure that HTTP_REFERER matches $pun_config['o_base_url']/$script 672 // 673 function confirm_referrer($script) 674 { 675 global $pun_config, $lang_common; 676 677 if (!preg_match('#^'.preg_quote(str_replace('www.', '', $pun_config['o_base_url']).'/'.$script, '#').'#i', str_replace('www.', '', (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '')))) 678 message($lang_common['Bad referrer']); 679 } 680 681 682 // 683 // Generate a random password of length $len 684 // 685 function random_pass($len) 686 { 687 $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; 688 689 $password = ''; 690 for ($i = 0; $i < $len; ++$i) 691 $password .= substr($chars, (mt_rand() % strlen($chars)), 1); 692 693 return $password; 694 } 695 696 697 // 698 // Compute a hash of $str 699 // Uses sha1() if available. If not, SHA1 through mhash() if available. If not, fall back on md5(). 700 // 701 function pun_hash($str) 702 { 703 if (function_exists('sha1')) // Only in PHP 4.3.0+ 704 return sha1($str); 705 else if (function_exists('mhash')) // Only if Mhash library is loaded 706 return bin2hex(mhash(MHASH_SHA1, $str)); 707 else 708 return md5($str); 709 } 710 711 712 // 713 // Try to determine the correct remote IP-address 714 // 715 function get_remote_address() 716 { 717 return $_SERVER['REMOTE_ADDR']; 718 } 719 720 721 // 722 // Equivalent to htmlspecialchars(), but allows &#[0-9]+ (for unicode) 723 // 724 function pun_htmlspecialchars($str) 725 { 726 $str = preg_replace('/&(?!#[0-9]+;)/s', '&', $str); 727 $str = str_replace(array('<', '>', '"'), array('<', '>', '"'), $str); 728 729 return $str; 730 } 731 732 733 // 734 // Equivalent to strlen(), but counts &#[0-9]+ as one character (for unicode) 735 // 736 function pun_strlen($str) 737 { 738 return strlen(preg_replace('/&#([0-9]+);/', '!', $str)); 739 } 740 741 742 // 743 // Convert \r\n and \r to \n 744 // 745 function pun_linebreaks($str) 746 { 747 return str_replace("\r", "\n", str_replace("\r\n", "\n", $str)); 748 } 749 750 751 // 752 // A more aggressive version of trim() 753 // 754 function pun_trim($str) 755 { 756 global $lang_common; 757 758 if (strpos($lang_common['lang_encoding'], '8859') !== false) 759 { 760 $fishy_chars = array(chr(0x81), chr(0x8D), chr(0x8F), chr(0x90), chr(0x9D), chr(0xA0)); 761 return trim(str_replace($fishy_chars, ' ', $str)); 762 } 763 else 764 return trim($str); 765 } 766 767 768 // 769 // Display a message when board is in maintenance mode 770 // 771 function maintenance_message() 772 { 773 global $db, $pun_config, $lang_common, $pun_user; 774 775 // Deal with newlines, tabs and multiple spaces 776 $pattern = array("\t", ' ', ' '); 777 $replace = array(' ', ' ', ' '); 778 $message = str_replace($pattern, $replace, $pun_config['o_maintenance_message']); 779 780 781 // Load the maintenance template 782 $tpl_maint = trim(file_get_contents(PUN_ROOT.'include/template/maintenance.tpl')); 783 784 785 // START SUBST - <pun_include "*"> 786 while (preg_match('#<pun_include "([^/\\\\]*?)\.(php[45]?|inc|html?|txt)">#', $tpl_maint, $cur_include)) 787 { 788 if (!file_exists(PUN_ROOT.'include/user/'.$cur_include[1].'.'.$cur_include[2])) 789 error('Unable to process user include '.htmlspecialchars($cur_include[0]).' from template maintenance.tpl. There is no such file in folder /include/user/'); 790 791 ob_start(); 792 include PUN_ROOT.'include/user/'.$cur_include[1].'.'.$cur_include[2]; 793 $tpl_temp = ob_get_contents(); 794 $tpl_maint = str_replace($cur_include[0], $tpl_temp, $tpl_maint); 795 ob_end_clean(); 796 } 797 // END SUBST - <pun_include "*"> 798 799 800 // START SUBST - <pun_content_direction> 801 $tpl_maint = str_replace('<pun_content_direction>', $lang_common['lang_direction'], $tpl_maint); 802 // END SUBST - <pun_content_direction> 803 804 805 // START SUBST - <pun_char_encoding> 806 $tpl_maint = str_replace('<pun_char_encoding>', $lang_common['lang_encoding'], $tpl_maint); 807 // END SUBST - <pun_char_encoding> 808 809 810 // START SUBST - <pun_head> 811 ob_start(); 812 813 ?> 814 <title><?php echo pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Maintenance'] ?></title> 815 <link rel="stylesheet" type="text/css" href="style/<?php echo $pun_user['style'].'.css' ?>" /> 816 <?php 817 818 $tpl_temp = trim(ob_get_contents()); 819 $tpl_maint = str_replace('<pun_head>', $tpl_temp, $tpl_maint); 820 ob_end_clean(); 821 // END SUBST - <pun_head> 822 823 824 // START SUBST - <pun_maint_heading> 825 $tpl_maint = str_replace('<pun_maint_heading>', $lang_common['Maintenance'], $tpl_maint); 826 // END SUBST - <pun_maint_heading> 827 828 829 // START SUBST - <pun_maint_message> 830 $tpl_maint = str_replace('<pun_maint_message>', $message, $tpl_maint); 831 // END SUBST - <pun_maint_message> 832 833 834 // End the transaction 835 $db->end_transaction(); 836 837 838 // Close the db connection (and free up any result data) 839 $db->close(); 840 841 exit($tpl_maint); 842 } 843 844 845 // 846 // Display $message and redirect user to $destination_url 847 // 848 function redirect($destination_url, $message) 849 { 850 global $db, $pun_config, $lang_common, $pun_user; 851 852 // Prefix with o_base_url (unless it's there already) 853 if (strpos($destination_url, $pun_config['o_base_url']) !== 0) 854 $destination_url = $pun_config['o_base_url'].'/'.$destination_url; 855 856 // Do a little spring cleaning 857 $destination_url = str_replace(array("\r", "\n", '%0a', '%0d', ';data:'), '', $destination_url); 858 859 // If the delay is 0 seconds, we might as well skip the redirect all together 860 if ($pun_config['o_redirect_delay'] == '0') 861 header('Location: '.str_replace('&', '&', $destination_url)); 862 863 864 // Load the redirect template 865 $tpl_redir = trim(file_get_contents(PUN_ROOT.'include/template/redirect.tpl')); 866 867 868 // START SUBST - <pun_include "*"> 869 while (preg_match('#<pun_include "([^/\\\\]*?)\.(php[45]?|inc|html?|txt)">#', $tpl_redir, $cur_include)) 870 { 871 if (!file_exists(PUN_ROOT.'include/user/'.$cur_include[1].'.'.$cur_include[2])) 872 error('Unable to process user include '.htmlspecialchars($cur_include[0]).' from template redirect.tpl. There is no such file in folder /include/user/'); 873 874 ob_start(); 875 include PUN_ROOT.'include/user/'.$cur_include[1].'.'.$cur_include[2]; 876 $tpl_temp = ob_get_contents(); 877 $tpl_redir = str_replace($cur_include[0], $tpl_temp, $tpl_redir); 878 ob_end_clean(); 879 } 880 // END SUBST - <pun_include "*"> 881 882 883 // START SUBST - <pun_content_direction> 884 $tpl_redir = str_replace('<pun_content_direction>', $lang_common['lang_direction'], $tpl_redir); 885 // END SUBST - <pun_content_direction> 886 887 888 // START SUBST - <pun_char_encoding> 889 $tpl_redir = str_replace('<pun_char_encoding>', $lang_common['lang_encoding'], $tpl_redir); 890 // END SUBST - <pun_char_encoding> 891 892 893 // START SUBST - <pun_head> 894 ob_start(); 895 896 ?> 897 <meta http-equiv="refresh" content="<?php echo $pun_config['o_redirect_delay'] ?>;URL=<?php echo str_replace(array('<', '>', '"'), array('<', '>', '"'), $destination_url) ?>" /> 898 <title><?php echo pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Redirecting'] ?></title> 899 <link rel="stylesheet" type="text/css" href="style/<?php echo $pun_user['style'].'.css' ?>" /> 900 <?php 901 902 $tpl_temp = trim(ob_get_contents()); 903 $tpl_redir = str_replace('<pun_head>', $tpl_temp, $tpl_redir); 904 ob_end_clean(); 905 // END SUBST - <pun_head> 906 907 908 // START SUBST - <pun_redir_heading> 909 $tpl_redir = str_replace('<pun_redir_heading>', $lang_common['Redirecting'], $tpl_redir); 910 // END SUBST - <pun_redir_heading> 911 912 913 // START SUBST - <pun_redir_text> 914 $tpl_temp = $message.'<br /><br />'.'<a href="'.$destination_url.'">'.$lang_common['Click redirect'].'</a>'; 915 $tpl_redir = str_replace('<pun_redir_text>', $tpl_temp, $tpl_redir); 916 // END SUBST - <pun_redir_text> 917 918 919 // START SUBST - <pun_footer> 920 ob_start(); 921 922 // End the transaction 923 $db->end_transaction(); 924 925 // Display executed queries (if enabled) 926 if (defined('PUN_SHOW_QUERIES')) 927 display_saved_queries(); 928 929 $tpl_temp = trim(ob_get_contents()); 930 $tpl_redir = str_replace('<pun_footer>', $tpl_temp, $tpl_redir); 931 ob_end_clean(); 932 // END SUBST - <pun_footer> 933 934 935 // Close the db connection (and free up any result data) 936 $db->close(); 937 938 exit($tpl_redir); 939 } 940 941 942 // 943 // Display a simple error message 944 // 945 function error($message, $file, $line, $db_error = false) 946 { 947 global $pun_config; 948 949 // Set a default title if the script failed before $pun_config could be populated 950 if (empty($pun_config)) 951 $pun_config['o_board_title'] = 'PunBB'; 952 953 // Empty output buffer and stop buffering 954 @ob_end_clean(); 955 956 // "Restart" output buffering if we are using ob_gzhandler (since the gzip header is already sent) 957 if (!empty($pun_config['o_gzip']) && extension_loaded('zlib') && (strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false || strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate') !== false)) 958 ob_start('ob_gzhandler'); 959 960 ?> 961 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 962 <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr"> 963 <head> 964 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> 965 <title><?php echo pun_htmlspecialchars($pun_config['o_board_title']) ?> / Error</title> 966 <style type="text/css"> 967 <!-- 968 BODY {MARGIN: 10% 20% auto 20%; font: 10px Verdana, Arial, Helvetica, sans-serif} 969 #errorbox {BORDER: 1px solid #B84623} 970 H2 {MARGIN: 0; COLOR: #FFFFFF; BACKGROUND-COLOR: #B84623; FONT-SIZE: 1.1em; PADDING: 5px 4px} 971 #errorbox DIV {PADDING: 6px 5px; BACKGROUND-COLOR: #F1F1F1} 972 --> 973 </style> 974 </head> 975 <body> 976 977 <div id="errorbox"> 978 <h2>An error was encountered</h2> 979 <div> 980 <?php 981 982 if (defined('PUN_DEBUG')) 983 { 984 echo "\t\t".'<strong>File:</strong> '.$file.'<br />'."\n\t\t".'<strong>Line:</strong> '.$line.'<br /><br />'."\n\t\t".'<strong>PunBB reported</strong>: '.$message."\n"; 985 986 if ($db_error) 987 { 988 echo "\t\t".'<br /><br /><strong>Database reported:</strong> '.pun_htmlspecialchars($db_error['error_msg']).(($db_error['error_no']) ? ' (Errno: '.$db_error['error_no'].')' : '')."\n"; 989 990 if ($db_error['error_sql'] != '') 991 echo "\t\t".'<br /><br /><strong>Failed query:</strong> '.pun_htmlspecialchars($db_error['error_sql'])."\n"; 992 } 993 } 994 else 995 echo "\t\t".'Error: <strong>'.$message.'.</strong>'."\n"; 996 997 ?> 998 </div> 999 </div> 1000 1001 </body> 1002 </html> 1003 <?php 1004 1005 // If a database connection was established (before this error) we close it 1006 if ($db_error) 1007 $GLOBALS['db']->close(); 1008 1009 exit; 1010 } 1011 1012 // DEBUG FUNCTIONS BELOW 1013 1014 // 1015 // Display executed queries (if enabled) 1016 // 1017 function display_saved_queries() 1018 { 1019 global $db, $lang_common; 1020 1021 // Get the queries so that we can print them out 1022 $saved_queries = $db->get_saved_queries(); 1023 1024 ?> 1025 1026 <div id="debug" class="blocktable"> 1027 <h2><span><?php echo $lang_common['Debug table'] ?></span></h2> 1028 <div class="box"> 1029 <div class="inbox"> 1030 <table cellspacing="0"> 1031 <thead> 1032 <tr> 1033 <th class="tcl" scope="col">Time (s)</th> 1034 <th class="tcr" scope="col">Query</th> 1035 </tr> 1036 </thead> 1037 <tbody> 1038 <?php 1039 1040 $query_time_total = 0.0; 1041 while (list(, $cur_query) = @each($saved_queries)) 1042 { 1043 $query_time_total += $cur_query[1]; 1044 1045 ?> 1046 <tr> 1047 <td class="tcl"><?php echo ($cur_query[1] != 0) ? $cur_query[1] : ' ' ?></td> 1048 <td class="tcr"><?php echo pun_htmlspecialchars($cur_query[0]) ?></td> 1049 </tr> 1050 <?php 1051 1052 } 1053 1054 ?> 1055 <tr> 1056 <td class="tcl" colspan="2">Total query time: <?php echo $query_time_total ?> s</td> 1057 </tr> 1058 </tbody> 1059 </table> 1060 </div> 1061 </div> 1062 </div> 1063 <?php 1064 1065 } 1066 1067 1068 // 1069 // Unset any variables instantiated as a result of register_globals being enabled 1070 // 1071 function unregister_globals() 1072 { 1073 $register_globals = @ini_get('register_globals'); 1074 if ($register_globals === "" || $register_globals === "0" || strtolower($register_globals) === "off") 1075 return; 1076 1077 // Prevent script.php?GLOBALS[foo]=bar 1078 if (isset($_REQUEST['GLOBALS']) || isset($_FILES['GLOBALS'])) 1079 exit('Ta seule richesse c\'est ton sentiment qui te pousse vers l\'avant.'); 1080 1081 // Variables that shouldn't be unset 1082 $no_unset = array('GLOBALS', '_GET', '_POST', '_COOKIE', '_REQUEST', '_SERVER', '_ENV', '_FILES'); 1083 1084 // Remove elements in $GLOBALS that are present in any of the superglobals 1085 $input = array_merge($_GET, $_POST, $_COOKIE, $_SERVER, $_ENV, $_FILES, isset($_SESSION) && is_array($_SESSION) ? $_SESSION : array()); 1086 foreach ($input as $k => $v) 1087 { 1088 if (!in_array($k, $no_unset) && isset($GLOBALS[$k])) 1089 { 1090 unset($GLOBALS[$k]); 1091 unset($GLOBALS[$k]); // Double unset to circumvent the zend_hash_del_key_or_index hole in PHP <4.4.3 and <5.1.4 1092 } 1093 } 1094 } 1095 1096 1097 // 1098 // Dump contents of variable(s) 1099 // 1100 function dump() 1101 { 1102 echo '<pre>'; 1103 1104 $num_args = func_num_args(); 1105 1106 for ($i = 0; $i < $num_args; ++$i) 1107 { 1108 print_r(func_get_arg($i)); 1109 echo "\n\n"; 1110 } 1111 1112 echo '</pre>'; 1113 exit; 1114 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sat Nov 24 22:44:38 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |