Source for file core.classes.php

Documentation is available at core.classes.php

  1. <?php
  2. /**
  3. @package Mambo
  4. @author Mambo Foundation Inc see README.php
  5. @copyright Mambo Foundation Inc.
  6. *  See COPYRIGHT.php for copyright notices and details.
  7. @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see
  8. *  LICENSE.php
  9. *  Mambo is free software; you can redistribute it and/or
  10. *  modify it under the terms of the GNU General Public License
  11. *  as published by the Free Software Foundation; version 2 of the
  12. *  License.
  13. */
  14.  
  15. /**
  16. * Mambo basic error object
  17. */
  18. define ('_MOS_ERROR_INFORM'0);
  19. define ('_MOS_ERROR_WARN'1);
  20. define ('_MOS_ERROR_SEVERE'2);
  21. define ('_MOS_ERROR_FATAL'3);
  22.  
  23. /**
  24.  * Enter description here...
  25.  *
  26.  */
  27. class mosError {
  28.     /**
  29.      * Enter description here...
  30.      *
  31.      * @var unknown_type 
  32.      */
  33.     var $text = '';
  34.     /**
  35.      * Enter description here...
  36.      *
  37.      * @var unknown_type 
  38.      */
  39.     var $level = 0;
  40.  
  41.     /**
  42.      * Enter description here...
  43.      *
  44.      * @param unknown_type $text 
  45.      * @param unknown_type $level 
  46.      * @return mosError 
  47.      */
  48.     function mosError ($text=''$level=_MOS_ERROR_INFORM{
  49.         $this->text = $text;
  50.         $this->level = $level;
  51.     }
  52. }
  53.  
  54. /**
  55. * Mambo group of errors for some particular operation
  56. */
  57. class mosErrorSet {
  58.     /**
  59.      * Enter description here...
  60.      *
  61.      * @var unknown_type 
  62.      */
  63.     var $errors = array();
  64.     /**
  65.      * Enter description here...
  66.      *
  67.      * @var unknown_type 
  68.      */
  69.     var $maxlevel = 0;
  70.  
  71.     // Parameter is an error object
  72.     /**
  73.      * Enter description here...
  74.      *
  75.      * @param unknown_type $error 
  76.      */
  77.     function addError ($error{
  78.         $this->errors[$error;
  79.         if ($error->level $this->maxlevel$this->maxlevel = $error->level;
  80.     }
  81.  
  82.     /**
  83.      * Enter description here...
  84.      *
  85.      * @param unknown_type $text 
  86.      * @param unknown_type $level 
  87.      */
  88.     function addErrorDetails ($text=''$level=_MOS_ERROR_INFORM{
  89.         $error new mosError($text$level);
  90.         $this->addError($error);
  91.     }
  92.  
  93.     /**
  94.      * Enter description here...
  95.      *
  96.      * @return unknown 
  97.      */
  98.     function &getErrors ({
  99.         return $this->errors;
  100.     }
  101.  
  102.     /**
  103.      * Enter description here...
  104.      *
  105.      * @return unknown 
  106.      */
  107.     function getMaxLevel ({
  108.         return $this->maxlevel;
  109.     }
  110.  
  111.     /**
  112.      * Enter description here...
  113.      *
  114.      * @return unknown 
  115.      */
  116.     function getCount ({
  117.         return count($this->errors);
  118.     }
  119.  
  120.     /**
  121.      * Enter description here...
  122.      *
  123.      * @param unknown_type $errorset 
  124.      */
  125.     function mergeAnother ($errorset{
  126.         $this->errors = array_merge($this->errors$errorset->errors);
  127.     }
  128.  
  129. }
  130.  
  131.  
  132. /* This is the new error handler to store errors in the database
  133. class mosErrorHandler {
  134. var $types = array (
  135. E_STRICT => 'Strict check',
  136. E_USER_WARNING => 'User Warning',
  137. E_USER_NOTICE => 'User Notice',
  138. E_WARNING => 'Warning',
  139. E_NOTICE => 'Notice',
  140. E_CORE_WARNING => 'Core Warning',
  141. E_COMPILE_WARNING => 'Compile Warning',
  142. E_USER_ERROR => 'User Error',
  143. E_ERROR => 'Error',
  144. E_PARSE => 'Parse error',
  145. E_CORE_ERROR => 'Core Error',
  146. E_COMPILE_ERROR => 'Compile Error'
  147. );
  148.  
  149. function mosErrorHandler () {
  150. set_error_handler(array(&$this, 'handler'));
  151. }
  152.  
  153. function handler ($errno, $errstr, $errfile, $errline, $errcontext) {
  154. if ($errno = E_STRICT) return;
  155. $string = $this->types[$errno].': '.$errstr.' in '.$errfile.' at '.$errline;
  156. $database =& mamboDatabase::getInstance();
  157. if (eregi('^(sql)$', $errstr)) {
  158. $extra = $database->getErrorMsg();
  159. }
  160. if (function_exists('debug_backtrace')) {
  161. foreach(debug_backtrace() as $back) {
  162. if (@$back['file']) {
  163. $extra .= "\n".$back['file'].':'.$back['line'];
  164. }
  165. }
  166. }
  167. $database->setQuery("DELETE FROM #__errors WHERE file=$errfile AND line=$errline AND number=$errno");
  168. $database->query();
  169. $database->setQuery("INSERT INTO #__errors VALUES (0, $errno, '$errfile', $errline, '$string', '$extra')");
  170. $database->query();
  171. }
  172. }
  173. */
  174.  
  175. /**
  176.  * Enter description here...
  177.  *
  178.  */
  179. class mamboCore {
  180.     /**
  181.      * Enter description here...
  182.      *
  183.      * @var unknown_type 
  184.      */
  185.     var $rootPath = '';
  186.     /**
  187.      * Enter description here...
  188.      *
  189.      * @var unknown_type 
  190.      */
  191.     var $Itemid = 0;
  192.     /**
  193.      * Enter description here...
  194.      *
  195.      * @var unknown_type 
  196.      */
  197.     var $option = '';
  198.     /**
  199.      * Enter description here...
  200.      *
  201.      * @var unknown_type 
  202.      */
  203.     var $subdirectory;
  204.     /**
  205.      * Enter description here...
  206.      *
  207.      * @var unknown_type 
  208.      */
  209.     var $current_user = null;
  210.     /**
  211.      * Enter description here...
  212.      *
  213.      * @var unknown_type 
  214.      */
  215.     var $do_gzip_compress = false;
  216.     /**
  217.      * Enter description here...
  218.      *
  219.      * @var unknown_type 
  220.      */
  221.     var $init_errorlevel = 0;
  222.  
  223.     /**
  224.      * Enter description here...
  225.      *
  226.      * @return mamboCore 
  227.      */
  228.     function mamboCore ({
  229.         global $adminside;
  230.         $this->init_errorlevel = error_reporting(0);
  231.         //$this->rootPath = str_replace('\\', '/', realpath(str_replace('includes', '', dirname(__FILE__))));
  232.         $this->rootPath = str_replace('\\''/',str_replace('includes'''dirname(__FILE__)));
  233.         $this->checkConfig();
  234.         $this->Itemid = mosGetParam($_REQUEST'Itemid'0);
  235.         $this->getConfig();
  236.         $this->fixLanguage();
  237.         @set_magic_quotes_runtime);
  238.         if (@$this->mosConfig_error_reporting OR @$this->mosConfig_error_reporting ===0error_reporting($this->mosConfig_error_reporting);
  239.         else error_reporting($this->init_errorlevel);
  240.     }
  241.  
  242.     /**
  243.      * Enter description here...
  244.      *
  245.      * @return unknown 
  246.      */
  247.     function &getMamboCore ({
  248.         static $instance;
  249.         if (!is_object($instance)) $instance new mamboCore();
  250.         return $instance;
  251.     }
  252.  
  253.     /**
  254.      * Enter description here...
  255.      *
  256.      * @return unknown 
  257.      */
  258.     function rootPath ({
  259.         //if (realpath($this->rootPath) === false) die ('Invalid program load path');
  260.         if (file_exists($this->rootPath=== falsedie ('Invalid program load path');
  261.         return $this->rootPath;
  262.     }
  263.  
  264.     /**
  265.      * Enter description here...
  266.      *
  267.      * @param unknown_type $property 
  268.      * @return unknown 
  269.      */
  270.     function get ($property{
  271.         $config =mamboCore::getMamboCore();
  272.         if ($property == 'mosConfig_absolute_path'{
  273.             //if (realpath($config->mosConfig_absolute_path) === false) die ('Invalid program load path');
  274.             if (file_exists($config->mosConfig_absolute_path=== falsedie ('Invalid program load path');
  275.             else return $config->rootPath;
  276.         }
  277.         if (isset($config->$property)) return $config->$property;
  278.         trigger_error("Invalid property ($property) requested from mamboCore");
  279.         return null;
  280.     }
  281.  
  282.     /**
  283.      * Enter description here...
  284.      *
  285.      * @param unknown_type $property 
  286.      * @return unknown 
  287.      */
  288.     function is_set ($property{
  289.         $config =mamboCore::getMamboCore();
  290.         return isset($config->$property);
  291.     }
  292.  
  293.     /**
  294.      * Enter description here...
  295.      *
  296.      * @param unknown_type $property 
  297.      * @param unknown_type $value 
  298.      * @return unknown 
  299.      */
  300.     function set ($property$value{
  301.         $config =mamboCore::getMamboCore();
  302.         $config->$property $value;
  303.         $GLOBALS[$property$value;
  304.         return $value;
  305.     }
  306.  
  307.     /**
  308.      * Enter description here...
  309.      *
  310.      */
  311.     function checkConfig ({
  312.         // checks for configuration file, if none found loads installation page
  313.         if (!file_exists($this->rootPath.'/configuration.php'OR filesize($this->rootPath.'/configuration.php'10 {
  314.             header'Location: installation/index.php' );
  315.             exit();
  316.         }
  317.     }
  318.  
  319.     /**
  320.      * Enter description here...
  321.      *
  322.      */
  323.     function getConfig ({
  324.         global $adminside;
  325.         $code '';
  326.         $f @fopen($this->rootPath.'/configuration.php','rb');
  327.         if ($f{
  328.             while ($f AND !feof($f)) {
  329.                 $line fgets($f);
  330.                 $altered str_replace('$''$this->'$line);
  331.                 if ($altered != $line$code .= $altered;
  332.             }
  333.         }
  334.         else {
  335.             #header( 'Location: installation/index.php' );
  336.             exit();
  337.         }
  338.         fclose($f);
  339.         eval($code);
  340.  
  341.  
  342.         /*if (isset($_SERVER['DOCUMENT_ROOT']) AND strlen($_SERVER['DOCUMENT_ROOT'])) {
  343.         $docroot = str_replace('\\', '/', str_replace('\\\\', '\\', $_SERVER['DOCUMENT_ROOT']));
  344.         }
  345.         else {*/
  346.         // Find information about where execution started
  347.         $origin array_pop(debug_backtrace());
  348.         // Find the PHP script at the start, with a fix for Windows slashes
  349.         $absolutepath str_replace('\\''/'$origin['file']);
  350.         $localpath $_SERVER['PHP_SELF'];
  351.         $docroot substr($absolutepath,0,strpos($absolutepath,$localpath));
  352.         /*}*/
  353.         $mamboroot str_replace('\\''/'rtrim($this->rootPath'\/'));
  354.         $this->subdirectory = substr($mamborootstrlen($docroot));
  355.  
  356.         $scheme = isset($_SERVER['HTTP_SCHEME']$_SERVER['HTTP_SCHEME'((isset($_SERVER['HTTPS']AND strtolower($_SERVER['HTTPS'!= 'off')) 'https' 'http');
  357.         if (isset($_SERVER['HTTP_HOST'])) {
  358.             $withport explode(':'$_SERVER['HTTP_HOST']);
  359.             $servername $withport[0];
  360.             if (isset($withport[1])) $port ':'.$withport[1];
  361.         }
  362.         elseif (isset($_SERVER['SERVER_NAME'])) $servername $_SERVER['SERVER_NAME'];
  363.         else trigger_error(T_('Impossible to determine the name of this server')E_USER_ERROR);
  364.         if (!isset($portAND !empty($_SERVER['SERVER_PORT'])) $port ':'.$_SERVER['SERVER_PORT'];
  365.         if (isset($port)) {
  366.             if (($scheme == 'http' AND $port == ':80'OR ($scheme == 'https' AND $port == ':443')) $port '';
  367.         }
  368.         else $port '';
  369.         $afterscheme '://'.$servername.$port.$this->subdirectory;
  370.         //$this->mosConfig_live_site = $this->mosConfig_secure_site = $scheme.$afterscheme;
  371.         $this->mosConfig_unsecure_site 'http'.$afterscheme;
  372.         $this->mosConfig_absolute_path $this->rootPath;
  373.         preg_match_all('/\$this\-\>([A-Za-z_][A-Za-z0-9_]*)/'$code$matches);
  374.         foreach ($matches[1as $match$GLOBALS[$match$this->$match;
  375.         if (!isset($this->mosConfig_register_globals)) {
  376.             $this->mosConfig_register_globals 0;
  377.             $GLOBALS['mosConfig_register_globals'0;
  378.         }
  379.  
  380.     }
  381.  
  382.     /**
  383.      * Enter description here...
  384.      *
  385.      * @return unknown 
  386.      */
  387.     function getFavIcon ({
  388.         // favourites icon
  389.         if (!isset($this->mosConfig_favicon)) $this->mosConfig_favicon 'favicon.ico';
  390.         if (!file_exists($this->rootPath.'/images/'.$this->mosConfig_favicon)) $this->mosConfig_favicon 'favicon.ico';
  391.         return $this->mosConfig_live_site.'/images/'.$this->mosConfig_favicon;
  392.     }
  393.  
  394.     /**
  395.      * Enter description here...
  396.      *
  397.      * @param unknown_type $user 
  398.      * @param unknown_type $database 
  399.      */
  400.     function offlineCheck (&$user&$database{
  401.         global $adminside;
  402.         if (($this->mosConfig_offline && !$adminsideOR file_exists($this->rootPath.'/installation/index.php')) {
  403.             require_once($this->rootPath().'/administrator/includes/admin.php');
  404.             session_name(md5($this->mosConfig_live_site));
  405.             session_start();
  406.             $session =mosSession::getCurrent();
  407.             $my =new mosUser();
  408.             $my->getSessionData();
  409.             if (mosSession::validate($my)) return;
  410.             include("$this->mosConfig_absolute_path/offline.php");
  411.             exit();
  412.         }
  413.     }
  414.  
  415.     /**
  416.      * Enter description here...
  417.      *
  418.      */
  419.     function fixLanguage ({
  420.         require_once($this->mosConfig_absolute_path.'/includes/phpgettext/phpgettext.class.php');
  421.         require_once($this->mosConfig_absolute_path.'/includes/phpgettext/error.php');
  422.         require_once($this->mosConfig_absolute_path.'/includes/mambofunc.php');
  423.         require_once($this->mosConfig_absolute_path.'/includes/mambolanguage.class.php');
  424.         $this->mosConfig_locale mosGetParam($_REQUEST'lang'$this->mosConfig_locale);
  425.  
  426.         $language =new mamboLanguage($this->mosConfig_locale$this->rootPath.'/language/');
  427.         $languages $language->getLanguages();
  428.         $charset $language->get('charset');
  429.         $dateformat $language->get('dateformat');
  430.         $this->mosConfig_lang $language->get('lang');
  431.         $this->current_language $language;
  432.         if (!defined('_ISO')) DEFINE('_ISO','charset='.$charset);
  433.         header('Content-type: text/html; '._ISO);
  434.         if (!defined('_DATE_FORMAT_LC')) DEFINE('_DATE_FORMAT_LC'$dateformat)//Uses PHP's strftime Command Format
  435.         if (!defined('_DATE_FORMAT_LC2')) DEFINE('_DATE_FORMAT_LC2'$dateformat);
  436.  
  437.         #error_reporting(E_ALL)        ;
  438.         ##########  DEPRECATED ############
  439.         if (isset($this->mosConfig_langAND $this->mosConfig_lang);
  440.         else $this->set('mosConfig_lang''english');
  441.         $language_file "$this->mosConfig_absolute_path/language/$this->mosConfig_lang.php";
  442.         if (file_exists($language_file)) require_once ($language_file);
  443.         else require_once ("$this->mosConfig_absolute_path/language/english.php");
  444.         ###################################
  445.  
  446.  
  447.  
  448.  
  449.     }
  450.  
  451.     /**
  452.      * Enter description here...
  453.      *
  454.      */
  455.     function handleGlobals ({
  456.         $superglobals array($_SERVER$_ENV$_FILES$_COOKIE$_POST$_GET);
  457.         if (isset$_SESSION )) array_unshift $superglobals $_SESSION );
  458.  
  459.         // Emulate register_globals on
  460.         if (!ini_get('register_globals'&& $this->mosConfig_register_globals{
  461.             while(list($key,$value)=each($_GET)) {
  462.                 if (!isset($GLOBALS[$key])) $GLOBALS[$key]=$value;
  463.             }
  464.             while(list($key,$value)=each($_POST)) {
  465.                 if (!isset($GLOBALS[$key])) $GLOBALS[$key]=$value;
  466.             }
  467.         }
  468.         // Emulate register_globals off
  469.         elseif (ini_get('register_globals'&& !$this->mosConfig_register_globals{
  470.             foreach $superglobals as $superglobal {
  471.                 foreach $superglobal as $key => $value{
  472.                     unset$GLOBALS[$key]);
  473.                     unset$GLOBALS[$key]);
  474.                 }
  475.             }
  476.         }
  477.     }
  478.  
  479.     /**
  480.      * Enter description here...
  481.      *
  482.      * @return unknown 
  483.      */
  484.     function determineOptionAndItemid ({
  485.         $this->Itemid = mosGetParam($_REQUEST'Itemid'0);
  486.         if ($option strtolower(mosGetParam($_REQUEST'option')));
  487.         else {
  488.             $menuhandler =mosMenuHandler::getInstance();
  489.             $menus =$menuhandler->getByParentOrder($this->Itemid'منوی Ø§ØµÙ„ÛŒ');
  490.             $this->Itemid = $menus[0]->id;
  491.             $_REQUEST['Itemid'$this->Itemid;
  492.             $link $menus[0]->link;
  493.             $pos strpos$link'?' );
  494.             if ($pos !== false$link substr$link$pos+)'&Itemid='.$this->Itemid;
  495.             parse_str$link$temp );
  496.             /** this is a patch, need to rework when globals are handled better */
  497.             foreach ($temp as $k=>$v$_GET[$k$_REQUEST[$k$v;
  498.             if (isset($temp['option'])) $option $temp['option'];
  499.             else return '';
  500.         }
  501.         /** patch to lessen the impact on templates */
  502.         if ($option == 'search'$option 'com_search';
  503.         // checking if we can find the Itemid thru the component
  504.         if ($this->Itemid === 0{
  505.             if $option == 'com_content'{
  506.                 require_once($this->rootPath().'/components/com_content/content.class.php');
  507.                 $handler =contentHandler::getInstance();
  508.                 $this->Itemid = $handler->getItemid(mosGetParam($_REQUEST'id'));
  509.                 $_REQUEST['Itemid'$this->Itemid;
  510.             }
  511.             else {
  512.                 $menuhandler =mosMenuHandler::getInstance();
  513.                 $this->Itemid = $menuhandler->getIdLikeLink("index.php?option=$option");
  514.                 if ($this->Itemid === 0{
  515.                     $menuhandler =mosMenuHandler::getInstance();
  516.                     $menus =$menuhandler->getByParentOrder($this->Itemid'منوی Ø§ØµÙ„ÛŒ');
  517.                 }
  518.             }
  519.         }
  520.         return $option;
  521.     }
  522.  
  523.     /**
  524.      * Enter description here...
  525.      *
  526.      * @param unknown_type $url 
  527.      * @param unknown_type $msg 
  528.      */
  529.     function redirect ($url$msg=''{
  530.         $callcheck array('InputFilter''process');
  531.         if (!is_callable($callcheck)) require_once(mamboCore::get('mosConfig_absolute_path').'/includes/phpInputFilter/class.inputfilter.php');
  532.         // specific filters
  533.         $iFilter =new InputFilter();
  534.         $url $iFilter->process$url );
  535.         $message trim($iFilter->process($msg));
  536.         if ($iFilter->badAttributeValue(array('href'$url))) $url mamboCore::get('mosConfig_live_site');
  537.         if ($message{
  538.             if (strpos($url'?')) $url .= '&mosmsg='.urlencode($message);
  539.             else $url .= '?mosmsg='.urlencode($message);
  540.         }
  541.         if (headers_sent()) echo "<script>document.location.href='$url';</script>\n";
  542.         else {
  543.             @ob_end_clean()// clear output buffer
  544.             header"Location: $url);
  545.         }
  546.         exit();
  547.     }
  548.  
  549.     /**
  550.      * Enter description here...
  551.      *
  552.      * @param unknown_type $text 
  553.      */
  554.     function logMessage ($text{
  555.         // JS Popup message
  556.         if (mosGetParam$_POST'message')) {
  557.             ?>
  558.             <script type="text/javascript">
  559.             <!--//
  560.             alert( "<?php echo $text?>" );
  561.             //-->
  562.             </script>
  563.             <?php
  564.         }
  565.         if ($return mosGetParam$_REQUEST'return''' )) {
  566.             $this->redirect$return );
  567.         }
  568.         else {
  569.             $this->redirect$this->mosConfig_live_site.'/index.php' );
  570.         }
  571.     }
  572.  
  573.     /**
  574.      * Enter description here...
  575.      *
  576.      */
  577.     function handleLogin ({
  578.         require_once($this->rootPath().'/includes/authenticator.php');
  579.         $authenticator =mamboAuthenticator::getInstance();
  580.         $loggedin $authenticator->loginUser();
  581.         if ($loggedin$this->logMessage(T_('You have Logged In succesfully'));
  582.         else mamboCore::redirect('index.php');
  583.     }
  584.  
  585.     /**
  586.      * Enter description here...
  587.      *
  588.      */
  589.     function handleLogout ({
  590.         require_once($this->rootPath().'/includes/authenticator.php');
  591.         $authenticator =mamboAuthenticator::getInstance();
  592.         $authenticator->logoutUser();
  593.         $this->logMessage(T_('You have Logged Out successfully'));
  594.     }
  595.  
  596.     /**
  597.      * Enter description here...
  598.      *
  599.      */
  600.     function standardHeaders ({
  601.         header'Expires: Mon, 26 Jul 1997 05:00:00 GMT' );
  602.         header'Last-Modified: ' gmdate'D, d M Y H:i:s' ' GMT' );
  603.         header'Cache-Control: no-store, no-cache, must-revalidate' );
  604.         header'Cache-Control: post-check=0, pre-check=0'false );
  605.         header'Pragma: no-cache' );
  606.         $mambothandler =mosMambotHandler::getInstance();
  607.         $mambothandler->loadBotGroup('system');
  608.         $mambothandler->trigger('onHeaders'array($this));
  609.     }
  610.  
  611.     /**
  612.      * Enter description here...
  613.      *
  614.      */
  615.     function initGzip({
  616.         $this->do_gzip_compress = FALSE;
  617.         //zlib.output_compression and ob_gzhandler don't get along well so we'll check to make
  618.         //that zlib.output_compression is not enable in the php.ini before turning on ob_gzhandler
  619.         if $this->mosConfig_gzip == AND (int)ini_get('zlib.output_compression'!= {
  620.             $phpver phpversion();
  621.             $useragent mosGetParam$_SERVER'HTTP_USER_AGENT''' );
  622.             $canZip mosGetParam$_SERVER'HTTP_ACCEPT_ENCODING''' );
  623.  
  624.             if $phpver >= '4.0.4pl1' AND
  625.             strpos($useragent,'compatible'!== false ||
  626.             strpos($useragent,'Gecko')      !== false
  627.             )
  628.             {
  629.                 if extension_loaded('zlib') ) {
  630.                     ob_start'ob_gzhandler' );
  631.                     return;
  632.                 }
  633.             else if $phpver '4.0' {
  634.                 if strpos($canZip,'gzip'!== false {
  635.                     if (extension_loaded'zlib' )) {
  636.                         $this->do_gzip_compress = TRUE;
  637.                         ob_start();
  638.                         ob_implicit_flush(0);
  639.  
  640.                         header'Content-Encoding: gzip' );
  641.                         return;
  642.                     }
  643.                 }
  644.             }
  645.         }
  646.         ob_start();
  647.     }
  648.  
  649.     /**
  650.     * Perform GZIP
  651.     */
  652.     function doGzip({
  653.         if $this->do_gzip_compress {
  654.             /**
  655.             *Borrowed from php.net!
  656.             */
  657.             $gzip_contents ob_get_contents();
  658.             ob_end_clean();
  659.  
  660.             $gzip_size strlen($gzip_contents);
  661.             $gzip_crc crc32($gzip_contents);
  662.  
  663.             $gzip_contents gzcompress($gzip_contents9);
  664.             $gzip_contents substr($gzip_contents0strlen($gzip_contents4);
  665.  
  666.             echo "\x1f\x8b\x08\x00\x00\x00\x00\x00";
  667.             echo $gzip_contents;
  668.             echo pack('V'$gzip_crc);
  669.             echo pack('V'$gzip_size);
  670.         else {
  671.             ob_end_flush();
  672.         }
  673.     }
  674.  
  675.     /**
  676.      * Enter description here...
  677.      *
  678.      * @param unknown_type $separator 
  679.      * @param unknown_type $field 
  680.      * @return unknown 
  681.      */
  682.     function getLastPart ($separator$field{
  683.         $parts explode($separator$field);
  684.         return $parts[count($parts)-1];
  685.     }
  686.  
  687.     /**
  688.      * Enter description here...
  689.      *
  690.      * @param unknown_type $separator 
  691.      * @param unknown_type $field 
  692.      * @return unknown 
  693.      */
  694.     function allButLast ($separator$field{
  695.         $lastSize strlen(mamboCore::getLastPart($separator,$field));
  696.         return substr($field0strlen($field)-$lastSize);
  697.     }
  698.  
  699. }
  700.  
  701.  
  702. /**
  703. * Sorts an Array of objects
  704. */
  705. class mosObjectSorter {
  706.     /**
  707.      * Enter description here...
  708.      *
  709.      * @var unknown_type 
  710.      */
  711.     var $_keyname = '';
  712.     /**
  713.      * Enter description here...
  714.      *
  715.      * @var unknown_type 
  716.      */
  717.     var $_direction = 0;
  718.     /**
  719.      * Enter description here...
  720.      *
  721.      * @var unknown_type 
  722.      */
  723.     var $_object_array = array();
  724.  
  725.     /**
  726.      * Enter description here...
  727.      *
  728.      * @param unknown_type $a 
  729.      * @param unknown_type $k 
  730.      * @param unknown_type $sort_direction 
  731.      * @return mosObjectSorter 
  732.      */
  733.     function mosObjectSorter (&$a$k$sort_direction=1{
  734.         $this->_keyname = $k;
  735.         $this->_direction = $sort_direction;
  736.         $this->_object_array =$a;
  737.         $this->sort();
  738.     }
  739.  
  740.     /**
  741.      * Enter description here...
  742.      *
  743.      * @param unknown_type $a 
  744.      * @param unknown_type $b 
  745.      * @return unknown 
  746.      */
  747.     function mosObjectCompare (&$a&$b{
  748.         $key $this->_keyname;
  749.         if ($a->$key $b->$keyreturn $this->_direction;
  750.         if ($a->$key $b->$keyreturn -$this->_direction;
  751.         return 0;
  752.     }
  753.  
  754.     /**
  755.      * Enter description here...
  756.      *
  757.      */
  758.     function sort ({
  759.         usort($this->_object_arrayarray($this,'mosObjectCompare'));
  760.     }
  761.  
  762. }
  763.  
  764. /**
  765. * Pathway handler
  766. @package Mambo
  767. */
  768. class mosPathway {
  769.     /** @var array Names for display in pathway */
  770.     var $_names = null;
  771.     /** @var array URLs for links from pathway */
  772.     var $_urls = null;
  773.  
  774.     /**
  775.     * Constructor
  776.     */
  777.     function mosPathway ({
  778.         $menuhandler =mosMenuHandler::getInstance();
  779.         $menus =$menuhandler->getByParentOrder(0,'منوی Ø§ØµÙ„ÛŒ');
  780.         $home $menus[0];
  781.         $this->_names[$home->name;
  782.         $this->_urls[sefRelToAbs($home->link."&Itemid=$home->id");
  783.     }
  784.  
  785.     /**
  786.     * Singleton accessor
  787.     */
  788.     function &getInstance ({
  789.         static $instance;
  790.         if (!is_object($instance)) $instance new mosPathway();
  791.         return $instance;
  792.     }
  793.  
  794.     /**
  795.     * Add an item to the pathway
  796.     */
  797.     function addItem ($name$givenurl{
  798.         $last count($this->_names1;
  799.         if (!$namereturn;
  800.         $url sefRelToAbs($givenurl);
  801.         if ($name == $this->_names[$lastAND $url == $this->_urls[$last]return;
  802.         $this->_names[$last+1$name;
  803.         $this->_urls[$last+1$url;
  804.     }
  805.  
  806.     /**
  807.      * Enter description here...
  808.      *
  809.      */
  810.     function reduceToOne ({
  811.         for ($i count($this->_names1$i 0$i--{
  812.             unset($this->_names[$i]);
  813.             unset($this->_urls[$i]);
  814.         }
  815.     }
  816.  
  817.     /**
  818.     * Make a pathway string for display
  819.     */
  820.     function makePathway ({
  821.         $mainframe =mosMainFrame::getInstance();
  822.         $customs $mainframe->getCustomPathWay();
  823.         $last count($this->_names1;
  824.         if ($last == AND count($customs == 0)) return '';
  825.         $result "<span class='pathway'>";
  826.         $config =mamboCore::getMamboCore();
  827.         $rootpath $config->rootPath();
  828.         $imgPath =  'templates/'.$mainframe->getTemplate().'/images/arrow.png';
  829.         if (file_exists"$rootpath/$imgPath)) $img "<img src='$config->mosConfig_live_site/$imgPath' border='0' alt='arrow' />";
  830.         else {
  831.             $imgPath '/images/M_images/arrow.png';
  832.             if (file_exists"$rootpath/$imgPath)) $img "<img src='$config->mosConfig_live_site/images/M_images/arrow.png' alt='arrow' />";
  833.             else $img '&gt;';
  834.         }
  835.         foreach ($this->_names as $i=>$name{
  836.             if ($i === $last AND count($customs== 0$result .= "$name</span>";
  837.             elseif (strstr($this->_urls[$i]'view')) $result .= "";
  838.             else {
  839.                 $sefurl sefRelToAbs($this->_urls[$i]);
  840.                 $result .= "<a href='$sefurl' class='pathway'>$name</a>";
  841.                 $result .= "&nbsp;$img&nbsp;";
  842.             }
  843.         }
  844.         foreach ($customs as $custom$result .= $custom;
  845.         if (count($customs)) $result .= '</span>';
  846.         return $result;
  847.     }
  848.  
  849. }
  850.  
  851. /**
  852. * Module database table class
  853. @package Mambo
  854. */
  855. class mosMenu extends mosDBTable {
  856.     /** @var int Primary key */
  857.     var $id=null;
  858.     /** @var string */
  859.     var $menutype=null;
  860.     /** @var string */
  861.     var $name=null;
  862.     /** @var string */
  863.     var $link=null;
  864.     /** @var int */
  865.     var $type=null;
  866.     /** @var int */
  867.     var $published=null;
  868.     /** @var int */
  869.     var $componentid=null;
  870.     /** @var int */
  871.     var $parent=null;
  872.     /** @var int */
  873.     var $sublevel=null;
  874.     /** @var int */
  875.     var $ordering=null;
  876.     /** @var boolean */
  877.     var $checked_out=null;
  878.     /** @var datetime */
  879.     var $checked_out_time=null;
  880.     /** @var boolean */
  881.     var $pollid=null;
  882.  
  883.     /** @var string */
  884.     var $browserNav=null;
  885.     /** @var int */
  886.     var $access=null;
  887.     /** @var int */
  888.     var $utaccess=null;
  889.     /** @var string */
  890.     var $params=null;
  891.  
  892.     /**
  893.     * @param database A database connector object
  894.     */
  895.     function mosMenu({
  896.         $db =mamboDatabase::getInstance();
  897.         $this->mosDBTable'#__menu''id'$db );
  898.     }
  899.     /**
  900.     *    binds an array/hash to this object
  901.     *    @param int $oid optional argument, if not specifed then the value of current key is used
  902.     *    @return any result from the database operation
  903.     */
  904.     function load$oid=null {
  905.         $k $this->_tbl_key;
  906.         if ($oid !== null$this->$k $oid;
  907.         if ($this->$k === nullreturn false;
  908.         $menuhandler =mosMenuHandler::getInstance();
  909.         $menu =$menuhandler->getMenuById($this->$k);
  910.         if ($menu{
  911.             foreach (get_object_vars($menuas $key=>$data$this->$key $data;
  912.             return true;
  913.         }
  914.         else return false;
  915.     }
  916.  
  917. }
  918.  
  919. /**
  920. * File Manager including safe mode provision?
  921. @package Mambo
  922. */
  923. class mosFileManager {
  924.  
  925.     /**
  926.     * Singleton accessor
  927.     */
  928.     function &getInstance ({
  929.         static $instance;
  930.         if (!is_object($instance)) $instance new mosFileManager();
  931.         return $instance;
  932.     }
  933.  
  934.     /**
  935.      * Enter description here...
  936.      *
  937.      * @param unknown_type $file 
  938.      * @return unknown 
  939.      */
  940.     function deleteFile ($file{
  941.         if (file_exists($file)) {
  942.             @chmod($file0644);
  943.             return unlink($file);
  944.         }
  945.         return true;
  946.     }
  947.  
  948.     /**
  949.      * Enter description here...
  950.      *
  951.      * @param unknown_type $dir 
  952.      * @return unknown 
  953.      */
  954.     function deleteDirectory ($dir{
  955.         if (file_exists($dir)) {
  956.             if (is_dir($dir)) {
  957.                 @chmod($dir0755);
  958.                 return rmdir($dir);
  959.             }
  960.             return false;
  961.         }
  962.         return true;
  963.     }
  964.  
  965.     /**
  966.      * Enter description here...
  967.      *
  968.      * @param unknown_type $fileSysObject 
  969.      */
  970.     function setPermissions ($fileSysObject{
  971.         if (file_exists($fileSysObject))  {
  972.             if (is_dir($fileSysObject)) $perms mamboCore::get('mosConfig_dirperms');
  973.             else $perms mamboCore::get('mosConfig_fileperms');
  974.             if ($perms{
  975.                 $origmask @umask(0);
  976.                 $mode octdec($perms);
  977.                 @chmod($fileSysObject$mode);
  978.                 @umask($origmask);
  979.             }
  980.         }
  981.     }
  982.  
  983.     /**
  984.      * Enter description here...
  985.      *
  986.      * @param unknown_type $dir 
  987.      * @return unknown 
  988.      */
  989.     function makeDirectory ($dir{
  990.         $perms mamboCore::get('mosConfig_dirperms');
  991.         $origmask @umask(0);
  992.         if ($perms$result @mkdir($diroctdec($perms));
  993.         else $result @mkdir($dir0755);
  994.         if ($result$this->setPermissions($dir);
  995.         @umask($origmask);
  996.         return $result;
  997.     }
  998.  
  999.  
  1000.     /**
  1001.      * Enter description here...
  1002.      *
  1003.      * @param unknown_type $dir 
  1004.      * @param unknown_type $onlyCheck 
  1005.      * @return unknown 
  1006.      */
  1007.     function createDirectory ($dir$onlyCheck=false{
  1008.         if (file_exists($dir)) {
  1009.             if (is_dir($dirAND is_writable($dir)) return true;
  1010.             else return false;
  1011.         }
  1012.         list($upDirectory$count$this->containingDirectory($dir);
  1013.         if ($count AND !file_exists($upDirectoryAND !($result $this->createDirectory($upDirectory$onlyCheck))) return false;
  1014.         if ($onlyCheck AND isset($result)) return true;
  1015.         if (!is_dir($upDirectoryOR !is_writable($upDirectory)) return false;
  1016.         if ($onlyCheckreturn true;
  1017.         else return $this->makeDirectory($dir);
  1018.     }
  1019.  
  1020.     /**
  1021.      * Enter description here...
  1022.      *
  1023.      * @param unknown_type $dir 
  1024.      * @return unknown 
  1025.      */
  1026.     function containingDirectory ($dir{
  1027.         $dirs preg_split('*[/|\\\]*'$dir);
  1028.         for ($i count($dirs)-1$i >= 0$i--{
  1029.             $text trim($dirs[$i]);
  1030.             unset($dirs[$i]);
  1031.             if ($textbreak;
  1032.         }
  1033.         $result2 count($dirs);
  1034.         $result1 implode('/',$dirs).($result2 '' '/');
  1035.         return array($result1$result2);
  1036.     }
  1037.  
  1038.     /**
  1039.      * Enter description here...
  1040.      *
  1041.      * @param unknown_type $from 
  1042.      * @param unknown_type $to 
  1043.      * @return unknown 
  1044.      */
  1045.     function simpleCopy ($from$to{
  1046.         if (@copy($from$to)) {
  1047.             $this->setPermissions($to);
  1048.             return true;
  1049.         }
  1050.         else return false;
  1051.     }
  1052.  
  1053.     /**
  1054.      * Enter description here...
  1055.      *
  1056.      * @param unknown_type $from 
  1057.      * @param unknown_type $to 
  1058.      * @return unknown 
  1059.      */
  1060.     function forceCopy ($from$to{
  1061.         $todir dirname($to);
  1062.         if (!file_exists($todir)) $this->createDirectory($todir);
  1063.         if (!file_exists($todir)) return false;
  1064.         $name basename($from);
  1065.         $this->deleteFile($to.$name);
  1066.         return $this->simpleCopy ($from$to);
  1067.     }
  1068.  
  1069.     /**
  1070.      * Enter description here...
  1071.      *
  1072.      * @param unknown_type $from 
  1073.      * @param unknown_type $to 
  1074.      * @return unknown 
  1075.      */
  1076.     function lightCopy ($from$to{
  1077.         $name basename($from);
  1078.         if (file_exists($to.$name)) return false;
  1079.         $todir dirname($to);
  1080.         if (!file_exists($todir)) $this->createDirectory($todir);
  1081.         if (!file_exists($todir)) return false;
  1082.         return $this->simpleCopy ($from$to);
  1083.     }
  1084.  
  1085.     /**
  1086.      * Enter description here...
  1087.      *
  1088.      * @param unknown_type $to 
  1089.      * @return unknown 
  1090.      */
  1091.     function acceptCopy ($to{
  1092.         $todir dirname($to);
  1093.         return $this->createDirectory($todirtrue);
  1094.     }
  1095.  
  1096.  
  1097.     /**
  1098.     * Function to strip additional / or \ in a path name
  1099.     * @param string The path
  1100.     * @param boolean Add trailing slash
  1101.     */
  1102.     function mosPathName($p_path$p_addtrailingslash=true{
  1103.         if (substr(PHP_OS03== 'WIN')    {
  1104.             $retval str_replace'/''\\'$p_path );
  1105.             if ($p_addtrailingslash AND substr$retval-!= '\\'$retval .= '\\';
  1106.             // Remove double \\
  1107.             $retval str_replace'\\\\''\\'$retval );
  1108.         }
  1109.         else {
  1110.             $retval str_replace'\\''/'$p_path );
  1111.             if ($p_addtrailingslash AND substr$retval-!= '/'$retval .= '/';
  1112.             // Remove double //
  1113.             $retval str_replace('//','/',$retval);
  1114.         }
  1115.         return $retval;
  1116.     }
  1117.  
  1118.     /**
  1119.     * Chmods files and directories recursively to mos global permissions. Available from 4.5.2 up.
  1120.     * @param path The starting file or directory (no trailing slash)
  1121.     * @param filemode Integer value to chmod files. NULL = dont chmod files.
  1122.     * @param dirmode Integer value to chmod directories. NULL = dont chmod directories.
  1123.     * @return TRUE=all succeeded FALSE=one or more chmods failed
  1124.     */
  1125.     function mosChmod($path)
  1126.     {
  1127.         $fileperms mamboCore::get('mosConfig_fileperms');
  1128.         if ($fileperms != ''$filemode octdec($fileperms);
  1129.         else $filemode null;
  1130.         $dirperms mamboCore::get('mosConfig_dirperms');
  1131.         if ($dirperms != ''$dirmode octdec($dirperms);
  1132.         else $dirmode null;
  1133.         if (isset($filemodeOR isset($dirmode))
  1134.         return $this->mosChmodRecursive($path$filemode$dirmode);
  1135.         return true;
  1136.     // mosChmod
  1137.  
  1138.     /**
  1139.     * Chmods files and directories recursively to given permissions. Available from 4.5.2 up.
  1140.     * @param path The starting file or directory (no trailing slash)
  1141.     * @param filemode Integer value to chmod files. NULL = dont chmod files.
  1142.     * @param dirmode Integer value to chmod directories. NULL = dont chmod directories.
  1143.     * @return TRUE=all succeeded FALSE=one or more chmods failed
  1144.     */
  1145.     function mosChmodRecursive($path$filemode=NULL$dirmode=NULL{
  1146.         $ret true;
  1147.         if (is_dir($path)) {
  1148.             $topdir =new mosDirectory($path);
  1149.             $files =$topdir->listFiles ('''file'truetrue);
  1150.             $dirs =$topdir->listFiles ('''dir'truetrue);
  1151.         }
  1152.         else {
  1153.             $files array($path);
  1154.             $dirs array();
  1155.         }
  1156.         if (isset($filemode)) foreach ($files as $file$ret @chmod($file$filemode$ret false;
  1157.         if (isset($dirmode)) foreach ($dirs as $dir$ret @chmod($dir$dirmode$ret false;
  1158.         return $ret;
  1159.     }
  1160.  
  1161. }
  1162.  
  1163. /**
  1164.  * Enter description here...
  1165.  *
  1166.  */
  1167. class mosDirectory {
  1168.     /**
  1169.      * Enter description here...
  1170.      *
  1171.      * @var unknown_type 
  1172.      */
  1173.     var $path = '';
  1174.  
  1175.     /**
  1176.      * Enter description here...
  1177.      *
  1178.      * @param unknown_type $path 
  1179.      * @return mosDirectory 
  1180.      */
  1181.     function mosDirectory ($path{
  1182.         $path str_replace('\\''/'$path);
  1183.         if (substr($path,-1,1== '/'$this->path = $path;
  1184.         else $this->path = $path.'/';
  1185.     }
  1186.  
  1187.     /**
  1188.      * Enter description here...
  1189.      *
  1190.      * @param unknown_type $type 
  1191.      * @param unknown_type $recurse 
  1192.      * @param unknown_type $fullpath 
  1193.      * @return unknown 
  1194.      */
  1195.     function &listAll ($type='file'$recurse=false$fullpath=false{
  1196.         $results array();
  1197.         if ($dir @opendir($this->path)) {
  1198.             while ($file readdir($dir)) {
  1199.                 if ($file == '.' OR $file == '..'continue;
  1200.                 if (is_dir($this->path.$file)) {
  1201.                     if ($recurse{
  1202.                         $subdir new mosDirectory($this->path.$file);
  1203.                         $results array_merge($results$subdir->listAll($type$recurse$fullpath));
  1204.                         unset($subdir);
  1205.                     }
  1206.                     if ($type == 'file'continue;
  1207.                 }
  1208.                 elseif ($type == 'dir'continue;
  1209.                 if ($fullpath$results[$this->path.$file;
  1210.                 else $results[$file;
  1211.             }
  1212.             closedir($dir);
  1213.         }
  1214.         return $results;
  1215.     }
  1216.  
  1217.     /**
  1218.      * Enter description here...
  1219.      *
  1220.      * @return unknown 
  1221.      */
  1222.     function soleDir ({
  1223.         $found '';
  1224.         if ($dir @opendir($this->path)) {
  1225.             while ($file readdir($dir)) {
  1226.                 if ($file == '.' OR $file == '..'continue;
  1227.                 if (is_dir($this->path.$file)) {
  1228.                     if ($foundreturn '';
  1229.                     else $found $file;
  1230.                 }
  1231.                 else return '';
  1232.             }
  1233.             closedir($dir);
  1234.         }
  1235.         return $found;
  1236.     }
  1237.  
  1238.     /**
  1239.      * Enter description here...
  1240.      *
  1241.      */
  1242.     function deleteAll ({
  1243.         if (!file_exists($this->path)) return;
  1244.         $subdirs =$this->listAll ('dir'falsetrue);
  1245.         foreach ($subdirs as $subdir{
  1246.             $subdirectory new mosDirectory($subdir);
  1247.             $subdirectory->deleteAll();
  1248.             unset($subdirectory);
  1249.         }
  1250.         $filemanager =mosFileManager::getInstance();
  1251.         $files =$this->listAll ('file'falsetrue);
  1252.         foreach ($files as $file$filemanager->deleteFile($file);
  1253.         $filemanager->deleteDirectory($this->path);
  1254.     }
  1255.  
  1256.     /**
  1257.      * Enter description here...
  1258.      *
  1259.      * @return unknown 
  1260.      */
  1261.     function createFresh ({
  1262.         $this->deleteAll();
  1263.         $filemanager =mosFileManager::getInstance();
  1264.         $filemanager->createDirectory($this->path);
  1265.         return true;
  1266.     }
  1267.  
  1268.     /**
  1269.      * Enter description here...
  1270.      *
  1271.      */
  1272.     function createIfNeeded ({
  1273.         if (!file_exists($this->path)) {
  1274.             $filemanager =mosFileManager::getInstance();
  1275.             $filemanager->createDirectory($this->path);
  1276.         }
  1277.     }
  1278.  
  1279.     /**
  1280.      * Enter description here...
  1281.      *
  1282.      * @param unknown_type $pattern 
  1283.      * @param unknown_type $type 
  1284.      * @param unknown_type $recurse 
  1285.      * @param unknown_type $fullpath 
  1286.      * @return unknown 
  1287.      */
  1288.     function &listFiles ($pattern=''$type='file'$recurse=false$fullpath=false{
  1289.         $results array();
  1290.         $all =$this->listAll($type$recurse$fullpath);
  1291.         foreach ($all as $file{
  1292.             $name basename($file);
  1293.             if ($pattern AND !preg_match"/$pattern/"$name )) continue;
  1294.             if (($name != 'index.html'AND ($name[0!= '.')) $results[$file;
  1295.         }
  1296.         return $results;
  1297.     }
  1298.  
  1299.     /**
  1300.      * Enter description here...
  1301.      *
  1302.      * @return unknown 
  1303.      */
  1304.     function getSize ({
  1305.         $totalsize 0;
  1306.         $files =$this->listFiles();
  1307.         foreach ($files as $file$totalsize += filesize($this->path.$file);
  1308.         return $totalsize;
  1309.     }
  1310.  
  1311. }
  1312.  
  1313.  
  1314. /**
  1315. * Menu handler
  1316. @package Mambo
  1317. */
  1318. class mosMenuHandler {
  1319.     /** @var array Menu objects currently available */
  1320.     var $_menus = null;
  1321.     /** @var array Counts of menu items by type and published status */
  1322.     var $_counts = null;
  1323.     /** @var array Access to stored menu objects by ID */
  1324.     var $_idlinks = null;
  1325.     /** @var array Items that may be useful for setting Itemid */
  1326.     var $_byParentOrder = null;
  1327.  
  1328.     /**
  1329.     * Constructor
  1330.     */
  1331.     function mosMenuHandler({
  1332.         $database =mamboDatabase::getInstance();
  1333.         $sql "SELECT * FROM #__menu ORDER BY name";
  1334.         $this->_menus =$database->doSQLget($sql'mosMenu');
  1335.         if (!$this->_menus$this->_menus = array();
  1336.         foreach ($this->_menus as $key=>$menu{
  1337.             $this->_idlinks[$menu->id$key;
  1338.             if ($menu->published == 1$this->_byParentOrder[$menu->parent][$menu->ordering][$menu->menutype$key;
  1339.             if (isset($this->_counts[$menu->menutype][$menu->published])) $this->_counts[$menu->menutype][$menu->published]++;
  1340.             else $this->_counts[$menu->menutype][$menu->published1;
  1341.         }
  1342.         if ($this->_byParentOrder{
  1343.             foreach ($this->_byParentOrder as $parent=>$outerksort($this->_byParentOrder[$parent]);
  1344.             ksort($this->_byParentOrder);
  1345.         }
  1346.     }
  1347.     /**
  1348.     * Singleton accessor
  1349.     */
  1350.     function &getInstance ({
  1351.         static $instance;
  1352.         if (!is_object($instance)) $instance new mosMenuHandler();
  1353.         return $instance;
  1354.     }
  1355.  
  1356.     /**
  1357.      * Enter description here...
  1358.      *
  1359.      * @param unknown_type $id 
  1360.      * @return unknown 
  1361.      */
  1362.     function &getMenuByID ($id{
  1363.         if (isset($this->_idlinks[$id])) {
  1364.             $key $this->_idlinks[$id];
  1365.             $result $this->_menus[$key];
  1366.         }
  1367.         else $result null;
  1368.         return $result;
  1369.     }
  1370.  
  1371.     /**
  1372.      * Enter description here...
  1373.      *
  1374.      * @param unknown_type $type 
  1375.      * @param unknown_type $published 
  1376.      * @return unknown 
  1377.      */
  1378.     function getMenuCount ($type$published{
  1379.         if (isset($this->_counts[$type][$published])) return $this->_counts[$type][$published];
  1380.         else return 0;
  1381.     }
  1382.  
  1383.     /**
  1384.      * Enter description here...
  1385.      *
  1386.      * @param unknown_type $types 
  1387.      * @return unknown 
  1388.      */
  1389.     function &getMenusByType ($types{
  1390.         $checker explode(','$types);
  1391.         $result null;
  1392.         foreach ($this->_menus as $menu{
  1393.             if (in_array($menu->menutype$checker)) $result[$menu;
  1394.         }
  1395.         return $result;
  1396.     }
  1397.  
  1398.     /**
  1399.      * Enter description here...
  1400.      *
  1401.      * @return unknown 
  1402.      */
  1403.     function &getMenuTypes ({
  1404.         $types array();
  1405.         foreach ($this->_menus as $menu{
  1406.             if (!isset($types[$menu->menutype])) $types[$menu->menutype0;
  1407.             $types[$menu->menutype]++;
  1408.         }
  1409.         return $types;
  1410.     }
  1411.  
  1412.     /**
  1413.      * Enter description here...
  1414.      *
  1415.      * @param unknown_type $type 
  1416.      * @param unknown_type $link 
  1417.      * @return unknown 
  1418.      */
  1419.     function getIDByTypeLink ($type$link{
  1420.         foreach ($this->_menus as $menu{
  1421.             if ($menu->published == AND ($type == '*' OR $menu->type == $typeAND $menu->link == $linkreturn $menu->id;
  1422.         }
  1423.         return null;
  1424.     }
  1425.  
  1426.     /**
  1427.      * Enter description here...
  1428.      *
  1429.      * @param unknown_type $link 
  1430.      * @return unknown 
  1431.      */
  1432.     function getIDLikeLink ($link{
  1433.         $exact $this->getIdByTypeLink('*'$link);
  1434.         if ($exact !== nullreturn $exact;
  1435.         foreach ($this->_menus as $menu{
  1436.             if ($menu->published == AND strpos($menu->link,$link=== 0return $menu->id;
  1437.         }
  1438.         return 0;
  1439.     }
  1440.  
  1441.     /**
  1442.      * Enter description here...
  1443.      *
  1444.      * @param unknown_type $type 
  1445.      * @param unknown_type $componentid 
  1446.      * @return unknown 
  1447.      */
  1448.     function getIDByTypeCid ($type$componentid{
  1449.         foreach ($this->_menus as $menu{
  1450.             if ($menu->published == AND $menu->type == $type AND $menu->componentid == $componentidreturn $menu->id;
  1451.         }
  1452.         return null;
  1453.     }
  1454.  
  1455.     /**
  1456.      * Enter description here...
  1457.      *
  1458.      * @return unknown 
  1459.      */
  1460.     function getGlobalBlogSectionCount ({
  1461.         $count 0;
  1462.         foreach ($this->_menus as $menu{
  1463.             if ($menu->type == 'content_blog_section' AND $menu->published == AND $menu->componentid == 0$count++;
  1464.         }
  1465.         return $count;
  1466.     }
  1467.  
  1468.     /**
  1469.      * Enter description here...
  1470.      *
  1471.      * @param unknown_type $Itemid 
  1472.      * @param unknown_type $type 
  1473.      * @param unknown_type $id 
  1474.      * @param unknown_type $catid 
  1475.      * @return unknown 
  1476.      */
  1477.     function getContentItemid ($Itemid$type$id$catid=0{
  1478.         if ($Itemidreturn $Itemid;
  1479.         foreach ($this->_menus as $menu{
  1480.             if (strpos($menu->link,'index.php?option=com_content'=== false AND strpos($menu->link,'index.php?option=content'=== falsecontinue;
  1481.             if (strpos($menu->link$type=== falsecontinue;
  1482.             if ($catid{
  1483.                 if (strpos($menu->link"&id=$catid"=== falsecontinue;
  1484.                 if (strpos($menu->link"&sectionid=$id"=== falsecontinue;
  1485.             }
  1486.             elseif (strpos($menu->link"&id=$id"=== falsecontinue;
  1487.             return $menu->id;
  1488.         }
  1489.         return 0;
  1490.     }
  1491.  
  1492.     /**
  1493.      * Enter description here...
  1494.      *
  1495.      * @return unknown 
  1496.      */
  1497.     function getBestQueryMatch ({
  1498.         parse_str($_SERVER['QUERY_STRING']$qitems);
  1499.         if (!isset($qitems['option'])) return 0;
  1500.         $failures 999;
  1501.         $best 0;
  1502.         foreach ($this->_menus as $menu{
  1503.             $split explode('?'$menu->link);
  1504.             if (isset($split[1])) parse_str($split[1]$mitems);
  1505.             else continue;
  1506.             if (!isset($mitems['option']OR $mitems['option'!= $qitems['option']continue;
  1507.             $thisfail 0;
  1508.             foreach ($mitems as $key=>$mitemif (!isset($qitems[$key]OR $mitem != $qitems[$key]$thisfail++;
  1509.             if ($thisfail $failures{
  1510.                 $best $menu->id;
  1511.                 $failures $thisfail;
  1512.             }
  1513.         }
  1514.         return $best;
  1515.     }
  1516.  
  1517.  
  1518.     /**
  1519.      * Enter description here...
  1520.      *
  1521.      * @param unknown_type $link 
  1522.      * @return unknown 
  1523.      */
  1524.     function &maxAccessLink ($link{
  1525.         $selected null;
  1526.         $access 0;
  1527.         foreach ($this->_menus as $key=>$menu{
  1528.             if (strpos($menu->link,$link=== AND $menu->access $access{
  1529.                 $access $menu->access;
  1530.                 $selected =$this->_menus[$key];
  1531.             }
  1532.         }
  1533.         return $selected;
  1534.     }
  1535.  
  1536.     /**
  1537.      * Enter description here...
  1538.      *
  1539.      * @param unknown_type $Itemid 
  1540.      * @param unknown_type $menutype 
  1541.      * @param unknown_type $maxaccess 
  1542.      * @param unknown_type $noparent 
  1543.      * @return unknown 
  1544.      */
  1545.     function &getByParentOrder ($Itemid$menutype$maxaccess=0$noparent=false{
  1546.         $result array();
  1547.         if ($this->_byParentOrder !== null{
  1548.             foreach ($this->_byParentOrder as $parent=>$outer{
  1549.                 foreach ($outer as $ordering=>$inner{
  1550.                     foreach ($inner as $mtype=>$last{
  1551.                         $key $this->_byParentOrder[$parent][$ordering][$mtype];
  1552.                         $menu $this->_menus[$key];
  1553.                         if ($menutype AND $mtype != $menutypecontinue;
  1554.                         if ($Itemid AND $Itemid != $menu->idcontinue;
  1555.                         if ($menu->access $maxaccesscontinue;
  1556.                         if ($noparent AND $parent != 0continue;
  1557.                         $result[$this->_menus[$key];
  1558.                     }
  1559.                 }
  1560.             }
  1561.         }
  1562.         return $result;
  1563.     }
  1564.  
  1565.     /**
  1566.      * Enter description here...
  1567.      *
  1568.      * @param unknown_type $Itemid 
  1569.      */
  1570.     function setPathway ($Itemid{
  1571.         if ($Itemid{
  1572.             $menu =$this->getMenuByID($Itemid);
  1573.             if ($menu->parent$this->setPathway($menu->parent);
  1574.             $pathway =mosPathway::getInstance();
  1575.             $pathway->addItem($menu->name$menu->link."&Itemid=$Itemid");
  1576.         }
  1577.     }
  1578.  
  1579.     /**
  1580.     * Checks whether a menu option is within the users access level
  1581.     * @param int Item id number
  1582.     * @param string The menu option
  1583.     * @param int The users group ID number
  1584.     * @param database A database connector object
  1585.     * @return boolean True if the visitor's group at least equal to the menu access
  1586.     */
  1587.     function menuCheck$Itemid$menu_option$task$gid {
  1588.         // Construct a link to this component - if no menu for it, assume it is OK
  1589.         $dblink="index.php?option=$menu_option";
  1590.         if ($this->getIDLikeLink($dblink== 0return true;
  1591.         if ($Itemid{
  1592.             $menu =$this->getMenuByID($Itemid);
  1593.             if (strpos($menu->link,$dblink===0{
  1594.                 $access $menu->access;
  1595.             elseif ($menu_option == 'com_content' AND $Itemid == 1{
  1596.                 return true;
  1597.             }
  1598.         }
  1599.         if (!isset($access)) {
  1600.             if ($task!=''$dblink .= "&task=$task";
  1601.             $menu =$this->maxAccessLink($dblink);
  1602.             if (isset($menu)) {
  1603.                 $access $menu->access;
  1604.                 mamboCore::set('Itemid'$menu->id);
  1605.             }
  1606.         }
  1607.         return isset($access$access <= $gid false;
  1608.     }
  1609.  
  1610.     /**
  1611.      * Enter description here...
  1612.      *
  1613.      * @param unknown_type $mitem 
  1614.      * @param unknown_type $level 
  1615.      * @param unknown_type $params 
  1616.      * @param unknown_type $Itemid 
  1617.      * @return unknown 
  1618.      */
  1619.     function mosGetMenuLink&$mitem$level=0&$params$Itemid {
  1620.         $txt '';
  1621.  
  1622.         switch ($mitem->type{
  1623.             case 'separator':
  1624.             case 'component_item_link':
  1625.                 break;
  1626.             case 'content_item_link':
  1627.                 $temp split("&task=view&id="$mitem->link);
  1628.                 if (isset($temp[1])) {
  1629.                     require_once(mamboCore::get('mosConfig_absolute_path').'/components/com_content/content.class.php');
  1630.                     $handler =contentHandler::getInstance();
  1631.                     $mitem->link .= '&Itemid='.$handler->getItemid($temp[1]);
  1632.                 }
  1633.                 break;
  1634.             case 'url':
  1635.                 $link strtolower($mitem->link);
  1636.                 if (substr($link,0,10== 'index.php?' AND strpos($link,'itemid='=== false$mitem->link .= '&Itemid='$mitem->id;
  1637.                 break;
  1638.             case 'content_typed':
  1639.             default:
  1640.                 $mitem->link .= '&Itemid='.$mitem->id;
  1641.                 break;
  1642.         }
  1643.         // Active Menu highlighting
  1644.         if $Itemid == $mitem->id $id 'id="active_menu'.$params->get'class_sfx' ).'"';
  1645.         else $id '';
  1646.         $mitem->link ampReplace$mitem->link );
  1647.         if (strcasecmp(substr($mitem->link,0,4)'http')) $mitem->link sefRelToAbs$mitem->link );
  1648.         if ($level 0$menuclass 'sublevel';
  1649.         else $menuclass 'mainlevel';
  1650.         $menuclass .= $params->get'class_sfx');
  1651.  
  1652.         switch ($mitem->browserNav{
  1653.             // cases are slightly different
  1654.             case 1:
  1655.                 // open in a new window
  1656.                 $txt '<a href="'$mitem->link .'" target="_blank" class="'$menuclass .'" '$id .'>'$mitem->name .'</a>';
  1657.                 break;
  1658.  
  1659.             case 2:
  1660.                 // open in a popup window
  1661.                 $txt "<a href=\"#\" onclick=\"javascript: window.open('"$mitem->link ."', '', 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=780,height=550'); return false\" class=\"$menuclass\" "$id .">"$mitem->name ."</a>\n";
  1662.                 break;
  1663.  
  1664.             case 3:
  1665.                 // don't link it
  1666.                 $txt '<span class="'$menuclass .'" '$id .'>'$mitem->name .'</span>';
  1667.                 break;
  1668.  
  1669.             default:    // formerly case 2
  1670.             // open in parent window
  1671.             $txt '<a href="'$mitem->link .'" class="'$menuclass .'" '$id .'>'$mitem->name .'</a>';
  1672.             break;
  1673.         }
  1674.  
  1675.         if $params->get'menu_images' ) ) {
  1676.             $menu_params =new mosParameters$mitem->params );
  1677.             $menu_image $menu_params->def'menu_image'-);
  1678.             if ($menu_image AND $menu_image <> '-1'{
  1679.                 $image '<img src="'mamboCore::get('mosConfig_live_site'.'/images/stories/'$menu_image .'" border="0" alt="'$mitem->name .'"/>';
  1680.                 if $params->get('menu_images_align')) $txt $txt .' '$image;
  1681.                 else $txt $image .' '$txt;
  1682.             }
  1683.         }
  1684.         return $txt;
  1685.     }
  1686.  
  1687.     /**
  1688.     * Vertically Indented Menu
  1689.     */
  1690.     function mosShowVIMenu(  &$params {
  1691.         global $my$cur_template$Itemid;
  1692.         if (mamboCore::get('mosConfig_shownoauth')) $maxaccess 0;
  1693.         else $maxaccess $my->gid;
  1694.         $rows =$this->getByParentOrder(0$params->get('menutype')$maxaccess);
  1695.         foreach ($rows as $i=>$row$crosslink[$row->id$i;
  1696.         // indent icons
  1697.         $base mamboCore::get('mosConfig_live_site');
  1698.         switch $params->get'indent_image' ) ) {
  1699.             case '1':
  1700.                 // Default images
  1701.                 for $i 1$i 7$i++ {
  1702.                     $img[$i"<img src=\"$base/images/M_images/indent$i.png\" alt=\"indent$i\" />";
  1703.                 }
  1704.                 break;
  1705.             case '2':
  1706.                 // Use Params
  1707.                 for $i 1$i 7$i++ {
  1708.                     $parm $params->get('indent_image'$i);
  1709.                     if ($parm == '-1' $img[$iNULL;
  1710.                     else $img[$i"<img src=\"$base/images/M_images/$parm\" alt=\"indent$i\" />";
  1711.                 }
  1712.                 break;
  1713.             case '3':
  1714.                 // None
  1715.                 for $i 1$i 7$i++ $img[$iNULL;
  1716.                 break;
  1717.             default:
  1718.                 // Template
  1719.                 $imgpath $base.'/templates/'$cur_template .'/images';
  1720.                 for $i 1$i 7$i++ {
  1721.                     $img[$i"<img src=\"$base/templates/$cur_template/images/indent$i.png\" alt=\"indent$i\" />";
  1722.                 }
  1723.                 break;
  1724.         }
  1725.  
  1726.         $indents array(
  1727.         // block prefix / item prefix / item suffix / block suffix
  1728.         array'<table width="100%" border="0" cellpadding="0" cellspacing="0">''<tr align="left"><td>' '</td></tr>''</table>' ),
  1729.         array'''<div style="padding-left: 4px">'$img[1'</div>''' ),
  1730.         array'''<div style="padding-left: 8px">'$img[2'</div>''' ),
  1731.         array'''<div style="padding-left: 12px">'$img[3'</div>''' ),
  1732.         array'''<div style="padding-left: 16px">'$img[4'</div>''' ),
  1733.         array'''<div style="padding-left: 20px">'$img[5'</div>''' ),
  1734.         array'''<div style="padding-left: 24px">'$img[6'</div>''' ),
  1735.         );
  1736.  
  1737.         // establish the hierarchy of the menu
  1738.         $children array();
  1739.         // first pass - collect children
  1740.         foreach ($rows as $v $children[$v->parent][$v;
  1741.         // second pass - collect 'open' menus
  1742.         $open array$Itemid );
  1743.         for ($i 0$i 20 AND isset($crosslink[$open[$i]]AND isset($rows[$crosslink[$open[$i]]])$i++{
  1744.             $next $rows[$crosslink[$open[$i]]]->parent;
  1745.             if ($next$open[$i+1$next;
  1746.             else break;
  1747.         }
  1748.  
  1749.         $this->mosRecurseVIMenu00$children$open$indents$params );
  1750.  
  1751.     }
  1752.  
  1753.     /**
  1754.     * Utility function to recursively work through a vertically indented
  1755.     * hierarchial menu
  1756.     */
  1757.     function mosRecurseVIMenu$id$level&$children&$open&$indents&$params {
  1758.         global $Itemid;
  1759.         if (@$children[$id]{
  1760.             $n min$levelcount($indents )-1);
  1761.             echo "\n".$indents[$n][0];
  1762.             foreach ($children[$idas $row{
  1763.                 echo "\n".$indents[$n][1];
  1764.                 echo $this->mosGetMenuLink$row$level$params$Itemid );
  1765.                 // show menu with menu expanded - submenus visible
  1766.                 if ($params->get('expand_menu'OR in_array($row->id$open)) $this->mosRecurseVIMenu$row->id$level+1$children$open$indents$params );
  1767.                 echo $indents[$n][2];
  1768.             }
  1769.             echo "\n".$indents[$n][3];
  1770.         }
  1771.     }
  1772.  
  1773.     /**
  1774.     * Draws a horizontal 'flat' style menu (very simple case)
  1775.     */
  1776.     function mosShowHFMenu(  &$params$style={
  1777.         global $my$cur_template$Itemid;
  1778.  
  1779.         if (mamboCore::get('mosConfig_shownoauth')) $maxaccess 0;
  1780.         else $maxaccess $my->gid;
  1781.         $rows =$this->getByParentOrder(0$params->get('menutype')$maxaccesstrue);
  1782.  
  1783.         $links array();
  1784.         foreach ($rows as $row$links[$this->mosGetMenuLink$row0$params$Itemid );
  1785.         $menuclass 'mainlevel'$params->get'class_sfx' );
  1786.         if (count$links )) {
  1787.             if ($style == 1{
  1788.                 echo '<ul id="'$menuclass .'">';
  1789.                 foreach ($links as $linkecho '<li>' $link '</li>';
  1790.                 echo '</ul>';
  1791.             }
  1792.             else {
  1793.                 echo '<table width="100%" border="0" cellpadding="0" cellspacing="1">';
  1794.                 echo '<tr>';
  1795.                 echo '<td nowrap="nowrap">';
  1796.                 echo '<span class="'$menuclass .'"> '$params->get'end_spacer' .' </span>';
  1797.                 echo implode'<span class="'$menuclass .'"> '$params->get'spacer' .' </span>'$links );
  1798.                 echo '<span class="'$menuclass .'"> '$params->get'end_spacer' .' </span>';
  1799.                 echo '</td></tr>';
  1800.                 echo '</table>';
  1801.             }
  1802.         }
  1803.     }
  1804. }
  1805.  
  1806. /**
  1807. * Plugin handler
  1808. @package Mambo
  1809. */
  1810.     /** @var array An array of functions in event groups */
  1811.     var $_events=null;
  1812.     /** @var array An array of lists */
  1813.     var $_lists=null;
  1814.     /** @var array An array of mambots */
  1815.     var $_bots=null;
  1816.     /** @var array An array of bools showing if corresponding bot is registered */
  1817.     var $_registered=array();
  1818.     /** @var int Index of the mambot being loaded */
  1819.     var $_loading=null;
  1820.  
  1821.     /**
  1822.     * Constructor
  1823.     */
  1824.     function mosMambotHandler({
  1825.         $my mamboCore::is_set('currentUser'mamboCore::get('currentUser'null;
  1826.         $gid $my $my->gid 0;
  1827.         $this->_events = array();
  1828.         $database =mamboDatabase::getInstance();
  1829.         $database->setQuery"SELECT folder, element, published, params, CONCAT_WS('/',folder,element) AS lookup"
  1830.         . "\nFROM #__mambots"
  1831.         . "\nWHERE published >= 1 AND access <= $gid"
  1832.         . "\nORDER BY ordering"
  1833.         );
  1834.         $this->_bots = $database->loadObjectList();
  1835.         if (!$this->_bots$this->_bots = array();
  1836.     }
  1837.     /**
  1838.     * Singleton accessor
  1839.     */
  1840.     function &getInstance ({
  1841.         static $instance;
  1842.         if (!is_object($instance)) $instance new mosMambotHandler();
  1843.         return $instance;
  1844.     }
  1845.     /**
  1846.     * Register a class-type mambot, provided it has a perform method
  1847.     * - can register for multiple events if desired
  1848.     * @param object The mambot object
  1849.     * @param mixed string or array of strings - the mambot events to be registered
  1850.     * @param int the subscript for use in the main array of mambots
  1851.     */
  1852.     function _botRegister (&$botObject&$selected$i{
  1853.         $function array(&$botObject'perform');
  1854.         if (!is_callable($function)) return;
  1855.         if (is_array($selected)) foreach ($selected as $select$this->_botRegister($botObject$select);
  1856.         $this->_events[$selected][array ($function$i);
  1857.         $this->_registered[$itrue;
  1858.     }
  1859.  
  1860.     /**
  1861.     * Loads all the bot files for a particular group
  1862.     * @param string The group name, relates to the sub-directory in the mambots directory
  1863.     */
  1864.     function loadBotGroup$group {
  1865.         global $_MAMBOTS;
  1866.         $group trim$group );
  1867.         $total 0;
  1868.         $basepath mamboCore::get('mosConfig_absolute_path');
  1869.         foreach ($this->_bots as $i=>$bot{
  1870.             if ($bot->folder != $group OR isset($this->_registered[$i])) continue;
  1871.             $path "$basepath/mambots/$bot->folder/$bot->element.php";
  1872.             if (file_exists$path )) {
  1873.                 $this->_loading = $i;
  1874.                 require_once$path );
  1875.                 if (!isset($this->_registered[$i])) {
  1876.                     $botclass str_replace('.','_',$bot->element);
  1877.                     if (class_exists($botclass)) {
  1878.                         $newbot new $botclass();
  1879.                         if (is_callable(array(&$newbot'register'))) {
  1880.                             $selected $newbot->register();
  1881.                             $this->_botRegister($newbot$selected$i);
  1882.                         }
  1883.                         unset($newbot);
  1884.                     }
  1885.                 }
  1886.                 $total++;
  1887.             }
  1888.         }
  1889.         $this->_loading = null;
  1890.         if ($totalreturn true;
  1891.         return false;
  1892.     }
  1893.     /**
  1894.     * Registers a function to a particular event group
  1895.     * @param string The event name
  1896.     * @param string The function name
  1897.     */
  1898.     function registerFunction$event$function {
  1899.         $this->_events[$event][array$function$this->_loading );
  1900.         $this->_registered[$this->_loadingtrue;
  1901.     }
  1902.     /**
  1903.     * Makes a option for a particular list in a group
  1904.     * @param string The group name
  1905.     * @param string The list name
  1906.     * @param string The value for the list option
  1907.     * @param string The text for the list option
  1908.     */
  1909.     function addListOption$group$listName$value$text='' {
  1910.         $this->_lists[$group][$listName][mosHTML::makeOption$value$text );
  1911.     }
  1912.     /**
  1913.     * @param string The group name
  1914.     * @param string The list name
  1915.     * @return array 
  1916.     */
  1917.     function getList$group$listName {
  1918.         return $this->_lists[$group][$listName];
  1919.     }
  1920.     /**
  1921.     * Calls all functions according to passed parameters
  1922.     * @param string The event name
  1923.     * @param array An array of arguments
  1924.     * @param boolean True is unpublished bots are to be processed
  1925.     * @return array An array of results from each function call
  1926.     */
  1927.     function &_runBots ($event$args$doUnpublished=false{
  1928.         $result array();
  1929.         if (isset$this->_events[$event)) {
  1930.             foreach ($this->_events[$eventas $func{
  1931.                 if (is_callable$func[0)) {
  1932.                     $botparams $this->_bots[$func[1]]->params;
  1933.                     if(!empty($botparams)){
  1934.                         $args[new mosParameters($botparams);
  1935.                         $args[$event;
  1936.                     }else {
  1937.                         $args[array();
  1938.                     }
  1939.                     if ($doUnpublished{
  1940.                         $args[0$this->_bots[$func[1]]->published;
  1941.                         $result[call_user_func_array$func[0]$args );
  1942.                     else if ($this->_bots[$func[1]]->published{
  1943.                         $result[call_user_func_array$func[0]$args );
  1944.                     }
  1945.                 }
  1946.             }
  1947.         }
  1948.         return $result;
  1949.     }
  1950.     /**
  1951.     * Calls all functions associated with an event group
  1952.     * @param string The event name
  1953.     * @param array An array of arguments
  1954.     * @param boolean True is unpublished bots are to be processed
  1955.     * @return array An array of results from each function call
  1956.     */
  1957.     function trigger$event$args=null$doUnpublished=false {
  1958.         if ($args === null$args array();
  1959.         // prepend the published argument
  1960.         if ($doUnpublishedarray_unshift$argsnull );
  1961.         $result =$this->_runBots($event$args$doUnpublished);
  1962.         return $result;
  1963.     }
  1964.     /**
  1965.     * Same as trigger but only returns the first event and
  1966.     * allows for a variable argument list
  1967.     * @param string The event name
  1968.     * @return array The result of the first function call
  1969.     */
  1970.     function call$event {
  1971.         $args =func_get_args();
  1972.         array_shift$args );
  1973.         $result =$this->_runBots($event$args);
  1974.         if (isset($result[0])) return $result[0];
  1975.         return null;
  1976.     }
  1977.  
  1978.     function getBot($element$folder{
  1979.         $returnBot '';
  1980.         foreach ($this->_bots as $i=>$bot{
  1981.             if ($bot->folder == $folder && $bot->element == $element){
  1982.                 $returnBot $bot;
  1983.                 break;
  1984.             }
  1985.         }
  1986.         return $returnBot;
  1987.     }
  1988. }
  1989.  
  1990. /**
  1991. * Users Table Class
  1992. *
  1993. * Provides access to the mos_templates table
  1994. @package Mambo
  1995. */
  1996. class mosUser extends mosDBTable {
  1997.     /** @var int Unique id*/
  1998.     var $id=null;
  1999.     /** @var string The users real name (or nickname)*/
  2000.     var $name=null;
  2001.     /** @var string The login name*/
  2002.     var $username=null;
  2003.     /** @var string email*/
  2004.     var $email=null;
  2005.     /** @var string MD5 encrypted password*/
  2006.     var $password=null;
  2007.     /** @var string */
  2008.     var $usertype=null;
  2009.     /** @var int */
  2010.     var $block=null;
  2011.     /** @var int */
  2012.     var $sendEmail=null;
  2013.     /** @var int The group id number */
  2014.     var $gid=null;
  2015.     /** @var int Group number from ACL */
  2016.     var $grp=null;
  2017.     /** @var datetime */
  2018.     var $registerDate=null;
  2019.     /** @var datetime */
  2020.     var $lastvisitDate=null;
  2021.     /** @var string activation hash*/
  2022.     var $activation=null;
  2023.     /** @var string */
  2024.     var $params=null;
  2025.  
  2026.     /**
  2027.     * @param database A database connector object
  2028.     */
  2029.     function mosUser({
  2030.         $database =mamboDatabase::getInstance();
  2031.         $this->mosDBTable'#__users''id'$database );
  2032.     }
  2033.  
  2034.     /**
  2035.      * Return true if this user is an administrator, false otherwise
  2036.      */
  2037.     function isAdmin({
  2038.         return strtolower$this->usertype == 'superadministrator' OR strtolower$this->usertype == 'super administrator' OR (isset($this->grpAND $this->grp == 16) ) true false;
  2039.     }
  2040.  
  2041.     /**
  2042.      * Fill a user object with information from the current session
  2043.      */
  2044.     function getSessionData({
  2045.         $session =mosSession::getCurrent();
  2046.         $this->id = intval$session->userid );
  2047.         $this->username = $session->username;
  2048.         $this->usertype = $session->usertype;
  2049.         $this->gid = intval ($session->gid);
  2050.     }
  2051.  
  2052.     function getSession ({
  2053.         $this->id = mosGetParam$_SESSION'session_user_id');
  2054.         $this->username = mosGetParam$_SESSION'session_username''' );
  2055.         $this->usertype = mosGetParam$_SESSION'session_usertype''' );
  2056.         $this->gid = mosGetParam$_SESSION'session_gid');
  2057.         $this->grp = mosGetParam$_SESSION'session_grp'0);
  2058.     }
  2059.     /**
  2060.      * Validation and filtering
  2061.      * @return boolean True is satisfactory
  2062.      */
  2063.     function check({
  2064.         Global $mosConfig_absolute_path;
  2065.         //include $mosConfig_absolute_path . ('/language/english.php');
  2066.         $this->_error = '';
  2067.         if ($this->name == ''$this->_error = _REGWARN_NAME;
  2068.         elseif ($this->username == ''$this->_error = _REGWARN_UNAME;
  2069.         elseif (strlen($this->usernameOR preg_match("/[\\<\\>\\\"\\'\\%\\;\\(\\)\\&\\+\\-]/"$this->username)) $this->_error = sprintf_VALID_AZ09_PROMPT_UNAME);
  2070.         elseif (($this->email == ''OR preg_match("/[\w\.\-]+@\w+[\w\.\-]*?\.\w{1,4}/"$this->email == 0$this->_error = _REGWARN_MAIL;
  2071.         else {
  2072.             // check for existing username
  2073.             $username strtolower($this->username);
  2074.             $this->_db->setQuery"SELECT COUNT(id) FROM #__users "
  2075.             . "\nWHERE LOWER(username)='$username' AND id!='$this->id'"
  2076.             );
  2077.             if ($this->_db->loadResult()) $this->_error = _REGWARN_INUSE;
  2078.             elseif (mamboCore::get('mosConfig_uniquemail')) {
  2079.                 // check for existing email
  2080.                 $this->_db->setQuery"SELECT COUNT(id) FROM #__users "
  2081.                 . "\nWHERE email='$this->email' AND id!='$this->id'"
  2082.                 );
  2083.                 if ($this->_db->loadResult()) $this->_error = _REGWARN_EMAIL_INUSE;
  2084.             }
  2085.         }
  2086.         if ($this->_errorreturn false;
  2087.         return true;
  2088.     }
  2089.  
  2090.     function store$updateNulls=false {
  2091.         global $acl$migrate;
  2092.         $section_value 'users';
  2093.         if$this->id AND !$migrate{
  2094.             // update existing record
  2095.             $ret $this->_db->updateObject$this->_tbl$this'id'$updateNulls );
  2096.             // syncronise ACL
  2097.             // single group handled at the moment
  2098.             // trivial to expand to multiple groups
  2099.             $groups $acl->get_object_groups$section_value$this->id'ARO' );
  2100.             $acl->del_group_object$groups[0]$section_value$this->id'ARO' );
  2101.             $acl->add_group_object$this->gid$section_value$this->id'ARO' );
  2102.             $object_id $acl->get_object_id$section_value$this->id'ARO' );
  2103.             $acl->edit_object$object_id$section_value$this->_db->getEscaped$this->name )$this->id00'ARO' );
  2104.         }
  2105.         else {
  2106.             // new record
  2107.             $ret $this->_db->insertObject$this->_tbl$this'id' );
  2108.             // syncronise ACL
  2109.             $acl->add_object$section_value$this->_db->getEscaped$this->name )$this->idnullnull'ARO' );
  2110.             $acl->add_group_object$this->gid$section_value$this->id'ARO' );
  2111.         }
  2112.         if ($retreturn true;
  2113.         $this->_error = "mosUser::store failed <br />" $this->_db->getErrorMsg();
  2114.         return false;
  2115.     }
  2116.  
  2117.     function delete($oid=null{
  2118.         global $acl;
  2119.         $k $this->_tbl_key;
  2120.         if ($oid$this->id = intval$oid );
  2121.         $aro_id $acl->get_object_id'users'$this->$k'ARO' );
  2122.         $acl->del_object$aro_id'ARO'true );
  2123.         //        $authoriser = mosAuthorisationAdmin::getInstance();
  2124.         //        $authoriser->dropAccess('mosUser', $this->id);
  2125.         $this->_error = '';
  2126.         $this->_db->setQuery"DELETE FROM $this->_tbl WHERE id = '".$this->id."'" );
  2127.         if ($this->_db->query()) {
  2128.             // cleanup related data
  2129.  
  2130.             // :: private messaging
  2131.             $this->_db->setQuery"DELETE FROM #__messages_cfg WHERE user_id='".$this->id."'" );
  2132.             if (!$this->_db->query()) $this->_error = $this->_db->getErrorMsg();
  2133.             else {
  2134.                 $this->_db->setQuery"DELETE FROM #__messages WHERE user_id_to='".$this->$k."'" );
  2135.                 if (!$this->_db->query()) $this->_error = $this->_db->getErrorMsg();
  2136.             }
  2137.         else $this->_error = $this->_db->getErrorMsg();
  2138.         if ($this->_errorreturn false;
  2139.         return true;
  2140.     }
  2141. }
  2142.  
  2143. /**
  2144. * User login details class
  2145. @package Mambo
  2146. */
  2147. class mosLoginDetails {
  2148.     var $_user = '';
  2149.     var $_password = '';
  2150.     var $_remember = '';
  2151.  
  2152.     function mosLoginDetails ($user$password=''$remember=''{
  2153.         $this->_user = $user;
  2154.         $this->_password = $password;
  2155.         $this->_remember = $remember;
  2156.     }
  2157.  
  2158.     function getUser ({
  2159.         return $this->_user;
  2160.     }
  2161.  
  2162.     function getPassword ({
  2163.         return $this->_password;
  2164.     }
  2165.  
  2166.     function getRemember ({
  2167.         return $this->_remember;
  2168.     }
  2169.  
  2170. }
  2171. /**
  2172. * Mambo Mainframe class
  2173. *
  2174. * Provide many supporting API functions
  2175. @package Mambo
  2176. */
  2177. class mosMainFrame {
  2178.     /** @var database Internal database class pointer */
  2179.     var $_db=null;
  2180.     /** @var object default option (e.g. component) */
  2181.     var $_option=null;
  2182.     /** @var string The current template */
  2183.     var $_template=null;
  2184.     /** @var array An array to hold global user state within a session */
  2185.     var $_userstate=null;
  2186.     /** @var array An array of page meta information */
  2187.     var $_head=null;
  2188.     /** @var string Custom html string to append to the pathway */
  2189.     var $_custom_pathway=array();
  2190.  
  2191.     /**
  2192.     * Class constructor
  2193.     * @param database A database connection object
  2194.     * @param string The url option
  2195.     * @param string The path of the mos directory
  2196.     */
  2197.     function mosMainFrame&$db$option$basePath$isAdmin=false {
  2198.         $this->_db =$db;
  2199.         // load the configuration values
  2200.         //return( $this->loadConfig() );
  2201.         $this->_setTemplate($isAdmin);
  2202.         if (substr($option,0,4!= 'com_'$this->_option = "com_$option";
  2203.         else $this->_option = $option;
  2204.         if (isset$_SESSION['session_userstate')) $this->_userstate =$_SESSION['session_userstate'];
  2205.         else $this->_userstate = null;
  2206.         $this->_head['title'$GLOBALS['mosConfig_sitename'];
  2207.         $this->_head['meta'array();
  2208.         $this->_head['custom'array();
  2209.         mosMainFrame::getInstance($this);
  2210.     }
  2211.  
  2212.     /**
  2213.     * Get the current user - deprecated - use mamboCore instead
  2214.     */
  2215.     function getUser({
  2216.         return mamboCore::get('currentUser');
  2217.     }
  2218.     /**
  2219.     * Logout the current user - deprecated - use the code here directly
  2220.     */
  2221.     function logout({
  2222.         require_once(mamboCore::get('mosConfig_absolute_path').'/includes/authenticator.php');
  2223.         $authenticator =mamboAuthenticator::getInstance();
  2224.         $authenticator->logoutUser();
  2225.     }
  2226.     /**
  2227.     * Login a user given name and password - deprecated - use the code here directly
  2228.     */
  2229.     function login ($username=null,$passwd=null{
  2230.         require_once(mamboCore::get('mosConfig_absolute_path').'/includes/authenticator.php');
  2231.         $authenticator =mamboAuthenticator::getInstance();
  2232.         return $authenticator->loginUser($username$passwd);
  2233.     }
  2234.  
  2235.     /**
  2236.     * @param object 
  2237.     */
  2238.     function &getInstance ({
  2239.         global $mainframe;
  2240.         if (isset($mainframe)) {
  2241.             return $mainframe;
  2242.         else {
  2243.             $result null;
  2244.             return $result;
  2245.         }
  2246.     }
  2247.  
  2248.     /**
  2249.     * @param string 
  2250.     */
  2251.     function setPageTitle$title=null {
  2252.         if (mamboCore::get('mosConfig_pagetitles')) {
  2253.             $title trim(htmlspecialchars($title));
  2254.             $base mamboCore::get('mosConfig_sitename');
  2255.             $this->_head['title'$title ?  $title.' - '.$base $base;
  2256.         }
  2257.     }
  2258.     /**
  2259.     * @return string 
  2260.     */
  2261.     function getPageTitle({
  2262.         return $this->_head['title'];
  2263.     }
  2264.  
  2265.     /**
  2266.     * @param string The value of the name attibute
  2267.     * @param string The value of the content attibute
  2268.     * @param string Text to display before the tag
  2269.     * @param string Text to display after the tag
  2270.     */
  2271.     function addMetaTag$name$content$prepend=''$append='' {
  2272.         list($name$content$this->_tidyMetaData($name$content);
  2273.         $prepend trim($prepend);
  2274.         $append trim($append);
  2275.         $this->_head['meta'][$namearray($content$prepend$append);
  2276.     }
  2277.     /**
  2278.     * @param string The value of the name attibute
  2279.     */
  2280.     function _getMetaTag ($name{
  2281.         return isset($this->_head['meta'][$name]?  $this->_head['meta'][$namearray('''''');
  2282.     }
  2283.     /**
  2284.     * @param string The value of the name attibute
  2285.     * @param string The value of the content attibute to append to the existing
  2286.     */
  2287.     function _tidyMetaData($name$content{
  2288.         $result[trim(htmlspecialchars($name));
  2289.         $result[trim(htmlspecialchars($content));
  2290.         return $result;
  2291.     }
  2292.     /**
  2293.     * @param string The value of the name attibute
  2294.     * @param string The value of the content attibute to append to the existing
  2295.     *  Tags ordered in with Site Keywords and Description first
  2296.     */
  2297.     function appendMetaTag$name$content$ifEmpty=false {
  2298.         list($name$content$this->_tidyMetaData($name$content);
  2299.         $tag $this->_getMetaTag($name);
  2300.         if ($tag[0AND $ifEmptyreturn;
  2301.         if ($tag[0AND $content$content .= ', ';
  2302.         $tag[0$content.$tag[0];
  2303.         $this->_head['meta'][$name=  $tag;
  2304.     }
  2305.  
  2306.     /**
  2307.     * @param string The value of the name attibute
  2308.     * @param string The value of the content attibute to append to the existing
  2309.     */
  2310.     function prependMetaTag$name$content {
  2311.         list($name$content$this->_tidyMetaData($name$content);
  2312.         $tag $this->_getMetaTag($name);
  2313.         $tag[0$content.$tag[0];
  2314.         $this->_head['meta'][$name=  $tag;
  2315.     }
  2316.     /**
  2317.      * Adds a custom html string to the head block
  2318.      * @param string The html to add to the head
  2319.      */
  2320.     function addCustomHeadTag$html {
  2321.         $this->_head['custom'][trim$html );
  2322.     }
  2323.     /**
  2324.     * @return string 
  2325.     */
  2326.     function getHead({
  2327.         $head['<title>'.$this->_head['title'].'</title>';
  2328.         foreach ($this->_head['meta'as $name=>$meta{
  2329.             if ($meta[1]$head[$meta[1];
  2330.             $head['<meta name="' $name '" content="' $meta[0'" />';
  2331.             if ($meta[2]$head[$meta[2];
  2332.         }
  2333.         foreach ($this->_head['custom'as $html$head[$html;
  2334.         return implode"\n"$head )."\n";
  2335.     }
  2336.     /**
  2337.     * @return string 
  2338.     */
  2339.     function getCustomPathWay({
  2340.         return $this->_custom_pathway;
  2341.     }
  2342.  
  2343.     function appendPathWay($html{
  2344.         $this->_custom_pathway[$html;
  2345.     }
  2346.  
  2347.     /**
  2348.     * Gets the value of a user state variable
  2349.     * @param string The name of the variable
  2350.     */
  2351.     function getUserState$var_name {
  2352.         return is_array($this->_userstatemosGetParam($this->_userstate$var_namenullnull;
  2353.     }
  2354.     /**
  2355.     * Sets the value of a user state variable
  2356.     * @param string The name of the variable
  2357.     * @param string The value of the variable
  2358.     */
  2359.     function setUserState$var_name$var_value {
  2360.         if (is_array$this->_userstate )) $this->_userstate[$var_name$var_value;
  2361.     }
  2362.     /**
  2363.     * Gets the value of a user state variable
  2364.     * @param string The name of the user state variable
  2365.     * @param string The name of the variable passed in a request
  2366.     * @param string The default value for the variable if not found
  2367.     */
  2368.     function getUserStateFromRequest$var_name$req_name$var_default=null {
  2369.         if (is_array($this->_userstate)) {
  2370.             if (isset($_REQUEST[$req_name])) $this->setUserState($var_name$_REQUEST[$req_name]);
  2371.             else if (isset($var_defaultAND !isset($this->_userstate[$var_name])) $this->setUserState($var_name$var_default);
  2372.             return $this->_userstate[$var_name];
  2373.         else {
  2374.             return null;
  2375.         }
  2376.     }
  2377.     /**
  2378.     * Initialises the user session
  2379.     *
  2380.     * Old sessions are flushed based on the configuration value for the cookie
  2381.     * lifetime. If an existing session, then the last access time is updated.
  2382.     * If a new session, a session id is generated and a record is created in
  2383.     * the mos_sessions table.
  2384.     */
  2385.     function &initSession({
  2386.         $session =mosSession::getCurrent();
  2387.         return $session;
  2388.     }
  2389.  
  2390.     /**
  2391.     * @param string The name of the variable (from configuration.php)
  2392.     * @return mixed The value of the configuration variable or null if not found
  2393.     */
  2394.     function getCfg$varname {
  2395.         return mamboCore::get('mosConfig_'.$varname);
  2396.     }
  2397.  
  2398.     function _setTemplate$isAdmin=false {
  2399.         global $Itemid;
  2400.         $cur_template '';
  2401.         $sql "SELECT template, client_id, menuid FROM #__templates_menu WHERE (client_id=0 or client_id=1)";
  2402.         if (isset($ItemidAND $Itemid$sql .= " AND (menuid=0 OR menuid=$Itemid)";
  2403.         else $sql .= " AND menuid=0";
  2404.         $sql .= " ORDER BY client_id, menuid";
  2405.         $this->_db->setQuery($sql);
  2406.         $templates $this->_db->loadObjectList();
  2407.         foreach ($templates as $template{
  2408.             if ($template->client_id == 1{
  2409.                 if ($isAdmin$cur_template $template->template;
  2410.             }
  2411.             else $cur_template $template->template;
  2412.         }
  2413.         if ($isAdmin{
  2414.             $path mamboCore::get('mosConfig_absolute_path')."/administrator/templates/$cur_template/index.php";
  2415.             if (!file_exists$path )) $cur_template 'mambo_admin';
  2416.         }
  2417.         else {
  2418.             // TemplateChooser Start
  2419.             $mos_user_template mosGetParam$_COOKIE'mos_user_template''' );
  2420.             $mos_change_template mosGetParam$_REQUEST'mos_change_template'$mos_user_template );
  2421.             if ($mos_change_template{
  2422.                 // check that template exists in case it was deleted
  2423.                 $path mamboCore::get('mosConfig_absolute_path')."/templates/$mos_change_template/index.php";
  2424.                 if (strpos($mos_change_template,'..'== false AND strpos($mos_change_template,':'== false AND file_exists($path)) {
  2425.                     $lifetime 60*10;
  2426.                     $cur_template $mos_change_template;
  2427.                     setcookie"mos_user_template""$mos_change_template"time()+$lifetime);
  2428.                 else     setcookie"mos_user_template"""time()-3600 );
  2429.             }
  2430.             // TemplateChooser End
  2431.         }
  2432.         $this->_template = $cur_template;
  2433.     }
  2434.  
  2435.     function getTemplate({
  2436.         return $this->_template;
  2437.     }
  2438.  
  2439.     /**
  2440.     * Checks to see if an image exists in the current templates image directory
  2441.      * if it does it loads this image.  Otherwise the default image is loaded.
  2442.     * Also can be used in conjunction with the menulist param to create the chosen image
  2443.     * load the default or use no image
  2444.     */
  2445.     function ImageCheck$file$directory='/images/M_images/'$param=NULL$param_directory='/images/M_images/'$alt=NULL$name='image'$type=1$align='middle' {
  2446.         $basepath mamboCore::get('mosConfig_live_site');
  2447.         if ($param$image $basepath.$param_directory.$param;
  2448.         else {
  2449.             $endpath '/templates/'.$this->getTemplate().'/images/'.$file;
  2450.             if (file_exists(mamboCore::get('mosConfig_absolute_path').$endpath)) $image $basepath.$endpath;
  2451.             else $image $basepath.$directory.$file;  // outputs only path to image
  2452.         }
  2453.         // outputs actual html <img> tag
  2454.         if ($type$image '<img src="'$image .'" alt="'$alt .'" align="'$align .'" name="'$name .'" border="0" />';
  2455.         return $image;
  2456.     }
  2457.  
  2458.     /**
  2459.     * Returns the first to be found of one or more files, or null
  2460.     *
  2461.     */
  2462.     function tryFiles ($first_choice$second_choice=null$third_choice=null{
  2463.         if (file_exists($first_choice)) return $first_choice;
  2464.         elseif ($second_choice AND file_exists($second_choice)) return $second_choice;
  2465.         elseif ($third_choice AND file_exists($third_choice)) return $third_choice;
  2466.         else return null;
  2467.     }
  2468.  
  2469.     /**
  2470.     * Returns a standard path variable
  2471.     *
  2472.     */
  2473.     function getPath$varname$option='' {
  2474.         $base mamboCore::get('mosConfig_absolute_path');
  2475.         $origoption $option;
  2476.         if (!$option$option $this->_option;
  2477.         $name substr($option,4);
  2478.         $bac_admin "$base/administrator/components/com_admin/";
  2479.         $baco "$base/administrator/components/$option/";
  2480.         $bttc "$base/templates/$this->_template/components/";
  2481.         $bco "$base/components/$option/";
  2482.         $bai "$base/administrator/includes/";
  2483.         $bi "$base/includes/";
  2484.  
  2485.         switch ($varname{
  2486.             case 'front'return $this->tryFiles ($bco."$name.php");
  2487.             case 'front_html'return $this->tryFiles ($bttc."$name.html.php"$bco."$name.html.php");
  2488.             case 'admin'return $this->tryFiles ($baco."admin.$name.php"$bac_admin.'admin.admin.php');
  2489.             case 'admin_html'return $this->tryFiles ($baco."admin.$name.html.php"$bac_admin.'admin.admin.html.php');
  2490.             case 'toolbar'return $this->tryFiles ($baco."toolbar.$name.php");
  2491.             case 'toolbar_html'return $this->tryFiles ($baco."toolbar.$name.html.php");
  2492.             case 'toolbar_default'return $this->tryFiles ($bai.'toolbar.html.php');
  2493.             case 'class'return $this->tryFiles ($bco."$name.class.php"$baco."$name.class.php"$bi."$name.php");
  2494.             case 'com_xml'return $this->tryFiles ($baco."$name.xml"$bco."$name.xml");
  2495.             case 'mod0_xml':
  2496.                 if ($origoption$path $base."/modules/$option.xml";
  2497.                 else $path $base.'/modules/custom.xml';
  2498.                 return $this->tryFiles ($path);
  2499.             case 'mod1_xml':
  2500.                 if ($origoption$path $base."/administrator/modules/$option.xml";
  2501.                 else $path $base.'/administrator/modules/custom.xml';
  2502.                 return $this->tryFiles ($path);
  2503.             case 'bot_xml'return $this->tryFiles ($base."/mambots/$option.xml");
  2504.             case 'menu_xml'return $this->tryFiles ($base."/administrator/components/com_menus/$option/$option.xml");
  2505.             case 'installer_html'return $this->tryFiles($base."/administrator/components/com_installer/$option/$option.html.php");
  2506.             case 'installer_class'return $this->tryFiles($base."/administrator/components/com_installer/$option/$option.class.php");
  2507.         }
  2508.     }
  2509.  
  2510.     /**
  2511.     * Detects a 'visit'
  2512.     *
  2513.     * This function updates the agent and domain table hits for a particular
  2514.     * visitor.  The user agent is recorded/incremented if this is the first visit.
  2515.     * A cookie is set to mark the first visit.
  2516.     */
  2517.     function detect({
  2518.         if (mamboCore::get('mosConfig_enable_stats'== 1{
  2519.             if (mosGetParam$_COOKIE'mosvisitor')) return;
  2520.             setcookie"mosvisitor""1" );
  2521.  
  2522.             $agent $_SERVER['HTTP_USER_AGENT'];
  2523.             $browser mosGetBrowser$agent );
  2524.             $os mosGetOS$agent );
  2525.             $domain gethostbyaddr$_SERVER['REMOTE_ADDR');
  2526.             // tease out the last element of the domain
  2527.             $tldomain split"\."$domain );
  2528.             $tldomain $tldomain[count$tldomain )-1];
  2529.             if (is_numeric$tldomain )) {
  2530.                 $tldomain "Unknown";
  2531.             }
  2532.  
  2533.             $this->_db->setQuery"SELECT count(*), type FROM #__stats_agents WHERE (agent='$browser' AND type=0) OR (agent='$os' AND type=1) OR (agent='$tldomain' AND type=2) GROUP BY type");
  2534.             $stats $this->_db->loadObjectList();
  2535.             $sql['browser'"INSERT INTO #__stats_agents (agent,type) VALUES ('$browser',0)";
  2536.             $sql['os'"INSERT INTO #__stats_agents (agent,type) VALUES ('$os',1)";
  2537.             $sql['domain'"INSERT INTO #__stats_agents (agent,type) VALUES ('$tldomain',2)";
  2538.             if ($statsforeach ($stats as $stat{
  2539.                 if ($stat->type == 0$sql['agents'"UPDATE #__stats_agents SET hits=(hits+1) WHERE agent='$browser' AND type=0";
  2540.                 if ($stat->type == 1$sql['os'"UPDATE #__stats_agents SET hits=(hits+1) WHERE agent='$os' AND type=1";
  2541.                 if ($stat->type == 2$sql['domain'"UPDATE #__stats_agents SET hits=(hits+1) WHERE agent='$tldomain' AND type=2";
  2542.             }
  2543.             $this->_db->setQuery(implode('; ',$sql));
  2544.             $this->_db->query_batch();
  2545.         }
  2546.     }
  2547.  
  2548.     /**
  2549.     * @return correct Itemid for Content Item
  2550.     */
  2551.     function getItemid ($id$typed=1$link=1$bs=1$bc=1$gbs=1{
  2552.         require_once(mamboCore::get('mosConfig_absolute_path').'/components/com_content/content.class.php');
  2553.         $handler =contentHandler::getInstance();
  2554.         return $handler->getItemid($id$typed$link$bs$bc$gbs);
  2555.     }
  2556.  
  2557.     function liveBookMark ({
  2558.         // support for Firefox Live Bookmarks ability for site syndication
  2559.         $live_bookmark 0;
  2560.         $c_handler =mosComponentHandler::getInstance();
  2561.         $params =$c_handler->getParamsByName('خروجی Ø³Ø§ÛŒØª');
  2562.         if (!is_null($params)){
  2563.             $live_bookmark $params->get'live_bookmark');
  2564.         }
  2565.  
  2566.         if ($live_bookmark{
  2567.             // custom bookmark file name
  2568.             $bookmark_file $params->get'bookmark_file'$live_bookmark );
  2569.             $link_file     mamboCore::get('mosConfig_live_site').'/cache/'$bookmark_file;
  2570.             $filename     mamboCore::get('mosConfig_absolute_path').'/cache/'$bookmark_file;
  2571.             $cache         $params->get'cache');
  2572.             $cache_time $params->get'cache_time'3600 );
  2573.             $title         $params->def'title'mamboCore::get('mosConfig_sitename') );
  2574.             // checks to see if cache file exists, to determine whether to create a new one
  2575.             if !file_exists$filename || ( ( time(filemtime$filename ) ) $cache_time ) ) {
  2576.                 $task        'live_bookmark';
  2577.                 // sets bookmark feed type
  2578.                 $_GET['feed'str_replace'.xml'''$live_bookmark );
  2579.                 // loads rss component to create bookmark file
  2580.                 require_oncemamboCore::get('mosConfig_absolute_path').'/components/com_rss/rss.php' );
  2581.             }
  2582.             // outputs link tag for page
  2583.             ?>
  2584.             <link rel="alternate" type="application/rss+xml" title="<?php echo $title?>" href="<?php echo $link_file?>" />
  2585.             <?php
  2586.         }
  2587.     }
  2588.  
  2589.     function mosShowHead ({
  2590.         global $_VERSION;
  2591.         $mosConfig_live_site mamboCore::get('mosConfig_live_site');
  2592.         $this->appendMetaTag'description'mamboCore::get('mosConfig_MetaDesc')true );
  2593.         $this->appendMetaTag'keywords'mamboCore::get('mosConfig_MetaKeys')true );
  2594.         $this->appendMetaTag'Generator''Generator by Mambo , Developed By Mambolearn.Com'true );
  2595.         echo $this->getHead();
  2596.         if (mamboCore::get('mosConfig_sef')) {
  2597.             echo "<base href=\"$mosConfig_live_site/\" />\r\n";
  2598.         }
  2599.         $my mamboCore::get('currentUser');
  2600.         if $my->id {
  2601.             ?>
  2602.             <script language="JavaScript1.2" src="<?php echo $mosConfig_live_site;?>/includes/js/mambojavascript.js" type="text/javascript"></script>
  2603.             <?php
  2604.         }
  2605.         $this->liveBookMark();
  2606.         // outputs link tag for page
  2607.         $configuration =mamboCore::getMamboCore();
  2608.         ?>
  2609.         <link rel="shortcut icon" href="<?php echo $configuration->getFavIcon();?>" />
  2610.         <?php
  2611.     }
  2612.  
  2613.  
  2614.     /**
  2615.     * retained for backward compatability
  2616.     */
  2617.     function getBlogSectionCount({
  2618.         require_once(mamboCore::get('mosConfig_absolute_path').'/components/com_content/content.class.php');
  2619.         $handler =new contentHandler();
  2620.         return $handler->getBlogSectionCount();
  2621.     }
  2622.  
  2623.     function getBlogCategoryCount({
  2624.         require_once(mamboCore::get('mosConfig_absolute_path').'/components/com_content/content.class.php');
  2625.         $handler =new contentHandler();
  2626.         return $handler->getBlogCategoryCount();
  2627.     }
  2628.  
  2629.     function getGlobalBlogSectionCount({
  2630.         require_once(mamboCore::get('mosConfig_absolute_path').'/components/com_content/content.class.php');
  2631.         $handler =new contentHandler();
  2632.         return $handler->getGlobalBlogSectionCount();
  2633.     }
  2634.  
  2635.     function getStaticContentCount({
  2636.         require_once(mamboCore::get('mosConfig_absolute_path').'/components/com_content/content.class.php');
  2637.         $handler =new contentHandler();
  2638.         return $handler->getStaticContentCount();
  2639.     }
  2640.  
  2641.     function getContentItemLinkCount({
  2642.         require_once(mamboCore::get('mosConfig_absolute_path').'/components/com_content/content.class.php');
  2643.         $handler =new contentHandler();
  2644.         return $handler->getContentItemLinkCount();
  2645.     }
  2646.     /**
  2647.     * retained for backward compatability
  2648.     */
  2649.  
  2650. }
  2651.  
  2652. /**
  2653. * Class to support function caching
  2654. @package Mambo
  2655. */
  2656. class mosCache {
  2657.     /**
  2658.     * @return object function cache object
  2659.     */
  2660.     function &getCache(  $group=''  {
  2661.         $mosConfig_absolute_path mamboCore::get('mosConfig_absolute_path');
  2662.         require_once($mosConfig_absolute_path.'/includes/Cache/Lite/Function.php');
  2663.         $path mamboCore::get('mosConfig_cachepath');
  2664.         $caching mamboCore::get('mosConfig_caching');
  2665.         $time mamboCore::get('mosConfig_cachetime');
  2666.         $options array(
  2667.         'cacheDir' => "$path/",
  2668.         'caching' => $caching,
  2669.         'defaultGroup' => $group,
  2670.         'lifeTime' => $time
  2671.         );
  2672.         $cache =new Cache_Lite_Function$options );
  2673.         return $cache;
  2674.     }
  2675.     /**
  2676.     * Cleans the cache
  2677.     */
  2678.     function cleanCache ($group=false{
  2679.         if (mamboCore::get('mosConfig_caching')) {
  2680.             $cache =mosCache::getCache$group );
  2681.             $cache->clean$group );
  2682.         }
  2683.     }
  2684. }
  2685.  
  2686. /**
  2687. * Session database table class
  2688. @package Mambo
  2689. */
  2690. class mosSession extends mosDBTable {
  2691.     /** @var int Primary key */
  2692.     var $session_id=null;
  2693.     /** @var time */
  2694.     var $time=null;
  2695.     /** @var int User ID */
  2696.     var $userid=0;
  2697.     /** @var string */
  2698.     var $usertype=null;
  2699.     /** @var string */
  2700.     var $username='';
  2701.     /** @var int User group ID */
  2702.     var $gid=0;
  2703.     /** @var int */
  2704.     var $guest=1;
  2705.     /** @var string */
  2706.     var $_session_cookie=null;
  2707.  
  2708.     /**
  2709.     * @param database A database connector object
  2710.     */
  2711.     function mosSession({
  2712.         $database =mamboDatabase::getInstance();
  2713.         $this->mosDBTable'#__session''session_id'$database );
  2714.         $this->time = time();
  2715.     }
  2716.  
  2717.     function validate ($user{
  2718.         // check against db record of session
  2719.         $session_id mosGetParam$_SESSION'session_id''' );
  2720.         $logintime mosGetParam$_SESSION'session_logintime''' );
  2721.         if ($session_id == md5$user->id.$user->username.$user->usertype.$logintime )) {
  2722.             $current_time time();
  2723.             $database =mamboDatabase::getInstance();
  2724.             $database->setQuery ("UPDATE #__session"
  2725.             . "\nSET time='$current_time', guest=-3-guest"
  2726.             . "\nWHERE session_id='$session_id'"
  2727.             . " AND username = '" $database->getEscaped$user->username "'"
  2728.             . " AND userid = " intval$user->id )
  2729.             );
  2730.             if (!$result $database->query()) echo $database->stderr();
  2731.             elseif ($database->getAffectedRows(== 1return true;
  2732.         }
  2733.         return false;
  2734.     }
  2735.  
  2736.     function &getCurrent ({
  2737.         static $currentSession;
  2738.         if (!is_object($currentSession)) {
  2739.             $currentSession new mosSession();
  2740.             mosSession::purge();
  2741.             $sessionCookieName md5('site'.mamboCore::get('mosConfig_live_site'));
  2742.             $sessioncookie mosGetParam($_COOKIE$sessionCookieNamenull);
  2743.             $usercookie mosGetParam($_COOKIE'usercookie'null);
  2744.             if ($currentSession->load(md5($sessioncookie.$_SERVER['REMOTE_ADDR']))) {
  2745.                 // Session cookie exists, update time in session table
  2746.                 $currentSession->time time();
  2747.                 $currentSession->update();
  2748.             else {
  2749.                 $currentSession->generateId();
  2750.                 if (!$currentSession->insert()) {
  2751.                     die$currentSession->getError() );
  2752.                 }
  2753.                 setcookie$sessionCookieName$currentSession->getCookie()time(43200'/' );
  2754.                 //$_COOKIE["sessioncookie"] = $session->getCookie();
  2755.                 if ($usercookie{
  2756.                     // Remember me cookie exists. Login with usercookie info.
  2757.                     require_once (mamboCore::get('mosConfig_absolute_path').'/includes/authenticator.php');
  2758.                     $authenticator =mamboAuthenticator::getInstance();
  2759.                     $authenticator->authenticateUser ($message$usercookie['username']$usercookie['password']null$currentSession);
  2760.                 }
  2761.             }
  2762.         }
  2763.         return $currentSession;
  2764.     }
  2765.  
  2766.     function insert({
  2767.         $ret $this->_db->insertObject$this->_tbl$this );
  2768.  
  2769.         if!$ret {
  2770.             $this->_error = strtolower(get_class$this ))."::store failed <br />" $this->_db->stderr();
  2771.             return false;
  2772.         else {
  2773.             return true;
  2774.         }
  2775.     }
  2776.  
  2777.     function update$updateNulls=false {
  2778.         $ret $this->_db->updateObject$this->_tbl$this'session_id'$updateNulls );
  2779.  
  2780.         if!$ret {
  2781.             $this->_error = strtolower(get_class$this ))."::store failed <br />" $this->_db->stderr();
  2782.             return false;
  2783.         else {
  2784.             return true;
  2785.         }
  2786.     }
  2787.  
  2788.     function generateId({
  2789.         $failsafe 20;
  2790.         $randnum 0;
  2791.         while ($failsafe--{
  2792.             $randnum md5uniqidmicrotime()) );
  2793.             if ($randnum != ""{
  2794.                 $cryptrandnum md5$randnum );
  2795.                 $this->_db->setQuery"SELECT $this->_tbl_key FROM $this->_tbl WHERE $this->_tbl_key=MD5('$randnum'));
  2796.                 if(!($result $this->_db->query())) {
  2797.                     die$this->_db->stderrtrue ));
  2798.                     // todo: handle gracefully
  2799.                 }
  2800.                 if ($this->_db->getNumRows($result== 0{
  2801.                     break;
  2802.                 }
  2803.             }
  2804.         }
  2805.         $this->_session_cookie = $randnum;
  2806.         $this->session_id = md5$randnum $_SERVER['REMOTE_ADDR');
  2807.     }
  2808.  
  2809.     function getCookie({
  2810.         return $this->_session_cookie;
  2811.     }
  2812.  
  2813.     function purge({
  2814.         $past time(intval(mamboCore::get('mosConfig_lifetime'));
  2815.         $adminpast time(3600;
  2816.         $database =mamboDatabase::getInstance();
  2817.         $database->setQuery("DELETE FROM #__session WHERE (time<$past AND guest>=0) OR (time<$adminpast AND guest<0)");
  2818.         return $database->query();
  2819.     }
  2820.  
  2821. }
  2822.  
  2823. /**
  2824. * Parameters handler
  2825. @package Mambo
  2826. */
  2827. class mosParameters {
  2828.     /** @var object */ 
  2829.  
  2830.     var $_params = null;
  2831.     /** @var string The raw params string */
  2832.     var $_raw = null;
  2833.     /**
  2834. * Constructor
  2835. @param string The raw parms text
  2836. @param string Path to the xml setup file
  2837. @var string The type of setup file
  2838. */
  2839.     function mosParameters$text$process_sections false{
  2840.         $this->_params = $this->parse$text$process_sections );
  2841.         $this->_raw = $text;
  2842.     }
  2843.     /**
  2844. * Get the result of parsing the string provided on creation
  2845. @return string parsed result
  2846. */
  2847.     function getParams ({
  2848.         return $this->_params;
  2849.     }
  2850.     /**
  2851. @param string The name of the param
  2852. @param string The value of the parameter
  2853. @return string The set value
  2854. */
  2855.     function set$key$value='' {
  2856.         $this->_params->$key $value;
  2857.         return $value;
  2858.     }
  2859.     /**
  2860. * Sets a default value if not alreay assigned
  2861. @param string The name of the param
  2862. @param string The value of the parameter
  2863. @return string The set value
  2864. */
  2865.     function def$key$value='' {
  2866.         return $this->set$key$this->get$key$value ) );
  2867.     }
  2868.     /**
  2869. @param string The name of the param
  2870. @param mixed The default value if not found
  2871. @return string 
  2872. */
  2873.     function get$key$default='' {
  2874.         if (isset$this->_params->$key )) return $this->_params->$key === '' $default $this->_params->$key;
  2875.         else return $default;
  2876.     }
  2877.     /**
  2878. * Look to see if string is bracketed by opener and closer
  2879. * If so, extract and trim the bracketed string
  2880. * Otherwise, return a null string
  2881. **/
  2882.  
  2883.     function getBracketed ($text$opener$closer{
  2884.         if (strlen($textAND ($text[0!= $opener OR substr($text,-1!= $closer)) return '';
  2885.         else return trim(substr($text,1,-1));
  2886.     }
  2887.     /**
  2888. * Parse an .ini string, based on phpDocumentor phpDocumentor_parse_ini_file function
  2889. @param mixed The ini string or array of lines
  2890. @param boolean add an associative index for each section [in brackets]
  2891. @return object 
  2892. */
  2893.     function parse$txt$process_sections false {
  2894.         $result new stdClass();
  2895.         if (is_string($txt)) $lines explode"\n"$txt );
  2896.         elseif (is_array($txt)) $lines $txt;
  2897.         else return $result;
  2898.  
  2899.         $sec_name '';
  2900.         $unparsed 0;
  2901.  
  2902.         foreach ($lines as $line{
  2903.             // ignore comments and null lines
  2904.             $line trim($line);
  2905.             if (strlen($line== OR $line[0== ';'continue;
  2906.  
  2907.             if ($sec_name $this->getBracketed($line'['']')) {
  2908.                 if ($process_sections$result->$sec_name new stdClass();
  2909.                 continue;
  2910.             }
  2911.  
  2912.             if (count($propsetter explode ('='$line2)) == 2{
  2913.                 $property trim($propsetter[0]);
  2914.                 if ($pquoted $this->getBracketed($property'"''"')) $property stripcslashes($pquoted);
  2915.                 $value trim($propsetter[1]);
  2916.                 if ($value == 'false'$value false;
  2917.                 elseif ($value == 'true'$value true;
  2918.                 else if ($vquoted $this->getBracketed($value'"''"')) $value stripcslashes($vquoted);
  2919.                 if ($process_sections AND $sec_name$result->$sec_name->$property $value;
  2920.                 else $result->$property $value;
  2921.             }
  2922.             else {
  2923.                 $property '__invalid' $unparsed++ . '__';
  2924.                 if ($process_sections AND $sec_name$result->$sec_name->$property $line;
  2925.                 else $result->$property $line;
  2926.             }
  2927.         }
  2928.         return $result;
  2929.     }
  2930.     /**
  2931.     * @param string The name of the control, or the default text area if a setup file is not found
  2932.     * @return string HTML
  2933.     */
  2934.     function render$name='params' {
  2935.         if (is_file($this->_path)) {
  2936.             $parser new mosXMLParams ($this->_path$this$name);
  2937.             if (count($parser->html)) return implode("\n"$parser->html);
  2938.         }
  2939.         $raw $this->_raw;
  2940.         return "<textarea name='$name' cols='40' rows='10' class='text_area'>$raw</textarea>";
  2941.     }
  2942.  
  2943.     /**
  2944.     * special handling for textarea param
  2945.     */
  2946.     function textareaHandling&$txt {
  2947.         foreach ($txt as $key=>$value$txt[$keystr_replace("\n"'<br />'$value);
  2948.         return implode"\n"$txt );
  2949.     }
  2950. }
  2951.  
  2952. /**
  2953. * Page generation time
  2954. @package Mambo
  2955. */
  2956. class mosProfiler {
  2957.     var $start=0;
  2958.     var $prefix='';
  2959.  
  2960.     function mosProfiler$prefix='' {
  2961.         $this->start = $this->getmicrotime();
  2962.         $this->prefix = $prefix;
  2963.     }
  2964.  
  2965.     function mark$label {
  2966.         return sprintf "\n<div class=\"profiler\">$this->prefix %.3f $label</div>"$this->getmicrotime($this->start );
  2967.     }
  2968.  
  2969.     function getmicrotime(){
  2970.         list($usec$secexplode(" ",microtime());
  2971.         return ((float)$usec + (float)$sec);
  2972.     }
  2973. }
  2974.  
  2975.  
  2976. /**
  2977.  * @author Mikolaj Jedrzejak <mikolajj@op.pl>
  2978.  * @copyright Copyright Mikolaj Jedrzejak (c) 2003-2004
  2979.  * @version 1.0 2004-07-27 00:37
  2980.  * @link http://www.unicode.org Unicode Homepage
  2981.  * @link http://www.mikkom.pl My Homepage
  2982.  * 
  2983.  ***/
  2984. $PATH_TO_CLASS dirname(ereg_replace("\\\\","/",__FILE__)) "/" "ConvertTables" "/";
  2985. @require_once($PATH_TO_CLASS."/charsetmapping.php");
  2986. define ("CONVERT_TABLES_DIR"$PATH_TO_CLASS);
  2987. define ("DEBUG_MODE"1);
  2988.  
  2989. /**
  2990.  * -- 1.0 2004-07-28 --
  2991.  * 
  2992.  * -- The most important thing --
  2993.  * I want to thank all people who helped me fix all bugs, small and big once.
  2994.  * I hope that you don't mind that your names are in this file.
  2995.  * 
  2996.  * -- Some Apache issues --
  2997.  * I get info from Lukas Lisa, that in some cases with special apache configuration
  2998.  * you have to put header() function with proper encoding to get your result
  2999.  * displayed correctly.
  3000.  * If you want to see what I mean, go to demo.php and demo1.php
  3001.  * 
  3002.  * -- BETA 1.0 2003-10-21 --
  3003.  * 
  3004.  * -- You should know about... --
  3005.  * For good understanding this class you shouls read all this stuff first :) but if you are
  3006.  * in a hurry just start the demo.php and see what's inside.
  3007.  * 1. That I'm not good in english at 03:45 :) - so forgive me all mistakes
  3008.  * 2. This class is a BETA version because I haven't tested it enough
  3009.  * 3. Feel free to contact me with questions, bug reports and mistakes in PHP and this documentation (email below)
  3010.  * 
  3011.  * -- In a few words... --
  3012.  * Why ConvertCharset class?
  3013.  * 
  3014.  * I have made this class because I had a lot of problems with diferent charsets. First because people
  3015.  * from Microsoft wanted to have thair own encoding, second because people from Macromedia didn't
  3016.  * thought about other languages, third because sometimes I need to use text written on MAC, and of course
  3017.  * it has its own encoding :)
  3018.  * 
  3019.  * Notice & remember:
  3020.  * - When I'm saying 1 byte string I mean 1 byte per char.
  3021.  * - When I'm saying multibyte string I mean more than one byte per char.
  3022.  * 
  3023.  * So, this are main FEATURES of this class:
  3024.  * - conversion between 1 byte charsets
  3025.  * - conversion from 1 byte to multi byte charset (utf-8)
  3026.  * - conversion from multibyte charset (utf-8) to 1 byte charset
  3027.  * - every conversion output can be save with numeric entities (browser charset independent - not a full truth)
  3028.  * 
  3029.  * This is a list of charsets you can operate with, the basic rule is that a char have to be in both charsets,
  3030.  * otherwise you'll get an error.
  3031.  * 
  3032.  * - WINDOWS
  3033.  * - windows-1250 - Central Europe
  3034.  * - windows-1251 - Cyrillic
  3035.  * - windows-1252 - Latin I
  3036.  * - windows-1253 - Greek
  3037.  * - windows-1254 - Turkish
  3038.  * - windows-1255 - Hebrew
  3039.  * - windows-1256 - Arabic
  3040.  * - windows-1257 - Baltic
  3041.  * - windows-1258 - Viet Nam
  3042.  * - cp874 - Thai - this file is also for DOS
  3043.  * 
  3044.  * - DOS
  3045.  * - cp437 - Latin US
  3046.  * - cp737 - Greek
  3047.  * - cp775 - BaltRim
  3048.  * - cp850 - Latin1
  3049.  * - cp852 - Latin2
  3050.  * - cp855 - Cyrylic
  3051.  * - cp857 - Turkish
  3052.  * - cp860 - Portuguese
  3053.  * - cp861 - Iceland
  3054.  * - cp862 - Hebrew
  3055.  * - cp863 - Canada
  3056.  * - cp864 - Arabic
  3057.  * - cp865 - Nordic
  3058.  * - cp866 - Cyrylic Russian (this is the one, used in IE "Cyrillic (DOS)" )
  3059.  * - cp869 - Greek2
  3060.  * 
  3061.  * - MAC (Apple)
  3062.  * - x-mac-cyrillic
  3063.  * - x-mac-greek
  3064.  * - x-mac-icelandic
  3065.  * - x-mac-ce
  3066.  * - x-mac-roman
  3067.  * 
  3068.  * - ISO (Unix/Linux)
  3069.  * - iso-8859-1
  3070.  * - iso-8859-2
  3071.  * - iso-8859-3
  3072.  * - iso-8859-4
  3073.  * - iso-8859-5
  3074.  * - iso-8859-6
  3075.  * - iso-8859-7
  3076.  * - iso-8859-8
  3077.  * - iso-8859-9
  3078.  * - iso-8859-10
  3079.  * - iso-8859-11
  3080.  * - iso-8859-12
  3081.  * - iso-8859-13
  3082.  * - iso-8859-14
  3083.  * - iso-8859-15
  3084.  * - iso-8859-16
  3085.  * 
  3086.  * - MISCELLANEOUS
  3087.  * - gsm0338 (ETSI GSM 03.38)
  3088.  * - cp037
  3089.  * - cp424
  3090.  * - cp500
  3091.  * - cp856
  3092.  * - cp875
  3093.  * - cp1006
  3094.  * - cp1026
  3095.  * - koi8-r (Cyrillic)
  3096.  * - koi8-u (Cyrillic Ukrainian)
  3097.  * - nextstep
  3098.  * - us-ascii
  3099.  * - us-ascii-quotes
  3100.  * 
  3101.  * - DSP implementation for NeXT
  3102.  * - stdenc
  3103.  * - symbol
  3104.  * - zdingbat
  3105.  * 
  3106.  * - And specially for old Polish programs
  3107.  * - mazovia
  3108.  *  
  3109.  * -- Now, to the point... --
  3110.  * Here are main variables.
  3111.  * 
  3112.  * DEBUG_MODE
  3113.  * 
  3114.  * You can set this value to:
  3115.  * - -1 - No errors or comments
  3116.  * - 0  - Only error messages, no comments
  3117.  * - 1  - Error messages and comments
  3118.  * 
  3119.  * Default value is 1, and during first steps with class it should be left as is.
  3120.  *
  3121.  * CONVERT_TABLES_DIR
  3122.  * 
  3123.  * This is a place where you store all files with charset encodings. Filenames should have
  3124.  * the same names as encodings. My advise is to keep existing names, because thay
  3125.  * were taken from unicode.org (www.unicode.org), and after update to unicode 3.0 or 4.0
  3126.  * the names of files will be the same, so if you want to save your time...uff, leave the
  3127.  * names as thay are for future updates.
  3128.  * 
  3129.  * The directory with edings files should be in a class location directory by default,
  3130.  * but of course you can change it if you like.
  3131.  * 
  3132.  * @package All about charset...
  3133.  * @author Mikolaj Jedrzejak <mikolajj@op.pl>
  3134.  * @copyright Copyright Mikolaj Jedrzejak (c) 2003-2004
  3135.  * @version 1.0 2004-07-27 23:11
  3136.  * @access public
  3137.  * 
  3138.  * @link http://www.unicode.org Unicode Homepage
  3139.  ***/
  3140. class ConvertCharset {
  3141.     var $RecognizedEncoding//This value keeps information if string contains multibyte chars.
  3142.     var $Entities// This value keeps information if output should be with numeric entities.
  3143.  
  3144.     /**
  3145.      * CharsetChange::NumUnicodeEntity()
  3146.      * 
  3147.      * Unicode encoding bytes, bits representation.
  3148.      * Each b represents a bit that can be used to store character data.
  3149.      * - bytes, bits, binary representation
  3150.      * - 1,   7,  0bbbbbbb
  3151.      * - 2,  11,  110bbbbb 10bbbbbb
  3152.      * - 3,  16,  1110bbbb 10bbbbbb 10bbbbbb
  3153.      * - 4,  21,  11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
  3154.      * 
  3155.      * This function is written in a "long" way, for everyone who woluld like to analize
  3156.      * the process of unicode encoding and understand it. All other functions like HexToUtf
  3157.      * will be written in a "shortest" way I can write tham :) it does'n mean thay are short
  3158.      * of course. You can chech it in HexToUtf() (link below) - very similar function.
  3159.      * 
  3160.      * IMPORTANT: Remember that $UnicodeString input CANNOT have single byte upper half
  3161.      * extended ASCII codes, why? Because there is a posibility that this function will eat
  3162.      * the following char thinking it's miltibyte unicode char.
  3163.      * 
  3164.      * @param string $UnicodeString Input Unicode string (1 char can take more than 1 byte)
  3165.      * @return string This is an input string olso with unicode chars, bus saved as entities
  3166.      * @see HexToUtf()
  3167.      ***/
  3168.     function UnicodeEntity ($UnicodeString)
  3169.     {
  3170.         $OutString  "";
  3171.         $StringLenght strlen ($UnicodeString);
  3172.         for ($CharPosition 0$CharPosition $StringLenght$CharPosition++)
  3173.         {
  3174.             $Char $UnicodeString [$CharPosition];
  3175.             $AsciiChar ord ($Char);
  3176.  
  3177.             if ($AsciiChar 128//1 7 0bbbbbbb (127)
  3178.             {
  3179.                 $OutString .= $Char;
  3180.             }
  3181.             else if ($AsciiChar >> == 6//2 11 110bbbbb 10bbbbbb (2047)
  3182.             {
  3183.                 $FirstByte ($AsciiChar 31);
  3184.                 $CharPosition++;
  3185.                 $Char $UnicodeString [$CharPosition];
  3186.                 $AsciiChar ord ($Char);
  3187.                 $SecondByte ($AsciiChar 63);
  3188.                 $AsciiChar ($FirstByte 64$SecondByte;
  3189.                 $Entity sprintf ("&#%d;"$AsciiChar);
  3190.                 $OutString .= $Entity;
  3191.             }
  3192.             else if ($AsciiChar >> 4  == 14)  //3 16 1110bbbb 10bbbbbb 10bbbbbb
  3193.             {
  3194.                 $FirstByte ($AsciiChar 31);
  3195.                 $CharPosition++;
  3196.                 $Char $UnicodeString [$CharPosition];
  3197.                 $AsciiChar ord ($Char);
  3198.                 $SecondByte ($AsciiChar 63);
  3199.                 $CharPosition++;
  3200.                 $Char $UnicodeString [$CharPosition];
  3201.                 $AsciiChar ord ($Char);
  3202.                 $ThidrByte ($AsciiChar 63);
  3203.                 $AsciiChar ((($FirstByte 64$SecondByte64$ThidrByte;
  3204.  
  3205.                 $Entity sprintf ("&#%d;"$AsciiChar);
  3206.                 $OutString .= $Entity;
  3207.             }
  3208.             else if ($AsciiChar >> == 30//4 21 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
  3209.             {
  3210.                 $FirstByte ($AsciiChar 31);
  3211.                 $CharPosition++;
  3212.                 $Char $UnicodeString [$CharPosition];
  3213.                 $AsciiChar ord ($Char);
  3214.                 $SecondByte ($AsciiChar 63);
  3215.                 $CharPosition++;
  3216.                 $Char $UnicodeString [$CharPosition];
  3217.                 $AsciiChar ord ($Char);
  3218.                 $ThidrByte ($AsciiChar 63);
  3219.                 $CharPosition++;
  3220.                 $Char $UnicodeString [$CharPosition];
  3221.                 $AsciiChar ord ($Char);
  3222.                 $FourthByte ($AsciiChar 63);
  3223.                 $AsciiChar ((((($FirstByte 64$SecondByte64$ThidrByte64$FourthByte;
  3224.  
  3225.                 $Entity sprintf ("&#%d;"$AsciiChar);
  3226.                 $OutString .= $Entity;
  3227.             }
  3228.         }
  3229.         return $OutString;
  3230.     }
  3231.  
  3232.     /**
  3233.      * ConvertCharset::HexToUtf()
  3234.      * 
  3235.      * This simple function gets unicode  char up to 4 bytes and return it as a regular char.
  3236.      * It is very similar to  UnicodeEntity function (link below). There is one difference
  3237.      * in returned format. This time it's a regular char(s), in most cases it will be one or two chars.
  3238.      * 
  3239.      * @param string $UtfCharInHex Hexadecimal value of a unicode char.
  3240.      * @return string Encoded hexadecimal value as a regular char.
  3241.      * @see UnicodeEntity()
  3242.      ***/
  3243.     function HexToUtf ($UtfCharInHex)
  3244.     {
  3245.         $OutputChar "";
  3246.         $UtfCharInDec hexdec($UtfCharInHex);
  3247.         if($UtfCharInDec<128$OutputChar .= chr($UtfCharInDec);
  3248.         else if($UtfCharInDec<2048)$OutputChar .= chr(($UtfCharInDec>>6)+192).chr(($UtfCharInDec&63)+128);
  3249.         else if($UtfCharInDec<65536)$OutputChar .= chr(($UtfCharInDec>>12)+224).chr((($UtfCharInDec>>6)&63)+128).chr(($UtfCharInDec&63)+128);
  3250.         else if($UtfCharInDec<2097152)$OutputChar .= chr($UtfCharInDec>>18+240).chr((($UtfCharInDec>>12)&63)+128).chr(($UtfCharInDec>>6)&63+128)chr($UtfCharInDec&63+128);
  3251.         return $OutputChar;
  3252.     }
  3253.  
  3254.  
  3255.     /**
  3256.      * CharsetChange::MakeConvertTable()
  3257.      * 
  3258.      * This function creates table with two SBCS (Single Byte Character Set). Every conversion
  3259.      * is through this table.
  3260.      *  
  3261.      * - The file with encoding tables have to be save in "Format A" of unicode.org charset table format! This is usualy writen in a header of every charset file.
  3262.      * - BOTH charsets MUST be SBCS
  3263.      * - The files with encoding tables have to be complet (Non of chars can be missing, unles you are sure you are not going to use it)
  3264.      * 
  3265.      * "Format A" encoding file, if you have to build it by yourself should aplly these rules:
  3266.      * - you can comment everything with #
  3267.      * - first column contains 1 byte chars in hex starting from 0x..
  3268.      * - second column contains unicode equivalent in hex starting from 0x....
  3269.      * - then every next column is optional, but in "Format A" it should contain unicode char name or/and your own comment
  3270.      * - the columns can be splited by "spaces", "tabs", "," or any combination of these
  3271.      * - below is an example
  3272.      * 
  3273.      * <code>
  3274.      * #
  3275.      * #    The entries are in ANSI X3.4 order.
  3276.      * #
  3277.      * 0x00    0x0000    #    NULL end extra comment, if needed
  3278.      * 0x01    0x0001    #    START OF HEADING
  3279.      * # Oh, one more thing, you can make comments inside of a rows if you like.
  3280.      * 0x02    0x0002    #    START OF TEXT
  3281.      * 0x03    0x0003    #    END OF TEXT
  3282.      * next line, and so on...
  3283.      * </code>
  3284.      * 
  3285.      * You can get full tables with encodings from http://www.unicode.org
  3286.      * 
  3287.      * @param string $FirstEncoding Name of first encoding and first encoding filename (thay have to be the same)
  3288.      * @param string $SecondEncoding Name of second encoding and second encoding filename (thay have to be the same). Optional for building a joined table.
  3289.      * @return array Table necessary to change one encoding to another.
  3290.      ***/
  3291.     function MakeConvertTable ($FirstEncoding$SecondEncoding "")
  3292.     {
  3293.         $ConvertTable array();
  3294.         for($i 0$i func_num_args()$i++)
  3295.         {
  3296.             /**
  3297.              * Because func_*** can't be used inside of another function call
  3298.              * we have to save it as a separate value.
  3299.              **/
  3300.             $FileName func_get_arg($i);
  3301.             if (!is_file(CONVERT_TABLES_DIR $FileName))
  3302.             {
  3303.                 print $this->DebugOutput(00CONVERT_TABLES_DIR $FileName)//Print an error message
  3304.                 exit;
  3305.             }
  3306.             $FileWithEncTabe fopen(CONVERT_TABLES_DIR $FileName"r"or die()//This die(); is just to make sure...
  3307.             while(!feof($FileWithEncTabe))
  3308.             {
  3309.                 /**
  3310.                  * We asume that line is not longer
  3311.                  * than 1024 which is the default value for fgets function 
  3312.                  **/
  3313.                 if($OneLine=trim(fgets($FileWithEncTabe1024)))
  3314.                 {
  3315.                     /**
  3316.                  * We don't need all comment lines. I check only for "#" sign, because
  3317.                  * this is a way of making comments by unicode.org in thair encoding files
  3318.                  * and that's where the files are from :-)
  3319.                  **/
  3320.                     if (substr($OneLine01!= "#")
  3321.                     {
  3322.                         /**
  3323.                      * Sometimes inside the charset file the hex walues are separated by
  3324.                      * "space" and sometimes by "tab", the below preg_split can also be used
  3325.                      * to split files where separator is a ",", "\r", "\n" and "\f"
  3326.                      **/
  3327.                         $HexValue preg_split ("/[\s,]+/"$OneLine3);  //We need only first 2 values
  3328.                         /**
  3329.                          * Sometimes char is UNDEFINED, or missing so we can't use it for convertion
  3330.                          **/
  3331.                         if (substr($HexValue[1]01!= "#")
  3332.                         {
  3333.                             $ArrayKey strtoupper(str_replace(strtolower("0x")""$HexValue[1]));
  3334.                             $ArrayValue strtoupper(str_replace(strtolower("0x")""$HexValue[0]));
  3335.                             $ConvertTable[func_get_arg($i)][$ArrayKey$ArrayValue;
  3336.                         }
  3337.                     //if (substr($OneLine,...
  3338.                 //if($OneLine=trim(f...
  3339.             //while(!feof($FirstFileWi...
  3340.         //for($i = 0; $i < func_...
  3341.         /**
  3342.      * The last thing is to check if by any reason both encoding tables are not the same.
  3343.      * For example, it will happen when you save the encoding table file with a wrong name
  3344.      *  - of another charset. 
  3345.      **/
  3346.         if ((func_num_args(1&& (count($ConvertTable[$FirstEncoding]== count($ConvertTable[$SecondEncoding])) && (count(array_diff_assoc($ConvertTable[$FirstEncoding]$ConvertTable[$SecondEncoding])) == 0))
  3347.         {
  3348.             print $this->DebugOutput(11"$FirstEncoding$SecondEncoding");
  3349.         }
  3350.         return $ConvertTable;
  3351.     }
  3352.  
  3353.  
  3354.  
  3355.     /**
  3356.      * ConvertCharset::Convert()
  3357.      * 
  3358.      * This is a basic function you are using. I hope that you can figure out this function syntax :-)
  3359.      * 
  3360.      * @param string $StringToChange The string you want to change :)
  3361.      * @param string $FromCharset Name of $StringToChange encoding, you have to know it.
  3362.      * @param string $ToCharset Name of a charset you want to get for $StringToChange.
  3363.      * @param boolean $TurnOnEntities Set to true or 1 if you want to use numeric entities insted of regular chars.
  3364.      * @return string Converted string in brand new encoding :)
  3365.      * @version 1.0 2004-07-27 01:09
  3366.      ***/
  3367.     function Convert ($StringToChange$FromCharset$ToCharset$TurnOnEntities false)
  3368.     {
  3369.         /**
  3370.          * Check are there all variables 
  3371.          **/
  3372.         /*if ($StringToChange == "")
  3373.         {
  3374.         print $this->DebugOutput(0, 3, "\$StringToChange");
  3375.         }
  3376.         else*/
  3377.         if ($FromCharset == "")
  3378.         {
  3379.             print $this->DebugOutput(03"\$FromCharset");
  3380.         }
  3381.         else if ($ToCharset == "")
  3382.         {
  3383.             print $this->DebugOutput(03"\$ToCharset");
  3384.         }
  3385.  
  3386.         /**
  3387.          * Now a few variables need to be set. 
  3388.          **/
  3389.         $NewString "";
  3390.         $this->Entities = $TurnOnEntities;
  3391.  
  3392.         /**
  3393.          * For all people who like to use uppercase for charset encoding names :) 
  3394.          **/
  3395.         $FromCharset strtolower($FromCharset);
  3396.         $ToCharset   strtolower($ToCharset);
  3397.  
  3398.         /**
  3399.          * Of course you can make a conversion from one charset to the same one :) 
  3400.          * but I feel obligate to let you know about it. 
  3401.          **/
  3402.         if ($FromCharset == $ToCharset)
  3403.         {
  3404.             print $this->DebugOutput(10$FromCharset);
  3405.         }
  3406.         if (($FromCharset == $ToCharsetAND ($FromCharset == "utf-8"))
  3407.         {
  3408.             print $this->DebugOutput(04$FromCharset);
  3409.             exit;
  3410.         }
  3411.  
  3412.         /**
  3413.          * This divison was made to prevent errors during convertion to/from utf-8 with
  3414.          * "entities" enabled, because we need to use proper destination(to)/source(from)
  3415.          * encoding table to write proper entities.
  3416.          * 
  3417.          * This is the first case. We are convertinf from 1byte chars...
  3418.          **/
  3419.         if ($FromCharset != "utf-8")
  3420.         {
  3421.             /**
  3422.                  * Now build table with both charsets for encoding change. 
  3423.                  **/
  3424.             if ($ToCharset != "utf-8")
  3425.             {
  3426.                 $CharsetTable $this->MakeConvertTable ($FromCharset$ToCharset);
  3427.             }
  3428.             else
  3429.             {
  3430.                 $CharsetTable $this->MakeConvertTable ($FromCharset);
  3431.             }
  3432.             /**
  3433.                  * For each char in a string... 
  3434.                  **/
  3435.             for ($i 0$i strlen($StringToChange)$i++)
  3436.             {
  3437.                 $HexChar "";
  3438.                 $UnicodeHexChar "";
  3439.                 $HexChar strtoupper(dechex(ord($StringToChange[$i])));
  3440.                 // This is fix from Mario Klingemann, it prevents
  3441.                 // droping chars below 16 because of missing leading 0 [zeros]
  3442.                 if (strlen($HexChar)==1$HexChar "0".$HexChar;
  3443.                 //end of fix by Mario Klingemann
  3444.                 // This is quick fix of 10 chars in gsm0338
  3445.                 // Thanks goes to Andrea Carpani who pointed on this problem
  3446.                 // and solve it ;)
  3447.                 if (($FromCharset == "gsm0338"&& ($HexChar == '1B')) {
  3448.                     $i++;
  3449.                     $HexChar .= strtoupper(dechex(ord($StringToChange[$i])));
  3450.                 }
  3451.                 // end of workarround on 10 chars from gsm0338
  3452.                 if ($ToCharset != "utf-8")
  3453.                 {
  3454.                     if (in_array($HexChar$CharsetTable[$FromCharset]))
  3455.                     {
  3456.                         $UnicodeHexChar array_search($HexChar$CharsetTable[$FromCharset]);
  3457.                         $UnicodeHexChars explode("+",$UnicodeHexChar);
  3458.                         for($UnicodeHexCharElement 0$UnicodeHexCharElement count($UnicodeHexChars)$UnicodeHexCharElement++)
  3459.                         {
  3460.                             if (array_key_exists($UnicodeHexChars[$UnicodeHexCharElement]$CharsetTable[$ToCharset]))
  3461.                             {
  3462.                                 if ($this->Entities == true)
  3463.                                 {
  3464.                                     $NewString .= $this->UnicodeEntity($this->HexToUtf($UnicodeHexChars[$UnicodeHexCharElement]));
  3465.                                 }
  3466.                                 else
  3467.                                 {
  3468.                                     $NewString .= chr(hexdec($CharsetTable[$ToCharset][$UnicodeHexChars[$UnicodeHexCharElement]]));
  3469.                                 }
  3470.                             }
  3471.                             else
  3472.                             {
  3473.                                 print $this->DebugOutput(01$StringToChange[$i]);
  3474.                             }
  3475.                         //for($UnicodeH...
  3476.                     }
  3477.                     else
  3478.                     {
  3479.                         print $this->DebugOutput(02,$StringToChange[$i]);
  3480.                     }
  3481.                 }
  3482.                 else
  3483.                 {
  3484.                     if (in_array("$HexChar"$CharsetTable[$FromCharset]))
  3485.                     {
  3486.                         $UnicodeHexChar array_search($HexChar$CharsetTable[$FromCharset]);
  3487.                         /**
  3488.                          * Sometimes there are two or more utf-8 chars per one regular char.
  3489.                              * Extream, example is polish old Mazovia encoding, where one char contains
  3490.                              * two lettes 007a (z) and 0142 (l slash), we need to figure out how to
  3491.                              * solve this problem.
  3492.                              * The letters are merge with "plus" sign, there can be more than two chars.
  3493.                              * In Mazowia we have 007A+0142, but sometimes it can look like this
  3494.                              * 0x007A+0x0142+0x2034 (that string means nothing, it just shows the possibility...)
  3495.                          **/
  3496.                         $UnicodeHexChars explode("+",$UnicodeHexChar);
  3497.                         for($UnicodeHexCharElement 0$UnicodeHexCharElement count($UnicodeHexChars)$UnicodeHexCharElement++)
  3498.                         {
  3499.                             if ($this->Entities == true)
  3500.                             {
  3501.                                 $NewString .= $this->UnicodeEntity($this->HexToUtf($UnicodeHexChars[$UnicodeHexCharElement]));
  3502.                             }
  3503.                             else
  3504.                             {
  3505.                                 $NewString .= $this->HexToUtf($UnicodeHexChars[$UnicodeHexCharElement]);
  3506.                             }
  3507.                         // for
  3508.                     }
  3509.                     else
  3510.                     {
  3511.                         print $this->DebugOutput(02$StringToChange[$i]);
  3512.                     }
  3513.                 }
  3514.             }
  3515.         }
  3516.         /**
  3517.          * This is second case. We are encoding from multibyte char string. 
  3518.          **/
  3519.         else if($FromCharset == "utf-8")
  3520.         {
  3521.             $HexChar "";
  3522.             $UnicodeHexChar "";
  3523.             $CharsetTable $this->MakeConvertTable ($ToCharset);
  3524.             foreach ($CharsetTable[$ToCharsetas $UnicodeHexChar => $HexChar)
  3525.             {
  3526.                 if ($this->Entities == true{
  3527.                     $EntitieOrChar $this->UnicodeEntity($this->HexToUtf($UnicodeHexChar));
  3528.                 }
  3529.                 else
  3530.                 {
  3531.                     $EntitieOrChar chr(hexdec($HexChar));
  3532.                 }
  3533.                 $StringToChange str_replace($this->HexToUtf($UnicodeHexChar)$EntitieOrChar$StringToChange);
  3534.             }
  3535.             $NewString $StringToChange;
  3536.         }
  3537.  
  3538.         return $NewString;
  3539.     }
  3540.  
  3541.     /**
  3542.      * ConvertCharset::DebugOutput()
  3543.      * 
  3544.      * This function is not really necessary, the debug output could stay inside of
  3545.      * source code but like this, it's easier to manage and translate.
  3546.      * Besides I couldn't find good coment/debug class :-) Maybe I'll write one someday...
  3547.      * 
  3548.      * All messages depend on DEBUG_MODE level, as I was writing before you can set this value to:
  3549.    * - -1 - No errors or notces are shown
  3550.    * - 0  - Only error messages are shown, no notices
  3551.    * - 1  - Error messages and notices are shown
  3552.      * 
  3553.      * @param int $Group Message groupe: error - 0, notice - 1
  3554.      * @param int $Number Following message number
  3555.      * @param mix $Value This walue is whatever you want, usualy it's some parameter value, for better message understanding.
  3556.      * @return string String with a proper message.
  3557.      ***/
  3558.     function DebugOutput ($Group$Number$Value false)
  3559.     {
  3560.         //$Debug [$Group][$Number] = "Message, can by with $Value";
  3561.         //$Group[0] - Errors
  3562.         //$Group[1] - Notice
  3563.         $Debug[0][0"Error, can NOT read file: " $Value "<br>";
  3564.         $Debug[0][1"Error, can't find maching char \""$Value ."\" in destination encoding table!" "<br>";
  3565.         $Debug[0][2"Error, can't find maching char \""$Value ."\" in source encoding table!" "<br>";
  3566.         $Debug[0][3"Error, you did NOT set variable " $Value " in Convert() function." "<br>";
  3567.         $Debug[0][4"You can NOT convert string from " $Value " to " $Value "!" .  "<BR>";
  3568.         $Debug[1][0"Notice, you are trying to convert string from "$Value ." to "$Value .", don't you feel it's strange? ;-)" "<br>";
  3569.         $Debug[1][1"Notice, both charsets " $Value " are identical! Check encoding tables files." "<br>";
  3570.         $Debug[1][2"Notice, there is no unicode char in the string you are trying to convert." "<br>";
  3571.  
  3572.         if (DEBUG_MODE >= $Group)
  3573.         {
  3574.             return $Debug[$Group][$Number];
  3575.         }
  3576.     // function DebugOutput
  3577.  
  3578. //class ends here
  3579. ?>

Documentation generated on Mon, 05 May 2008 16:18:59 +0400 by phpDocumentor 1.4.0