| [ Index ] |
PHP Cross Reference of Nucleus CMS 3.32 |
[Summary view] [Print] [Text view]
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(