[ Index ]

PHP Cross Reference of Nucleus CMS 3.32

title

Body

[close]

/nucleus/libs/ -> globalfunctions.php (source)

   1  <?php
   2  
   3  /*
   4   * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
   5   * Copyright (C) 2002-2007 The Nucleus Group
   6   *
   7   * This program is free software; you can redistribute it and/or
   8   * modify it under the terms of the GNU General Public License
   9   * as published by the Free Software Foundation; either version 2
  10   * of the License, or (at your option) any later version.
  11   * (see nucleus/documentation/index.html#license for more info)
  12   */
  13  /**
  14   * @license http://nucleuscms.org/license.txt GNU General Public License
  15   * @copyright Copyright (C) 2002-2007 The Nucleus Group
  16   * @version $Id: globalfunctions.php 1211 2007-10-21 17:43:27Z kaigreve $
  17  
  18   */
  19  
  20  // needed if we include globalfunctions from install.php
  21  global $nucleus, $CONF, $DIR_LIBS, $DIR_LANG, $manager, $member;
  22  
  23  $nucleus['version'] = 'v3.32';
  24  $nucleus['codename'] = '';
  25  
  26  checkVars(array('nucleus', 'CONF', 'DIR_LIBS', 'MYSQL_HOST', 'MYSQL_USER', 'MYSQL_PASSWORD', 'MYSQL_DATABASE', 'DIR_LANG', 'DIR_PLUGINS', 'HTTP_GET_VARS', 'HTTP_POST_VARS', 'HTTP_COOKIE_VARS', 'HTTP_ENV_VARS', 'HTTP_SESSION_VARS', 'HTTP_POST_FILES', 'HTTP_SERVER_VARS', 'GLOBALS', 'argv', 'argc', '_GET', '_POST', '_COOKIE', '_ENV', '_SESSION', '_SERVER', '_FILES'));
  27  
  28  $CONF['debug'] = 0;
  29  if ($CONF['debug']) {
  30      error_reporting(E_ALL);    // report all errors!
  31  } else {
  32      error_reporting(E_ERROR | E_WARNING | E_PARSE);
  33  }
  34  
  35  // Avoid notices
  36  if (!isset($CONF['Self'])) {
  37      $CONF['Self'] = htmlspecialchars($_SERVER['PHP_SELF'],ENT_QUOTES);
  38  }
  39  
  40  /*
  41      Indicates when Nucleus should display startup errors. Set to 1 if you want
  42      the error enabled (default), false otherwise
  43  
  44      alertOnHeadersSent
  45          Displays an error when visiting a public Nucleus page and headers have
  46          been sent out to early. This usually indicates an error in either a
  47          configuration file or a language file, and could cause Nucleus to
  48          malfunction
  49      alertOnSecurityRisk
  50          Displays an error only when visiting the admin area, and when one or
  51          more of the installation files (install.php, install.sql, upgrades/
  52          directory) are still on the server.
  53  */
  54  $CONF['alertOnHeadersSent'] = 1;
  55  $CONF['alertOnSecurityRisk'] = 1;
  56  $CONF['ItemURL'] = $CONF['Self'];
  57  $CONF['ArchiveURL'] = $CONF['Self'];
  58  $CONF['ArchiveListURL'] = $CONF['Self'];
  59  $CONF['MemberURL'] = $CONF['Self'];
  60  $CONF['SearchURL'] = $CONF['Self'];
  61  $CONF['BlogURL'] = $CONF['Self'];
  62  $CONF['CategoryURL'] = $CONF['Self'];
  63  
  64  // switch URLMode back to normal when $CONF['Self'] ends in .php
  65  // this avoids urls like index.php/item/13/index.php/item/15
  66  if (!isset($CONF['URLMode']) || (($CONF['URLMode'] == 'pathinfo') && (substr($CONF['Self'], strlen($CONF['Self']) - 4) == '.php'))) {
  67      $CONF['URLMode'] = 'normal';
  68  }
  69  
  70  if (getNucleusPatchLevel() > 0) {
  71      $nucleus['version'] .= '/' . getNucleusPatchLevel();
  72  }
  73  
  74  // Avoid notices
  75  if (!isset($CONF['installscript'])) {
  76      $CONF['installscript'] = 0;
  77  }
  78  
  79  // we will use postVar, getVar, ... methods instead of HTTP_GET_VARS or _GET
  80  if ($CONF['installscript'] != 1) { // vars were already included in install.php
  81      if (phpversion() >= '4.1.0') {
  82          include_once ($DIR_LIBS . 'vars4.1.0.php');
  83      } else {
  84          include_once ($DIR_LIBS . 'vars4.0.6.php');
  85      }
  86  }
  87  
  88  // sanitize option
  89  $bLoggingSanitizedResult=0;
  90  $bSanitizeAndContinue=0;
  91  
  92  $orgRequestURI = serverVar('REQUEST_URI');
  93  sanitizeParams();
  94  
  95  // get all variables that can come from the request and put them in the global scope
  96  $blogid    = requestVar('blogid');
  97  $itemid    = intRequestVar('itemid');
  98  $catid = intRequestVar('catid');
  99  $skinid    = requestVar('skinid');
 100  $memberid = requestVar('memberid');
 101  $archivelist = requestVar('archivelist');
 102  $imagepopup = requestVar('imagepopup');
 103  $archive = requestVar('archive');
 104  $query = requestVar('query');
 105  $highlight = requestVar('highlight');
 106  $amount = requestVar('amount');
 107  $action = requestVar('action');
 108  $nextaction = requestVar('nextaction');
 109  $maxresults = requestVar('maxresults');
 110  $startpos = intRequestVar('startpos');
 111  $errormessage = '';
 112  $error = '';
 113  $virtualpath = ((getVar('virtualpath') != null) ? getVar('virtualpath') : serverVar('PATH_INFO'));
 114  
 115  if (!headers_sent() ) {
 116      header('Generator: Nucleus CMS ' . $nucleus['version']);
 117  }
 118  
 119  // include core classes that are needed for login & plugin handling
 120  include ($DIR_LIBS . 'mysql.php');
 121  include ($DIR_LIBS . 'MEMBER.php');
 122  include ($DIR_LIBS . 'ACTIONLOG.php');
 123  include ($DIR_LIBS . 'MANAGER.php');
 124  include ($DIR_LIBS . 'PLUGIN.php');
 125  
 126  $manager =& MANAGER::instance();
 127  
 128  // make sure there's no unnecessary escaping:
 129  set_magic_quotes_runtime(0);
 130  
 131  // Avoid notices
 132  if (!isset($CONF['UsingAdminArea'])) {
 133      $CONF['UsingAdminArea'] = 0;
 134  }
 135  
 136  // only needed when updating logs
 137  if ($CONF['UsingAdminArea']) {
 138      include ($DIR_LIBS . 'xmlrpc.inc.php');    // XML-RPC client classes
 139      include_once ($DIR_LIBS . 'ADMIN.php');
 140  }
 141  
 142  // connect to database
 143  sql_connect();
 144  $SQLCount = 0;
 145  
 146  // logs sanitized result if need
 147  if ($orgRequestURI!==serverVar('REQUEST_URI')) {
 148      $msg = "Sanitized [" . serverVar('REMOTE_ADDR') . "] ";
 149      $msg .= $orgRequestURI . " -> " . serverVar('REQUEST_URI');
 150      if ($bLoggingSanitizedResult) {
 151          addToLog(WARNING, $msg);
 152      }
 153      if (!$bSanitizeAndContinue) {
 154          die("");
 155      }
 156  }
 157  
 158  // makes sure database connection gets closed on script termination
 159  register_shutdown_function('sql_disconnect');
 160  
 161  // read config
 162  getConfig();
 163  
 164  // automatically use simpler toolbar for mozilla
 165  if (($CONF['DisableJsTools'] == 0) && strstr(serverVar('HTTP_USER_AGENT'), 'Mozilla/5.0') && strstr(serverVar('HTTP_USER_AGENT'), 'Gecko') ) {
 166      $CONF['DisableJsTools'] = 2;
 167  }
 168  
 169  // login if cookies set
 170  $member = new MEMBER();
 171  
 172  // secure cookie key settings (either 'none', 0, 8, 16, 24, or 32)
 173  if (!isset($CONF['secureCookieKey'])) $CONF['secureCookieKey']=24;
 174  switch($CONF['secureCookieKey']){
 175  case 8:
 176      $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+\.[0-9]+\.[0-9]+$/','',serverVar('REMOTE_ADDR'));
 177      break;
 178  case 16:
 179      $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+\.[0-9]+$/','',serverVar('REMOTE_ADDR'));
 180      break;
 181  case 24:
 182      $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+$/','',serverVar('REMOTE_ADDR'));
 183      break;
 184  case 32:
 185      $CONF['secureCookieKeyIP']=serverVar('REMOTE_ADDR');
 186      break;
 187  default:
 188      $CONF['secureCookieKeyIP']='';
 189  }
 190  
 191  // login/logout when required or renew cookies
 192  if ($action == 'login') {
 193      // Form Authentication
 194      $login = postVar('login');
 195      $pw = postVar('password');
 196      $shared    = intPostVar('shared');    // shared computer or not
 197  
 198      $pw=substr($pw,0,40); // avoid md5 collision by using a long key
 199  
 200      if ($member->login($login, $pw) ) {
 201  
 202          $member->newCookieKey();
 203          $member->setCookies($shared);
 204  
 205          if ($CONF['secureCookieKey']!=='none') {
 206              // secure cookie key
 207              $member->setCookieKey(md5($member->getCookieKey().$CONF['secureCookieKeyIP']));
 208              $member->write();
 209          }
 210  
 211          // allows direct access to parts of the admin area after logging in
 212          if ($nextaction) {
 213              $action = $nextaction;
 214          }
 215  
 216          $manager->notify('LoginSuccess', array('member' => &$member) );
 217          $errormessage = '';
 218          ACTIONLOG::add(INFO, "Login successful for $login (sharedpc=$shared)");
 219      } else {
 220          // errormessage for [%errordiv%]
 221          $errormessage = 'Login failed for ' . $login;
 222  
 223          $manager->notify('LoginFailed', array('username' => $login) );
 224          ACTIONLOG::add(INFO, $errormessage);
 225      }
 226  /*
 227  
 228  Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for details
 229  
 230  } elseif (serverVar('PHP_AUTH_USER') && serverVar('PHP_AUTH_PW')) {
 231      // HTTP Authentication
 232      $login  = serverVar('PHP_AUTH_USER');
 233      $pw     = serverVar('PHP_AUTH_PW');
 234  
 235      if ($member->login($login, $pw) ) {
 236          $manager->notify('LoginSuccess',array('member' => &$member));
 237          ACTIONLOG::add(INFO, "HTTP authentication successful for $login");
 238      } else {
 239          $manager->notify('LoginFailed',array('username' => $login));
 240          ACTIONLOG::add(INFO, 'HTTP authentication failed for ' . $login);
 241  
 242          //Since bad credentials, generate an apropriate error page
 243          header("WWW-Authenticate: Basic realm=\"Nucleus CMS {$nucleus['version']}\"");
 244          header('HTTP/1.0 401 Unauthorized');
 245          echo 'Invalid username or password';
 246          exit;
 247      }
 248  */
 249  
 250  } elseif (($action == 'logout') && (!headers_sent() ) && cookieVar($CONF['CookiePrefix'] . 'user') ) {
 251      // remove cookies on logout
 252      setcookie($CONF['CookiePrefix'] . 'user', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
 253      setcookie($CONF['CookiePrefix'] . 'loginkey', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
 254      $manager->notify('Logout', array('username' => cookieVar($CONF['CookiePrefix'] . 'user') ) );
 255  } elseif (cookieVar($CONF['CookiePrefix'] . 'user') ) {
 256      // Cookie Authentication
 257      $ck=cookieVar($CONF['CookiePrefix'] . 'loginkey');
 258      // secure cookie key
 259      $ck=substr($ck,0,32); // avoid md5 collision by using a long key
 260      if ($CONF['secureCookieKey']!=='none') $ck=md5($ck.$CONF['secureCookieKeyIP']);
 261      $res = $member->cookielogin(cookieVar($CONF['CookiePrefix'] . 'user'), $ck );
 262      unset($ck);
 263  
 264      // renew cookies when not on a shared computer
 265      if ($res && (cookieVar($CONF['CookiePrefix'] . 'sharedpc') != 1) && (!headers_sent() ) ) {
 266          $member->setCookieKey(cookieVar($CONF['CookiePrefix'] . 'loginkey'));
 267          $member->setCookies();
 268      }
 269  }
 270  
 271  // login completed
 272  $manager->notify('PostAuthentication', array('loggedIn' => $member->isLoggedIn() ) );
 273  ticketForPlugin();
 274  
 275  // first, let's see if the site is disabled or not. always allow admin area access.
 276  if ($CONF['DisableSite'] && !$member->isAdmin() && !$CONF['UsingAdminArea']) {
 277      redirect($CONF['DisableSiteURL']);
 278      exit;
 279  }
 280  
 281  // load other classes
 282  include ($DIR_LIBS . 'PARSER.php');
 283  include ($DIR_LIBS . 'SKIN.php');
 284  include ($DIR_LIBS . 'TEMPLATE.php');
 285  include ($DIR_LIBS . 'BLOG.php');
 286  include ($DIR_LIBS . 'BODYACTIONS.php');
 287  include ($DIR_LIBS . 'COMMENTS.php');
 288  include ($DIR_LIBS . 'COMMENT.php');
 289  //include($DIR_LIBS . 'ITEM.php');
 290  include ($DIR_LIBS . 'NOTIFICATION.php');
 291  include ($DIR_LIBS . 'BAN.php');
 292  include ($DIR_LIBS . 'PAGEFACTORY.php');
 293  include ($DIR_LIBS . 'SEARCH.php');
 294  include ($DIR_LIBS . 'entity.php');
 295  
 296  
 297  // set lastVisit cookie (if allowed)
 298  if (!headers_sent() ) {
 299      if ($CONF['LastVisit']) {
 300          setcookie($CONF['CookiePrefix'] . 'lastVisit', time(), time() + 2592000, $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
 301      } else {
 302          setcookie($CONF['CookiePrefix'] . 'lastVisit', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
 303      }
 304  }
 305  
 306  // read language file, only after user has been initialized
 307  $language = getLanguageName();
 308  include($DIR_LANG . ereg_replace( '[\\|/]', '', $language) . '.php');
 309  
 310  /*
 311      Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for details
 312  
 313  // To remove after v2.5 is released and language files have been updated.
 314  // Including this makes sure that language files for v2.5beta can still be used for v2.5final
 315  // without having weird _SETTINGS_EXTAUTH string showing up in the admin area.
 316  if (!defined('_MEMBERS_BYPASS'))
 317  {
 318      define('_SETTINGS_EXTAUTH',            'Enable External Authentication');
 319      define('_WARNING_EXTAUTH',            'Warning: Enable only if needed.');
 320      define('_MEMBERS_BYPASS',            'Use External Authentication');
 321  }
 322  
 323  */
 324  
 325  // make sure the archivetype skinvar keeps working when _ARCHIVETYPE_XXX not defined
 326  if (!defined('_ARCHIVETYPE_MONTH') ) {
 327      define('_ARCHIVETYPE_DAY', 'day');
 328      define('_ARCHIVETYPE_MONTH', 'month');
 329  }
 330  
 331  // decode path_info
 332  if ($CONF['URLMode'] == 'pathinfo') {
 333      // initialize keywords if this hasn't been done before
 334      if ($CONF['ItemKey'] == '') {
 335          $CONF['ItemKey'] = 'item';
 336      }
 337  
 338      if ($CONF['ArchiveKey'] == '') {
 339          $CONF['ArchiveKey'] = 'archive';
 340      }
 341  
 342      if ($CONF['ArchivesKey'] == '') {
 343          $CONF['ArchivesKey'] = 'archives';
 344      }
 345  
 346      if ($CONF['MemberKey'] == '') {
 347          $CONF['MemberKey'] = 'member';
 348      }
 349  
 350      if ($CONF['BlogKey'] == '') {
 351          $CONF['BlogKey'] = 'blog';
 352      }
 353  
 354      if ($CONF['CategoryKey'] == '') {
 355          $CONF['CategoryKey'] = 'category';
 356      }
 357  
 358      if ($CONF['SpecialskinKey'] == '') {
 359          $CONF['SpecialskinKey'] = 'special';
 360      }
 361  
 362      $parsed = false;
 363      $manager->notify(
 364          'ParseURL',
 365          array(
 366              'type' => basename(serverVar('SCRIPT_NAME') ), // e.g. item, blog, ...
 367              'info' => $virtualpath,
 368              'complete' => &$parsed
 369          )
 370      );
 371  
 372      if (!$parsed) {
 373          // default implementation
 374          $data = explode("/", $virtualpath );
 375          for ($i = 0; $i < sizeof($data); $i++) {
 376              switch ($data[$i]) {
 377                  case $CONF['ItemKey']: // item/1 (blogid)
 378                      $i++;
 379  
 380                      if ($i < sizeof($data) ) {
 381                          $itemid = intval($data[$i]);
 382                      }
 383                      break;
 384  
 385                  case $CONF['ArchivesKey']: // archives/1 (blogid)
 386                      $i++;
 387  
 388                      if ($i < sizeof($data) ) {
 389                          $archivelist = intval($data[$i]);
 390                      }
 391                      break;
 392  
 393                  case $CONF['ArchiveKey']: // two possibilities: archive/yyyy-mm or archive/1/yyyy-mm (with blogid)
 394                      if ((($i + 1) < sizeof($data) ) && (!strstr($data[$i + 1], '-') ) ) {
 395                          $blogid = intval($data[++$i]);
 396                      }
 397  
 398                      $i++;
 399  
 400                      if ($i < sizeof($data) ) {
 401                          $archive = $data[$i];
 402                      }
 403                      break;
 404  
 405                  case 'blogid': // blogid/1
 406                  case $CONF['BlogKey']: // blog/1
 407                      $i++;
 408  
 409                      if ($i < sizeof($data) ) {
 410                          $blogid = intval($data[$i]);
 411                      }
 412                      break;
 413  
 414                  case $CONF['CategoryKey']: // category/1 (catid)
 415                  case 'catid':
 416                      $i++;
 417  
 418                      if ($i < sizeof($data) ) {
 419                          $catid = intval($data[$i]);
 420                      }
 421                      break;
 422  
 423                  case $CONF['MemberKey']:
 424                      $i++;
 425  
 426                      if ($i < sizeof($data) ) {
 427                          $memberid = intval($data[$i]);
 428                      }
 429                      break;
 430  
 431                  case $CONF['SpecialskinKey']:
 432                      $i++;
 433  
 434                      if ($i < sizeof($data) ) {
 435                          $_REQUEST['special'] = $data[$i];
 436                      }
 437                      break;
 438  
 439                  default:
 440                      // skip...
 441              }
 442          }
 443      }
 444  }
 445  
 446  function intPostVar($name) {
 447      return intval(postVar($name) );
 448  }
 449  
 450  function intGetVar($name) {
 451      return intval(getVar($name) );
 452  }
 453  
 454  function intRequestVar($name) {
 455      return intval(requestVar($name) );
 456  }
 457  
 458  function intCookieVar($name) {
 459      return intval(cookieVar($name) );
 460  }
 461  
 462  /**
 463    * returns the currently used version (100 = 1.00, 101 = 1.01, etc...)
 464    */
 465  function getNucleusVersion() {
 466      return 332;
 467  }
 468  
 469  /**
 470   * power users can install patches in between nucleus releases. These patches
 471   * usually add new functionality in the plugin API and allow those to
 472   * be tested without having to install CVS.
 473   */
 474  function getNucleusPatchLevel() {
 475      return 0;
 476  }
 477  
 478  /**
 479    * Connects to mysql server
 480    */
 481  function sql_connect() {
 482      global $MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD, $MYSQL_DATABASE, $MYSQL_CONN;
 483  
 484      $MYSQL_CONN = @mysql_connect($MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD) or startUpError('<p>Could not connect to MySQL database.</p>', 'Connect Error');
 485      mysql_select_db($MYSQL_DATABASE) or startUpError('<p>Could not select database: ' . mysql_error() . '</p>', 'Connect Error');
 486  
 487      return $MYSQL_CONN;
 488  }
 489  
 490  /**
 491   * returns a prefixed nucleus table name
 492   */
 493  function sql_table($name) {
 494      global $MYSQL_PREFIX;
 495  
 496      if ($MYSQL_PREFIX) {
 497          return $MYSQL_PREFIX . 'nucleus_' . $name;
 498      } else {
 499          return 'nucleus_' . $name;
 500      }
 501  }
 502  
 503  function sendContentType($contenttype, $pagetype = '', $charset = _CHARSET) {
 504      global $manager, $CONF;
 505  
 506      if (!headers_sent() ) {
 507          // if content type is application/xhtml+xml, only send it to browsers
 508          // that can handle it (IE6 cannot). Otherwise, send text/html
 509  
 510          // v2.5: For admin area pages, keep sending text/html (unless it's a debug version)
 511          //       application/xhtml+xml still causes too much problems with the javascript implementations
 512  
 513          // v3.3: ($CONF['UsingAdminArea'] && !$CONF['debug']) gets removed,
 514          //       application/xhtml+xml seems to be working, so we're going to use it if we can.
 515          if (
 516                  ($contenttype == 'application/xhtml+xml')
 517              &&    (!stristr(serverVar('HTTP_ACCEPT'), 'application/xhtml+xml') )
 518              ) {
 519              $contenttype = 'text/html';
 520          }
 521  
 522          $manager->notify(
 523              'PreSendContentType',
 524              array(
 525                  'contentType' => &$contenttype,
 526                  'charset' => &$charset,
 527                  'pageType' => $pagetype
 528              )
 529          );
 530  
 531          // strip strange characters
 532          $contenttype = preg_replace('|[^a-z0-9-+./]|i', '', $contenttype);
 533          $charset = preg_replace('|[^a-z0-9-_]|i', '', $charset);
 534  
 535          if ($charset != '') {
 536              header('Content-Type: ' . $contenttype . '; charset=' . $charset);
 537          } else {
 538              header('Content-Type: ' . $contenttype);
 539          }
 540      }
 541  }
 542  
 543  /**
 544   * Errors before the database connection has been made
 545   */
 546  function startUpError($msg, $title) {
 547      ?>
 548      <html xmlns="http://www.w3.org/1999/xhtml">
 549          <head><title><?php echo htmlspecialchars($title)?></title></head>
 550          <body>
 551              <h1><?php echo htmlspecialchars($title)?></h1>
 552              <?php echo $msg?>
 553          </body>
 554      </html>
 555      <?php    exit;
 556  }
 557  
 558  /**
 559    * disconnects from SQL server
 560    */
 561  function sql_disconnect() {
 562      @mysql_close();
 563  }
 564  
 565  /**
 566    * executes an SQL query
 567    */
 568  function sql_query($query) {
 569      global $SQLCount;
 570      $SQLCount++;
 571      $res = mysql_query($query) or print("mySQL error with query $query: " . mysql_error() . '<p />');
 572      return $res;
 573  }
 574  
 575  
 576  /**
 577   * Highlights a specific query in a given HTML text (not within HTML tags) and returns it
 578   *
 579   * @param $text
 580   *        text to be highlighted
 581   * @param $expression
 582   *        regular expression to be matched (can be an array of expressions as well)
 583   * @param $highlight
 584   *        highlight to be used (use \\0 to indicate the matched expression)
 585   *
 586   */
 587  function highlight($text, $expression, $highlight) {
 588      if (!$highlight || !$expression) {
 589          return $text;
 590      }
 591  
 592      if (is_array($expression) && (count(