00001 <?php
00002
00006 require_once getShopBasePath()."core/smarty/Smarty.class.php";
00007
00012 class oxUtils extends oxSuperCfg
00013 {
00014
00020 private static $_instance = null;
00021
00027 protected $_iCurPrecision = null;
00028
00034 protected $_sEmailTpl = "^([-!#\$%&'*+./0-9=?A-Z^_`a-z{|}~\177])+@([-!#\$%&'*+/0-9=?A-Z^_`a-z{|}~\177]+\\.)+[a-zA-Z]{2,6}\$";
00035
00041 public static function getInstance()
00042 {
00043
00044 if ( defined( 'OXID_PHP_UNIT' ) ) {
00045 static $inst = array();
00046 self::$_instance = $inst[oxClassCacheKey()];
00047
00048 }
00049
00050 if ( !self::$_instance instanceof oxUtils ) {
00051
00052
00053 self::$_instance = oxNew( 'oxUtils' );
00054
00055 if ( defined( 'OXID_PHP_UNIT' ) ) {
00056 $inst[oxClassCacheKey()] = self::$_instance;
00057 }
00058 }
00059 return self::$_instance;
00060 }
00061
00067 protected $_aStaticCache;
00068
00074 protected $_blSeoIsActive = null;
00075
00081 public function stripGpcMagicQuotes()
00082 {
00083 if (!get_magic_quotes_gpc()) {
00084 return;
00085 }
00086 $_REQUEST = self::_stripQuotes($_REQUEST);
00087 $_POST = self::_stripQuotes($_POST);
00088 $_GET = self::_stripQuotes($_GET);
00089 $_COOKIE = self::_stripQuotes($_COOKIE);
00090 }
00091
00100 public function strMan( $sVal, $sKey = null )
00101 {
00102 $sKey = $sKey?$sKey:'oxid123456789';
00103 $sVal = "ox{$sVal}id";
00104
00105 $sKey = str_repeat( $sKey, strlen( $sVal ) / strlen( $sKey ) + 5 );
00106 $sVal = $this->strRot13( $sVal );
00107 $sVal = $sVal ^ $sKey;
00108 $sVal = base64_encode( $sVal );
00109 $sVal = str_replace( "=", "!", $sVal );
00110
00111 return "ox_$sVal";
00112 }
00113
00122 public function strRem( $sVal, $sKey = null )
00123 {
00124 $sKey = $sKey?$sKey:'oxid123456789';
00125 $sKey = str_repeat( $sKey, strlen( $sVal ) / strlen( $sKey ) + 5 );
00126
00127 $sVal = substr( $sVal, 3 );
00128 $sVal = str_replace( '!', '=', $sVal );
00129 $sVal = base64_decode( $sVal );
00130 $sVal = $sVal ^ $sKey;
00131 $sVal = $this->strRot13( $sVal );
00132
00133 return substr( $sVal, 2, -2 );
00134 }
00135
00143 public function getArrFldName( $sName)
00144 {
00145 return str_replace( ".", "__", $sName);
00146 }
00147
00156 public function assignValuesFromText( $sIn, $dVat = null)
00157 {
00158 $aRet = array();
00159 $aPieces = explode( '@@', $sIn );
00160 while ( list( $sKey, $sVal ) = each( $aPieces ) ) {
00161 if ( $sVal ) {
00162 $aName = explode( '__', $sVal );
00163 if ( isset( $aName[0] ) && isset( $aName[1] ) ) {
00164 $aRet[] = $this->_fillExplodeArray( $aName, $dVat );
00165 }
00166 }
00167 }
00168 return $aRet;
00169 }
00170
00178 public function assignValuesToText( $aIn)
00179 {
00180 $sRet = "";
00181 reset( $aIn );
00182 while (list($sKey, $sVal) = each($aIn)) {
00183 $sRet .= $sKey;
00184 $sRet .= "__";
00185 $sRet .= $sVal;
00186 $sRet .= "@@";
00187 }
00188 return $sRet;
00189 }
00190
00199 public function formatCurrency( $dValue, $oActCur = null )
00200 {
00201 if (!$oActCur) {
00202 $oActCur = $this->getConfig()->getActShopCurrencyObject();
00203 }
00204 $sFormated = number_format( $dValue, $oActCur->decimal, $oActCur->dec, $oActCur->thousand);
00205
00206 return $sFormated;
00207 }
00208
00216 public function currency2Float( $sValue)
00217 {
00218 $fRet = $sValue;
00219 $iPos = strrpos( $sValue, ".");
00220 if ($iPos && ((strlen($sValue)-1-$iPos) < 2+1)) {
00221
00222 $fRet = substr_replace( $fRet, ",", $iPos, 1);
00223 }
00224
00225 $fRet = str_replace( array(" ","."), "", $fRet);
00226
00227 $fRet = str_replace( ",", ".", $fRet);
00228 return (float) $fRet;
00229 }
00230
00238 public function isSearchEngine( $sClient = null )
00239 {
00240 $myConfig = $this->getConfig();
00241 $blIsSe = false;
00242
00243 if ( !( $myConfig->getConfigParam( 'iDebug' ) && $this->isAdmin() ) ) {
00244
00245
00246 $blIsSe = $myConfig->getGlobalParameter( 'blIsSearchEngine' );
00247 if ( !isset( $blIsSe ) ) {
00248
00249 $aRobots = $myConfig->getConfigParam( 'aRobots' );
00250 $aRobots = is_array( $aRobots )?$aRobots:array();
00251
00252 $aRobotsExcept = $myConfig->getConfigParam( 'aRobotsExcept' );
00253 $aRobotsExcept = is_array( $aRobotsExcept )?$aRobotsExcept:array();
00254
00255 $sClient = $sClient?$sClient:strtolower( getenv( 'HTTP_USER_AGENT' ) );
00256 $blIsSe = false;
00257 $aRobots = array_merge( $aRobots, $aRobotsExcept );
00258 foreach ( $aRobots as $sRobot ) {
00259 if ( strpos( $sClient, $sRobot ) !== false ) {
00260 $blIsSe = true;
00261 break;
00262 }
00263 }
00264 $myConfig->setGlobalParameter( 'blIsSearchEngine', $blIsSe );
00265 }
00266 }
00267
00268 return $blIsSe;
00269 }
00270
00279 public function isValidEmail( $sEmail )
00280 {
00281 $blValid = true;
00282 if ( $sEmail != 'admin' ) {
00283 $blValid = ( eregi( $this->_sEmailTpl, $sEmail ) != 0 );
00284 }
00285
00286 return $blValid;
00287 }
00288
00294 public function rebuildCache()
00295 {
00296
00297
00298
00299
00300
00301 if ( function_exists( "UserdefinedRebuildCache")) {
00302 UserdefinedRebuildCache();
00303 }
00304 }
00305
00313 public function loadAdminProfile($aInterfaceProfiles)
00314 {
00315
00316
00317 $aInterfaceProfiles = $aInterfaceProfiles;
00318 if ( is_array( $aInterfaceProfiles ) ) {
00319 $sPrevProfile = oxUtilsServer::getInstance()->getOxCookie('oxidadminprofile');
00320 if (isset($sPrevProfile)) {
00321 $aPrevProfile = @explode("@", trim($sPrevProfile));
00322 }
00323
00324
00325 $aProfiles = array();
00326 foreach ( $aInterfaceProfiles as $iPos => $sProfile) {
00327 $aProfileSettings = array($iPos, $sProfile);
00328 $aProfiles[] = $aProfileSettings;
00329 }
00330
00331 if (isset($aPrevProfile[0]) && isset($aProfiles[$aPrevProfile[0]])) {
00332 $aProfiles[$aPrevProfile[0]][2] = 1;
00333 }
00334
00335 oxSession::setVar("aAdminProfiles", $aProfiles);
00336 return $aProfiles;
00337 }
00338 return null;
00339 }
00340
00349 public function fRound($sVal, $oCur = null)
00350 {
00351 startProfile('fround');
00352
00353
00354 $iCurPrecision = null;
00355 if (! defined('OXID_PHP_UNIT')) {
00356 $iCurPrecision = $this->_iCurPrecision;
00357 }
00358
00359 if (is_null($iCurPrecision)) {
00360 if ( !$oCur ) {
00361 $oCur = $this->getConfig()->getActShopCurrencyObject();
00362 }
00363
00364 $iCurPrecision = $oCur->decimal;
00365 $this->_iCurPrecision = $iCurPrecision;
00366 }
00367
00368
00369 static $dprez = null;
00370 if (!$dprez) {
00371 $prez = @ini_get("precision");
00372 if (!$prez) {
00373 $prez = 9;
00374 }
00375 $dprez = pow(10, -$prez);
00376 }
00377
00378
00379 stopProfile('fround');
00380
00381 return round($sVal + $dprez, $iCurPrecision);
00382 }
00383
00393 public function toStaticCache( $sName, $sContent, $sKey = null )
00394 {
00395
00396 if ( $sKey ) {
00397 $this->_aStaticCache[$sName][$sKey] = $sContent;
00398 } else {
00399 $this->_aStaticCache[$sName] = $sContent;
00400 }
00401 }
00402
00410 public function fromStaticCache( $sName)
00411 {
00412 if ( isset( $this->_aStaticCache[$sName])) {
00413 return $this->_aStaticCache[$sName];
00414 }
00415 return null;
00416 }
00417
00425 public function cleanStaticCache($sCacheName = null)
00426 {
00427 if ($sCacheName) {
00428 unset($this->_aStaticCache[$sCacheName]);
00429 } else {
00430 $this->_aStaticCache = null;
00431 }
00432 }
00433
00443 protected function _oxFileCache( $blMode, $sName, $sInput = null )
00444 {
00445 $sVersionPrefix = "";
00446
00447
00448 $sVersionPrefix = 'pe';
00449
00450 $sFilePath = $this->getConfig()->getConfigParam( 'sCompileDir' ) . "/ox$sVersionPrefix"."c_".$sName.".txt";
00451
00452 $sRet = null;
00453 if ( $blMode) {
00454
00455
00456
00457
00458
00459 $hFile = fopen( $sFilePath, "w");
00460 if ( $hFile) {
00461 fwrite( $hFile, $sInput, strlen( $sInput));
00462 fclose( $hFile);
00463 }
00464 } else {
00465 if ( file_exists( $sFilePath) && is_readable($sFilePath)) {
00466
00467 $sRet = file_get_contents( $sFilePath);
00468 }
00469 }
00470 return $sRet;
00471 }
00472
00481 public function toFileCache($sKey, $sContents)
00482 {
00483 $sStaticCacheKey = 'staticfilecache|' . $sKey;
00484 $this->toStaticCache($sStaticCacheKey, $sContents);
00485
00486 $sContents = serialize($sContents);
00487 return $this->_oxFileCache(true, $sKey, $sContents);
00488 }
00489
00497 public function fromFileCache( $sKey )
00498 {
00499 $sStaticCacheKey = "staticfilecache|$sKey";
00500
00501
00502 $sRes = $this->fromStaticCache( $sStaticCacheKey );
00503
00504 if ( is_null( $sRes ) ) {
00505 $sRes = unserialize( $this->_oxFileCache( false, $sKey ) );
00506 $this->toStaticCache( $sStaticCacheKey, $sRes );
00507 }
00508
00509 return $sRes;
00510 }
00511
00518 public function oxResetFileCache()
00519 {
00520 $sFilePath = $this->getConfig()->getConfigParam( 'sCompileDir' ) . "/oxc_*.txt";
00521 $aPathes = glob( $sFilePath);
00522 if (is_array($aPathes)) {
00523 foreach ($aPathes as $sFilename) {
00524
00525 @unlink( $sFilename);
00526 }
00527 }
00528 }
00529
00539 public function getRemoteCachePath($sRemote, $sLocal)
00540 {
00541 clearstatcache();
00542 if ( file_exists( $sLocal ) && filemtime( $sLocal ) && filemtime( $sLocal ) > time() - 86400 ) {
00543 return $sLocal;
00544 }
00545 $hRemote = @fopen( $sRemote, "rb");
00546 $blSuccess = false;
00547 if ( isset( $hRemote) && $hRemote ) {
00548 $hLocal = fopen( $sLocal, "wb");
00549 stream_copy_to_stream($hRemote, $hLocal);
00550 fclose($hRemote);
00551 fclose($hLocal);
00552 $blSuccess = true;
00553 } else {
00554
00555 $aUrl = @parse_url( $sRemote);
00556 if ( !empty( $aUrl["host"])) {
00557 $sPath = $aUrl["path"];
00558 if ( empty( $sPath ) ) {
00559 $sPath = "/";
00560 }
00561 $sHost = $aUrl["host"];
00562
00563 $hSocket = @fsockopen( $sHost, 80, $iErrorNumber, $iErrStr, 5);
00564 if ( $hSocket) {
00565 fputs( $hSocket, "GET ".$sPath." HTTP/1.0\r\nHost: $sHost\r\n\r\n");
00566 $headers = stream_get_line($hSocket, 4096, "\r\n\r\n");
00567 $hLocal = @fopen( $sLocal, "wb");
00568 stream_copy_to_stream($hSocket, $hLocal);
00569 fclose( $hSocket);
00570 fclose($hLocal);
00571 $blSuccess = true;
00572 }
00573 }
00574 }
00575 if ( $blSuccess || file_exists( $sLocal ) ) {
00576 return $sLocal;
00577 } else {
00578 return false;
00579 }
00580 }
00581
00587 public function checkAccessRights()
00588 {
00589 $myConfig = $this->getConfig();
00590
00591 $blIsAuth = false;
00592
00593 $sUserID = oxSession::getVar( "auth");
00594
00595
00596 oxSession::setVar( "malladmin", 0);
00597 oxSession::setVar( "blIsAdmin", 0);
00598 oxSession::deleteVar( "blIsAdmin" );
00599 $myConfig->setConfigParam( 'blMallAdmin', false );
00600
00601 $myConfig->setConfigParam( 'blAllowInheritedEdit', false );
00602
00603 if ( $sUserID) {
00604
00605 $sUserID = oxDb::getDb()->Quote($sUserID);
00606 $sRights = oxDb::getDb()->GetOne("select oxrights from oxuser where oxid = $sUserID");
00607
00608 if ( $sRights != "user") {
00609
00610 if ( $sRights == "malladmin") {
00611 oxSession::setVar( "malladmin", 1);
00612 $myConfig->setConfigParam( 'blMallAdmin', true );
00613
00614
00615
00616 $myConfig->setConfigParam( 'blAllowSharedEdit', true );
00617
00618 $sShop = oxSession::getVar( "actshop");
00619 if ( !isset($sShop)) {
00620 oxSession::setVar( "actshop", $myConfig->getBaseShopId());
00621 }
00622 $blIsAuth = true;
00623 } else {
00624 $sShopID = oxDb::getDb()->GetOne("select oxid from oxshops where oxid = '{$sRights}'");
00625 if ( isset( $sShopID) && $sShopID) {
00626
00627 oxSession::setVar( "actshop", $sRights);
00628 oxSession::setVar( "currentadminshop", $sRights);
00629 oxSession::setVar( "shp", $sRights);
00630
00631
00632 if ('chshp' == oxConfig::getParameter( 'fnc' )) {
00633
00634 $blIsAuth = false;
00635 } else {
00636 $blIsAuth = true;
00637
00638 $aShopIdVars = array('actshop', 'shp', 'currentadminshop');
00639 foreach ($aShopIdVars as $sShopIdVar) {
00640 if ($sGotShop = oxConfig::getParameter( $sShopIdVar )) {
00641 if ($sGotShop != $sRights) {
00642 $blIsAuth = false;
00643 break;
00644 }
00645 }
00646 }
00647 }
00648 }
00649 }
00650
00651 oxSession::setVar( "blIsAdmin", 1);
00652 }
00653 }
00654 return $blIsAuth;
00655 }
00656
00666 public function seoIsActive( $blReset = false, $sShopId = null, $iActLang = null )
00667 {
00668 if ( !is_null( $this->_blSeoIsActive ) && !$blReset ) {
00669 return $this->_blSeoIsActive;
00670 }
00671
00672 $myConfig = $this->getConfig();
00673
00674 if ( $this->isAdmin() ) {
00675
00676 $this->_blSeoIsActive = false;
00677 } elseif ( ( $this->_blSeoIsActive = $myConfig->getConfigParam( 'blSeoMode' ) ) === null ) {
00678 $this->_blSeoIsActive = true;
00679
00680 $aSeoModes = $myConfig->getconfigParam( 'aSeoModes' );
00681 $sActShopId = $sShopId ? $sShopId : $myConfig->getActiveShop()->getId();
00682 $iActLang = $iActLang ? $iActLang : (int) oxLang::getInstance()->getBaseLanguage();
00683
00684
00685 if ( is_array( $aSeoModes ) && isset( $aSeoModes[$sActShopId] ) && isset( $aSeoModes[$sActShopId][$iActLang] ) ) {
00686 $this->_blSeoIsActive = (bool) $aSeoModes[$sActShopId][$iActLang];
00687 }
00688 }
00689
00690 return $this->_blSeoIsActive;
00691 }
00692
00702 public function getShopBit( $iShopId )
00703 {
00704 $iShopId = (int) $iShopId;
00705
00706 $iRes = oxDb::getDb()->getOne( "select 1 << ( $iShopId - 1 ) as shopbit" );
00707
00708
00709 return $iRes;
00710 }
00711
00721 public function bitwiseAnd( $iVal1, $iVal2 )
00722 {
00723
00724 $iRes = oxDb::getDb()->getOne( "select ($iVal1 & $iVal2) as bitwiseAnd" );
00725
00726
00727 return $iRes;
00728 }
00729
00739 public function bitwiseOr( $iVal1, $iVal2 )
00740 {
00741
00742 $iRes = oxDb::getDb()->getOne( "select ($iVal1 | $iVal2) as bitwiseOr" );
00743
00744
00745 return $iRes;
00746 }
00747
00755 public function isValidAlpha( $sField )
00756 {
00757 return (boolean) preg_match( "#^[\w]*$#", $sField );
00758 }
00759
00769 protected function _simpleRedirect( $sUrl, $sHeaderCode )
00770 {
00771 header( $sHeaderCode );
00772 header( "Location: $sUrl" );
00773 header( "Connection: close" );
00774 }
00775
00784 public function redirect( $sUrl, $blAddRedirectParam = true )
00785 {
00786
00787
00788 if ( $blAddRedirectParam && oxConfig::getParameter( 'redirected' ) ) {
00789 return;
00790 }
00791
00792 if ( $blAddRedirectParam ) {
00793 $sUrl = $this->_addUrlParameters( $sUrl, array( 'redirected' => 1 ) );
00794 }
00795
00796 $sUrl = str_ireplace( "&", "&", $sUrl );
00797 $this->_simpleRedirect( $sUrl, "HTTP/1.1 301 Moved Permanently" );
00798
00799 try {
00800 $this->getSession()->freeze();
00801 } catch( oxException $oEx ) {
00802 $oEx->debugOut();
00803
00804 }
00805
00806 if ( defined( 'OXID_PHP_UNIT' ) ) {
00807 return;
00808 }
00809
00810 exit;
00811 }
00812
00820 public function showMessageAndExit( $sMsg )
00821 {
00822 $this->getSession()->freeze();
00823 die( $sMsg );
00824 }
00825
00834 protected function _addUrlParameters( $sUrl, $aParams )
00835 {
00836 $sDelim = ( ( strpos( $sUrl, '?' ) !== false ) )?'&':'?';
00837 foreach ( $aParams as $sName => $sVal ) {
00838 $sUrl = $sUrl . $sDelim . $sName . '=' . $sVal;
00839 $sDelim = '&';
00840 }
00841
00842 return $sUrl;
00843 }
00844
00856 protected function _fillExplodeArray( $aName, $dVat = null)
00857 {
00858 $myConfig = $this->getConfig();
00859 $oObject = new OxstdClass();
00860 $aPrice = explode( '!P!', $aName[0]);
00861
00862 if ( ( $myConfig->getConfigParam( 'bl_perfLoadSelectLists' ) && $myConfig->getConfigParam( 'bl_perfUseSelectlistPrice' ) && isset( $aPrice[0] ) && isset( $aPrice[1] ) ) || $this->isAdmin() ) {
00863
00864
00865 $oObject->price = $aPrice[1];
00866 $aName[0] = $aPrice[0];
00867
00868 $iPercPos = strpos( $oObject->price, '%' );
00869 if ( $iPercPos !== false ) {
00870 $oObject->priceUnit = '%';
00871 $oObject->fprice = $oObject->price;
00872 $oObject->price = substr( $oObject->price, 0, $iPercPos );
00873 } else {
00874 $oCur = $myConfig->getActShopCurrencyObject();
00875 $oObject->price = str_replace(',', '.', $oObject->price);
00876 $oObject->fprice = oxLang::getInstance()->formatCurrency( $oObject->price * $oCur->rate, $oCur);
00877 $oObject->priceUnit = 'abs';
00878 }
00879
00880
00881 if ( !$this->isAdmin() ) {
00882 $aName[0] .= " ";
00883 if ( $oObject->price > 0 ) {
00884 $aName[0] .= "+";
00885 }
00886
00887 if ( $dVat != null && $oObject->priceUnit == 'abs' ) {
00888 $oPrice = oxNew('oxPrice');
00889 $oPrice->setPrice($oObject->price, $dVat);
00890 $aName[0] .= oxLang::getInstance()->formatCurrency( $oPrice->getBruttoPrice() * $oCur->rate, $oCur);
00891 } else {
00892 $aName[0] .= $oObject->fprice;
00893 }
00894 if ( $oObject->priceUnit == 'abs' ) {
00895 $aName[0] .= " ".$oCur->sign;
00896 }
00897 }
00898 } elseif ( isset( $aPrice[0] ) && isset($aPrice[1] ) ) {
00899
00900 $aName[0] = ereg_replace( "!P!.*", "", $aName[0] );
00901 }
00902
00903 $oObject->name = $aName[0];
00904 $oObject->value = $aName[1];
00905 return $oObject;
00906 }
00907
00915 public function oxMimeContentType( $sFileName )
00916 {
00917 $sFileName = strtolower( $sFileName );
00918 $iLastDot = strrpos( $sFileName, '.' );
00919
00920 if ( $iLastDot !== false ) {
00921 $sType = substr( $sFileName, $iLastDot + 1 );
00922 switch ( $sType ) {
00923 case 'gif':
00924 $sType = 'image/gif';
00925 break;
00926 case 'jpeg':
00927 case 'jpg':
00928 $sType = 'image/jpeg';
00929 break;
00930 case 'png':
00931 $sType = 'image/png';
00932 break;
00933 default:
00934 $sType = false;
00935 break;
00936 }
00937 }
00938 return $sType;
00939 }
00940
00949 public function logger( $sText, $blNewline = false )
00950 { $myConfig = $this->getConfig();
00951
00952 if ( $myConfig->getConfigParam( 'iDebug' ) == -2) {
00953 if ( gettype( $sText ) != 'string' ) {
00954 $sText = var_export( $sText, true);
00955 }
00956 @error_log("----------------------------------------------\n$sText".( ( $blNewline ) ?"\n":"" )."\n", 3, $myConfig->getConfigParam( 'sCompileDir' ).'/log.txt' );
00957 }
00958
00959 }
00960
00968 protected function _stripQuotes($mInput)
00969 {
00970 return is_array($mInput) ? array_map( array( $this, '_stripQuotes' ), $mInput) : stripslashes( $mInput );
00971 }
00972
00980 public function strRot13( $sStr )
00981 {
00982 $sFrom = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
00983 $sTo = 'nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM';
00984
00985 return strtr( $sStr, $sFrom, $sTo );
00986 }
00987
00988
00998 public function prepareUrlForNoSession($sUrl)
00999 {
01000 if ( oxUtils::getInstance()->seoIsActive() ) {
01001 return $sUrl;
01002 }
01003
01004 $sUrl = preg_replace('/sid=[a-z0-9\._]*&?(amp;)?/i', '', $sUrl);
01005
01006 if ($qpos = strpos($sUrl, '?')) {
01007 if ($qpos == strlen($sUrl)-1) {
01008 $sSep = '';
01009 } else {
01010 $sSep = '&';
01011 }
01012 } else {
01013 $sSep = '?';
01014 }
01015
01016 if (!preg_match('/[&?](amp;)?lang=[0-9]+/i', $sUrl)) {
01017 $sUrl .= "{$sSep}lang=".oxLang::getInstance()->getBaseLanguage();
01018 $sSep = '&';
01019 }
01020
01021 if (!preg_match('/[&?](amp;)?cur=[0-9]+/i', $sUrl)) {
01022 $iCur = (int) oxConfig::getParameter('currency');
01023 if ($iCur) {
01024 $sUrl .= "{$sSep}cur=".$iCur;
01025 $sSep = '&';
01026 }
01027 }
01028
01029 return $sUrl;
01030 }
01031
01032 }