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 if ( $iModStat ) {
00576 $sClientVersion = mysql_get_client_info();
00577 if (version_compare( $sClientVersion, '5', '<' )) {
00578 $iModStat = 1;
00579 if (version_compare( $sClientVersion, '4', '<' )) {
00580 $iModStat = 0;
00581 }
00582 } elseif (version_compare($sClientVersion, '5.0.36', '>=') && version_compare($sClientVersion, '5.0.38', '<')) {
00583
00584 $iModStat = 0;
00585 } elseif (version_compare($sClientVersion, '5.0.40', '>') && version_compare($sClientVersion, '5.0.42', '<')) {
00586
00587 $iModStat = 0;
00588 }
00589 if (strpos($sClientVersion, 'mysqlnd') !== false) {
00590
00591 $iModStat = 2;
00592 }
00593 }
00594 return $iModStat;
00595 }
00596
00604 public function checkMysqlVersion( $sVersion = null )
00605 {
00606 if ( $sVersion === null ) {
00607 $aRez = oxDb::getDb()->getAll( "SHOW VARIABLES LIKE 'version'" );
00608 foreach ( $aRez as $aRecord ) {
00609 $sVersion = $aRecord[1];
00610 break;
00611 }
00612 }
00613
00614 $iModStat = 0;
00615 if ( version_compare( $sVersion, '5.0.3', '>=' ) && version_compare( $sVersion, '5.0.37', '<>' ) ) {
00616 $iModStat = 2;
00617 }
00618
00619 return $iModStat;
00620 }
00621
00627 public function checkGdInfo()
00628 {
00629 $iModStat = extension_loaded( 'gd' ) ? 1 : 0;
00630 $iModStat = function_exists( 'imagecreatetruecolor' ) ? 2 : $iModStat;
00631 $iModStat = function_exists( 'imagecreatefromjpeg' ) ? $iModStat : 0;
00632 return $iModStat;
00633 }
00634
00640 public function checkIniSet()
00641 {
00642 return ( @ini_set('session.name', 'sid' ) !== false ) ? 2 : 0;
00643 }
00644
00650 public function checkRegisterGlobals()
00651 {
00652 $sGlobStatus = ( strtolower( (string) @ini_get( 'register_globals' ) ) );
00653 return in_array( $sGlobStatus, array( 'on', '1' ) ) ? 0 : 2;
00654 }
00655
00661 public function checkMemoryLimit()
00662 {
00663 if ( $sMemLimit = @ini_get('memory_limit') ) {
00664
00665 $sDefLimit = '14M';
00666 $sRecLimit = '30M';
00667
00668
00669 $iMemLimit = $this->_getBytes( $sMemLimit );
00670 $iModStat = ( $iMemLimit >= $this->_getBytes( $sDefLimit ) ) ? 1 : 0;
00671 $iModStat = $iModStat ? ( ( $iMemLimit >= $this->_getBytes( $sRecLimit ) ) ? 2 : $iModStat ) : $iModStat;
00672
00673 } else {
00674 $iModStat = -1;
00675 }
00676 return $iModStat;
00677 }
00678
00684 public function checkZendOptimizer()
00685 {
00690 return 2;
00691 }
00692
00698 public function checkZendPlatformOrServer()
00699 {
00700 if (function_exists( 'output_cache_get' )) {
00701 return 2;
00702 }
00703 if (function_exists( 'zend_disk_cache_fetch' )) {
00704 return 2;
00705 }
00706 if (function_exists( 'zend_shm_cache_fetch' )) {
00707 return 2;
00708 }
00709 return 1;
00710 }
00711
00717 protected function _getAdditionalCheck()
00718 {
00719 $sSelect = '';
00720 foreach ( $this->_aException as $sTable => $sColumn ) {
00721 $sSelect .= 'and ( t.TABLE_NAME != "'.$sTable.'" and c.COLUMN_NAME != "'.$sColumn.'" ) ';
00722 }
00723 return $sSelect;
00724 }
00725
00731 public function checkCollation()
00732 {
00733 $myConfig = $this->getConfig();
00734
00735 $aCollations = array();
00736 $sCollation = '';
00737
00738 $sSelect = 'select t.TABLE_NAME, c.COLUMN_NAME, c.COLLATION_NAME from INFORMATION_SCHEMA.tables t ' .
00739 'LEFT JOIN INFORMATION_SCHEMA.columns c ON t.TABLE_NAME = c.TABLE_NAME ' .
00740 'where t.TABLE_SCHEMA = "'.$myConfig->getConfigParam( 'dbName' ).'" ' .
00741 'and c.TABLE_SCHEMA = "'.$myConfig->getConfigParam( 'dbName' ).'" ' .
00742 'and c.COLUMN_NAME in ("'.implode('", "', $this->_aColumns).'") ' . $this->_getAdditionalCheck() .
00743 ' ORDER BY (t.TABLE_NAME = "oxarticles") DESC';
00744 $aRez = oxDb::getDb()->getAll($sSelect);
00745 foreach ( $aRez as $aRetTable ) {
00746 if ( !$sCollation ) {
00747 $sCollation = $aRetTable[2];
00748 } else {
00749 if ( $aRetTable[2] && $sCollation != $aRetTable[2]) {
00750 $aCollations[$aRetTable[0]][$aRetTable[1]] = $aRetTable[2];
00751 }
00752 }
00753 }
00754
00755 if ( $this->_blSysReqStatus === null ) {
00756 $this->_blSysReqStatus = true;
00757 }
00758 if ( count($aCollations) > 0 ) {
00759 $this->_blSysReqStatus = false;
00760 }
00761 return $aCollations;
00762 }
00763
00769 public function checkDatabaseCluster()
00770 {
00771 return 2;
00772 }
00773
00779 public function checkUnicodeSupport()
00780 {
00781 return (@preg_match('/\pL/u', 'a') == 1) ? 2 : 1;
00782 }
00783
00789 public function getSysReqStatus()
00790 {
00791 if ( $this->_blSysReqStatus == null ) {
00792 $this->_blSysReqStatus = true;
00793 $this->getSystemInfo();
00794 $this->checkCollation();
00795 }
00796 return $this->_blSysReqStatus;
00797 }
00798
00813 public function getSystemInfo()
00814 {
00815 $aSysInfo = array();
00816 $aRequiredModules = $this->getRequiredModules();
00817 $this->_blSysReqStatus = true;
00818 foreach ( $aRequiredModules as $sModule => $sGroup ) {
00819 if ( isset($aSysInfo[$sGroup]) && !$aSysInfo[$sGroup] ) {
00820 $aSysInfo[$sGroup] = array();
00821 }
00822 $iModuleState = $this->getModuleInfo( $sModule );
00823 $aSysInfo[$sGroup][$sModule] = $iModuleState;
00824 $this->_blSysReqStatus = $this->_blSysReqStatus && ( bool ) abs( $iModuleState );
00825 }
00826 return $aSysInfo;
00827 }
00828
00836 public function getModuleInfo( $sModule = null )
00837 {
00838 if ( $sModule ) {
00839 $iModStat = null;
00840 $sCheckFunction = "check".str_replace(" ", "", ucwords(str_replace("_", " ", $sModule)));
00841 $iModStat = $this->$sCheckFunction();
00842
00843 return $iModStat;
00844 }
00845 }
00846
00854 public function getReqInfoUrl( $sIdent)
00855 {
00856 $sUrl = $this->_sReqInfoUrl;
00857 $aInfoMap = $this->_aInfoMap;
00858
00859
00860 if ( isset( $aInfoMap[$sIdent] ) ) {
00861 $sUrl .= "#".$aInfoMap[$sIdent];
00862 }
00863
00864 return $sUrl;
00865 }
00866
00874 protected function _getBytes( $sBytes )
00875 {
00876 $sBytes = trim( $sBytes );
00877 $sLast = strtolower($sBytes[strlen($sBytes)-1]);
00878 switch( $sLast ) {
00879
00880 case 'g':
00881 $sBytes *= 1024;
00882 case 'm':
00883 $sBytes *= 1024;
00884 case 'k':
00885 $sBytes *= 1024;
00886 break;
00887 }
00888
00889 return $sBytes;
00890 }
00891
00902 protected function _checkTemplateBlock($sTemplate, $sBlockName)
00903 {
00904 $sTplFile = $this->getConfig()->getTemplatePath($sTemplate, false);
00905 if (!$sTplFile || !file_exists($sTplFile)) {
00906 return false;
00907 }
00908
00909 $sFile = file_get_contents($sTplFile);
00910 $sBlockNameQuoted = preg_quote($sBlockName, '/');
00911 return (bool)preg_match('/\[\{\s*block\s+name\s*=\s*([\'"])'.$sBlockNameQuoted.'\1\s*\}\]/is', $sFile);
00912 }
00913
00923 public function getMissingTemplateBlocks()
00924 {
00925 $oDb = oxDb::getDb( true );
00926 $aCache = array();
00927 $oConfig = $this->getConfig();
00928
00929 $sShpIdParam = $oDb->quote($oConfig->getShopId());
00930 $sSql = "select * from oxtplblocks where oxactive=1 and oxshopid=$sShpIdParam";
00931 $rs = $oDb->execute($sSql);
00932 $aRet = array();
00933 if ($rs != false && $rs->recordCount() > 0) {
00934 while (!$rs->EOF) {
00935 $blStatus = false;
00936 if (isset($aCache[$rs->fields['OXTEMPLATE']]) && isset($aCache[$rs->fields['OXTEMPLATE']][$rs->fields['OXBLOCKNAME']])) {
00937 $blStatus = $aCache[$rs->fields['OXTEMPLATE']][$rs->fields['OXBLOCKNAME']];
00938 } else {
00939 $blStatus = $this->_checkTemplateBlock($rs->fields['OXTEMPLATE'], $rs->fields['OXBLOCKNAME']);
00940 $aCache[$rs->fields['OXTEMPLATE']][$rs->fields['OXBLOCKNAME']] = $blStatus;
00941 }
00942
00943 if (!$blStatus) {
00944 $aRet[] = array(
00945 'module' => $rs->fields['OXMODULE'],
00946 'block' => $rs->fields['OXBLOCKNAME'],
00947 'template' => $rs->fields['OXTEMPLATE'],
00948 );
00949 }
00950 $rs->moveNext();
00951 }
00952 }
00953
00954 return $aRet;
00955 }
00956 }