Index

PHP Cross Reference of Joomla! 1.0.12 eCommerce Edition

title

Body

[close]

/includes/ -> joomla.php (source)

   1  <?php
   2  /**
   3  * @version $Id: joomla.php 5866 2006-11-28 01:13:26Z friesengeist $
   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      * Deperciated 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          // check to see if session id corresponds with correct format
 771          if ( $session_id == md5( $my->id . $my->username . $my->usertype . $logintime ) ) {
 772              // if task action is to `save` or `apply` complete action before doing session checks.
 773              if ($task != 'save' && $task != 'apply') {
 774                  // test for session_life_admin
 775                  if ( @$GLOBALS['mosConfig_session_life_admin'] ) {
 776                      $session_life_admin = $GLOBALS['mosConfig_session_life_admin'];
 777                  } else {
 778                      $session_life_admin = 1800;
 779                  }
 780  
 781                  // purge expired admin sessions only
 782                  $past = time() - $session_life_admin;
 783                  $query = "DELETE FROM #__session"
 784                  . "\n WHERE time < '" . (int) $past . "'"
 785                  . "\n AND guest = 1"
 786                  . "\n AND gid = 0"
 787                  . "\n AND userid <> 0"
 788                  ;
 789                  $this->_db->setQuery( $query );
 790                  $this->_db->query();
 791  
 792                  // update session timestamp
 793                  $current_time = time();
 794                  $query = "UPDATE #__session"
 795                  . "\n SET time = " . $this->_db->Quote( $current_time )
 796                  . "\n WHERE session_id = " . $this->_db->Quote( $session_id )
 797                  ;
 798                  $this->_db->setQuery( $query );
 799                  $this->_db->query();
 800  
 801                  // set garbage cleaning timeout
 802                  $this->setSessionGarbageClean();
 803  
 804                  // check against db record of session
 805                  $query = "SELECT COUNT( session_id )"
 806                  . "\n FROM #__session"
 807                  . "\n WHERE session_id = " . $this->_db->Quote( $session_id )
 808                  . "\n AND username = ". $this->_db->Quote( $my->username )
 809                  . "\n AND userid = ". intval( $my->id )
 810                  ;
 811                  $this->_db->setQuery( $query );
 812                  $count = $this->_db->loadResult();
 813  
 814                  // if no entry in session table that corresponds boot from admin area
 815                  if ( $count == 0 ) {
 816                      $link     = NULL;
 817  
 818                      if ($_SERVER['QUERY_STRING']) {
 819                          $link = 'index2.php?'. $_SERVER['QUERY_STRING'];
 820                      }
 821  
 822                      // check if site designated as a production site
 823                      // for a demo site disallow expired page functionality
 824                      // link must also be a Joomla link to stop malicious redirection
 825                      if ( $link && strpos( $link, 'index2.php?option=com_' ) === 0 && $_VERSION->SITE == 1 && @$mosConfig_admin_expired === '1' ) {
 826                          $now     = time();
 827  
 828                          $file     = $this->getPath( 'com_xml', 'com_users' );
 829                          $params =& new mosParameters( $my->params, $file, 'component' );
 830  
 831                          // return to expired page functionality
 832                          $params->set( 'expired',         $link );
 833                          $params->set( 'expired_time',     $now );
 834  
 835                          // param handling
 836                          if (is_array( $params->toArray() )) {
 837                              $txt = array();
 838                              foreach ( $params->toArray() as $k=>$v) {
 839                                  $txt[] = "$k=$v";
 840                              }
 841                              $saveparams = implode( "\n", $txt );
 842                          }
 843  
 844                          // save expired page info to user data
 845                          $query = "UPDATE #__users"
 846                          . "\n SET params = ". $this->_db->Quote( $saveparams )
 847                          . "\n WHERE id = " . (int) $my->id
 848                          . "\n AND username = ". $this->_db->Quote( $my->username )
 849                          . "\n AND usertype = ". $this->_db->Quote( $my->usertype )
 850                          ;
 851                          $this->_db->setQuery( $query );
 852                          $this->_db->query();
 853                      }
 854  
 855                      echo "<script>document.location.href='index.php?mosmsg=Admin Session Expired'</script>\n";
 856                      exit();
 857                  } else {
 858                      // load variables into session, used to help secure /popups/ functionality
 859                      $_SESSION['option'] = $option;
 860                      $_SESSION['task']     = $task;
 861                  }
 862              }
 863          } else if ($session_id == '') {
 864              // no session_id as user has not attempted to login, or session.auto_start is switched on
 865              if (ini_get( 'session.auto_start' ) || !ini_get( 'session.use_cookies' )) {
 866                  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";
 867              } else {
 868                  echo "<script>document.location.href='index.php?mosmsg=You need to login'</script>\n";
 869              }
 870              exit();
 871          } else {
 872              // session id does not correspond to required session format
 873              echo "<script>document.location.href='index.php?mosmsg=Invalid Session'</script>\n";
 874              exit();
 875          }
 876  
 877          return $my;
 878      }
 879  
 880      /*
 881      * Function used to set Session Garbage Cleaning
 882      * garbage cleaning set at configured session time + 600 seconds
 883      * Added as of 1.0.8
 884      * Deperciated 1.1
 885      */
 886  	function setSessionGarbageClean() {
 887          /** ensure that funciton is only called once */
 888          if (!defined( '_JOS_GARBAGECLEAN' )) {
 889              define( '_JOS_GARBAGECLEAN', 1 );
 890  
 891              $garbage_timeout = $this->getCfg('session_life_admin') + 600;
 892              @ini_set('session.gc_maxlifetime', $garbage_timeout);
 893          }
 894      }
 895  
 896      /*
 897      * Static Function used to generate the Session Cookie Name
 898      * Added as of 1.0.8
 899      * Deperciated 1.1
 900      */
 901  	function sessionCookieName() {
 902          global $mainframe;
 903  
 904          return md5( 'site' . $mainframe->getCfg( 'live_site' ) );
 905      }
 906  
 907      /*
 908      * Static Function used to generate the Session Cookie Value
 909      * Added as of 1.0.8
 910      * Deperciated 1.1
 911      */
 912  	function sessionCookieValue( $id=null ) {
 913          global $mainframe;
 914  
 915          $type         = $mainframe->getCfg( 'session_type' );
 916  
 917          $browser     = @$_SERVER['HTTP_USER_AGENT'];
 918  
 919          switch ($type) {
 920              case 2:
 921              // 1.0.0 to 1.0.7 Compatibility
 922              // lowest level security
 923                  $value             = md5( $id . $_SERVER['REMOTE_ADDR'] );
 924                  break;
 925  
 926              case 1:
 927              // slightly reduced security - 3rd level IP authentication for those behind IP Proxy
 928                  $remote_addr     = explode('.',$_SERVER['REMOTE_ADDR']);
 929                  $ip                = $remote_addr[0] .'.'. $remote_addr[1] .'.'. $remote_addr[2];
 930                  $value             = mosHash( $id . $ip . $browser );
 931                  break;
 932  
 933              default:
 934              // Highest security level - new default for 1.0.8 and beyond
 935                  $ip                = $_SERVER['REMOTE_ADDR'];
 936                  $value             = mosHash( $id . $ip . $browser );
 937                  break;
 938          }
 939  
 940          return $value;
 941      }
 942  
 943      /*
 944      * Static Function used to generate the Rememeber Me Cookie Name for Username information
 945      * Added as of 1.0.8
 946      * Depreciated 1.1
 947      */
 948  	function remCookieName_User() {
 949          $value = mosHash( 'remembermecookieusername'. mosMainFrame::sessionCookieName() );
 950  
 951          return $value;
 952      }
 953  
 954      /*
 955      * Static Function used to generate the Rememeber Me Cookie Name for Password information
 956      * Added as of 1.0.8
 957      * Depreciated 1.1
 958      */
 959  	function remCookieName_Pass() {
 960          $value = mosHash( 'remembermecookiepassword'. mosMainFrame::sessionCookieName() );
 961  
 962          return $value;
 963      }
 964  
 965      /*
 966      * Static Function used to generate the Remember Me Cookie Value for Username information
 967      * Added as of 1.0.8
 968      * Depreciated 1.1
 969      */
 970  	function remCookieValue_User( $username ) {
 971          $value = md5( $username . mosHash( @$_SERVER['HTTP_USER_AGENT'] ) );
 972  
 973          return $value;
 974      }
 975  
 976      /*
 977      * Static Function used to generate the Remember Me Cookie Value for Password information
 978      * Added as of 1.0.8
 979      * Depreciated 1.1
 980      */
 981  	function remCookieValue_Pass( $passwd ) {
 982          $value     = md5( $passwd . mosHash( @$_SERVER['HTTP_USER_AGENT'] ) );
 983  
 984          return $value;
 985      }
 986  
 987      /**
 988      * Login validation function
 989      *
 990      * Username and encoded password is compare to db entries in the jos_users
 991      * table. A successful validation updates the current session record with
 992      * the users details.
 993      */
 994  	function login( $username=null,$passwd=null, $remember=0, $userid=NULL ) {
 995          global $acl, $_VERSION;
 996  
 997          $bypost = 0;
 998  
 999          // if no username and password passed from function, then function is being called from login module/component
1000          if (!$username || !$passwd) {
1001              $username     = stripslashes( strval( mosGetParam( $_POST, 'username', '' ) ) );
1002              $passwd     = stripslashes( strval( mosGetParam( $_POST, 'passwd', '' ) ) );
1003              $passwd     = md5( $passwd );
1004  
1005              $bypost     = 1;
1006  
1007              // extra check to ensure that Joomla! sessioncookie exists
1008              if (!$this->_session->session_id) {
1009                  mosErrorAlert( _ALERT_ENABLED );
1010                  return;
1011              }
1012  
1013              josSpoofCheck(NULL,1);
1014          }
1015  
1016          $row = null;
1017          if (!$username || !$passwd) {
1018              mosErrorAlert( _LOGIN_INCOMPLETE );
1019              exit();
1020          } else {
1021              if ( $remember && strlen($username) == 32 && strlen($passwd) == 32 && $userid ) {
1022              // query used for remember me cookie
1023                  $harden = mosHash( @$_SERVER['HTTP_USER_AGENT'] );
1024  
1025                  $query = "SELECT id, name, username, password, usertype, block, gid"
1026                  . "\n FROM #__users"
1027                  . "\n WHERE id = " . (int) $userid
1028                  ;
1029                  $this->_db->setQuery( $query );
1030                  $this->_db->loadObject($user);
1031  
1032                  $check_username = md5( $user->username . $harden );
1033                  $check_password = md5( $user->password . $harden );
1034  
1035                  if ( $check_username == $username && $check_password == $passwd ) {
1036                      $row = $user;
1037                  }
1038              } else {
1039              // query used for login via login module
1040                  $query = "SELECT id, name, username, password, usertype, block, gid"
1041                  . "\n FROM #__users"
1042                  . "\n WHERE username = ". $this->_db->Quote( $username )
1043                  . "\n AND password = ". $this->_db->Quote( $passwd )
1044                  ;
1045                  $this->_db->setQuery( $query );
1046                  $this->_db->loadObject( $row );
1047              }
1048  
1049              if (is_object($row)) {
1050                  // user blocked from login
1051                  if ($row->block == 1) {
1052                      mosErrorAlert(_LOGIN_BLOCKED);
1053                  }
1054  
1055                  // fudge the group stuff
1056                  $grp = $acl->getAroGroup( $row->id );
1057                  $row->gid = 1;
1058                  if ($acl->is_group_child_of( $grp->name, 'Registered', 'ARO' ) || $acl->is_group_child_of( $grp->name, 'Public Backend', 'ARO' )) {
1059                      // fudge Authors, Editors, Publishers and Super Administrators into the Special Group
1060                      $row->gid = 2;
1061                  }
1062                  $row->usertype = $grp->name;
1063  
1064                  // initialize session data
1065                  $session             =& $this->_session;
1066                  $session->guest     = 0;
1067                  $session->username     = $row->username;
1068                  $session->userid     = intval( $row->id );
1069                  $session->usertype     = $row->usertype;
1070                  $session->gid         = intval( $row->gid );
1071                  $session->update();
1072  
1073                  // check to see if site is a production site
1074                  // allows multiple logins with same user for a demo site
1075                  if ( $_VERSION->SITE ) {
1076                      // delete any old front sessions to stop duplicate sessions
1077                      $query = "DELETE FROM #__session"
1078                      . "\n WHERE session_id != ". $this->_db->Quote( $session->session_id )
1079                      . "\n AND username = ". $this->_db->Quote( $row->username )
1080                      . "\n AND userid = " . (int) $row->id
1081                      . "\n AND gid = " . (int) $row->gid
1082                      . "\n AND guest = 0"
1083                      ;
1084                      $this->_db->setQuery( $query );
1085                      $this->_db->query();
1086                  }
1087  
1088                  // update user visit data
1089                  $currentDate = date("Y-m-d\TH:i:s");
1090  
1091                  $query = "UPDATE #__users"
1092                  . "\n SET lastvisitDate = ". $this->_db->Quote( $currentDate )
1093                  . "\n WHERE id = " . (int) $session->userid
1094                  ;
1095                  $this->_db->setQuery($query);
1096                  if (!$this->_db->query()) {
1097                      die($this->_db->stderr(true));
1098                  }
1099  
1100                  // set remember me cookie if selected
1101                  $remember = strval( mosGetParam( $_POST, 'remember', '' ) );
1102                  if ( $remember == 'yes' ) {
1103                      // cookie lifetime of 365 days
1104                      $lifetime         = time() + 365*24*60*60;
1105                      $remCookieName     = mosMainFrame::remCookieName_User();
1106                      $remCookieValue = mosMainFrame::remCookieValue_User( $row->username ) . mosMainFrame::remCookieValue_Pass( $row->password ) . $row->id;
1107                      setcookie( $remCookieName, $remCookieValue, $lifetime, '/' );
1108                  }
1109                  mosCache::cleanCache();
1110              } else {
1111                  if ( $bypost ) {
1112                      mosErrorAlert(_LOGIN_INCORRECT);
1113                  } else {
1114                      $this->logout();
1115                      mosRedirect('index.php');
1116                  }
1117                  exit();
1118              }
1119          }
1120      }
1121  
1122      /**
1123      * User logout
1124      *
1125      * Reverts the current session record back to 'anonymous' parameters
1126      */
1127  	function logout() {
1128          mosCache::cleanCache();
1129  
1130          $session             =& $this->_session;
1131          $session->guest     = 1;
1132          $session->username     = '';
1133          $session->userid     = '';
1134          $session->usertype     = '';
1135          $session->gid         = 0;
1136  
1137          $session->update();
1138  
1139          // kill remember me cookie
1140          $lifetime         = time() - 86400;
1141          $remCookieName     = mosMainFrame::remCookieName_User();
1142          setcookie( $remCookieName, ' ', $lifetime, '/' );
1143  
1144          @session_destroy();
1145      }
1146  
1147      /**
1148      * @return mosUser A user object with the information from the current session
1149      */
1150  	function getUser() {
1151          global $database;
1152  
1153          $user = new mosUser( $this->_db );
1154  
1155          $user->id             = intval( $this->_session->userid );
1156          $user->username     = $this->_session->username;
1157          $user->usertype     = $this->_session->usertype;
1158          $user->gid             = intval( $this->_session->gid );
1159  
1160          if ($user->id) {
1161              $query = "SELECT id, name, email, block, sendEmail, registerDate, lastvisitDate, activation, params"
1162              . "\n FROM #__users"
1163              . "\n WHERE id = " . (int) $user->id
1164              ;
1165              $database->setQuery( $query );
1166              $database->loadObject( $my );
1167  
1168              $user->params             = $my->params;
1169              $user->name                = $my->name;
1170              $user->email            = $my->email;
1171              $user->block            = $my->block;
1172              $user->sendEmail        = $my->sendEmail;
1173              $user->registerDate        = $my->registerDate;
1174              $user->lastvisitDate    = $my->lastvisitDate;
1175              $user->activation        = $my->activation;
1176          }
1177  
1178          return $user;
1179      }
1180      /**
1181       * @param string The name of the variable (from configuration.php)
1182       * @return mixed The value of the configuration variable or null if not found
1183       */
1184  	function getCfg( $varname ) {
1185          $varname = 'mosConfig_' . $varname;
1186          if (isset( $GLOBALS[$varname] )) {
1187              return $GLOBALS[$varname];
1188          } else {
1189              return null;
1190          }
1191      }
1192  
1193  	function _setTemplate( $isAdmin=false ) {
1194          global $Itemid;
1195          $mosConfig_absolute_path = $this->getCfg( 'absolute_path' );
1196  
1197          if ($isAdmin) {
1198              $query = "SELECT template"
1199              . "\n FROM #__templates_menu"
1200              . "\n WHERE client_id = 1"
1201              . "\n AND menuid = 0"
1202              ;
1203              $this->_db->setQuery( $query );
1204              $cur_template = $this->_db->loadResult();
1205              $path = "$mosConfig_absolute_path/administrator/templates/$cur_template/index.php";
1206              if (!file_exists( $path )) {
1207                  $cur_template = 'joomla_admin';
1208              }
1209          } else {
1210              $assigned = ( !empty( $Itemid ) ? " OR menuid = " . (int) $Itemid : '' );
1211  
1212              $query = "SELECT template"
1213              . "\n FROM #__templates_menu"
1214              . "\n WHERE client_id = 0"
1215              . "\n AND ( menuid = 0 $assigned )"
1216              . "\n ORDER BY menuid DESC"
1217              ;
1218              $this->_db->setQuery( $query, 0, 1 );
1219              $cur_template = $this->_db->loadResult();
1220  
1221              // TemplateChooser Start
1222              $jos_user_template         = strval( mosGetParam( $_COOKIE, 'jos_user_template', '' ) );
1223              $jos_change_template     = strval( mosGetParam( $_REQUEST, 'jos_change_template', $jos_user_template ) );
1224              if ($jos_change_template) {
1225                  // clean template name
1226                  $jos_change_template = preg_replace( '#\W#', '', $jos_change_template );
1227                  if ( strlen( $jos_change_template ) >= 40 ) {
1228                      $jos_change_template = substr($jos_change_template, 0 , 39);
1229                  }
1230  
1231                  // check that template exists in case it was deleted
1232                  if (file_exists( $mosConfig_absolute_path .'/templates/'. $jos_change_template .'/index.php' )) {
1233                      $lifetime         = 60*10;
1234                      $cur_template     = $jos_change_template;
1235                      setcookie( 'jos_user_template', "$jos_change_template", time()+$lifetime);
1236                  } else {
1237                      setcookie( 'jos_user_template', '', time()-3600 );
1238                  }
1239              }
1240              // TemplateChooser End
1241          }
1242  
1243          $this->_template = $cur_template;
1244      }
1245  
1246  	function getTemplate() {
1247          return $this->_template;
1248      }
1249  
1250      /**
1251      * Determines the paths for including engine and menu files
1252      * @param string The current option used in the url
1253      * @param string The base path from which to load the configuration file
1254      */
1255  	function _setAdminPaths( $option, $basePath='.' ) {
1256          $option         = strtolower( $option );
1257  
1258          $this->_path     = new stdClass();
1259  
1260          // security check to disable use of `/`, `\\` and `:` in $options variable
1261          if (strpos($option, '/') !== false || strpos($option, '\\') !== false || strpos($option, ':') !== false) {
1262              mosErrorAlert( 'Restricted access' );
1263              return;
1264          }
1265  
1266          $prefix = substr( $option, 0, 4 );
1267          if ($prefix != 'com_' && $prefix != 'mod_') {
1268              // ensure backward compatibility with existing links
1269              $name     = $option;
1270              $option = "com_$option";
1271          } else {
1272              $name     = substr( $option, 4 );
1273          }
1274  
1275          // components
1276          if (file_exists( "$basePath/templates/$this->_template/components/$name.html.php" )) {
1277              $this->_path->front         = "$basePath/components/$option/$name.php";
1278              $this->_path->front_html     = "$basePath/templates/$this->_template/components/$name.html.php";
1279          } else if (file_exists( "$basePath/components/$option/$name.php" )) {
1280              $this->_path->front         = "$basePath/components/$option/$name.php";
1281              $this->_path->front_html     = "$basePath/components/$option/$name.html.php";
1282          }
1283  
1284          if (file_exists( "$basePath/administrator/components/$option/admin.$name.php" )) {
1285              $this->_path->admin         = "$basePath/administrator/components/$option/admin.$name.php";
1286              $this->_path->admin_html     = "$basePath/administrator/components/$option/admin.$name.html.php";
1287          }
1288  
1289          if (file_exists( "$basePath/administrator/components/$option/toolbar.$name.php" )) {
1290              $this->_path->toolbar             = "$basePath/administrator/components/$option/toolbar.$name.php";
1291              $this->_path->toolbar_html         = "$basePath/administrator/components/$option/toolbar.$name.html.php";
1292              $this->_path->toolbar_default     = "$basePath/administrator/includes/toolbar.html.php";
1293          }
1294  
1295          if (file_exists( "$basePath/components/$option/$name.class.php" )) {
1296              $this->_path->class = "$basePath/components/$option/$name.class.php";
1297          } else if (file_exists( "$basePath/administrator/components/$option/$name.class.php" )) {
1298              $this->_path->class = "$basePath/administrator/components/$option/$name.class.php";
1299          } else if (file_exists( "$basePath/includes/$name.php" )) {
1300              $this->_path->class = "$basePath/includes/$name.php";
1301          }
1302  
1303          if ($prefix == 'mod_' && file_exists("$basePath/administrator/modules/$option.php")) {
1304              $this->_path->admin         = "$basePath/administrator/modules/$option.php";
1305              $this->_path->admin_html     = "$basePath/administrator/modules/mod_$name.html.php";
1306          } else if (file_exists("$basePath/administrator/components/$option/admin.$name.php" )) {
1307              $this->_path->admin         = "$basePath/administrator/components/$option/admin.$name.php";
1308              $this->_path->admin_html     = "$basePath/administrator/components/$option/admin.$name.html.php";
1309          } else {
1310              $this->_path->admin         = "$basePath/administrator/components/com_admin/admin.admin.php";
1311              $this->_path->admin_html     = "$basePath/administrator/components/com_admin/admin.admin.html.php";
1312          }
1313      }
1314      /**
1315      * Returns a stored path variable
1316      *
1317      */
1318  	function getPath( $varname, $option='' ) {
1319          global $mosConfig_absolute_path;
1320          if ($option) {
1321              $temp = $this->_path;
1322              $this->_setAdminPaths( $option, $this->getCfg( 'absolute_path' ) );
1323          }
1324          $result = null;
1325          if (isset( $this->_path->$varname )) {
1326              $result = $this->_path->$varname;
1327          } else {
1328              switch ($varname) {
1329                  case 'com_xml':
1330                      $name = substr( $option, 4 );
1331                      $path = "$mosConfig_absolute_path/administrator/components/$option/$name.xml";
1332                      if (file_exists( $path )) {
1333                          $result = $path;
1334                      } else {
1335                          $path = "$mosConfig_absolute_path/components/$option/$name.xml";
1336                          if (file_exists( $path )) {
1337                              $result = $path;
1338                          }
1339                      }
1340                      break;
1341  
1342                  case 'mod0_xml':
1343                      // Site modules
1344                      if ($option == '') {
1345                          $path = $mosConfig_absolute_path . "/modules/custom.xml";
1346                      } else {
1347                          $path = $mosConfig_absolute_path . "/modules/$option.xml";
1348                      }
1349                      if (file_exists( $path )) {
1350                          $result = $path;
1351                      }
1352                      break;
1353  
1354                  case 'mod1_xml':
1355                      // admin modules
1356                      if ($option == '') {
1357                          $path = $mosConfig_absolute_path . '/administrator/modules/custom.xml';
1358                      } else {
1359                          $path = $mosConfig_absolute_path . "/administrator/modules/$option.xml";
1360                      }
1361                      if (file_exists( $path )) {
1362                          $result = $path;
1363                      }
1364                      break;
1365  
1366                  case 'bot_xml':
1367                      // Site mambots
1368                      $path = $mosConfig_absolute_path . "/mambots/$option.xml";
1369                      if (file_exists( $path )) {
1370                          $result = $path;
1371                      }
1372                      break;
1373  
1374                  case 'menu_xml':
1375                      $path = $mosConfig_absolute_path . "/administrator/components/com_menus/$option/$option.xml";
1376                      if (file_exists( $path )) {
1377                          $result = $path;
1378                      }
1379                      break;
1380  
1381                  case 'installer_html':
1382                      $path = $mosConfig_absolute_path . "/administrator/components/com_installer/$option/$option.html.php";
1383                      if (file_exists( $path )) {
1384                          $result = $path;
1385                      }
1386                      break;
1387  
1388                  case 'installer_class':
1389                      $path = $mosConfig_absolute_path . "/administrator/components/com_installer/$option/$option.class.php";
1390                      if (file_exists( $path )) {
1391                          $result = $path;
1392                      }
1393                      break;
1394              }
1395          }
1396          if ($option) {
1397              $this->_path = $temp;
1398          }
1399          return $result;
1400      }
1401      /**
1402      * Detects a 'visit'
1403      *
1404      * This function updates the agent and domain table hits for a particular
1405      * visitor.  The user agent is recorded/incremented if this is the first visit.
1406      * A cookie is set to mark the first visit.
1407      */
1408  	function detect() {
1409          global $mosConfig_enable_stats;
1410          if ($mosConfig_enable_stats == 1) {
1411              if (mosGetParam( $_COOKIE, 'mosvisitor', 0 )) {
1412                  return;
1413              }
1414              setcookie( 'mosvisitor', 1 );
1415  
1416              if (phpversion() <= '4.2.1') {
1417                  $agent = getenv( 'HTTP_USER_AGENT' );
1418                  $domain = @gethostbyaddr( getenv( "REMOTE_ADDR" ) );
1419              } else {
1420                  if ( isset($_SERVER['HTTP_USER_AGENT']) ) {
1421                      $agent = $_SERVER['HTTP_USER_AGENT'];
1422                  } else {
1423                      $agent = 'Unknown';
1424                  }
1425  
1426                  $domain = @gethostbyaddr( $_SERVER['REMOTE_ADDR'] );
1427              }
1428  
1429              $browser = mosGetBrowser( $agent );
1430  
1431              $query = "SELECT COUNT(*)"
1432              . "\n FROM #__stats_agents"
1433              . "\n WHERE agent = " . $this->_db->Quote( $browser )
1434              . "\n AND type = 0"
1435              ;
1436              $this->_db->setQuery( $query );
1437              if ($this->_db->loadResult()) {
1438                  $query = "UPDATE #__stats_agents"
1439                  . "\n SET hits = ( hits + 1 )"
1440                  . "\n WHERE agent = " . $this->_db->Quote( $browser )
1441                  . "\n AND type = 0"
1442                  ;
1443                  $this->_db->setQuery( $query );
1444              } else {
1445                  $query = "INSERT INTO #__stats_agents"
1446                  . "\n ( agent, type )"
1447                  . "\n VALUES ( " . $this->_db->Quote( $browser ) . ", 0 )"
1448                  ;
1449                  $this->_db->setQuery( $query );
1450              }
1451              $this->_db->query();
1452  
1453              $os = mosGetOS( $agent );
1454  
1455              $query = "SELECT COUNT(*)"
1456              . "\n FROM #__stats_agents"
1457              . "\n WHERE agent = " . $this->_db->Quote( $os )
1458              . "\n AND type = 1"
1459              ;
1460              $this->_db->setQuery( $query );
1461              if ($this->_db->loadResult()) {
1462                  $query = "UPDATE #__stats_agents"
1463                  . "\n SET hits = ( hits + 1 )"
1464                  . "\n WHERE agent = " . $this->_db->Quote( $os )
1465                  . "\n AND type = 1"
1466                  ;
1467                  $this->_db->setQuery( $query );
1468              } else {
1469                  $query = "INSERT INTO #__stats_agents"
1470                  . "\n ( agent, type )"
1471                  . "\n VALUES ( " . $this->_db->Quote( $os ) . ", 1 )"
1472                  ;
1473                  $this->_db->setQuery( $query );
1474              }
1475              $this->_db->query();
1476  
1477              // tease out the last element of the domain
1478              $tldomain = split( "\.", $domain );
1479              $tldomain = $tldomain[count( $tldomain )-1];
1480  
1481              if (is_numeric( $tldomain )) {
1482                  $tldomain = "Unknown";
1483              }
1484  
1485              $query = "SELECT COUNT(*)"
1486              . "\n FROM #__stats_agents"
1487              . "\n WHERE agent = " . $this->_db->Quote( $tldomain )
1488              . "\n AND type = 2"
1489              ;
1490              $this->_db->setQuery( $query );
1491              if ($this->_db->loadResult()) {
1492                  $query = "UPDATE #__stats_agents"
1493                  . "\n SET hits = ( hits + 1 )"
1494                  . "\n WHERE agent = " . $this->_db->Quote( $tldomain )
1495                  . "\n AND type = 2"
1496                  ;
1497                  $this->_db->setQuery( $query );
1498              } else {
1499                  $query = "INSERT INTO #__stats_agents"
1500                  . "\n ( agent, type )"
1501                  . "\n VALUES ( " . $this->_db->Quote( $tldomain ) . ", 2 )"
1502                  ;
1503                  $this->_db->setQuery( $query );
1504              }
1505              $this->_db->query();
1506          }
1507      }
1508  
1509      /**
1510      * @return correct Itemid for Content Item
1511      */
1512  	function getItemid( $id, $typed=1, $link=1, $bs=1, $bc=1, $gbs=1 ) {
1513          global $Itemid;
1514  
1515          $_Itemid = '';
1516  
1517          if ($_Itemid == '' && $typed && $this->getStaticContentCount()) {
1518              $exists = 0;
1519              foreach( $this->get( '_ContentTyped', array() ) as $key => $value ) {
1520                  // check if id has been tested before, if it is pull from class variable store
1521                  if ( $key == $id ) {
1522                      $_Itemid     = $value;
1523                      $exists     = 1;
1524                      break;
1525                  }
1526              }
1527              // if id hasnt been checked before initaite query
1528              if ( !$exists ) {
1529                  // Search for typed link
1530                  $query = "SELECT id"
1531                  . "\n FROM #__menu"
1532                  . "\n WHERE type = 'content_typed'"
1533                  . "\n AND published = 1"
1534                  . "\n AND link = 'index.php?option=com_content&task=view&id=" . (int) $id . "'"
1535                  ;
1536                  $this->_db->setQuery( $query );
1537                  // pull existing query storage into temp variable
1538                  $ContentTyped         = $this->get( '_ContentTyped', array() );
1539                  // add query result to temp array storage
1540                  $ContentTyped[$id]     = $this->_db->loadResult();
1541                  // save temp array to main array storage
1542                  $this->set( '_ContentTyped', $ContentTyped );
1543  
1544                  $_Itemid = $ContentTyped[$id];
1545              }
1546          }
1547  
1548          if ($_Itemid == '' && $link && $this->getContentItemLinkCount()) {
1549              $exists = 0;
1550              foreach( $this->get( '_ContentItemLink', array() ) as $key => $value ) {
1551              // check if id has been tested before, if it is pull from class variable store
1552                  if ( $key == $id ) {
1553                      $_Itemid     = $value;
1554                      $exists     = 1;
1555                      break;
1556                  }
1557              }
1558              // if id hasnt been checked before initaite query
1559              if ( !$exists ) {
1560                  // Search for item link
1561                  $query = "SELECT id"
1562                  ."\n FROM #__menu"
1563                  ."\n WHERE type = 'content_item_link'"
1564                  . "\n AND published = 1"
1565                  . "\n AND link = 'index.php?option=com_content&task=view&id=" . (int) $id . "'"
1566                  ;
1567                  $this->_db->setQuery( $query );
1568                  // pull existing query storage into temp variable
1569                  $ContentItemLink         = $this->get( '_ContentItemLink', array() );
1570                  // add query result to temp array storage
1571                  $ContentItemLink[$id]     = $this->_db->loadResult();
1572                  // save temp array to main array storage
1573                  $this->set( '_ContentItemLink', $ContentItemLink );
1574  
1575                  $_Itemid = $ContentItemLink[$id];
1576              }
1577          }
1578  
1579          if ($_Itemid == '') {
1580              $exists = 0;
1581              foreach( $this->get( '_ContentSection', array() ) as $key => $value ) {
1582              // check if id has been tested before, if it is pull from class variable store
1583                  if ( $key == $id ) {
1584                      $_Itemid     = $value;
1585                      $exists     = 1;
1586                      break;
1587                  }
1588              }
1589              // if id hasnt been checked before initaite query
1590              if ( !$exists ) {
1591                  $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"
1592                  . "\n FROM #__content AS i"
1593                  . "\n LEFT JOIN #__sections AS s ON i.sectionid = s.id"
1594                  . "\n LEFT JOIN #__menu AS ms ON ms.componentid = s.id "
1595                  . "\n LEFT JOIN #__categories AS c ON i.catid = c.id"
1596                  . "\n LEFT JOIN #__menu AS mc ON mc.componentid = c.id "
1597                  . "\n WHERE ( ms.type IN ( 'content_section', 'content_blog_section' ) OR mc.type IN ( 'content_blog_category', 'content_category' ) )"
1598                  . "\n AND i.id = " . (int) $id
1599                  . "\n ORDER BY ms.type DESC, mc.type DESC, ms.id, mc.id"
1600                  ;
1601                  $this->_db->setQuery( $query );
1602                  $links = $this->_db->loadObjectList();
1603  
1604                  if (count($links)) {
1605                      foreach($links as $link) {
1606                          if ($link->stype == 'content_section' && $link->sectionid == $id && !isset($content_section) && $link->spub == 1) {
1607                              $content_section = $link->sid;
1608                          }
1609  
1610                          if ($link->stype == 'content_blog_section' && $link->sectionid == $id && !isset($content_blog_section) && $link->spub == 1) {
1611                              $content_blog_section = $link->sid;
1612                          }
1613  
1614                          if ($link->ctype == 'content_blog_category' && $link->catid == $id && !isset($content_blog_category) && $link->cpub == 1) {
1615                              $content_blog_category = $link->cid;
1616                          }
1617  
1618                          if ($link->ctype == 'content_category' && $link->catid == $id && !isset($content_category) && $link->cpub == 1) {
1619                              $content_category = $link->cid;
1620                          }
1621                      }
1622                  }
1623  
1624                  if (!isset($content_section)) {
1625                      $content_section = null;
1626                  }
1627  
1628                  // pull existing query storage into temp variable
1629                  $ContentSection         = $this->get( '_ContentSection', array() );
1630                  // add query result to temp array storage
1631                  $ContentSection[$id]     = $content_section;
1632                  // save temp array to main array storage
1633                  $this->set( '_ContentSection', $ContentSection );
1634  
1635                  $_Itemid = $ContentSection[$id];
1636              }
1637          }
1638  
1639          if ($_Itemid == '') {
1640              $exists = 0;
1641              foreach( $this->get( '_ContentBlogCategory', array() ) as $key => $value ) {
1642                  // check if id has been tested before, if it is pull from class variable store
1643                  if ( $key == $id ) {
1644                      $_Itemid     = $value;
1645                      $exists     = 1;
1646                      break;
1647                  }
1648              }
1649              // if id hasnt been checked before initaite query
1650              if ( !$exists ) {
1651                  if (!isset($content_blog_category)) {
1652                      $content_blog_category = null;
1653                  }
1654  
1655                  // pull existing query storage into temp variable
1656                  $ContentBlogCategory         = $this->get( '_ContentBlogCategory', array() );
1657                  // add query result to temp array storage
1658                  $ContentBlogCategory[$id]     = $content_blog_category;
1659                  // save temp array to main array storage
1660                  $this->set( '_ContentBlogCategory', $ContentBlogCategory );
1661  
1662                  $_Itemid = $ContentBlogCategory[$id];
1663              }
1664          }
1665  
1666          if ($_Itemid == '') {
1667              // ensure that query is only called once
1668              if ( !$this->get( '_GlobalBlogSection' ) && !defined( '_JOS_GBS' ) ) {
1669                  define( '_JOS_GBS', 1 );
1670  
1671                  // Search in global blog section
1672                  $query = "SELECT id "
1673                  . "\n FROM #__menu "
1674                  . "\n WHERE type = 'content_blog_section'"
1675                  . "\n AND published = 1"
1676                  . "\n AND componentid = 0"
1677                  ;
1678                  $this->_db->setQuery( $query );
1679                  $this->set( '_GlobalBlogSection', $this->_db->loadResult() );
1680              }
1681  
1682              $_Itemid = $this->get( '_GlobalBlogSection' );
1683          }
1684  
1685          if ($_Itemid == '') {
1686              $exists = 0;
1687              foreach( $this->get( '_ContentBlogSection', array() ) as $key => $value ) {
1688                  // check if id has been tested before, if it is pull from class variable store
1689                  if ( $key == $id ) {
1690                      $_Itemid     = $value;
1691                      $exists     = 1;
1692                      break;
1693                  }
1694              }
1695              // if id hasnt been checked before initaite query
1696              if ( !$exists ) {
1697                  if (!isset($content_blog_section)) {
1698                      $content_blog_section = null;
1699                  }
1700  
1701                  // pull existing query storage into temp variable
1702                  $ContentBlogSection         = $this->get( '_ContentBlogSection', array() );
1703                  // add query result to temp array storage
1704                  $ContentBlogSection[$id]     = $content_blog_section;
1705                  // save temp array to main array storage
1706                  $this->set( '_ContentBlogSection', $ContentBlogSection );
1707  
1708                  $_Itemid = $ContentBlogSection[$id];
1709              }
1710          }
1711  
1712          if ($_Itemid == '') {
1713              $exists = 0;
1714              foreach( $this->get( '_ContentCategory', array() ) as $key => $value ) {
1715                  // check if id has been tested before, if it is pull from class variable store
1716                  if ( $key == $id ) {
1717                      $_Itemid     = $value;
1718                      $exists     = 1;
1719                      break;
1720                  }
1721              }
1722              // if id hasnt been checked before initaite query
1723              if ( !$exists ) {
1724                  if (!isset($content_category)) {
1725                      $content_category = null;
1726                  }
1727  
1728                  // pull existing query storage into temp variable
1729                  $ContentCategory         = $this->get( '_ContentCategory', array() );
1730                  // add query result to temp array storage
1731                  //$ContentCategory[$id]     = $this->_db->loadResult();
1732                  $ContentCategory[$id]     = $content_category;
1733                  // save temp array to main array storage
1734                  $this->set( '_ContentCategory', $ContentCategory );
1735  
1736                  $_Itemid = $ContentCategory[$id];
1737              }
1738          }
1739  
1740          if ($_Itemid == '') {
1741              // ensure that query is only called once
1742              if ( !$this->get( '_GlobalBlogCategory' ) && !defined( '_JOS_GBC' ) ) {
1743                  define( '_JOS_GBC', 1 );
1744  
1745                  // Search in global blog category
1746                  $query = "SELECT id "
1747                  . "\n FROM #__menu "
1748                  . "\n WHERE type = 'content_blog_category'"
1749                  . "\n AND published = 1"
1750                  . "\n AND componentid = 0"
1751                  ;
1752                  $this->_db->setQuery( $query );
1753                  $this->set( '_GlobalBlogCategory', $this->_db->loadResult() );
1754              }
1755  
1756              $_Itemid = $this->get( '_GlobalBlogCategory' );
1757          }
1758  
1759          if ( $_Itemid != '' ) {
1760          // if Itemid value discovered by queries, return this value
1761              return $_Itemid;
1762          } else if ( $Itemid != 99999999 && $Itemid === 0 ) {
1763          // if queries do not return Itemid value, return Itemid of page - if it is not 99999999
1764              return $Itemid;
1765          }
1766      }
1767  
1768      /**
1769      * @return number of Published Blog Sections
1770      * Kept for Backward Compatability
1771      */
1772  	function getBlogSectionCount( ) {
1773          return 1;
1774      }
1775  
1776      /**
1777      * @return number of Published Blog Categories
1778      * Kept for Backward Compatability
1779      */
1780  	function getBlogCategoryCount( ) {
1781          return 1;
1782      }
1783  
1784      /**
1785      * @return number of Published Global Blog Sections
1786      * Kept for Backward Compatability
1787      */
1788  	function getGlobalBlogSectionCount( ) {
1789          return 1;
1790      }
1791  
1792      /**
1793      * @return number of Static Content
1794      */
1795  	function getStaticContentCount( ) {
1796          // ensure that query is only called once
1797          if ( !$this->get( '_StaticContentCount' ) && !defined( '_JOS_SCC' ) ) {
1798              define( '_JOS_SCC', 1 );
1799  
1800              $query = "SELECT COUNT( id )"
1801              ."\n FROM #__menu "
1802              ."\n WHERE type = 'content_typed'"
1803              ."\n AND published = 1"
1804              ;
1805              $this->_db->setQuery( $query );
1806              // saves query result to variable
1807              $this->set( '_StaticContentCount', $this->_db->loadResult() );
1808          }
1809  
1810          return $this->get( '_StaticContentCount' );
1811      }
1812  
1813      /**
1814      * @return number of Content Item Links
1815      */
1816  	function getContentItemLinkCount( ) {
1817          // ensure that query is only called once
1818          if ( !$this->get( '_ContentItemLinkCount' ) && !defined( '_JOS_CILC' ) ) {
1819              define( '_JOS_CILC', 1 );
1820  
1821              $query = "SELECT COUNT( id )"
1822              ."\n FROM #__menu "
1823              ."\n WHERE type = 'content_item_link'"
1824              ."\n AND published = 1"
1825              ;
1826              $this->_db->setQuery( $query );
1827              // saves query result to variable
1828              $this->set( '_ContentItemLinkCount', $this->_db->loadResult() );
1829          }
1830  
1831          return $this->get( '_ContentItemLinkCount' );
1832      }
1833  
1834      /**
1835      * @param string The name of the property
1836      * @param mixed The value of the property to set
1837      */
1838  	function set( $property, $value=null ) {
1839          $this->$property = $value;
1840      }
1841  
1842      /**
1843      * @param string The name of the property
1844      * @param mixed  The default value
1845      * @return mixed The value of the property
1846      */
1847  	function get($property, $default=null) {
1848          if(isset($this->$property)) {
1849              return $this->$property;
1850          } else {
1851              return $default;
1852          }
1853      }
1854  
1855      /** Is admin interface?
1856       * @return boolean
1857       * @since 1.0.2
1858       */
1859  	function isAdmin() {
1860          return $this->_isAdmin;
1861      }
1862  }
1863  
1864  /**
1865  * Component database table class
1866  * @package Joomla
1867  */
1868  class mosComponent extends mosDBTable {
1869      /** @var int Primary key */
1870      var $id                    = null;
1871      /** @var string */
1872      var $name                = null;
1873      /** @var string */
1874      var $link                = null;
1875      /** @var int */
1876      var $menuid                = null;
1877      /** @var int */
1878      var $parent                = null;
1879      /** @var string */
1880      var $admin_menu_link    = null;
1881      /** @var string */
1882      var $admin_menu_alt        = null;
1883      /** @var string */
1884      var $option                = null;
1885      /** @var string */
1886      var $ordering            = null;
1887      /** @var string */
1888      var $admin_menu_img        = null;
1889      /** @var int */
1890      var $iscore                = null;
1891      /** @var string */
1892      var $params                = null;
1893  
1894      /**
1895      * @param database A database connector object
1896      */
1897  	function mosComponent( &$db ) {
1898          $this->mosDBTable( '#__components', 'id', $db );
1899      }
1900  }
1901  
1902  /**
1903  * Utility class for all HTML drawing classes
1904  * @package Joomla
1905  */
1906  class mosHTML {
1907  	function makeOption( $value, $text='', $value_name='value', $text_name='text' ) {
1908          $obj = new stdClass;
1909          $obj->$value_name = $value;
1910          $obj->$text_name = trim( $text ) ? $text : $value;
1911          return $obj;
1912      }
1913  
1914    function writableCell( $folder, $relative=1, $text='', $visible=1 ) {
1915      $writeable         = '<b><font color="green">Writeable</font></b>';
1916      $unwriteable     = '<b><font color="red">Unwriteable</font></b>';
1917  
1918        echo '<tr>';
1919        echo '<td class="item">';
1920      echo $text;
1921      if ( $visible ) {
1922          echo $folder . '/';
1923      }
1924      echo '</td>';
1925        echo '<td align="left">';
1926      if ( $relative ) {
1927          echo is_writable( "../$folder" )     ? $writeable : $unwriteable;
1928      } else {
1929          echo is_writable( "$folder" )         ? $writeable : $unwriteable;
1930      }
1931      echo '</td>';
1932        echo '</tr>';
1933    }
1934  
1935      /**
1936      * Generates an HTML select list
1937      * @param array An array of objects
1938      * @param string The value of the HTML name attribute
1939      * @param string Additional HTML attributes for the <select> tag
1940      * @param string The name of the object variable for the option value
1941      * @param string The name of the object variable for the option text
1942      * @param mixed The key that is selected
1943      * @returns string HTML for the select list
1944      */
1945  	function selectList( &$arr, $tag_name, $tag_attribs, $key, $text, $selected=NULL ) {
1946          // check if array
1947          if ( is_array( $arr ) ) {
1948              reset( $arr );
1949          }
1950  
1951          $html     = "\n<select name=\"$tag_name\" $tag_attribs>";
1952          $count     = count( $arr );
1953  
1954          for ($i=0, $n=$count; $i < $n; $i++ ) {
1955              $k = $arr[$i]->$key;
1956              $t = $arr[$i]->$text;
1957              $id = ( isset($arr[$i]->id) ? @$arr[$i]->id : null);
1958  
1959              $extra = '';
1960              $extra .= $id ? " id=\"" . $arr[$i]->id . "\"" : '';
1961              if (is_array( $selected )) {
1962                  foreach ($selected as $obj) {
1963                      $k2 = $obj->$key;
1964                      if ($k == $k2) {
1965                          $extra .= " selected=\"selected\"";
1966                          break;
1967                      }
1968                  }
1969              } else {
1970                  $extra .= ($k == $selected ? " selected=\"selected\"" : '');
1971              }
1972              $html .= "\n\t<option value=\"".$k."\"$extra>" . $t . "</option>";
1973          }
1974          $html .= "\n</select>\n";
1975  
1976          return $html;
1977      }
1978  
1979      /**
1980      * Writes a select list of integers
1981      * @param int The start integer
1982      * @param int The end integer
1983      * @param int The increment
1984      * @param string The value of the HTML name attribute
1985      * @param string Additional HTML attributes for the <select> tag
1986      * @param mixed The key that is selected
1987      * @param string The printf format to be applied to the number
1988      * @returns string HTML for the select list
1989      */
1990  	function integerSelectList( $start, $end, $inc, $tag_name, $tag_attribs, $selected, $format="" ) {
1991          $start     = intval( $start );
1992          $end     = intval( $end );
1993          $inc     = intval( $inc );
1994          $arr     = array();
1995  
1996          for ($i=$start; $i <= $end; $i+=$inc) {
1997              $fi = $format ? sprintf( "$format", $i ) : "$i";
1998              $arr[] = mosHTML::makeOption( $fi, $fi );
1999          }
2000  
2001          return mosHTML::selectList( $arr, $tag_name, $tag_attribs, 'value', 'text', $selected );
2002      }
2003  
2004      /**
2005      * Writes a select list of month names based on Language settings
2006      * @param string The value of the HTML name attribute
2007      * @param string Additional HTML attributes for the <select> tag
2008      * @param mixed The key that is selected
2009      * @returns string HTML for the select list values
2010      */
2011  	function monthSelectList( $tag_name, $tag_attribs, $selected ) {
2012          $arr = array(
2013              mosHTML::makeOption( '01', _JAN ),
2014              mosHTML::makeOption( '02', _FEB ),
2015              mosHTML::makeOption( '03', _MAR ),
2016              mosHTML::makeOption( '04', _APR ),
2017              mosHTML::makeOption( '05', _MAY ),
2018              mosHTML::makeOption( '06', _JUN ),
2019              mosHTML::makeOption( '07', _JUL ),
2020              mosHTML::makeOption( '08', _AUG ),
2021              mosHTML::makeOption( '09', _SEP ),
2022              mosHTML::makeOption( '10', _OCT ),
2023              mosHTML::makeOption( '11', _NOV ),
2024              mosHTML::makeOption( '12', _DEC )
2025          );
2026  
2027          return mosHTML::selectList( $arr,