00001 <?php
00002
00006 class oxSysRequirements
00007 {
00013 protected $_aRequiredModules = null;
00014
00020 protected $_blSysReqStatus = null;
00021
00027 protected $_aException = array( 'OXDELIVERY' => 'OXDELTYPE',
00028 'OXSELECTLIST' => 'OXIDENT');
00029
00035 protected $_aColumns = array( 'OXID',
00036 'OXOBJECTID',
00037 'OXARTICLENID',
00038 'OXACTIONID',
00039 'OXARTID',
00040 'OXUSERID',
00041 'OXADDRESSUSERID',
00042 'OXCOUNTRYID',
00043 'OXSESSID',
00044 'OXITMID',
00045 'OXPARENTID',
00046 'OXAMITEMID',
00047 'OXAMTASKID',
00048 'OXVENDORID',
00049 'OXMANUFACTURERID',
00050 'OXROOTID',
00051 'OXATTRID',
00052 'OXCATID',
00053 'OXDELID',
00054 'OXDELSETID',
00055 'OXITMARTID',
00056 'OXFIELDID',
00057 'OXROLEID',
00058 'OXCNID',
00059 'OXANID',
00060 'OXARTICLENID',
00061 'OXCATNID',
00062 'OXDELIVERYID',
00063 'OXDISCOUNTID',
00064 'OXGROUPSID',
00065 'OXLISTID',
00066 'OXPAYMENTID',
00067 'OXDELTYPE',
00068 'OXROLEID',
00069 'OXSELNID',
00070 'OXBILLCOUNTRYID',
00071 'OXDELCOUNTRYID',
00072 'OXPAYMENTID',
00073 'OXCARDID',
00074 'OXPAYID',
00075 'OXIDENT',
00076 'OXDEFCAT',
00077 'OXBASKETID',
00078 'OXPAYMENTSID',
00079 'OXORDERID',
00080 'OXVOUCHERSERIEID');
00081
00087 protected $_sReqInfoUrl = "http://www.oxidforge.org/wiki/Installation";
00088
00094 protected $_aInfoMap = array( "php_version" => "PHP_version_at_least_5.2.0",
00095 "lib_xml2" => "LIB_XML2",
00096 "php_xml" => "DOM",
00097 "open_ssl" => "OpenSSL",
00098 "soap" => "SOAP",
00099 "j_son" => "JSON",
00100 "i_conv" => "ICONV",
00101 "tokenizer" => "Tokenizer",
00102 "mysql_connect" => "MySQL_client_connector_for_MySQL_5",
00103 "gd_info" => "GDlib_v2_.5Bv1.5D_incl._JPEG_support",
00104 "mb_string" => "mbstring",
00105 "bc_math" => "BCMath",
00106 "allow_url_fopen" => "allow_url_fopen_or_fsockopen_to_port_80",
00107 "php4_compat" => "Zend_compatibility_mode_must_be_off",
00108 "request_uri" => "REQUEST_URI_set",
00109 "ini_set" => "ini_set_allowed",
00110 "register_globals" => "register_globals_must_be_off",
00111 "memory_limit" => "PHP_Memory_limit_.28min._14MB.2C_30MB_recommended.29",
00112 "unicode_support" => "UTF-8_support",
00113 "mod_rewrite" => "apache_mod_rewrite_module",
00114 "server_permissions" => "Files_.26_Folder_Permission_Setup",
00115 "zend_optimizer" => "Zend_Optimizer",
00116 "bug53632" => "Not_recommended_PHP_versions",
00117
00118 );
00119
00125 public function __construct()
00126 {
00127 }
00128
00140 public function __call( $sMethod, $aArgs )
00141 {
00142 if ( defined( 'OXID_PHP_UNIT' ) ) {
00143 if ( substr( $sMethod, 0, 4) == "UNIT" ) {
00144 $sMethod = str_replace( "UNIT", "_", $sMethod );
00145 }
00146 if ( method_exists( $this, $sMethod)) {
00147 return call_user_func_array( array( & $this, $sMethod ), $aArgs );
00148 }
00149 }
00150
00151 throw new oxSystemComponentException( "Function '$sMethod' does not exist or is not accessible! (" . get_class($this) . ")".PHP_EOL);
00152 }
00153
00159 public function getConfig()
00160 {
00161 return oxConfig::getInstance();
00162 }
00163
00169 public function getRequiredModules()
00170 {
00171 if ( $this->_aRequiredModules == null ) {
00172 $aRequiredPHPExtensions = array(
00173 'php_version',
00174 'lib_xml2',
00175 'php_xml',
00176 'j_son',
00177 'i_conv',
00178 'tokenizer',
00179 'mysql_connect',
00180 'gd_info',
00181 'mb_string',
00182 'curl',
00183 'bc_math',
00184 'open_ssl',
00185 'soap',
00186 );
00187
00188 $aRequiredPHPConfigs = array(
00189 'allow_url_fopen',
00190 'php4_compat',
00191 'request_uri',
00192 'ini_set',
00193 'register_globals',
00194 'memory_limit',
00195 'unicode_support'
00196 );
00197
00198 $aRequiredServerConfigs = array(
00199 'mod_rewrite',
00200 'server_permissions',
00201 'bug53632'
00202 );
00203
00204
00205 if ( isAdmin() ) {
00206 $aRequiredServerConfigs[] = 'mysql_version';
00207 }
00208 $this->_aRequiredModules = array_fill_keys( $aRequiredPHPExtensions, 'php_extennsions' ) +
00209 array_fill_keys( $aRequiredPHPConfigs, 'php_config' ) +
00210 array_fill_keys( $aRequiredServerConfigs, 'server_config' );
00211 }
00212 return $this->_aRequiredModules;
00213 }
00214
00223 public function checkBug53632()
00224 {
00225 $iState = 1;
00226 if ( version_compare( PHP_VERSION, "5.3", ">=" ) ) {
00227 if ( version_compare( PHP_VERSION, "5.3.5", ">=" ) && version_compare( PHP_VERSION, "5.3.7", "!=" ) ) {
00228 $iState = 2;
00229 }
00230 } elseif ( version_compare( PHP_VERSION, '5.2', ">=" ) ) {
00231 $iState = version_compare( PHP_VERSION, "5.2.17", ">=" ) ? 2 : $iState;
00232 }
00233 return $iState;
00234 }
00235
00241 public function checkCurl()
00242 {
00243 return extension_loaded( 'curl' ) ? 2 : 1;
00244 }
00245
00251 public function checkMbString()
00252 {
00253 return extension_loaded( 'mbstring' ) ? 2 : 1;
00254 }
00255
00264 public function checkServerPermissions( $sPath = null, $iMinPerm = 777 )
00265 {
00266 $sVerPrefix = '';
00267
00268 clearstatcache();
00269 $sPath = $sPath ? $sPath : getShopBasePath();
00270
00271
00272 $sFullPath = $sPath . "config.inc.php";
00273 if ( !is_readable( $sFullPath ) ||
00274 ( isAdmin() && is_writable( $sFullPath ) ) ||
00275 ( !isAdmin() && !is_writable( $sFullPath ) )
00276 ) {
00277 return 0;
00278 }
00279
00280 $sTmp = "$sPath/tmp$sVerPrefix/";
00281 if (class_exists('oxConfig')) {
00282 $sCfgTmp = $this->getConfig()->getConfigParam('sCompileDir');
00283 if (strpos($sCfgTmp, '<sCompileDir_') === false) {
00284 $sTmp = $sCfgTmp;
00285 }
00286 }
00287
00288 $aPathsToCheck = array(
00289 $sPath."out/pictures{$sVerPrefix}/promo/",
00290 $sPath."out/pictures{$sVerPrefix}/media/",
00291 $sPath."out/pictures{$sVerPrefix}/master/",
00292 $sPath."out/pictures{$sVerPrefix}/generated/",
00293 $sPath."log/",
00294 $sTmp
00295 );
00296 $iModStat = 2;
00297 $sPathToCheck = reset( $aPathsToCheck );
00298 while ( $sPathToCheck ) {
00299
00300 if ( !file_exists( $sPathToCheck ) ) {
00301 $iModStat = 0;
00302 break;
00303 }
00304
00305 if ( is_dir( $sPathToCheck ) ) {
00306
00307 $aSubF = glob( $sPathToCheck."*", GLOB_ONLYDIR );
00308 if (is_array($aSubF)) {
00309 foreach ( $aSubF as $sNewFolder ) {
00310 $aPathsToCheck[] = $sNewFolder . "/";
00311 }
00312 }
00313 }
00314
00315
00316
00317 if ( !is_readable( $sPathToCheck ) || !is_writable( $sPathToCheck ) ) {
00318 $iModStat = 0;
00319 break;
00320 }
00321
00322 $sPathToCheck = next( $aPathsToCheck );
00323 }
00324
00325 return $iModStat;
00326 }
00327
00334 protected function _getShopHostInfoFromConfig()
00335 {
00336 $sShopURL = $this->getConfig()->getConfigParam( 'sShopURL' );
00337 if (preg_match('#^(https?://)?([^/:]+)(:([0-9]+))?(/.*)?$#i', $sShopURL, $m)) {
00338 $sHost = $m[2];
00339 $iPort = (int)$m[4];
00340 $blSsl = (strtolower($m[1])=='https://');
00341 if (!$iPort) {
00342 $iPort = $blSsl?443:80;
00343 }
00344 $sScript = rtrim($m[5], '/').'/';
00345 return array(
00346 'host'=>$sHost,
00347 'port'=>$iPort,
00348 'dir'=>$sScript,
00349 'ssl'=>$blSsl,
00350 );
00351 } else {
00352 return false;
00353 }
00354 }
00355
00362 protected function _getShopHostInfoFromServerVars()
00363 {
00364
00365 $sScript = $_SERVER['SCRIPT_NAME'];
00366 $iPort = (int) $_SERVER['SERVER_PORT'];
00367 $blSsl = (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on'));
00368 if (!$iPort) {
00369 $iPort = $blSsl?443:80;
00370 }
00371 $sScript = rtrim(dirname(dirname( $sScript )), '/').'/';
00372 return array(
00373 'host'=>$_SERVER['HTTP_HOST'],
00374 'port'=>$iPort,
00375 'dir'=>$sScript,
00376 'ssl'=>$blSsl,
00377 );
00378 }
00379
00385 protected function _getShopHostInfo()
00386 {
00387 if ( isAdmin() ) {
00388 return $this->_getShopHostInfoFromConfig();
00389 } else {
00390 return $this->_getShopHostInfoFromServerVars();
00391 }
00392 }
00393
00399 public function checkModRewrite()
00400 {
00401 $iModStat = null;
00402 if ( ($aHostInfo = $this->_getShopHostInfo()) && $rFp = @fsockopen( ($aHostInfo['ssl']?'ssl://':'').$aHostInfo['host'], $aHostInfo['port'], $iErrNo, $sErrStr, 10 ) ) {
00403 $sReq = "POST {$aHostInfo['dir']}oxseo.php?mod_rewrite_module_is=off HTTP/1.1\r\n";
00404 $sReq .= "Host: {$aHostInfo['host']}\r\n";
00405 $sReq .= "User-Agent: OXID eShop setup\r\n";
00406 $sReq .= "Content-Type: application/x-www-form-urlencoded\r\n";
00407 $sReq .= "Content-Length: 0\r\n";
00408 $sReq .= "Connection: close\r\n\r\n";
00409
00410 $sOut = '';
00411 fwrite( $rFp, $sReq );
00412 while ( !feof( $rFp ) ) {
00413 $sOut .= fgets( $rFp, 100 );
00414 }
00415 fclose( $rFp );
00416
00417 $iModStat = ( strpos( $sOut, 'mod_rewrite_on' ) !== false ) ? 2 : 0;
00418 } else {
00419 if ( function_exists( 'apache_get_modules' ) ) {
00420
00421 $iModStat = in_array( 'mod_rewrite', apache_get_modules() ) ? 1 : 0;
00422 } else {
00423 $iModStat = -1;
00424 }
00425 }
00426 return $iModStat;
00427 }
00428
00434 public function checkAllowUrlFopen()
00435 {
00436 $iModStat = @ini_get('allow_url_fopen');
00437 $iModStat = ( $iModStat && strcasecmp( '1', $iModStat ) ) ? 2 : 1;
00438 if ( $iModStat == 1 ) {
00439 $iErrNo = 0;
00440 $sErrStr = '';
00441 if ( $oRes = @fsockopen( 'www.example.com', 80, $iErrNo, $sErrStr, 10 ) ) {
00442 $iModStat = 2;
00443 fclose( $oRes );
00444 }
00445 }
00446 $iModStat = ( !$iModStat ) ? 1 : $iModStat;
00447 return $iModStat;
00448 }
00449
00456 public function checkPhp4Compat()
00457 {
00458 $sZendStatus = ( strtolower( (string) @ini_get( 'zend.ze1_compatibility_mode' ) ) );
00459 return in_array( $sZendStatus, array( 'on', '1' ) ) ? 0 : 2;
00460 }
00461
00468 public function checkPhpVersion()
00469 {
00470 $iModStat = ( version_compare( PHP_VERSION, '5.1', '>' ) ) ? 1 : 0;
00471 $iModStat = ( $iModStat == 0 ) ? $iModStat : ( version_compare( PHP_VERSION, '5.2', '>=' ) ? 2 : 1 );
00472 return $iModStat;
00473 }
00474
00480 public function checkRequestUri()
00481 {
00482 return ( isset( $_SERVER['REQUEST_URI'] ) || isset( $_SERVER['SCRIPT_URI'] ) ) ? 2 : 0;
00483 }
00484
00490 public function checkLibXml2()
00491 {
00492 return class_exists( 'DOMDocument' ) ? 2 : 0;
00493 }
00494
00500 public function checkPhpXml()
00501 {
00502 return class_exists( 'DOMDocument' ) ? 2 : 0;
00503 }
00504
00510 public function checkJSon()
00511 {
00512 return extension_loaded( 'json' ) ? 2 : 0;
00513 }
00514
00520 public function checkIConv()
00521 {
00522 return extension_loaded( 'iconv' ) ? 2 : 0;
00523 }
00524
00530 public function checkTokenizer()
00531 {
00532 return extension_loaded( 'tokenizer' ) ? 2 : 0;
00533 }
00534
00540 public function checkBcMath()
00541 {
00542 return extension_loaded( 'bcmath' ) ? 2 : 1;
00543 }
00544
00550 public function checkOpenSsl()
00551 {
00552 return extension_loaded( 'openssl' ) ? 2 : 1;
00553 }
00554
00560 public function checkSoap()
00561 {
00562 return extension_loaded( 'soap' ) ? 2 : 1;
00563 }
00564
00570 public function checkMysqlConnect()
00571 {
00572
00573 $iModStat = ( extension_loaded( 'mysql' ) || extension_loaded( 'mysqli' ) || extension_loaded( 'pdo_mysql' ) ) ? 2 : 0;
00574
00575
00576 if ( $iModStat ) {
00577 $sClientVersion = mysql_get_client_info();
00578 if (version_compare( $sClientVersion, '5', '<' )) {
00579 $iModStat = 1;
00580 if (version_compare( $sClientVersion, '4', '<' )) {
00581 $iModStat = 0;
00582 }
00583 } elseif (version_compare($sClientVersion, '5.0.36', '>=') && version_compare($sClientVersion, '5.0.38', '<')) {
00584
00585 $iModStat = 0;
00586 } elseif (version_compare($sClientVersion, '5.0.40', '>') && version_compare($sClientVersion, '5.0.42', '<')) {
00587
00588 $iModStat = 0;
00589 }
00590 if ( strpos($sClientVersion, 'mysqlnd') !== false ) {
00591
00592 $iModStat = 2;
00593 }
00594 }
00595 return $iModStat;
00596 }
00597
00605 public function checkMysqlVersion( $sVersion = null )
00606 {
00607 if ( $sVersion === null ) {
00608 $aRez = oxDb::getDb()->getAll( "SHOW VARIABLES LIKE 'version'" );
00609 foreach ( $aRez as $aRecord ) {
00610 $sVersion = $aRecord[1];
00611 break;
00612 }
00613 }
00614
00615 $iModStat = 0;
00616 if ( version_compare( $sVersion, '5.0.3', '>=' ) && version_compare( $sVersion, '5.0.37', '<>' ) ) {
00617 $iModStat = 2;
00618 }
00619
00620 return $iModStat;
00621 }
00622
00628 public function checkGdInfo()
00629 {
00630 $iModStat = extension_loaded( 'gd' ) ? 1 : 0;
00631 $iModStat = function_exists( 'imagecreatetruecolor' ) ? 2 : $iModStat;
00632 $iModStat = function_exists( 'imagecreatefromjpeg' ) ? $iModStat : 0;
00633 return $iModStat;
00634 }
00635
00641 public function checkIniSet()
00642 {
00643 return ( @ini_set('session.name', 'sid' ) !== false ) ? 2 : 0;
00644 }
00645
00651 public function checkRegisterGlobals()
00652 {
00653 $sGlobStatus = ( strtolower( (string) @ini_get( 'register_globals' ) ) );
00654 return in_array( $sGlobStatus, array( 'on', '1' ) ) ? 0 : 2;
00655 }
00656
00662 public function checkMemoryLimit()
00663 {
00664 if ( $sMemLimit = @ini_get('memory_limit') ) {
00665
00666 $sDefLimit = '14M';
00667 $sRecLimit = '30M';
00668
00669
00670 $iMemLimit = $this->_getBytes( $sMemLimit );
00671 $iModStat = ( $iMemLimit >= $this->_getBytes( $sDefLimit ) ) ? 1 : 0;
00672 $iModStat = $iModStat ? ( ( $iMemLimit >= $this->_getBytes( $sRecLimit ) ) ? 2 : $iModStat ) : $iModStat;
00673
00674 } else {
00675 $iModStat = -1;
00676 }
00677 return $iModStat;
00678 }
00679
00685 public function checkZendOptimizer()
00686 {
00691 return 2;
00692 }
00693
00699 public function checkZendPlatformOrServer()
00700 {
00701 if (function_exists( 'output_cache_get' )) {
00702 return 2;
00703 }
00704 if (function_exists( 'zend_disk_cache_fetch' )) {
00705 return 2;
00706 }
00707 if (function_exists( 'zend_shm_cache_fetch' )) {
00708 return 2;
00709 }
00710 return 1;
00711 }
00712
00718 protected function _getAdditionalCheck()
00719 {
00720 $sSelect = '';
00721 foreach ( $this->_aException as $sTable => $sColumn ) {
00722 $sSelect .= 'and ( t.TABLE_NAME != "'.$sTable.'" and c.COLUMN_NAME != "'.$sColumn.'" ) ';
00723 }
00724 return $sSelect;
00725 }
00726
00732 public function checkCollation()
00733 {
00734 $myConfig = $this->getConfig();
00735
00736 $aCollations = array();
00737 $sCollation = '';
00738
00739 $sSelect = 'select t.TABLE_NAME, c.COLUMN_NAME, c.COLLATION_NAME from INFORMATION_SCHEMA.tables t ' .
00740 'LEFT JOIN INFORMATION_SCHEMA.columns c ON t.TABLE_NAME = c.TABLE_NAME ' .
00741 'where t.TABLE_SCHEMA = "'.$myConfig->getConfigParam( 'dbName' ).'" ' .
00742 'and c.TABLE_SCHEMA = "'.$myConfig->getConfigParam( 'dbName' ).'" ' .
00743 'and c.COLUMN_NAME in ("'.implode('", "', $this->_aColumns).'") ' . $this->_getAdditionalCheck() .
00744 ' ORDER BY (t.TABLE_NAME = "oxarticles") DESC';
00745 $aRez = oxDb::getDb()->getAll($sSelect);
00746 foreach ( $aRez as $aRetTable ) {
00747 if ( !$sCollation ) {
00748 $sCollation = $aRetTable[2];
00749 } else {
00750 if ( $aRetTable[2] && $sCollation != $aRetTable[2]) {
00751 $aCollations[$aRetTable[0]][$aRetTable[1]] = $aRetTable[2];
00752 }
00753 }
00754 }
00755
00756 if ( $this->_blSysReqStatus === null ) {
00757 $this->_blSysReqStatus = true;
00758 }
00759 if ( count($aCollations) > 0 ) {
00760 $this->_blSysReqStatus = false;
00761 }
00762 return $aCollations;
00763 }
00764
00770 public function checkDatabaseCluster()
00771 {
00772 return 2;
00773 }
00774
00780 public function checkUnicodeSupport()
00781 {
00782 return (@preg_match('/\pL/u', 'a') == 1) ? 2 : 1;
00783 }
00784
00790 public function getSysReqStatus()
00791 {
00792 if ( $this->_blSysReqStatus == null ) {
00793 $this->_blSysReqStatus = true;
00794 $this->getSystemInfo();
00795 $this->checkCollation();
00796 }
00797 return $this->_blSysReqStatus;
00798 }
00799
00814 public function getSystemInfo()
00815 {
00816 $aSysInfo = array();
00817 $aRequiredModules = $this->getRequiredModules();
00818 $this->_blSysReqStatus = true;
00819 foreach ( $aRequiredModules as $sModule => $sGroup ) {
00820 if ( isset($aSysInfo[$sGroup]) && !$aSysInfo[$sGroup] ) {
00821 $aSysInfo[$sGroup] = array();
00822 }
00823 $iModuleState = $this->getModuleInfo( $sModule );
00824 $aSysInfo[$sGroup][$sModule] = $iModuleState;
00825 $this->_blSysReqStatus = $this->_blSysReqStatus && ( bool ) abs( $iModuleState );
00826 }
00827 return $aSysInfo;
00828 }
00829
00837 public function getModuleInfo( $sModule = null )
00838 {
00839 if ( $sModule ) {
00840 $iModStat = null;
00841 $sCheckFunction = "check".str_replace(" ", "", ucwords(str_replace("_", " ", $sModule)));
00842 $iModStat = $this->$sCheckFunction();
00843
00844 return $iModStat;
00845 }
00846 }
00847
00855 public function getReqInfoUrl( $sIdent)
00856 {
00857 $sUrl = $this->_sReqInfoUrl;
00858 $aInfoMap = $this->_aInfoMap;
00859
00860
00861 if ( isset( $aInfoMap[$sIdent] ) ) {
00862 $sUrl .= "#".$aInfoMap[$sIdent];
00863 }
00864
00865 return $sUrl;
00866 }
00867
00875 protected function _getBytes( $sBytes )
00876 {
00877 $sBytes = trim( $sBytes );
00878 $sLast = strtolower($sBytes[strlen($sBytes)-1]);
00879 switch( $sLast ) {
00880
00881 case 'g':
00882 $sBytes *= 1024;
00883 case 'm':
00884 $sBytes *= 1024;
00885 case 'k':
00886 $sBytes *= 1024;
00887 break;
00888 }
00889
00890 return $sBytes;
00891 }
00892
00903 protected function _checkTemplateBlock($sTemplate, $sBlockName)
00904 {
00905 $sTplFile = $this->getConfig()->getTemplatePath($sTemplate, false);
00906 if (!$sTplFile || !file_exists($sTplFile)) {
00907 return false;
00908 }
00909
00910 $sFile = file_get_contents($sTplFile);
00911 $sBlockNameQuoted = preg_quote($sBlockName, '/');
00912 return (bool)preg_match('/\[\{\s*block\s+name\s*=\s*([\'"])'.$sBlockNameQuoted.'\1\s*\}\]/is', $sFile);
00913 }
00914
00924 public function getMissingTemplateBlocks()
00925 {
00926 $oDb = oxDb::getDb( true );
00927 $aCache = array();
00928 $oConfig = $this->getConfig();
00929
00930 $sShpIdParam = $oDb->quote($oConfig->getShopId());
00931 $sSql = "select * from oxtplblocks where oxactive=1 and oxshopid=$sShpIdParam";
00932 $rs = $oDb->execute($sSql);
00933 $aRet = array();
00934 if ($rs != false && $rs->recordCount() > 0) {
00935 while (!$rs->EOF) {
00936 $blStatus = false;
00937 if (isset($aCache[$rs->fields['OXTEMPLATE']]) && isset($aCache[$rs->fields['OXTEMPLATE']][$rs->fields['OXBLOCKNAME']])) {
00938 $blStatus = $aCache[$rs->fields['OXTEMPLATE']][$rs->fields['OXBLOCKNAME']];
00939 } else {
00940 $blStatus = $this->_checkTemplateBlock($rs->fields['OXTEMPLATE'], $rs->fields['OXBLOCKNAME']);
00941 $aCache[$rs->fields['OXTEMPLATE']][$rs->fields['OXBLOCKNAME']] = $blStatus;
00942 }
00943
00944 if (!$blStatus) {
00945 $aRet[] = array(
00946 'module' => $rs->fields['OXMODULE'],
00947 'block' => $rs->fields['OXBLOCKNAME'],
00948 'template' => $rs->fields['OXTEMPLATE'],
00949 );
00950 }
00951 $rs->moveNext();
00952 }
00953 }
00954
00955 return $aRet;
00956 }
00957 }