[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * @version $Id: joomla.php 9997 2008-02-07 11:27:04Z eddieajau $ 4 * @package Joomla 5 * @copyright Copyright (C) 2005 Open Source Matters. All rights reserved. 6 * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php 7 * Joomla! is free software. This version may have been modified pursuant 8 * to the GNU General Public License, and as distributed it includes or 9 * is derivative of works licensed under the GNU General Public License or 10 * other free or open source software licenses. 11 * See COPYRIGHT.php for copyright notices and details. 12 */ 13 14 // no direct access 15 defined( '_VALID_MOS' ) or die( 'Restricted access' ); 16 define( '_MOS_MAMBO_INCLUDED', 1 ); 17 18 /** 19 * Page generation time 20 * @package Joomla 21 */ 22 class mosProfiler { 23 /** @var int Start time stamp */ 24 var $start=0; 25 /** @var string A prefix for mark messages */ 26 var $prefix=''; 27 28 /** 29 * Constructor 30 * @param string A prefix for mark messages 31 */ 32 function mosProfiler( $prefix='' ) { 33 $this->start = $this->getmicrotime(); 34 $this->prefix = $prefix; 35 } 36 37 /** 38 * @return string A format message of the elapsed time 39 */ 40 function mark( $label ) { 41 return sprintf ( "\n<div class=\"profiler\">$this->prefix %.3f $label</div>", $this->getmicrotime() - $this->start ); 42 } 43 44 /** 45 * @return float The current time in milliseconds 46 */ 47 function getmicrotime(){ 48 list($usec, $sec) = explode(" ",microtime()); 49 return ((float)$usec + (float)$sec); 50 } 51 } 52 53 if (phpversion() < '4.2.0') { 54 require_once( dirname( __FILE__ ) . '/compat.php41x.php' ); 55 } 56 if (phpversion() < '4.3.0') { 57 require_once( dirname( __FILE__ ) . '/compat.php42x.php' ); 58 } 59 if (version_compare( phpversion(), '5.0' ) < 0) { 60 require_once( dirname( __FILE__ ) . '/compat.php50x.php' ); 61 } 62 63 @set_magic_quotes_runtime( 0 ); 64 65 if ( @$mosConfig_error_reporting === 0 || @$mosConfig_error_reporting === '0' ) { 66 error_reporting( 0 ); 67 } else if (@$mosConfig_error_reporting > 0) { 68 error_reporting( $mosConfig_error_reporting ); 69 } 70 71 require_once ( $mosConfig_absolute_path . '/includes/version.php' ); 72 require_once ( $mosConfig_absolute_path . '/includes/database.php' ); 73 require_once ( $mosConfig_absolute_path . '/includes/gacl.class.php' ); 74 require_once ( $mosConfig_absolute_path . '/includes/gacl_api.class.php' ); 75 require_once ( $mosConfig_absolute_path . '/includes/phpmailer/class.phpmailer.php' ); 76 require_once ( $mosConfig_absolute_path . '/includes/joomla.xml.php' ); 77 require_once ( $mosConfig_absolute_path . '/includes/phpInputFilter/class.inputfilter.php' ); 78 79 $database = new database( $mosConfig_host, $mosConfig_user, $mosConfig_password, $mosConfig_db, $mosConfig_dbprefix ); 80 if ($database->getErrorNum()) { 81 $mosSystemError = $database->getErrorNum(); 82 $basePath = dirname( __FILE__ ); 83 include $basePath . '/../configuration.php'; 84 include $basePath . '/../offline.php'; 85 exit(); 86 } 87 $database->debug( $mosConfig_debug ); 88 $acl = new gacl_api(); 89 90 // platform neurtral url handling 91 if ( isset( $_SERVER['REQUEST_URI'] ) ) { 92 $request_uri = $_SERVER['REQUEST_URI']; 93 } else { 94 $request_uri = $_SERVER['SCRIPT_NAME']; 95 // Append the query string if it exists and isn't null 96 if ( isset( $_SERVER['QUERY_STRING'] ) && !empty( $_SERVER['QUERY_STRING'] ) ) { 97 $request_uri .= '?' . $_SERVER['QUERY_STRING']; 98 } 99 } 100 $_SERVER['REQUEST_URI'] = $request_uri; 101 102 // current server time 103 $now = date( 'Y-m-d H:i', time() ); 104 DEFINE( '_CURRENT_SERVER_TIME', $now ); 105 DEFINE( '_CURRENT_SERVER_TIME_FORMAT', '%Y-%m-%d %H:%M:%S' ); 106 107 // Non http/https URL Schemes 108 $url_schemes = 'data:, file:, ftp:, gopher:, imap:, ldap:, mailto:, news:, nntp:, telnet:, javascript:, irc:, mms:'; 109 DEFINE( '_URL_SCHEMES', $url_schemes ); 110 111 // disable strict mode in MySQL 5 112 if (!defined( '_JOS_SET_SQLMODE' )) { 113 /** ensure that functions are declared only once */ 114 define( '_JOS_SET_SQLMODE', 1 ); 115 116 // if running mysql 5, set sql-mode to mysql40 - thereby circumventing strict mode problems 117 if ( strpos( $database->getVersion(), '5' ) === 0 ) { 118 $query = "SET sql_mode = 'MYSQL40'"; 119 $database->setQuery( $query ); 120 $database->query(); 121 } 122 } 123 124 /** 125 * @package Joomla 126 * @abstract 127 */ 128 class mosAbstractLog { 129 /** @var array */ 130 var $_log = null; 131 132 /** 133 * Constructor 134 */ 135 function mosAbstractLog() { 136 $this->__constructor(); 137 } 138 139 /** 140 * Generic constructor 141 */ 142 function __constructor() { 143 $this->_log = array(); 144 } 145 146 /** 147 * @param string Log message 148 * @param boolean True to append to last message 149 */ 150 function log( $text, $append=false ) { 151 $n = count( $this->_log ); 152 if ($append && $n > 0) { 153 $this->_log[count( $this->_log )-1] .= $text; 154 } else { 155 $this->_log[] = $text; 156 } 157 } 158 159 /** 160 * @param string The glue for each log item 161 * @return string Returns the log 162 */ 163 function getLog( $glue='<br/>', $truncate=9000, $htmlSafe=false ) { 164 $logs = array(); 165 foreach ($this->_log as $log) { 166 if ($htmlSafe) { 167 $log = htmlspecialchars( $log ); 168 } 169 $logs[] = substr( $log, 0, $truncate ); 170 } 171 return implode( $glue, $logs ); 172 } 173 } 174 175 /** 176 * Task routing class 177 * @package Joomla 178 * @abstract 179 */ 180 class mosAbstractTasker { 181 /** @var array An array of the class methods to call for a task */ 182 var $_taskMap = null; 183 /** @var string The name of the current task*/ 184 var $_task = null; 185 /** @var array An array of the class methods*/ 186 var $_methods = null; 187 /** @var string A url to redirect to */ 188 var $_redirect = null; 189 /** @var string A message about the operation of the task */ 190 var $_message = null; 191 192 // action based access control 193 194 /** @var string The ACO Section */ 195 var $_acoSection = null; 196 /** @var string The ACO Section value */ 197 var $_acoSectionValue = null; 198 199 /** 200 * Constructor 201 * @param string Set the default task 202 */ 203 function mosAbstractTasker( $default='' ) { 204 $this->_taskMap = array(); 205 $this->_methods = array(); 206 foreach (get_class_methods( get_class( $this ) ) as $method) { 207 if (substr( $method, 0, 1 ) != '_') { 208 $this->_methods[] = strtolower( $method ); 209 // auto register public methods as tasks 210 $this->_taskMap[strtolower( $method )] = $method; 211 } 212 } 213 $this->_redirect = ''; 214 $this->_message = ''; 215 if ($default) { 216 $this->registerDefaultTask( $default ); 217 } 218 } 219 220 /** 221 * Sets the access control levels 222 * @param string The ACO section (eg, the component) 223 * @param string The ACO section value (if using a constant value) 224 */ 225 function setAccessControl( $section, $value=null ) { 226 $this->_acoSection = $section; 227 $this->_acoSectionValue = $value; 228 } 229 /** 230 * Access control check 231 */ 232 function accessCheck( $task ) { 233 global $acl, $my; 234 235 // only check if the derived class has set these values 236 if ($this->_acoSection) { 237 // ensure user has access to this function 238 if ($this->_acoSectionValue) { 239 // use a 'constant' task for this task handler 240 $task = $this->_acoSectionValue; 241 } 242 return $acl->acl_check( $this->_acoSection, $task, 'users', $my->usertype ); 243 } else { 244 return true; 245 } 246 } 247 248 /** 249 * Set a URL to redirect the browser to 250 * @param string A URL 251 */ 252 function setRedirect( $url, $msg = null ) { 253 $this->_redirect = $url; 254 if ($msg !== null) { 255 $this->_message = $msg; 256 } 257 } 258 /** 259 * Redirects the browser 260 */ 261 function redirect() { 262 if ($this->_redirect) { 263 mosRedirect( $this->_redirect, $this->_message ); 264 } 265 } 266 /** 267 * Register (map) a task to a method in the class 268 * @param string The task 269 * @param string The name of the method in the derived class to perform for this task 270 */ 271 function registerTask( $task, $method ) { 272 if (in_array( strtolower( $method ), $this->_methods )) { 273 $this->_taskMap[strtolower( $task )] = $method; 274 } else { 275 $this->methodNotFound( $method ); 276 } 277 } 278 /** 279 * Register the default task to perfrom if a mapping is not found 280 * @param string The name of the method in the derived class to perform if the task is not found 281 */ 282 function registerDefaultTask( $method ) { 283 $this->registerTask( '__default', $method ); 284 } 285 /** 286 * Perform a task by triggering a method in the derived class 287 * @param string The task to perform 288 * @return mixed The value returned by the function 289 */ 290 function performTask( $task ) { 291 $this->_task = $task; 292 293 $task = strtolower( $task ); 294 if (isset( $this->_taskMap[$task] )) { 295 $doTask = $this->_taskMap[$task]; 296 } else if (isset( $this->_taskMap['__default'] )) { 297 $doTask = $this->_taskMap['__default']; 298 } else { 299 return $this->taskNotFound( $this->_task ); 300 } 301 302 if ($this->accessCheck( $doTask )) { 303 return call_user_func( array( &$this, $doTask ) ); 304 } else { 305 return $this->notAllowed( $task ); 306 } 307 } 308 /** 309 * Get the last task that was to be performed 310 * @return string The task that was or is being performed 311 */ 312 function getTask() { 313 return $this->_task; 314 } 315 /** 316 * Basic method if the task is not found 317 * @param string The task 318 * @return null 319 */ 320 function taskNotFound( $task ) { 321 echo 'Task ' . $task . ' not found'; 322 return null; 323 } 324 /** 325 * Basic method if the registered method is not found 326 * @param string The name of the method in the derived class 327 * @return null 328 */ 329 function methodNotFound( $name ) { 330 echo 'Method ' . $name . ' not found'; 331 return null; 332 } 333 /** 334 * Basic method if access is not permitted to the task 335 * @param string The name of the method in the derived class 336 * @return null 337 */ 338 function notAllowed( $name ) { 339 echo _NOT_AUTH; 340 341 return null; 342 } 343 } 344 /** 345 * Class to support function caching 346 * @package Joomla 347 */ 348 class mosCache { 349 /** 350 * @return object A function cache object 351 */ 352 function &getCache( $group='' ) { 353 global $mosConfig_absolute_path, $mosConfig_caching, $mosConfig_cachepath, $mosConfig_cachetime; 354 355 require_once ( $mosConfig_absolute_path . '/includes/joomla.cache.php' ); 356 357 $options = array( 358 'cacheDir' => $mosConfig_cachepath . '/', 359 'caching' => $mosConfig_caching, 360 'defaultGroup' => $group, 361 'lifeTime' => $mosConfig_cachetime 362 ); 363 $cache = new JCache_Lite_Function( $options ); 364 return $cache; 365 } 366 /** 367 * Cleans the cache 368 */ 369 function cleanCache( $group=false ) { 370 global $mosConfig_caching; 371 if ($mosConfig_caching) { 372 $cache =& mosCache::getCache( $group ); 373 $cache->clean( $group ); 374 } 375 } 376 } 377 /** 378 * Joomla! Mainframe class 379 * 380 * Provide many supporting API functions 381 * @package Joomla 382 */ 383 class mosMainFrame { 384 /** @var database Internal database class pointer */ 385 var $_db = null; 386 /** @var object An object of configuration variables */ 387 var $_config = null; 388 /** @var object An object of path variables */ 389 var $_path = null; 390 /** @var mosSession The current session */ 391 var $_session = null; 392 /** @var string The current template */ 393 var $_template = null; 394 /** @var array An array to hold global user state within a session */ 395 var $_userstate = null; 396 /** @var array An array of page meta information */ 397 var $_head = null; 398 /** @var string Custom html string to append to the pathway */ 399 var $_custom_pathway = null; 400 /** @var boolean True if in the admin client */ 401 var $_isAdmin = false; 402 403 404 /** 405 * Class constructor 406 * @param database A database connection object 407 * @param string The url option 408 * @param string The path of the mos directory 409 */ 410 function mosMainFrame( &$db, $option, $basePath, $isAdmin=false ) { 411 $this->_db =& $db; 412 413 // load the configuration values 414 $this->_setTemplate( $isAdmin ); 415 $this->_setAdminPaths( $option, $this->getCfg( 'absolute_path' ) ); 416 if (isset( $_SESSION['session_userstate'] )) { 417 $this->_userstate =& $_SESSION['session_userstate']; 418 } else { 419 $this->_userstate = null; 420 } 421 $this->_head = array(); 422 $this->_head['title'] = $GLOBALS['mosConfig_sitename']; 423 $this->_head['meta'] = array(); 424 $this->_head['custom'] = array(); 425 426 //set the admin check 427 $this->_isAdmin = (boolean) $isAdmin; 428 429 $now = date( 'Y-m-d H:i:s', time() ); 430 $this->set( 'now', $now ); 431 } 432 433 /** 434 * Gets the id number for a client 435 * @param mixed A client identifier 436 */ 437 function getClientID( $client ) { 438 switch ($client) { 439 case '2': 440 case 'installation': 441 return 2; 442 break; 443 444 case '1': 445 case 'admin': 446 case 'administrator': 447 return 1; 448 break; 449 450 case '0': 451 case 'site': 452 case 'front': 453 default: 454 return 0; 455 break; 456 } 457 } 458 459 /** 460 * Gets the client name 461 * @param int The client identifier 462 * @return strint The text name of the client 463 */ 464 function getClientName( $client_id ) { 465 // do not translate 466 $clients = array( 'site', 'admin', 'installer' ); 467 return mosGetParam( $clients, $client_id, 'unknown' ); 468 } 469 470 /** 471 * Gets the base path for the client 472 * @param mixed A client identifier 473 * @param boolean True (default) to add traling slash 474 */ 475 function getBasePath( $client=0, $addTrailingSlash=true ) { 476 global $mosConfig_absolute_path; 477 478 switch ($client) { 479 case '0': 480 case 'site': 481 case 'front': 482 default: 483 return mosPathName( $mosConfig_absolute_path, $addTrailingSlash ); 484 break; 485 486 case '2': 487 case 'installation': 488 return mosPathName( $mosConfig_absolute_path . '/installation', $addTrailingSlash ); 489 break; 490 491 case '1': 492 case 'admin': 493 case 'administrator': 494 return mosPathName( $mosConfig_absolute_path . '/administrator', $addTrailingSlash ); 495 break; 496 497 } 498 } 499 500 /** 501 * @param string 502 */ 503 function setPageTitle( $title=null ) { 504 if (@$GLOBALS['mosConfig_pagetitles']) { 505 $title = trim( htmlspecialchars( $title ) ); 506 $title = stripslashes($title); 507 $this->_head['title'] = $title ? $GLOBALS['mosConfig_sitename'] . ' - '. $title : $GLOBALS['mosConfig_sitename']; 508 } 509 } 510 /** 511 * @param string The value of the name attibute 512 * @param string The value of the content attibute 513 * @param string Text to display before the tag 514 * @param string Text to display after the tag 515 */ 516 function addMetaTag( $name, $content, $prepend='', $append='' ) { 517 $name = trim( htmlspecialchars( $name ) ); 518 $content = trim( htmlspecialchars( $content ) ); 519 $prepend = trim( $prepend ); 520 $append = trim( $append ); 521 $this->_head['meta'][] = array( $name, $content, $prepend, $append ); 522 } 523 /** 524 * @param string The value of the name attibute 525 * @param string The value of the content attibute to append to the existing 526 * Tags ordered in with Site Keywords and Description first 527 */ 528 function appendMetaTag( $name, $content ) { 529 $name = trim( htmlspecialchars( $name ) ); 530 $n = count( $this->_head['meta'] ); 531 for ($i = 0; $i < $n; $i++) { 532 if ($this->_head['meta'][$i][0] == $name) { 533 $content = trim( htmlspecialchars( $content ) ); 534 if ( $content ) { 535 if ( !$this->_head['meta'][$i][1] ) { 536 $this->_head['meta'][$i][1] = $content ; 537 } else { 538 $this->_head['meta'][$i][1] = $content .', '. $this->_head['meta'][$i][1]; 539 } 540 } 541 return; 542 } 543 } 544 $this->addMetaTag( $name , $content ); 545 } 546 547 /** 548 * @param string The value of the name attibute 549 * @param string The value of the content attibute to append to the existing 550 */ 551 function prependMetaTag( $name, $content ) { 552 $name = trim( htmlspecialchars( $name ) ); 553 $n = count( $this->_head['meta'] ); 554 for ($i = 0; $i < $n; $i++) { 555 if ($this->_head['meta'][$i][0] == $name) { 556 $content = trim( htmlspecialchars( $content ) ); 557 $this->_head['meta'][$i][1] = $content . $this->_head['meta'][$i][1]; 558 return; 559 } 560 } 561 $this->addMetaTag( $name, $content ); 562 } 563 /** 564 * Adds a custom html string to the head block 565 * @param string The html to add to the head 566 */ 567 function addCustomHeadTag( $html ) { 568 $this->_head['custom'][] = trim( $html ); 569 } 570 /** 571 * @return string 572 */ 573 function getHead() { 574 $head = array(); 575 $head[] = '<title>' . $this->_head['title'] . '</title>'; 576 foreach ($this->_head['meta'] as $meta) { 577 if ($meta[2]) { 578 $head[] = $meta[2]; 579 } 580 $head[] = '<meta name="' . $meta[0] . '" content="' . $meta[1] . '" />'; 581 if ($meta[3]) { 582 $head[] = $meta[3]; 583 } 584 } 585 foreach ($this->_head['custom'] as $html) { 586 $head[] = $html; 587 } 588 return implode( "\n", $head ) . "\n"; 589 } 590 591 592 /** 593 * @return string 594 */ 595 function getPageTitle() { 596 return $this->_head['title']; 597 } 598 599 /** 600 * @return string 601 */ 602 function getCustomPathWay() { 603 return $this->_custom_pathway; 604 } 605 606 function appendPathWay( $html ) { 607 $this->_custom_pathway[] = $html; 608 } 609 610 /** 611 * Gets the value of a user state variable 612 * @param string The name of the variable 613 */ 614 function getUserState( $var_name ) { 615 if (is_array( $this->_userstate )) { 616 return mosGetParam( $this->_userstate, $var_name, null ); 617 } else { 618 return null; 619 } 620 } 621 /** 622 * Gets the value of a user state variable 623 * @param string The name of the user state variable 624 * @param string The name of the variable passed in a request 625 * @param string The default value for the variable if not found 626 */ 627 function getUserStateFromRequest( $var_name, $req_name, $var_default=null ) { 628 if (is_array( $this->_userstate )) { 629 if (isset( $_REQUEST[$req_name] )) { 630 $this->setUserState( $var_name, $_REQUEST[$req_name] ); 631 } else if (!isset( $this->_userstate[$var_name] )) { 632 $this->setUserState( $var_name, $var_default ); 633 } 634 635 // filter input 636 $iFilter = new InputFilter(); 637 $this->_userstate[$var_name] = $iFilter->process( $this->_userstate[$var_name] ); 638 639 return $this->_userstate[$var_name]; 640 } else { 641 return null; 642 } 643 } 644 /** 645 * Sets the value of a user state variable 646 * @param string The name of the variable 647 * @param string The value of the variable 648 */ 649 function setUserState( $var_name, $var_value ) { 650 if (is_array( $this->_userstate )) { 651 $this->_userstate[$var_name] = $var_value; 652 } 653 } 654 /** 655 * Initialises the user session 656 * 657 * Old sessions are flushed based on the configuration value for the cookie 658 * lifetime. If an existing session, then the last access time is updated. 659 * If a new session, a session id is generated and a record is created in 660 * the jos_sessions table. 661 */ 662 function initSession() { 663 // initailize session variables 664 $session =& $this->_session; 665 $session = new mosSession( $this->_db ); 666 667 // purge expired sessions 668 $session->purge('core'); 669 670 // Session Cookie `name` 671 $sessionCookieName = mosMainFrame::sessionCookieName(); 672 // Get Session Cookie `value` 673 $sessioncookie = strval( mosGetParam( $_COOKIE, $sessionCookieName, null ) ); 674 675 // Session ID / `value` 676 $sessionValueCheck = mosMainFrame::sessionCookieValue( $sessioncookie ); 677 678 // Check if existing session exists in db corresponding to Session cookie `value` 679 // extra check added in 1.0.8 to test sessioncookie value is of correct length 680 if ( $sessioncookie && strlen($sessioncookie) == 32 && $sessioncookie != '-' && $session->load($sessionValueCheck) ) { 681 // update time in session table 682 $session->time = time(); 683 $session->update(); 684 } else { 685 // Remember Me Cookie `name` 686 $remCookieName = mosMainFrame::remCookieName_User(); 687 688 // test if cookie found 689 $cookie_found = false; 690 if ( isset($_COOKIE[$sessionCookieName]) || isset($_COOKIE[$remCookieName]) || isset($_POST['force_session']) ) { 691 $cookie_found = true; 692 } 693 694 // check if neither remembermecookie or sessioncookie found 695 if (!$cookie_found) { 696 // create sessioncookie and set it to a test value set to expire on session end 697 setcookie( $sessionCookieName, '-', false, '/' ); 698 } else { 699 // otherwise, sessioncookie was found, but set to test val or the session expired, prepare for session registration and register the session 700 $url = strval( mosGetParam( $_SERVER, 'REQUEST_URI', null ) ); 701 // stop sessions being created for requests to syndicated feeds 702 if ( strpos( $url, 'option=com_rss' ) === false && strpos( $url, 'feed=' ) === false ) { 703 $session->guest = 1; 704 $session->username = ''; 705 $session->time = time(); 706 $session->gid = 0; 707 // Generate Session Cookie `value` 708 $session->generateId(); 709 710 if (!$session->insert()) { 711 die( $session->getError() ); 712 } 713 714 // create Session Tracking Cookie set to expire on session end 715 setcookie( $sessionCookieName, $session->getCookie(), false, '/' ); 716 } 717 } 718 719 // Cookie used by Remember me functionality 720 $remCookieValue = strval( mosGetParam( $_COOKIE, $remCookieName, null ) ); 721 722 // test if cookie is correct length 723 if ( strlen($remCookieValue) > 64 ) { 724 // Separate Values from Remember Me Cookie 725 $remUser = substr( $remCookieValue, 0, 32 ); 726 $remPass = substr( $remCookieValue, 32, 32 ); 727 $remID = intval( substr( $remCookieValue, 64 ) ); 728 729 // check if Remember me cookie exists. Login with usercookie info. 730 if ( strlen($remUser) == 32 && strlen($remPass) == 32 ) { 731 $this->login( $remUser, $remPass, 1, $remID ); 732 } 733 } 734 } 735 } 736 737 /* 738 * Function used to conduct admin session duties 739 * Added as of 1.0.8 740 * Deprecated 1.1 741 */ 742 function initSessionAdmin($option, $task) { 743 global $_VERSION, $mosConfig_admin_expired; 744 745 // logout check 746 if ($option == 'logout') { 747 require $GLOBALS['mosConfig_absolute_path'] .'/administrator/logout.php'; 748 exit(); 749 } 750 751 $site = $GLOBALS['mosConfig_live_site']; 752 753 // check if session name corresponds to correct format 754 if ( session_name() != md5( $site ) ) { 755 echo "<script>document.location.href='index.php'</script>\n"; 756 exit(); 757 } 758 759 // restore some session variables 760 $my = new mosUser( $this->_db ); 761 $my->id = intval( mosGetParam( $_SESSION, 'session_user_id', '' ) ); 762 $my->username = strval( mosGetParam( $_SESSION, 'session_username', '' ) ); 763 $my->usertype = strval( mosGetParam( $_SESSION, 'session_usertype', '' ) ); 764 $my->gid = intval( mosGetParam( $_SESSION, 'session_gid', '' ) ); 765 $my->params = mosGetParam( $_SESSION, 'session_user_params', '' ); 766 767 $session_id = mosGetParam( $_SESSION, 'session_id', '' ); 768 $logintime = mosGetParam( $_SESSION, 'session_logintime', '' ); 769 770 if ($session_id != session_id()) { 771 // session id does not correspond to required session format 772 echo "<script>document.location.href='index.php?mosmsg=Invalid Session'</script>\n"; 773 exit(); 774 } 775 776 // check to see if session id corresponds with correct format 777 if ($session_id == md5( $my->id . $my->username . $my->usertype . $logintime )) { 778 // if task action is to `save` or `apply` complete action before doing session checks. 779 if ($task != 'save' && $task != 'apply') { 780 // test for session_life_admin 781 if ( @$GLOBALS['mosConfig_session_life_admin'] ) { 782 $session_life_admin = $GLOBALS['mosConfig_session_life_admin']; 783 } else { 784 $session_life_admin = 1800; 785 } 786 787 // purge expired admin sessions only 788 $past = time() - $session_life_admin; 789 $query = "DELETE FROM #__session" 790 . "\n WHERE time < '" . (int) $past . "'" 791 . "\n AND guest = 1" 792 . "\n AND gid = 0" 793 . "\n AND userid <> 0" 794 ; 795 $this->_db->setQuery( $query ); 796 $this->_db->query(); 797 798 $current_time = time(); 799 800 // update session timestamp 801 $query = "UPDATE #__session" 802 . "\n SET time = " . $this->_db->Quote( $current_time ) 803 . "\n WHERE session_id = " . $this->_db->Quote( $session_id ) 804 ; 805 $this->_db->setQuery( $query ); 806 $this->_db->query(); 807 808 // set garbage cleaning timeout 809 $this->setSessionGarbageClean(); 810 811 // check against db record of session 812 $query = "SELECT COUNT( session_id )" 813 . "\n FROM #__session" 814 . "\n WHERE session_id = " . $this->_db->Quote( $session_id ) 815 . "\n AND username = ". $this->_db->Quote( $my->username ) 816 . "\n AND userid = ". intval( $my->id ) 817 ; 818 $this->_db->setQuery( $query ); 819 $count = $this->_db->loadResult(); 820 821 // if no entry in session table that corresponds boot from admin area 822 if ( $count == 0 ) { 823 $link = NULL; 824 825 if ($_SERVER['QUERY_STRING']) { 826 $link = 'index2.php?'. $_SERVER['QUERY_STRING']; 827 } 828 829 // check if site designated as a production site 830 // for a demo site disallow expired page functionality 831 // link must also be a Joomla link to stop malicious redirection 832 if ( $link && strpos( $link, 'index2.php?option=com_' ) === 0 && $_VERSION->SITE == 1 && @$mosConfig_admin_expired === '1' ) { 833 $now = time(); 834 835 $file = $this->getPath( 'com_xml', 'com_users' ); 836 $params =& new mosParameters( $my->params, $file, 'component' ); 837 838 // return to expired page functionality 839 $params->set( 'expired', $link ); 840 $params->set( 'expired_time', $now ); 841 842 // param handling 843 if (is_array( $params->toArray() )) { 844 $txt = array(); 845 foreach ( $params->toArray() as $k=>$v) { 846 $txt[] = "$k=$v"; 847 } 848 $saveparams = implode( "\n", $txt ); 849 } 850 851 // save expired page info to user data 852 $query = "UPDATE #__users" 853 . "\n SET params = ". $this->_db->Quote( $saveparams ) 854 . "\n WHERE id = " . (int) $my->id 855 . "\n AND username = ". $this->_db->Quote( $my->username ) 856 . "\n AND usertype = ". $this->_db->Quote( $my->usertype ) 857 ; 858 $this->_db->setQuery( $query ); 859 $this->_db->query(); 860 } 861 862 echo "<script>document.location.href='index.php?mosmsg=Admin Session Expired'</script>\n"; 863 exit(); 864 } else { 865 // load variables into session, used to help secure /popups/ functionality 866 $_SESSION['option'] = $option; 867 $_SESSION['task'] = $task; 868 } 869 } 870 } else if ($session_id == '') { 871 // no session_id as user has not attempted to login, or session.auto_start is switched on 872 if (ini_get( 'session.auto_start' ) || !ini_get( 'session.use_cookies' )) { 873 echo "<script>document.location.href='index.php?mosmsg=You need to login. If PHP\'s session.auto_start setting is on or session.use_cookies setting is off, you may need to correct this before you will be able to login.'</script>\n"; 874 } else { 875 echo "<script>document.location.href='index.php?mosmsg=You need to login'</script>\n"; 876 } 877 exit(); 878 } else { 879 // session id does not correspond to required session format 880 echo "<script>document.location.href='index.php?mosmsg=Invalid Session'</script>\n"; 881 exit(); 882 } 883 884 return $my; 885 } 886 887 /* 888 * Function used to set Session Garbage Cleaning 889 * garbage cleaning set at configured session time + 600 seconds 890 * Added as of 1.0.8 891 * Deprecated 1.1 892 */ 893 function setSessionGarbageClean() { 894 /** ensure that funciton is only called once */ 895 if (!defined( '_JOS_GARBAGECLEAN' )) { 896 define( '_JOS_GARBAGECLEAN', 1 ); 897 898 $garbage_timeout = $this->getCfg('session_life_admin') + 600; 899 @ini_set('session.gc_maxlifetime', $garbage_timeout); 900 } 901 } 902 903 /* 904 * Static Function used to generate the Session Cookie Name 905 * Added as of 1.0.8 906 * Deprecated 1.1 907 */ 908 function sessionCookieName() { 909 global $mainframe, $mosConfig_live_site; 910 911 if( substr( $mosConfig_live_site, 0, 7 ) == 'http://' ) { 912 $hash = md5( 'site' . substr( $mosConfig_live_site, 7 ) ); 913 } elseif( substr( $mosConfig_live_site, 0, 8 ) == 'https://' ) { 914 $hash = md5( 'site' . substr( $mosConfig_live_site, 8 ) ); 915 } else { 916 $hash = md5( 'site' . $mainframe->getCfg( 'live_site' ) ); 917 } 918 919 return $hash; 920 } 921 922 /* 923 * Static Function used to generate the Session Cookie Value 924 * Added as of 1.0.8 925 * Deprecated 1.1 926 */ 927 function sessionCookieValue( $id=null ) { 928 global $mainframe; 929 930 $type = $mainframe->getCfg( 'session_type' ); 931 932 $browser = @$_SERVER['HTTP_USER_AGENT']; 933 934 switch ($type) { 935 case 2: 936 // 1.0.0 to 1.0.7 Compatibility 937 // lowest level security 938 $value = md5( $id . $_SERVER['REMOTE_ADDR'] ); 939 break; 940 941 case 1: 942 // slightly reduced security - 3rd level IP authentication for those behind IP Proxy 943 $remote_addr = explode('.',$_SERVER['REMOTE_ADDR']); 944 $ip = $remote_addr[0] .'.'. $remote_addr[1] .'.'. $remote_addr[2]; 945 $value = mosHash( $id . $ip . $browser ); 946 break; 947 948 default: 949 // Highest security level - new default for 1.0.8 and beyond 950 $ip = $_SERVER['REMOTE_ADDR']; 951 $value = mosHash( $id . $ip . $browser ); 952 break; 953 } 954 955 return $value; 956 } 957 958 /* 959 * Static Function used to generate the Rememeber Me Cookie Name for Username information 960 * Added as of 1.0.8 961 * Depreciated 1.1 962 */ 963 function remCookieName_User() { 964 $value = mosHash( 'remembermecookieusername'. mosMainFrame::sessionCookieName() ); 965 966 return $value; 967 } 968 969 /* 970 * Static Function used to generate the Rememeber Me Cookie Name for Password information 971 * Added as of 1.0.8 972 * Depreciated 1.1 973 */ 974 function remCookieName_Pass() { 975 $value = mosHash( 'remembermecookiepassword'. mosMainFrame::sessionCookieName() ); 976 977 return $value; 978 } 979 980 /* 981 * Static Function used to generate the Remember Me Cookie Value for Username information 982 * Added as of 1.0.8 983 * Depreciated 1.1 984 */ 985 function remCookieValue_User( $username ) { 986 $value = md5( $username . mosHash( @$_SERVER['HTTP_USER_AGENT'] ) ); 987 988 return $value; 989 } 990 991 /* 992 * Static Function used to generate the Remember Me Cookie Value for Password information 993 * Added as of 1.0.8 994 * Depreciated 1.1 995 */ 996 function remCookieValue_Pass( $passwd ) { 997 $value = md5( $passwd . mosHash( @$_SERVER['HTTP_USER_AGENT'] ) ); 998 999 return $value; 1000 } 1001 1002 /** 1003 * Login validation function 1004 * 1005 * Username and encoded password is compare to db entries in the jos_users 1006 * table. A successful validation updates the current session record with 1007 * the users details. 1008 */ 1009 function login( $username=null, $passwd=null, $remember=0, $userid=NULL ) { 1010 global $acl, $_VERSION; 1011 1012 $bypost = 0; 1013 $valid_remember = false; 1014 1015 // if no username and password passed from function, then function is being called from login module/component 1016 if (!$username || !$passwd) { 1017 $username = stripslashes( strval( mosGetParam( $_POST, 'username', '' ) ) ); 1018 $passwd = stripslashes( strval( mosGetParam( $_POST, 'passwd', '' ) ) ); 1019 1020 $bypost = 1; 1021 1022 // extra check to ensure that Joomla! sessioncookie exists 1023 if (!$this->_session->session_id) { 1024 mosErrorAlert( _ALERT_ENABLED ); 1025 return; 1026 } 1027 1028 josSpoofCheck(NULL,1); 1029 } 1030 1031 $row = null; 1032 if (!$username || !$passwd) { 1033 mosErrorAlert( _LOGIN_INCOMPLETE ); 1034 exit(); 1035 } else { 1036 if ( $remember && strlen($username) == 32 && $userid ) { 1037 // query used for remember me cookie 1038 $harden = mosHash( @$_SERVER['HTTP_USER_AGENT'] ); 1039 1040 $query = "SELECT id, name, username, password, usertype, block, gid" 1041 . "\n FROM #__users" 1042 . "\n WHERE id = " . (int) $userid 1043 ; 1044 $this->_db->setQuery( $query ); 1045 $this->_db->loadObject($user); 1046 1047 list($hash, $salt) = explode(':', $user->password); 1048 1049 $check_username = md5( $user->username . $harden ); 1050 $check_password = md5( $hash . $harden ); 1051 1052 if ( $check_username == $username && $check_password == $passwd ) { 1053 $row = $user; 1054 $valid_remember = true; 1055 } 1056 } else { 1057 // query used for login via login module 1058 $query = "SELECT id, name, username, password, usertype, block, gid" 1059 . "\n FROM #__users" 1060 . "\n WHERE username = ". $this->_db->Quote( $username ) 1061 ; 1062 1063 $this->_db->setQuery( $query ); 1064 $this->_db->loadObject( $row ); 1065 } 1066 1067 if (is_object($row)) { 1068 // user blocked from login 1069 if ($row->block == 1) { 1070 mosErrorAlert(_LOGIN_BLOCKED); 1071 } 1072 1073 if (!$valid_remember) { 1074 // Conversion to new type 1075 if ((strpos($row->password, ':') === false) && $row->password == md5($passwd)) { 1076 // Old password hash storage but authentic ... lets convert it 1077 $salt = mosMakePassword(16); 1078 $crypt = md5($passwd.$salt); 1079 $row->password = $crypt.':'.$salt; 1080 1081 // Now lets store it in the database 1082 $query = 'UPDATE #__users' 1083 . ' SET password = '.$this->_db->Quote($row->password) 1084 . ' WHERE id = '.(int)$row->id; 1085 $this->_db->setQuery($query); 1086 if (!$this->_db->query()) { 1087 // This is an error but not sure what to do with it ... we'll still work for now 1088 } 1089 } 1090 1091 list($hash, $salt) = explode(':', $row->password); 1092 $cryptpass = md5($passwd.$salt); 1093 if ($hash != $cryptpass) { 1094 if ( $bypost ) { 1095 mosErrorAlert(_LOGIN_INCORRECT); 1096 } else { 1097 $this->logout(); 1098 mosRedirect('index.php'); 1099 } 1100 exit(); 1101 } 1102 } 1103 1104 // fudge the group stuff 1105 $grp = $acl->getAroGroup( $row->id ); 1106 $row->gid = 1; 1107 if ($acl->is_group_child_of( $grp->name, 'Registered', 'ARO' ) || $acl->is_group_child_of( $grp->name, 'Public Backend', 'ARO' )) { 1108 // fudge Authors, Editors, Publishers and Super Administrators into the Special Group 1109 $row->gid = 2; 1110 } 1111 $row->usertype = $grp->name; 1112 1113 // initialize session data 1114 $session =& $this->_session; 1115 $session->guest = 0; 1116 $session->username = $row->username; 1117 $session->userid = intval( $row->id ); 1118 $session->usertype = $row->usertype; 1119 $session->gid = intval( $row->gid ); 1120 $session->update(); 1121 1122 // check to see if site is a production site 1123 // allows multiple logins with same user for a demo site 1124 if ( $_VERSION->SITE ) { 1125 // delete any old front sessions to stop duplicate sessions 1126 $query = "DELETE FROM #__session" 1127 . "\n WHERE session_id != ". $this->_db->Quote( $session->session_id ) 1128 . "\n AND username = ". $this->_db->Quote( $row->username ) 1129 . "\n AND userid = " . (int) $row->id 1130 . "\n AND gid = " . (int) $row->gid 1131 . "\n AND guest = 0" 1132 ; 1133 $this->_db->setQuery( $query ); 1134 $this->_db->query(); 1135 } 1136 1137 // update user visit data 1138 $currentDate = date("Y-m-d\TH:i:s"); 1139 1140 $query = "UPDATE #__users" 1141 . "\n SET lastvisitDate = ". $this->_db->Quote( $currentDate ) 1142 . "\n WHERE id = " . (int) $session->userid 1143 ; 1144 $this->_db->setQuery($query); 1145 if (!$this->_db->query()) { 1146 die($this->_db->stderr(true)); 1147 } 1148 1149 // set remember me cookie if selected 1150 $remember = strval( mosGetParam( $_POST, 'remember', '' ) ); 1151 if ( $remember == 'yes' ) { 1152 // cookie lifetime of 365 days 1153 $lifetime = time() + 365*24*60*60; 1154 $remCookieName = mosMainFrame::remCookieName_User(); 1155 $remCookieValue = mosMainFrame::remCookieValue_User( $row->username ) . mosMainFrame::remCookieValue_Pass( $hash ) . $row->id; 1156 setcookie( $remCookieName, $remCookieValue, $lifetime, '/' ); 1157 } 1158 mosCache::cleanCache(); 1159 } else { 1160 if ( $bypost ) { 1161 mosErrorAlert(_LOGIN_INCORRECT); 1162 } else { 1163 $this->logout(); 1164 mosRedirect('index.php'); 1165 } 1166 exit(); 1167 } 1168 } 1169 } 1170 1171 /** 1172 * User logout 1173 * 1174 * Reverts the current session record back to 'anonymous' parameters 1175 */ 1176 function logout() { 1177 mosCache::cleanCache(); 1178 1179 $session =& $this->_session; 1180 $session->guest = 1; 1181 $session->username = ''; 1182 $session->userid = ''; 1183 $session->usertype = ''; 1184 $session->gid = 0; 1185 1186 $session->update(); 1187 1188 // kill remember me cookie 1189 $lifetime = time() - 86400; 1190 $remCookieName = mosMainFrame::remCookieName_User(); 1191 setcookie( $remCookieName, ' ', $lifetime, '/' ); 1192 1193 @session_destroy(); 1194 } 1195 1196 /** 1197 * @return mosUser A user object with the information from the current session 1198 */ 1199 function getUser() { 1200 global $database; 1201 1202 $user = new mosUser( $this->_db ); 1203 1204 $user->id = intval( $this->_session->userid ); 1205 $user->username = $this->_session->username; 1206 $user->usertype = $this->_session->usertype; 1207 $user->gid = intval( $this->_session->gid ); 1208 1209 if ($user->id) { 1210 $query = "SELECT id, name, email, block, sendEmail, registerDate, lastvisitDate, activation, params" 1211 . "\n FROM #__users" 1212 . "\n WHERE id = " . (int) $user->id 1213 ; 1214 $database->setQuery( $query ); 1215 $database->loadObject( $my ); 1216 1217 $user->params = $my->params; 1218 $user->name = $my->name; 1219 $user->email = $my->email; 1220 $user->block = $my->block; 1221 $user->sendEmail = $my->sendEmail; 1222 $user->registerDate = $my->registerDate; 1223 $user->lastvisitDate = $my->lastvisitDate; 1224 $user->activation = $my->activation; 1225 } 1226 1227 return $user; 1228 } 1229 /** 1230 * @param string The name of the variable (from configuration.php) 1231 * @return mixed The value of the configuration variable or null if not found 1232 */ 1233 function getCfg( $varname ) { 1234 $varname = 'mosConfig_' . $varname; 1235 if (isset( $GLOBALS[$varname] )) { 1236 return $GLOBALS[$varname]; 1237 } else { 1238 return null; 1239 } 1240 } 1241 1242 function _setTemplate( $isAdmin=false ) { 1243 global $Itemid; 1244 $mosConfig_absolute_path = $this->getCfg( 'absolute_path' ); 1245 1246 if ($isAdmin) { 1247 $query = "SELECT template" 1248 . "\n FROM #__templates_menu" 1249 . "\n WHERE client_id = 1" 1250 . "\n AND menuid = 0" 1251 ; 1252 $this->_db->setQuery( $query ); 1253 $cur_template = $this->_db->loadResult(); 1254 $path = "$mosConfig_absolute_path/administrator/templates/$cur_template/index.php"; 1255 if (!file_exists( $path )) { 1256 $cur_template = 'joomla_admin'; 1257 } 1258 } else { 1259 $assigned = ( !empty( $Itemid ) ? " OR menuid = " . (int) $Itemid : '' ); 1260 1261 $query = "SELECT template" 1262 . "\n FROM #__templates_menu" 1263 . "\n WHERE client_id = 0" 1264 . "\n AND ( menuid = 0 $assigned )" 1265 . "\n ORDER BY menuid DESC" 1266 ; 1267 $this->_db->setQuery( $query, 0, 1 ); 1268 $cur_template = $this->_db->loadResult(); 1269 1270 // TemplateChooser Start 1271 $jos_user_template = strval( mosGetParam( $_COOKIE, 'jos_user_template', '' ) ); 1272 $jos_change_template = strval( mosGetParam( $_REQUEST, 'jos_change_template', $jos_user_template ) ); 1273 if ($jos_change_template) { 1274 // clean template name 1275 $jos_change_template = preg_replace( '#\W#', '', $jos_change_template ); 1276 if ( strlen( $jos_change_template ) >= 40 ) { 1277 $jos_change_template = substr($jos_change_template, 0 , 39); 1278 } 1279 1280 // check that template exists in case it was deleted 1281 if (file_exists( $mosConfig_absolute_path .'/templates/'. $jos_change_template .'/index.php' )) { 1282 $lifetime = 60*10; 1283 $cur_template = $jos_change_template; 1284 setcookie( 'jos_user_template', "$jos_change_template", time()+$lifetime); 1285 } else { 1286 setcookie( 'jos_user_template', '', time()-3600 ); 1287 } 1288 } 1289 // TemplateChooser End 1290 } 1291 1292 $this->_template = $cur_template; 1293 } 1294 1295 function getTemplate() { 1296 return $this->_template; 1297 } 1298 1299 /** 1300 * Determines the paths for including engine and menu files 1301 * @param string The current option used in the url 1302 * @param string The base path from which to load the configuration file 1303 */ 1304 function _setAdminPaths( $option, $basePath='.' ) { 1305 $option = strtolower( $option ); 1306 1307 $this->_path = new stdClass(); 1308 1309 // security check to disable use of `/`, `\\` and `:` in $options variable 1310 if (strpos($option, '/') !== false || strpos($option, '\\') !== false || strpos($option, ':') !== false) { 1311 mosErrorAlert( 'Restricted access' ); 1312 return; 1313 } 1314 1315 $prefix = substr( $option, 0, 4 ); 1316 if ($prefix != 'com_' && $prefix != 'mod_') { 1317 // ensure backward compatibility with existing links 1318 $name = $option; 1319 $option = "com_$option"; 1320 } else { 1321 $name = substr( $option, 4 ); 1322 } 1323 1324 // components 1325 if (file_exists( "$basePath/templates/$this->_template/components/$name.html.php" )) { 1326 $this->_path->front = "$basePath/components/$option/$name.php"; 1327 $this->_path->front_html = "$basePath/templates/$this->_template/components/$name.html.php"; 1328 } else if (file_exists( "$basePath/components/$option/$name.php" )) { 1329 $this->_path->front = "$basePath/components/$option/$name.php"; 1330 $this->_path->front_html = "$basePath/components/$option/$name.html.php"; 1331 } 1332 1333 if (file_exists( "$basePath/administrator/components/$option/admin.$name.php" )) { 1334 $this->_path->admin = "$basePath/administrator/components/$option/admin.$name.php"; 1335 $this->_path->admin_html = "$basePath/administrator/components/$option/admin.$name.html.php"; 1336 } 1337 1338 if (file_exists( "$basePath/administrator/components/$option/toolbar.$name.php" )) { 1339 $this->_path->toolbar = "$basePath/administrator/components/$option/toolbar.$name.php"; 1340 $this->_path->toolbar_html = "$basePath/administrator/components/$option/toolbar.$name.html.php"; 1341 $this->_path->toolbar_default = "$basePath/administrator/includes/toolbar.html.php"; 1342 } 1343 1344 if (file_exists( "$basePath/components/$option/$name.class.php" )) { 1345 $this->_path->class = "$basePath/components/$option/$name.class.php"; 1346 } else if (file_exists( "$basePath/administrator/components/$option/$name.class.php" )) { 1347 $this->_path->class = "$basePath/administrator/components/$option/$name.class.php"; 1348 } else if (file_exists( "$basePath/includes/$name.php" )) { 1349 $this->_path->class = "$basePath/includes/$name.php"; 1350 } 1351 1352 if ($prefix == 'mod_' && file_exists("$basePath/administrator/modules/$option.php")) { 1353 $this->_path->admin = "$basePath/administrator/modules/$option.php"; 1354 $this->_path->admin_html = "$basePath/administrator/modules/mod_$name.html.php"; 1355 } else if (file_exists("$basePath/administrator/components/$option/admin.$name.php" )) { 1356 $this->_path->admin = "$basePath/administrator/components/$option/admin.$name.php"; 1357 $this->_path->admin_html = "$basePath/administrator/components/$option/admin.$name.html.php"; 1358 } else { 1359 $this->_path->admin = "$basePath/administrator/components/com_admin/admin.admin.php"; 1360 $this->_path->admin_html = "$basePath/administrator/components/com_admin/admin.admin.html.php"; 1361 } 1362 } 1363 /** 1364 * Returns a stored path variable 1365 * 1366 */ 1367 function getPath( $varname, $option='' ) { 1368 global $mosConfig_absolute_path; 1369 if ($option) { 1370 $temp = $this->_path; 1371 $this->_setAdminPaths( $option, $this->getCfg( 'absolute_path' ) ); 1372 } 1373 $result = null; 1374 if (isset( $this->_path->$varname )) { 1375 $result = $this->_path->$varname; 1376 } else { 1377 switch ($varname) { 1378 case 'com_xml': 1379 $name = substr( $option, 4 ); 1380 $path = "$mosConfig_absolute_path/administrator/components/$option/$name.xml"; 1381 if (file_exists( $path )) { 1382 $result = $path; 1383 } else { 1384 $path = "$mosConfig_absolute_path/components/$option/$name.xml"; 1385 if (file_exists( $path )) { 1386 $result = $path; 1387 } 1388 } 1389 break; 1390 1391 case 'mod0_xml': 1392 // Site modules 1393 if ($option == '') { 1394 $path = $mosConfig_absolute_path . "/modules/custom.xml"; 1395 } else { 1396 $path = $mosConfig_absolute_path . "/modules/$option.xml"; 1397 } 1398 if (file_exists( $path )) { 1399 $result = $path; 1400 } 1401 break; 1402 1403 case 'mod1_xml': 1404 // admin modules 1405 if ($option == '') { 1406 $path = $mosConfig_absolute_path . '/administrator/modules/custom.xml'; 1407 } else { 1408 $path = $mosConfig_absolute_path . "/administrator/modules/$option.xml"; 1409 } 1410 if (file_exists( $path )) { 1411 $result = $path; 1412 } 1413 break; 1414 1415 case 'bot_xml': 1416 // Site mambots 1417 $path = $mosConfig_absolute_path . "/mambots/$option.xml"; 1418 if (file_exists( $path )) { 1419 $result = $path; 1420 } 1421 break; 1422 1423 case 'menu_xml': 1424 $path = $mosConfig_absolute_path . "/administrator/components/com_menus/$option/$option.xml"; 1425 if (file_exists( $path )) { 1426 $result = $path; 1427 } 1428 break; 1429 1430 case 'installer_html': 1431 $path = $mosConfig_absolute_path . "/administrator/components/com_installer/$option/$option.html.php"; 1432 if (file_exists( $path )) { 1433 $result = $path; 1434 } 1435 break; 1436 1437 case 'installer_class': 1438 $path = $mosConfig_absolute_path . "/administrator/components/com_installer/$option/$option.class.php"; 1439 if (file_exists( $path )) { 1440 $result = $path; 1441 } 1442 break; 1443 } 1444 } 1445 if ($option) { 1446 $this->_path = $temp; 1447 } 1448 return $result; 1449 } 1450 /** 1451 * Detects a 'visit' 1452 * 1453 * This function updates the agent and domain table hits for a particular 1454 * visitor. The user agent is recorded/incremented if this is the first visit. 1455 * A cookie is set to mark the first visit. 1456 */ 1457 function detect() { 1458 global $mosConfig_enable_stats; 1459 if ($mosConfig_enable_stats == 1) { 1460 if (mosGetParam( $_COOKIE, 'mosvisitor', 0 )) { 1461 return; 1462 } 1463 setcookie( 'mosvisitor', 1 ); 1464 1465 if (phpversion() <= '4.2.1') { 1466 $agent = getenv( 'HTTP_USER_AGENT' ); 1467 $domain = @gethostbyaddr( getenv( "REMOTE_ADDR" ) ); 1468 } else { 1469 if ( isset($_SERVER['HTTP_USER_AGENT']) ) { 1470 $agent = $_SERVER['HTTP_USER_AGENT']; 1471 } else { 1472 $agent = 'Unknown'; 1473 } 1474 1475 $domain = @gethostbyaddr( $_SERVER['REMOTE_ADDR'] ); 1476 } 1477 1478 $browser = mosGetBrowser( $agent ); 1479 1480 $query = "SELECT COUNT(*)" 1481 . "\n FROM #__stats_agents" 1482 . "\n WHERE agent = " . $this->_db->Quote( $browser ) 1483 . "\n AND type = 0" 1484 ; 1485 $this->_db->setQuery( $query ); 1486 if ($this->_db->loadResult()) { 1487 $query = "UPDATE #__stats_agents" 1488 . "\n SET hits = ( hits + 1 )" 1489 . "\n WHERE agent = " . $this->_db->Quote( $browser ) 1490 . "\n AND type = 0" 1491 ; 1492 $this->_db->setQuery( $query ); 1493 } else { 1494 $query = "INSERT INTO #__stats_agents" 1495 . "\n ( agent, type )" 1496 . "\n VALUES ( " . $this->_db->Quote( $browser ) . ", 0 )" 1497 ; 1498 $this->_db->setQuery( $query ); 1499 } 1500 $this->_db->query(); 1501 1502 $os = mosGetOS( $agent ); 1503 1504 $query = "SELECT COUNT(*)" 1505 . "\n FROM #__stats_agents" 1506 . "\n WHERE agent = " . $this->_db->Quote( $os ) 1507 . "\n AND type = 1" 1508 ; 1509 $this->_db->setQuery( $query ); 1510 if ($this->_db->loadResult()) { 1511 $query = "UPDATE #__stats_agents" 1512 . "\n SET hits = ( hits + 1 )" 1513 . "\n WHERE agent = " . $this->_db->Quote( $os ) 1514 . "\n AND type = 1" 1515 ; 1516 $this->_db->setQuery( $query ); 1517 } else { 1518 $query = "INSERT INTO #__stats_agents" 1519 . "\n ( agent, type )" 1520 . "\n VALUES ( " . $this->_db->Quote( $os ) . ", 1 )" 1521 ; 1522 $this->_db->setQuery( $query ); 1523 } 1524 $this->_db->query(); 1525 1526 // tease out the last element of the domain 1527 $tldomain = split( "\.", $domain ); 1528 $tldomain = $tldomain[count( $tldomain )-1]; 1529 1530 if (is_numeric( $tldomain )) { 1531 $tldomain = "Unknown"; 1532 } 1533 1534 $query = "SELECT COUNT(*)" 1535 . "\n FROM #__stats_agents" 1536 . "\n WHERE agent = " . $this->_db->Quote( $tldomain ) 1537 . "\n AND type = 2" 1538 ; 1539 $this->_db->setQuery( $query ); 1540 if ($this->_db->loadResult()) { 1541 $query = "UPDATE #__stats_agents" 1542 . "\n SET hits = ( hits + 1 )" 1543 . "\n WHERE agent = " . $this->_db->Quote( $tldomain ) 1544 . "\n AND type = 2" 1545 ; 1546 $this->_db->setQuery( $query ); 1547 } else { 1548 $query = "INSERT INTO #__stats_agents" 1549 . "\n ( agent, type )" 1550 . "\n VALUES ( " . $this->_db->Quote( $tldomain ) . ", 2 )" 1551 ; 1552 $this->_db->setQuery( $query ); 1553 } 1554 $this->_db->query(); 1555 } 1556 } 1557 1558 /** 1559 * @return correct Itemid for Content Item 1560 */ 1561 function getItemid( $id, $typed=1, $link=1, $bs=1, $bc=1, $gbs=1 ) { 1562 global $Itemid; 1563 1564 // getItemid compatibility mode, holds maintenance version number 1565 $compat = (int) $this->getCfg('itemid_compat'); 1566 $compat = ($compat == 0)? 12 : $compat; 1567 1568 $_Itemid = ''; 1569 1570 if ($_Itemid == '' && $typed && $this->getStaticContentCount()) { 1571 $exists = 0; 1572 foreach( $this->get( '_ContentTyped', array() ) as $key => $value ) { 1573 // check if id has been tested before, if it is pull from class variable store 1574 if ( $key == $id ) { 1575 $_Itemid = $value; 1576 $exists = 1; 1577 break; 1578 } 1579 } 1580 // if id hasnt been checked before initaite query 1581 if ( !$exists ) { 1582 // Search for typed link 1583 $query = "SELECT id" 1584 . "\n FROM #__menu" 1585 . "\n WHERE type = 'content_typed'" 1586 . "\n AND published = 1" 1587 . "\n AND link = 'index.php?option=com_content&task=view&id=" . (int) $id . "'" 1588 ; 1589 $this->_db->setQuery( $query ); 1590 // pull existing query storage into temp variable 1591 $ContentTyped = $this->get( '_ContentTyped', array() ); 1592 // add query result to temp array storage 1593 $ContentTyped[$id] = $this->_db->loadResult(); 1594 // save temp array to main array storage 1595 $this->set( '_ContentTyped', $ContentTyped ); 1596 1597 $_Itemid = $ContentTyped[$id]; 1598 } 1599 } 1600 1601 if ($_Itemid == '' && $link && $this->getContentItemLinkCount()) { 1602 $exists = 0; 1603 foreach( $this->get( '_ContentItemLink', array() ) as $key => $value ) { 1604 // check if id has been tested before, if it is pull from class variable store 1605 if ( $key == $id ) { 1606 $_Itemid = $value; 1607 $exists = 1; 1608 break; 1609 } 1610 } 1611 // if id hasnt been checked before initaite query 1612 if ( !$exists ) { 1613 // Search for item link 1614 $query = "SELECT id" 1615 ."\n FROM #__menu" 1616 ."\n WHERE type = 'content_item_link'" 1617 . "\n AND published = 1" 1618 . "\n AND link = 'index.php?option=com_content&task=view&id=" . (int) $id . "'" 1619 ; 1620 $this->_db->setQuery( $query ); 1621 // pull existing query storage into temp variable 1622 $ContentItemLink = $this->get( '_ContentItemLink', array() ); 1623 // add query result to temp array storage 1624 $ContentItemLink[$id] = $this->_db->loadResult(); 1625 // save temp array to main array storage 1626 $this->set( '_ContentItemLink', $ContentItemLink ); 1627 1628 $_Itemid = $ContentItemLink[$id]; 1629 } 1630 } 1631 1632 if ($_Itemid == '') { 1633 $exists = 0; 1634 foreach( $this->get( '_ContentSection', array() ) as $key => $value ) { 1635 // check if id has been tested before, if it is pull from class variable store 1636 if ( $key == $id ) { 1637 $_Itemid = $value; 1638 $exists = 1; 1639 break; 1640 } 1641 } 1642 // if id hasnt been checked before initaite query 1643 if ( !$exists ) { 1644 $query = "SELECT ms.id AS sid, ms.type AS stype, mc.id AS cid, mc.type AS ctype, i.id as sectionid, i.id As catid, ms.published AS spub, mc.published AS cpub" 1645 . "\n FROM #__content AS i" 1646 . "\n LEFT JOIN #__sections AS s ON i.sectionid = s.id" 1647 . "\n LEFT JOIN #__menu AS ms ON ms.componentid = s.id " 1648 . "\n LEFT JOIN #__categories AS c ON i.catid = c.id" 1649 . "\n LEFT JOIN #__menu AS mc ON mc.componentid = c.id " 1650 . "\n WHERE ( ms.type IN ( 'content_section', 'content_blog_section' ) OR mc.type IN ( 'content_blog_category', 'content_category' ) )" 1651 . "\n AND i.id = " . (int) $id 1652 . "\n ORDER BY ms.type DESC, mc.type DESC, ms.id, mc.id" 1653 ; 1654 $this->_db->setQuery( $query ); 1655 $links = $this->_db->loadObjectList(); 1656 1657 if (count($links)) { 1658 foreach($links as $link) { 1659 if ($link->stype == 'content_section' && $link->sectionid == $id && !isset($content_section) && $link->spub == 1) { 1660 $content_section = $link->sid; 1661 } 1662 1663 if ($link->stype == 'content_blog_section' && $link->sectionid == $id && !isset($content_blog_section) && $link->spub == 1) { 1664 $content_blog_section = $link->sid; 1665 } 1666 1667 if ($link->ctype == 'content_blog_category' && $link->catid == $id && !isset($content_blog_category) && $link->cpub == 1) { 1668 $content_blog_category = $link->cid; 1669 } 1670 1671 if ($link->ctype == 'content_category' && $link->catid == $id && !isset($content_category) && $link->cpub == 1) { 1672 $content_category = $link->cid; 1673 } 1674 } 1675 } 1676 1677 if (!isset($content_section)) { 1678 $content_section = null; 1679 } 1680 1681 // pull existing query storage into temp variable 1682 $ContentSection = $this->get( '_ContentSection', array() ); 1683 // add query result to temp array storage 1684 $ContentSection[$id] = $content_section; 1685 // save temp array to main array storage 1686 $this->set( '_ContentSection', $ContentSection ); 1687 1688 $_Itemid = $ContentSection[$id]; 1689 } 1690 } 1691 1692 if ( $compat <= 11 && $_Itemid == '') { 1693 $exists = 0; 1694 foreach( $this->get( '_ContentBlogSection', array() ) as $key => $value ) { 1695 // check if id has been tested before, if it is pull from class variable store 1696 if ( $key == $id ) { 1697 $_Itemid = $value; 1698 $exists = 1; 1699 break; 1700 } 1701 } 1702 // if id hasnt been checked before initaite query 1703 if ( !$exists ) { 1704 if (!isset($content_blog_section)) { 1705 $content_blog_section = null; 1706 } 1707 1708 // pull existing query storage into temp variable 1709 $ContentBlogSection = $this->get( '_ContentBlogSection', array() ); 1710 // add query result to temp array storage 1711 $ContentBlogSection[$id] = $content_blog_section; 1712 // save temp array to main array storage 1713 $this->set( '_ContentBlogSection', $ContentBlogSection ); 1714 1715 $_Itemid = $ContentBlogSection[$id]; 1716 } 1717 } 1718 1719 if ($_Itemid == '') { 1720 $exists = 0; 1721 foreach( $this->get( '_ContentBlogCategory', array() ) as $key => $value ) { 1722 // check if id has been tested before, if it is pull from class variable store 1723 if ( $key == $id ) { 1724 $_Itemid = $value; 1725 $exists = 1; 1726 break; 1727 } 1728 } 1729 // if id hasnt been checked before initaite query 1730 if ( !$exists ) { 1731 if (!isset($content_blog_category)) { 1732 $content_blog_category = null; 1733 } 1734 1735 // pull existing query storage into temp variable 1736 $ContentBlogCategory = $this->get( '_ContentBlogCategory', array() ); 1737 // add query result to temp array storage 1738 $ContentBlogCategory[$id] = $content_blog_category; 1739 // save temp array to main array storage 1740 $this->set( '_ContentBlogCategory', $ContentBlogCategory ); 1741 1742 $_Itemid = $ContentBlogCategory[$id]; 1743 } 1744 } 1745 1746 if ($_Itemid == '') { 1747 // ensure that query is only called once 1748 if ( !$this->get( '_GlobalBlogSection' ) && !defined( '_JOS_GBS' ) ) { 1749 define( '_JOS_GBS', 1 ); 1750 1751 // Search in global blog section 1752 $query = "SELECT id " 1753 . "\n FROM #__menu " 1754 . "\n WHERE type = 'content_blog_section'" 1755 . "\n AND published = 1" 1756 . "\n AND componentid = 0" 1757 ; 1758 $this->_db->setQuery( $query ); 1759 $this->set( '_GlobalBlogSection', $this->_db->loadResult() ); 1760 } 1761 1762 $_Itemid = $this->get( '_GlobalBlogSection' ); 1763 } 1764 1765 if ($compat >= 12 && $_Itemid == '') { 1766 $exists = 0; 1767 foreach( $this->get( '_ContentBlogSection', array() ) as $key => $value ) { 1768 // check if id has been tested before, if it is pull from class variable store 1769 if ( $key == $id ) { 1770 $_Itemid = $value; 1771 $exists = 1; 1772 break; 1773 } 1774 } 1775 // if id hasnt been checked before initaite query 1776 if ( !$exists ) { 1777 if (!isset($content_blog_section)) { 1778 $content_blog_section = null; 1779 } 1780 1781 // pull existing query storage into temp variable 1782 $ContentBlogSection = $this->get( '_ContentBlogSection', array() ); 1783 // add query result to temp array storage 1784 $ContentBlogSection[$id] = $content_blog_section; 1785 // save temp array to main array storage 1786 $this->set( '_ContentBlogSection', $ContentBlogSection ); 1787 1788 $_Itemid = $ContentBlogSection[$id]; 1789 } 1790 } 1791 1792 if ($_Itemid == '') { 1793 $exists = 0; 1794 foreach( $this->get( '_ContentCategory', array() ) as $key => $value ) { 1795 // check if id has been tested before, if it is pull from class variable store 1796 if ( $key == $id ) { 1797 $_Itemid = $value; 1798 $exists = 1; 1799 break; 1800 } 1801 } 1802 // if id hasnt been checked before initaite query 1803 if ( !$exists ) { 1804 if (!isset($content_category)) { 1805 $content_category = null; 1806 } 1807 1808 // pull existing query storage into temp variable 1809 $ContentCategory = $this->get( '_ContentCategory', array() ); 1810 // add query result to temp array storage 1811 //$ContentCategory[$id] = $this->_db->loadResult(); 1812 $ContentCategory[$id] = $content_category; 1813 // save temp array to main array storage 1814 $this->set( '_ContentCategory', $ContentCategory ); 1815 1816 $_Itemid = $ContentCategory[$id]; 1817 } 1818 } 1819 1820 if ($_Itemid == '') { 1821 // ensure that query is only called once 1822 if ( !$this->get( '_GlobalBlogCategory' ) && !defined( '_JOS_GBC' ) ) { 1823 define( '_JOS_GBC', 1 ); 1824 1825 // Search in global blog category 1826 $query = "SELECT id " 1827 . "\n FROM #__menu " 1828 . "\n WHERE type = 'content_blog_category'" 1829 . "\n AND published = 1" 1830 . "\n AND componentid = 0" 1831 ; 1832 $this->_db->setQuery( $query ); 1833 $this->set( '_GlobalBlogCategory', $this->_db->loadResult() ); 1834 } 1835 1836 $_Itemid = $this->get( '_GlobalBlogCategory' ); 1837 } 1838 1839 if ( $_Itemid != '' ) { 1840 // if Itemid value discovered by queries, return this value 1841 return $_Itemid; 1842 } else if ( $compat >= 12 && $Itemid != 99999999 && $Itemid > 0 ) { 1843 // if queries do not return Itemid value, return Itemid of page - if it is not 99999999 1844 return $Itemid; 1845 } else if ( $compat <= 11 && $Itemid === 0 ) { 1846 // if queries do not return Itemid value, return Itemid of page - if it is not 99999999 1847 return $Itemid; 1848 } 1849 } 1850 1851 /** 1852 * @return number of Published Blog Sections 1853 * Kept for Backward Compatability 1854 */ 1855 function getBlogSectionCount( ) { 1856 return 1; 1857 } 1858 1859 /** 1860 * @return number of Published Blog Categories 1861 * Kept for Backward Compatability 1862 */ 1863 function getBlogCategoryCount( ) { 1864 return 1; 1865 } 1866 1867 /** 1868 * @return number of Published Global Blog Sections 1869 * Kept for Backward Compatability 1870 */ 1871 function getGlobalBlogSectionCount( ) { 1872 return 1; 1873 } 1874 1875 /** 1876 * @return number of Static Content 1877 */ 1878 function getStaticContentCount( ) { 1879 // ensure that query is only called once 1880 if ( !$this->get( '_StaticContentCount' ) && !defined( '_JOS_SCC' ) ) { 1881 define( '_JOS_SCC', 1 ); 1882 1883 $query = "SELECT COUNT( id )" 1884 ."\n FROM #__menu " 1885 ."\n WHERE type = 'content_typed'" 1886 ."\n AND published = 1" 1887 ; 1888 $this->_db->setQuery( $query ); 1889 // saves query result to variable 1890 $this->set( '_StaticContentCount', $this->_db->loadResult() ); 1891 } 1892 1893 return $this->get( '_StaticContentCount' ); 1894 } 1895 1896 /** 1897 * @return number of Content Item Links 1898 */ 1899 function getContentItemLinkCount( ) { 1900 // ensure that query is only called once 1901 if ( !$this->get( '_ContentItemLinkCount' ) && !defined( '_JOS_CILC' ) ) { 1902 define( '_JOS_CILC', 1 ); 1903 1904 $query = "SELECT COUNT( id )" 1905 ."\n FROM #__menu " 1906 ."\n WHERE type = 'content_item_link'" 1907 ."\n AND published = 1" 1908 ; 1909 $this->_db->setQuery( $query ); 1910 // saves query result to variable 1911 $this->set( '_ContentItemLinkCount', $this->_db->loadResult() ); 1912 } 1913 1914 return $this->get( '_ContentItemLinkCount' ); 1915 } 1916 1917 /** 1918 * @param string The name of the property 1919 * @param mixed The value of the property to set 1920 */ 1921 function set( $property, $value=null ) { 1922 $this->$property = $value; 1923 } 1924 1925 /** 1926 * @param string The name of the property 1927 * @param mixed The default value 1928 * @return mixed The value of the property 1929 */ 1930 function get($property, $default=null) { 1931 if(isset($this->$property)) { 1932 return $this->$property; 1933 } else { 1934 return $default; 1935 } 1936 } 1937 1938 /** Is admin interface? 1939 * @return boolean 1940 * @since 1.0.2 1941 */ 1942 function isAdmin() { 1943 return $this->_isAdmin; 1944 } 1945 } 1946 1947 /** 1948 * Component database table class 1949 * @package Joomla 1950 */ 1951 class mosComponent extends mosDBTable { 1952 /** @var int Primary key */ 1953 var $id = null; 1954 /** @var string */ 1955 var $name = null; 1956 /** @var string */ 1957 var $link = null; 1958 /** @var int */ 1959 var $menuid = null; 1960 /** @var int */ 1961 var $parent = null; 1962 /** @var string */ 1963 var $admin_menu_link = null; 1964 /** @var string */ 1965 var $admin_menu_alt = null; 1966 /** @var string */ 1967 var $option = null; 1968 /** @var string */ 1969 var $ordering = null; 1970 /** @var string */ 1971 var $admin_menu_img = null; 1972 /** @var int */ 1973 var $iscore = null; 1974 /** @var string */ 1975 var $params = null; 1976 1977 /** 1978 * @param database A database connector object 1979 */ 1980 function mosComponent( &$db ) { 1981 $this->mosDBTable( '#__components', 'id', $db ); 1982 } 1983 } 1984 1985 /** 1986 * Utility class for all HTML drawing classes 1987 * @package Joomla 1988 */ 1989 class mosHTML { 1990 function makeOption( $value, $text='', $value_name='value', $text_name='text' ) { 1991 $obj = new stdClass; 1992 $obj->$value_name = $value; 1993 $obj->$text_name = trim( $text ) ? $text : $value; 1994 return $obj; 1995 } 1996 1997 function writableCell( $folder, $relative=1, $text='', $visible=1 ) { 1998 $writeable = '<b><font color="green">Writeable</font></b>'; 1999 $unwriteable = '<b><font color="red">Unwriteable</font></b>'; 2000 2001 echo '<tr>'; 2002 echo '<td class="item">'; 2003 echo $text; 2004 if ( $visible ) { 2005 echo $folder . '/'; 2006 } 2007 echo '</td>'; 2008 echo '<td align="left">'; 2009 if ( $relative ) { 2010 echo is_writable( "../$folder" ) ? $writeable : $unwriteable; 2011 } else { 2012 echo is_writable( "$folder" ) ? $writeable : $unwriteable; 2013 } 2014 echo '</td>'; 2015 echo '</tr>'; 2016 } 2017 2018 /** 2019 * Generates an HTML select list 2020 * @param array An array of objects 2021 * @param string The value of the HTML name attribute 2022 * @param string Additional HTML attributes for the <select> tag 2023 * @param string The name of the object variable for the option value 2024 * @param string The name of the object variable for the option text 2025 * @param mixed The key that is selected 2026 * @returns string HTML for the select list 2027 */ 2028 function selectList( &$arr, $tag_name, $tag_attribs, $key, $text, $selected=NULL ) { 2029 // check if array 2030 if ( is_array( $arr ) ) { 2031 reset( $arr ); 2032 } 2033 2034 $html = "\n<select name=\"$tag_name\" $tag_attribs>"; 2035 $count =