[ PHPXref.com ] [ Generated: Sun Jul 20 18:58:57 2008 ] [ NextBBS 0.4.4 ]
[ Index ]     [ Variables ]     [ Functions ]     [ Classes ]     [ Constants ]     [ Statistics ]

title

Body

[close]

/ -> common.php (source)

   1  <?php // common.php
   2  /*
   3  The Next BBS - Forums Software
   4  Copyright (C) 2006 Chris F. Ravenscroft
   5  
   6  This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
   7  
   8  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   9  
  10  You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  11  
  12  Questions? We can be reached at http://forums.sf.net
  13  */
  14  
  15  require_once  "tidbit.php";
  16  
  17  class Common
  18  {
  19  var $perf_startat;
  20  var $crumbs;
  21  var $pagetitle;
  22  var $SID;
  23  var $total_members;
  24  var $total_guests;
  25  var $total_bots;
  26  var $newestuser_id;
  27  var $newestuser_name;
  28  var $total_accounts;
  29  var $total_posts;
  30  var $neighbours;
  31  
  32  var $cache;
  33  var $base_url;
  34  var $bSkinOK;
  35  var $skinOverride = -1;
  36  
  37  var $OVERRIDE_ACLS = 1;
  38  var $EDIT_POST = 2;
  39  var $DELETE_POST = 4;
  40  var $MOVE_TOPIC = 8;
  41  var $SPLIT_TOPIC = 16;
  42  var $MERGE_TOPICS = 32;
  43  var $CLOSE_TOPIC = 64;
  44  var $PIN_TOPIC = 128;
  45  
  46  var $POST_NEW = 1;
  47  var $POST_REPLY = 2;
  48  var $POST_EDIT = 3;
  49  
  50  var $ACTION_PM = 1;
  51  var $ACTION_AIM = 2;
  52  var $ACTION_MSN = 3;
  53  var $ACTION_YIM = 4;
  54  var $ACTION_ICQ = 5;
  55  var $ACTION_WWW = 6;
  56  
  57  var $MCGET = 1;
  58  var $MCSET = 2;
  59  var $MCADD = 3;
  60  var $MCREP = 4;
  61  var $MCDEL = 5;
  62  
  63  	function Common()
  64      {
  65          $this->perf_startat = $this->microtime_float();
  66          $this->total_members = $this->total_guests = $this->total_bots = 0;
  67          $this->cache = array();
  68          $this->base_url = null;
  69          $this->bSkinOK = null;
  70      }
  71  
  72  	function microtime_float() 
  73      { 
  74          // *nix only
  75          if(function_exists('getrusage'))
  76          {
  77              $used = getrusage();
  78              return (
  79                  (($used['ru_utime.tv_usec'])+
  80                  ($used['ru_stime.tv_usec']))/
  81                  1000000);
  82          }
  83          // less accurate fallback
  84          list($usec, $sec) = explode(" ", microtime()); 
  85          return ((float)$usec + (float)$sec); 
  86      } 
  87  
  88      /**
  89       * Return how long it took to parse this page
  90       * @return String time elapsed, formatted
  91       */
  92  	function howLong()
  93      {
  94          return sprintf("%1.2f", ($this->microtime_float() - $this->perf_startat));
  95      }
  96  
  97      /**
  98       * Return how long it took to run all database queries
  99       * @return String time used, formatted
 100       */
 101  	function howLongDB()
 102      {
 103          global $DB, $CONFIG;
 104  
 105          if($CONFIG->debuglevel>=2)
 106              return sprintf(" (Queries: %1.2f)", $DB->getTotalTime());
 107          else
 108              return "";
 109      }
 110  
 111  	function now()
 112      {
 113          return time();
 114      }
 115  
 116      /**
 117       * Display an error message and lets the user go back...
 118       */
 119  	function error($msg, $memorize=true)
 120      {
 121          global $INPUT;
 122  
 123          $title = "Error";
 124          $subtext = '<input type="submit" name="ErrorSubmit" value="Go Back"></form>';
 125  
 126          $referer = &$_SERVER['HTTP_REFERER'];
 127  
 128          $extra = '<form action="'.$referer.'" method="post">';
 129          
 130          if($memorize)
 131          {
 132              // First, let's make sure that the referer string is always right
 133              $ref = array();
 134              $sides = explode('?', $referer);
 135              if(count($sides)>1)
 136              {
 137                  $blocks = explode('&', $sides[1]);
 138                  foreach($blocks as $block)
 139                  {
 140                      $parts = explode('=', $block);
 141                      if(count($parts)>1)
 142                      {
 143                          $ref[$parts[0]] = $parts[1];
 144                      }
 145                  }
 146              }
 147              //
 148              foreach($INPUT as $key => $value)
 149              {
 150                  if($key=='do' || $key=='w' || $key=='act' || 0 == strncmp('submit', $key, 6) || isset($ref[$key]))
 151                      continue;
 152  
 153                  $extra .= '<input type="hidden" name="'.$key.'" value="'.$value.'">';
 154              }
 155          }
 156  
 157          $this->intermediate($title, $msg, $subtext, $extra);
 158          exit; // Just to be sure...
 159      }
 160  
 161      /**
 162       * Log hack attempt and die
 163       */
 164  	function hacker($msg,$logkey="unknown",$action="unknown" )
 165      {
 166          global $LOG;
 167  
 168          $this->loganddie($msg, $logkey, $action, $LOG->HACK_LEVEL);
 169      }
 170  
 171      /**
 172       * Log, report and die. Baaad!
 173       */
 174  	function loganddie($msg, $logkey="unknown",$action="unknown",$level=-1)
 175      {
 176          global $LOG;
 177  
 178          if($level==-1) $level=$LOG->PANIC_LEVEL;
 179          $LOG->note($level,$logkey,$action,$msg);
 180          $msg = "<div style='border:1px solid #121729;color:blue; background-color:#eeee00; padding:5; margin:5 }'>".
 181              $msg.
 182              "</div>";
 183          if($level==$LOG->HACK_LEVEL)
 184              $msg = "<font color='red'><b>Note: A hack attempt was detected.<br />
 185                  It is being logged and reported to the admin along with your IP address:<br /><br /></b>".
 186                  $msg.
 187                  "</font>";
 188          die($msg);
 189      }
 190  
 191  	function dberror()
 192      {
 193      }
 194  
 195      /**
 196       * Do not call directly
 197       */
 198  	function _getSettingValue($setting_key, $uid=-1)
 199      {
 200          global $CONFIG, $DB;
 201          
 202          $qry = "SELECT setting_value FROM {$CONFIG->dbprfx}settings
 203                  WHERE setting_server='{$CONFIG->server}' AND
 204                  setting_key='{$setting_key}' AND
 205                  setting_userid='{$uid}'";
 206          $res = $DB->query($qry);
 207          if($res->numrows()==1)
 208          {
 209              $row = $res->fetchRow(DB_FETCHMODE_ASSOC);
 210              return $row['setting_value'];
 211          }
 212          else
 213              return null;
 214      }
 215      /**
 216       * Return a setting stored in the database
 217       */
 218  	function getUserSettingValue($setting_key)
 219      {
 220          global $USER;
 221          
 222          return $this->_getSettingValue($setting_key, $USER->id);
 223      }
 224      
 225      /**
 226       * Return a setting stored in the database
 227       */
 228  	function getGlobalSettingValue($setting_key)
 229      {
 230          return $this->_getSettingValue($setting_key, -1);
 231      }
 232  
 233      /**
 234       * Update an existing setting value
 235       */
 236  	function _updateSettingValue($setting_key, $setting_value, $uid=-1)
 237      {
 238          global $CONFIG, $DB;
 239  
 240          $qry = "UPDATE {$CONFIG->dbprfx}settings
 241                  SET setting_value='{$setting_value}'
 242                  WHERE setting_server='{$CONFIG->server}' AND
 243                  setting_key='{$setting_key}' AND
 244                  setting_userid='{$uid}'";
 245          $DB->query($qry);
 246      }
 247  
 248  	function updateUserSettingValue($setting_key, $setting_value)
 249      {
 250          global $USER;
 251  
 252          $this->_updateSettingValue($setting_key, $setting_value, $USER->id);
 253      }
 254  
 255  	function updateGlobalSettingValue($setting_key, $setting_value)
 256      {
 257          $this->_updateSettingValue($setting_key, $setting_value, -1);
 258      }
 259  
 260      /**
 261       * @TODO Important: this method should be called when saving a user, not when accessing posts!!
 262       */
 263  	function getUserTitle($posts)
 264      {
 265          global $COMMON, $USER;
 266  
 267          if($USER->title!='')
 268          {
 269              // User Custom Title!
 270              return $USER->title;
 271          }
 272  
 273          if(!isset($this->usertitles))
 274          {
 275              $this->usertitles = unserialize(base64_decode($COMMON->getGlobalSettingValue('user_titles')));
 276              if(empty($this->usertitles))
 277                  $this->usertitles = array();
 278              ksort($this->usertitles);
 279          }
 280  
 281          $lasttitle = '';
 282          foreach($this->usertitles as $u_posts => $u_values)
 283          {
 284              if($u_posts > $posts)
 285                  break;
 286              $lasttitle = $u_values['customtitle'];
 287          }
 288          return $lasttitle;
 289      }
 290  
 291      /**
 292       * Return a date formatted for display; short format.
 293       * @param dateValue long: time in ms
 294       * @return String formatted date
 295       */
 296  	function formatDate($dateValue,$customFormat="M j, Y, g:i a")
 297      {
 298          global $CONFIG, $USER;
 299          // First, adjust date
 300          $offset = ($USER->timezone - $CONFIG->board->timezone) * 60;
 301          $dateValue += $offset;
 302          //
 303          return date($customFormat, $dateValue);
 304      }
 305  
 306      /**
 307       * Return a user name with a hyperlink to its info page if available
 308       */
 309  	function formatUserName($userid,$userName,$displayPrefix='',$displaySuffix='')
 310      {
 311          if($userid==-1)
 312              return $userName;
 313          else
 314              return "<a href='?do=profile&id={$userid}'>{$displayPrefix}{$userName}{$displaySuffix}</a>";
 315      }
 316  
 317      /**
 318       * Return a properly formatted action
 319       */
 320  	function formatAction($action_id, $action_arg, $textInfo=null)
 321      {
 322          if($action_arg=='')
 323              return;
 324  
 325          switch($action_id)
 326          {
 327              case $this->ACTION_PM:
 328                  $ret = "<a href='?do=handlemsg&act=msg&MessageRecipient=".$action_arg."'>".($textInfo==null?"<img src='".$this->getSkinIncludesDirectory()."/p_pm.gif'>":$action_arg)."</a>";
 329                  break;
 330              case $this->ACTION_WWW:
 331                  $ret = "<a href='http://".$action_arg."' target='_blank'>".($textInfo==null?"<img src='".$this->getSkinIncludesDirectory()."/p_www.gif'>":$textInfo['in_www'])."</a>";
 332                  break;
 333              case $this->ACTION_AIM:
 334                  $ret = "<a href=\"javascript: openWindow('index.php?do=delegator&no2buf=true&action=messenger&type=aim&user=".$action_arg."',156,224);\">".($textInfo==null?"<img src='".$this->getSkinIncludesDirectory()."/p_aim.gif'>":$textInfo['in_aim'])."</a>";
 335                  break;
 336              case $this->ACTION_MSN:
 337                  $ret = "<a href=\"javascript: openWindow('index.php?do=delegator&no2buf=true&action=messenger&type=msn&user=".$action_arg."',156,224);\">".($textInfo==null?"<img src='".$this->getSkinIncludesDirectory()."/p_msn.gif'>":$textInfo['in_msn'])."</a>";
 338                  break;
 339              case $this->ACTION_YIM:
 340                  $ret = "<a href=\"javascript: openWindow('index.php?do=delegator&no2buf=true&action=messenger&type=yahoo&user=".$action_arg."',156,224);\">".($textInfo==null?"<img src='".$this->getSkinIncludesDirectory()."/p_yim.gif'>":$textInfo['in_yahoo'])."</a>";
 341                  break;
 342              case $this->ACTION_ICQ:
 343                  $ret = "<a href=\"javascript: openWindow('index.php?do=delegator&no2buf=true&action=messenger&type=icq&user=".$action_arg."',320,160);\">".($textInfo==null?"<img src='".$this->getSkinIncludesDirectory()."/p_icq.gif'>":$textInfo['in_icq'])."</a>";
 344                  break;
 345          }
 346          return $ret;
 347      }
 348  
 349      /**
 350       * Return a properly formatted ip address
 351       */
 352  	function formatIP($ip_address)
 353      {
 354          $ret = '<a href="http://ws.arin.net/whois?queryinput='.$ip_address.'" target="_blank">'.$ip_address.'</a>';
 355          return $ret;
 356      }
 357  
 358      /**
 359       * Return a properly formatted user agent string
 360       */
 361  	function formatAgent($user_agent)
 362      {
 363          $ret = $user_agent;
 364          return $ret;
 365      }
 366  
 367      /**
 368       * Return URL of the script currently being executed
 369       */
 370  	function getURL()
 371      {
 372          // Assumption: no SSL
 373          return "http://".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
 374      }
 375  
 376      /**
 377       * Return URL of the script currently being executed and its parameters
 378       */
 379  	function getExtendedURL()
 380      {
 381          // Assumption: no SSL
 382          return $this->getURL().'?'.$_SERVER['argv'][0];
 383      }
 384  
 385      /**
 386       * Return URL of the script currently being executed without the filename
 387       */
 388  	function getBaseURL()
 389      {
 390          global $CONFIG;
 391          
 392          if($this->base_url==null)
 393          {    
 394              $this->base_url = $this->getURL();        
 395              if($CONFIG->board->rewrite=="true")
 396              {
 397                  $p = strpos($this->base_url, "/do");
 398                  if($p!==false)
 399                  {
 400                      $this->base_url = substr($this->base_url, 0, $p-1);
 401                  }
 402              }    
 403              $p = strrpos($this->base_url, "/");
 404              if($p!==false)
 405                  $this->base_url = substr($this->base_url, 0, $p).'/';
 406          }
 407          return $this->base_url;
 408      }
 409  
 410      /**
 411       * Check whether an ip address belongs to a subnet
 412       * @param subnet String: an IP address in that subnet - may be: 'ip' or an ip with a classless mask: 'ip/xx'
 413       * @param ip String: the IP address we are curious about
 414       * @return boolean true if it belongs
 415       */
 416  	function isSubnet($subnet, $ip)
 417      {
 418          // Classless (in more than one way) comparison
 419          $cursubnet = explode('/', $subnet);
 420          $longsubnet = ip2long($cursubnet[0]);
 421          $longip = ip2long($ip);
 422  
 423          if(count($cursubnet)<2)
 424          {
 425              // Compare IP itself
 426              return ($longip==$longsubnet);
 427          }
 428          
 429          // IPv4 only!
 430          $subnetmask = 0xffffffff << (32-$cursubnet[1]);
 431          return (($longip & $subnetmask) == ($longsubnet & $subnetmask));
 432      }
 433  
 434  
 435      /**
 436       * Check whether the current user is a spider, such as Google's
 437       */
 438  	function checkSpider($ip, $agent='')
 439      {
 440          global $COMMON, $CONFIG, $USER;
 441  
 442          $spiders_ranges = array(
 443              '72.36.171.210' => 'Militate Spider',
 444              '66.249.64.0/19' => 'Google Spider',
 445              '64.124.85.0/24' => 'Become Spider',
 446              '65.54.188.0/24' => 'Msn Spider',
 447              '66.228.160.0/19 ' => 'Overture Spider',
 448              '207.248.240.118/19' => 'Alestra Spider',
 449              '69.28.242.87' => 'Stupid Spam Bot',
 450              '64.193.62.232' => 'Some Bot (Skiplink)',
 451              '66.246.120.114' => 'Some Bot (NAT)',
 452              '65.254.35.10' => 'Some Bot (GNAX)',
 453              '69.73.166.108' => 'Some Bot (Nocdirect)',
 454              '148.244.150.52' => 'Some South American Bot',
 455              '64.242.88.10/24' => 'Looksmart Spider',
 456              '68.142.192.0/18' => 'Inktomi Spider',
 457              '72.30.0.0/16' => 'Inktomi Spider',
 458              '64.124.122.224/27' => 'Rufus Bot',
 459              '202.108.22.78' => 'Baidu Spider',
 460              '151.138.18.44' => 'Superpages Spider',
 461              '65.214.44.143' => 'Ask Jeeves Spider',
 462              '66.154.103.125' => 'GigaBot',
 463              '210.173.180.166' => 'Ichiro Spider',
 464              '64.34.145.197' => 'SiteSell Spider',
 465              );
 466  
 467          foreach($spiders_ranges as $spider_range => $spider_name)
 468          {
 469              if($COMMON->isSubnet($spider_range, $ip))
 470              {
 471                  return $spider_name;
 472              }
 473          }
 474  
 475          // Not found any? What if it's a new IP range? We could use their user agent too...
 476          // Of course, it could be empty...
 477          if(empty($agent))
 478              return 'Unknown bot';
 479          // NOTE: This is a *very rough* implementation
 480          if($CONFIG->spiders->agent=='true')
 481          {
 482              require  'helpers/user_agents.php';
 483              // Extract browser string...yeah, right
 484              preg_match('/([0-9a-zA-Z]+)/', $agent, $browserName);
 485              if(in_array($browserName, $spiders_agents))
 486                  return $browserName;
 487          }
 488  
 489          // OK OK...well, maybe it's unknown but it's user agent gave it away anyway?
 490          if($agent=='Spider')
 491          {
 492              return 'Unknown Bot';
 493          }
 494  
 495          return null;
 496      }
 497  
 498      /**
 499       * Test if an IP address is banned
 500       * @param ipaddress a string: ip address to test
 501       * @return boolean true if banned
 502       */
 503  	function isBanned($ipaddress)
 504      {
 505          global $CONFIG, $USER;
 506  
 507          if($USER->isAdmin())
 508              return false;
 509  
 510          // Of course, we first need to ensure that you were not suspended...
 511          if($USER->suspended > 0)
 512              return true;
 513  
 514          $userip = ip2long($ipaddress);
 515          $banips = explode("\n", $CONFIG->ban->ips);
 516          foreach ($banips as $banip)
 517          {
 518              if($this->isSubnet($banip, $userip))
 519                  return true;
 520          }
 521          return false;
 522      }
 523  
 524      /**
 525       * Check whether the board is offline and that is relevant to the user
 526       * @return boolean true if board is offline
 527       */
 528  	function isBoardOffline()
 529      {
 530          global $CONFIG, $USER;
 531  
 532          if($USER->isAdmin())
 533              return false;
 534  
 535          if($CONFIG->boardonoff->onoff=='off')
 536              return true;
 537      }
 538  
 539      /**
 540       * Display a redirect page then send the user to wherever...
 541       * @param page a string: what the software expects after '?do=' / 'null' means 'hard redirect'
 542       * @param page a string: text to be displayed
 543       * @param delay how many seconds shall we wait? '-1' means 'use config. default'
 544       */
 545  	function redirect($page, $text, $delay=-1)
 546      {
 547          global $TEMPLATE, $LANG, $CONFIG;
 548  
 549          if($page==null)
 550          {
 551              if($CONFIG->board->rewrite=="true")
 552              {
 553                  if(!strncmp($text, 'admin', 5))
 554                  {
 555                      $hdr = $this->getURL().'?act='.$text;
 556                  }
 557                  else
 558                  {
 559                      $hdr = str_replace(
 560                          array('&', '='),
 561                          array('_', '_'),
 562                          str_replace(
 563                              'index.php',
 564                              '',
 565                              $this->getBaseURL()).'do='.$text);
 566                  }
 567              }
 568              else
 569              {
 570                  $hdr = $this->getURL().'?do='.$text;
 571              }
 572              
 573              Header("Location: ".$hdr);
 574              exit;
 575          }
 576  
 577          if($delay==-1)
 578              $delay = $CONFIG->redirect->delay;
 579          $TEMPLATE->assign("includes", $this->getSkinIncludesDirectory());
 580          $TEMPLATE->assign("glang", $LANG->globalAccessor());
 581          $TEMPLATE->assign("text", $text);
 582