<?php
/***************************************************************
*  Copyright notice
*
*  (c) 1999-2005 Kasper Skaarhoj (kasperYYYY@typo3.com)
*  (c) 2005-2006 Karsten Dambekalns <karsten@typo3.org>
*  (c) 2006 Chi Hoang <chibox@gmail.com>
*  All rights reserved
*
*  This script is part of the TYPO3 project. The TYPO3 project is
*  free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  The GNU General Public License can be found at
*  http://www.gnu.org/copyleft/gpl.html.
*  A copy is found in the textfile GPL.txt and important notices to the license
*  from the author is found in LICENSE.txt distributed with these scripts.
*
*
*  This script is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/

if (!defined ('PATH_tslib')) {
	define('PATH_tslib', '../../../sysext/cms/tslib/');
}

if (!defined ('PATH_txchlem')) {
	define('PATH_txchlem', t3lib_extMgm::extPath('ch_lightem'));
}

require_once(PATH_tslib.'class.tslib_content.php');
require_once(PATH_tslib.'class.tslib_pibase.php');
require_once(PATH_txchlem.'class.em_tslib_pibase.php');

if(t3lib_div::int_from_ver(TYPO3_version) <= t3lib_div::int_from_ver('4.0.0')) {	
	require_once(PATH_txchlem.'class.em_terconnection.php');
	require_once(PATH_txchlem.'class.em_xmlhandler.php');
}


class ux_SC_mod_tools_em_index extends SC_mod_tools_em_index {

    var $defaultStatesString = 'alpha,beta,stable,experimental,test,obsolete';
    var $defaultCatString = ',be,module,fe,plugin,misc,services,templates,example,doc';
    
    var $order = array ('DESC' => 'ASC', 'ASC' => 'DESC');    

    /**
	 * Simple function to replicate PHP5 behaviour
	 */
	function microtime_float()
	{
	    list($usec, $sec) = explode(" ", microtime());
	    return ((float)$usec + (float)$sec);
	}

    function memory_get_usage() {
       //If its Windows
       //Tested on Win XP Pro SP2. Should work on Win 2003 Server too
       //Doesn't work for 2000
       //If you need it to work for 2000 look at http://us2.php.net/manual/en/function.memory-get-usage.php#54642
       if ( substr(PHP_OS,0,3) == 'WIN') {
               $output = array();
               exec( 'tasklist /FI "PID eq ' . getmypid() . '" /FO LIST', $output );      
               return preg_replace( '/[\D]/', '', $output[5] ) * 1024;           
        } else {
           //We now assume the OS is UNIX
           //Tested on Mac OS X 10.4.6 and Linux Red Hat Enterprise 4
           //This should work on most UNIX systems
           $pid = getmypid();
           exec("ps -eo user,vsz,rss,start,time,pid | grep $pid", $output);
           $output= explode(" ", $output[0]);
           //rss is given in 1024 byte units
           return $output;
       }
    }
    
	/*********************************
	*
	* Standard module initialization
	*
	*********************************/

        /**
         * Standard init function of a module.
         *
         * @return      void
         */
        function init() {
                global $BE_USER,$LANG,$BACK_PATH,$TYPO3_CONF_VARS;

                // Setting paths of install scopes:
                $this->typePaths = Array (
                        'S' => TYPO3_mainDir.'sysext/',
                        'G' => TYPO3_mainDir.'ext/',
                        'L' => 'typo3conf/ext/'
                );
                $this->typeBackPaths = Array (
                        'S' => '../../../',
                        'G' => '../../../',
                        'L' => '../../../../'.TYPO3_mainDir
                );

                // Setting module configuration:
                $this->MCONF = $GLOBALS['MCONF'];

                // Setting GPvars:
                $this->CMD = t3lib_div::_GP('CMD');
                $this->lookUpStr = trim(t3lib_div::_GP('_lookUp'));
                $this->listRemote = t3lib_div::_GP('ter_connect');
                $this->listRemote_search = trim(t3lib_div::_GP('ter_search'));

                        // Configure menu
                $this->menuConfig();

                        // Setting internal static:
                if ($TYPO3_CONF_VARS['EXT']['allowSystemInstall'])      $this->systemInstall = 1;
                $this->requiredExt = t3lib_div::trimExplode(',',$TYPO3_CONF_VARS['EXT']['requiredExt'],1);

                        // Initialize helper object
                $this->terConnection = t3lib_div::makeInstance('SC_mod_tools_em_terconnection');
                $this->terConnection->emObj =& $this;
                $this->terConnection->wsdlURL = $TYPO3_CONF_VARS['EXT']['em_wsdlURL'];
                $this->xmlhandler = t3lib_div::makeInstance('SC_mod_tools_em_xmlhandler');
                $this->xmlhandler->emObj =& $this;
		
				if(t3lib_div::int_from_ver(TYPO3_version) < t3lib_div::int_from_ver('4.2.0')) {
		
						// Initialize Document Template object:
					$this->doc = t3lib_div::makeInstance('noDoc');
					$this->doc->backPath = $BACK_PATH;
					$this->doc->docType = 'xhtml_trans';
			
						// JavaScript
					$this->doc->JScode = $this->doc->wrapScriptTags('
						script_ended = 0;
						function jumpToUrl(URL) {       //
							window.location.href = URL;
						}
					');
					$this->doc->form = '<form action="index.php" method="post" name="pageform">';
		
				} else {
		
						// Initialize Document Template object:
					$this->doc = t3lib_div::makeInstance('template');
					$this->doc->backPath = $BACK_PATH;
					$this->doc->setModuleTemplate('templates/em_index.html');
					$this->doc->docType='xhtml_trans';
			
						// JavaScript
					$this->doc->JScode = $this->doc->wrapScriptTags('
						script_ended = 0;
						function jumpToUrl(URL)	{	//
							window.location.href = URL;
						}
					');
			
						// Reload left frame menu
					if ($this->CMD['refreshMenu']) {
						$this->doc->JScode .= $this->doc->wrapScriptTags('
							if(top.refreshMenu) {
								top.refreshMenu();
							} else {
								top.TYPO3ModuleMenu.refreshMenu();
							}
						');
					}
		
				}

                // Descriptions:
                $this->descrTable = '_MOD_'.$this->MCONF['name'];
                if ($BE_USER->uc['edit_showFieldHelp']) {
                        $LANG->loadSingleTableDescription($this->descrTable);
                }

                // Setting username/password etc. for upload-user:
                $this->fe_user['username'] = $this->MOD_SETTINGS['fe_u'];
                $this->fe_user['password'] = $this->MOD_SETTINGS['fe_p'];
                parent::init();
                $this->handleExternalFunctionValue('singleDetails');
                
                
			if(t3lib_div::int_from_ver(TYPO3_version) >= t3lib_div::int_from_ver('4.2.0')) {
				/**
				* This function is a copy of the same function in t3lib_SCbase with one modification:
				* In contrast to t3lib_SCbase::handleExternalFunctionValue() this function merges the $this->extClassConf array
				* instead of overwriting it. That was necessary for including the Kickstarter as a submodule into the 'singleDetails'
				* selectorbox as well as in the main 'function' selectorbox.
				*
				* @param	string		Mod-setting array key
				* @param	string		Mod setting value, overriding the one in the key
				* @return	void
				* @see t3lib_SCbase::handleExternalFunctionValue()
				*/
				function handleExternalFunctionValue($MM_key='function', $MS_value=NULL)	{
					$MS_value = is_null($MS_value) ? $this->MOD_SETTINGS[$MM_key] : $MS_value;
					$externalItems = $this->getExternalItemConfig($this->MCONF['name'],$MM_key,$MS_value);
					if (is_array($externalItems))	$this->extClassConf = array_merge($externalItems,is_array($this->extClassConf)?$this->extClassConf:array());
					if (is_array($this->extClassConf) && $this->extClassConf['path'])	{
						$this->include_once[]=$this->extClassConf['path'];
					}
				}
			}

        }



	/**
	 * Configuration of which mod-menu items can be used
	 *
	 * @return	void
	 */
	function menuConfig()	{
		global $BE_USER, $TYPO3_CONF_VARS;

		// MENU-ITEMS:
		$this->MOD_MENU = array(
			'function' => array(
				0 => 'Loaded extensions',
				1 => 'Install extensions',
				2 => 'Import extensions',
				4 => 'Translation handling',
				3 => 'Settings',
			),
            'cat' => array (
                'all' => 'All',
                'be' => 'Backend',
                'module' => 'Backend Modules',
                'fe' => 'Frontend',
                'plugin' => 'Frontend Plugins',
                'misc' => 'Miscellaneous',
                'services' => 'Services',
                'templates' => 'Templates',
                'example' => 'Examples',
                'doc' => 'Documentation',
                '' => 'Noname',
                'fab74.de' => "fab74.de extensions",
                'lib' => "library",
                'fe,be' => "fe,be",
                'ICE Pack - Individual Content' => "ICE Pack - Individual Content",
                'ABC T3Pack.org' => "ABC T3Pack.org",
			),
            'state' => Array (
                'all' => 'All',
                'alpha' => 'Alpha',
                'beta' => 'Beta',
                'stable' => 'Stable',
                'experimental' => 'Experimental',
                'test' => 'Test',
                'obsolete' => 'Obsolete',
            ),
			'listOrder' => array(
				'cat' => 'Category',
                'author_company' => 'Author',
				'state' => 'State',
			),
			'display_details' => array(
                                        1 => 'Details',
                                        0 => 'Description',
                                        2 => 'More details',
                        
                                        3 => 'Technical (takes time!)',
                                        4 => 'Validating (takes time!)',
                                        5 => 'Changed? (takes time!)',
			),
			'display_shy' => '',
			'display_own' => '',
			'display_unsupported' => '',
			'display_obsolete' => '',
			'display_unchecked' => '',

			'singleDetails' => array(
				'info' => 'Information',
				'edit' => 'Edit files',
				'backup' => 'Backup/Delete',
				'dump' => 'Dump DB',
				'upload' => 'Upload to TER',
				'updateModule' => 'UPDATE!',
			),
			'fe_u' => '',
			'fe_p' => '',

			'mirrorListURL' => '',
			'rep_url' => '',
			'extMirrors' => '',
			'selectedMirror' => '',

			'selectedLanguages' => ''
		);

		if(t3lib_div::int_from_ver(TYPO3_version) <= t3lib_div::int_from_ver('4.0.0')) {
			$this->MOD_MENU['function'] = array(
				0 => 'Loaded extensions',
				1 => 'Install extensions',
				2 => 'Import extensions',
				3 => 'Settings',
			);				
		}
		
		$this->MOD_MENU['singleDetails'] = $this->mergeExternalItems($this->MCONF['name'],'singleDetails',$this->MOD_MENU['singleDetails']);

		// page/be_user TSconfig settings and blinding of menu-items
		if (!$BE_USER->getTSConfigVal('mod.'.$this->MCONF['name'].'.allowTVlisting'))	{
			unset($this->MOD_MENU['display_details'][3]);
			unset($this->MOD_MENU['display_details'][4]);
			unset($this->MOD_MENU['display_details'][5]);
		}

		// CLEANSE SETTINGS
		$this->MOD_SETTINGS = t3lib_BEfunc::getModuleData($this->MOD_MENU, t3lib_div::_GP('SET'), $this->MCONF['name']);

		if ($this->MOD_SETTINGS['function']==2)	{
			// If listing from online repository, certain items are removed though:
			unset($this->MOD_MENU['listOrder']['type']);
			unset($this->MOD_MENU['display_details'][2]);
			unset($this->MOD_MENU['display_details'][3]);
			unset($this->MOD_MENU['display_details'][4]);
			unset($this->MOD_MENU['display_details'][5]);
			$this->MOD_SETTINGS = t3lib_BEfunc::getModuleData($this->MOD_MENU, t3lib_div::_GP('SET'), $this->MCONF['name']);
		}
        
        	t3lib_SCbase::menuConfig();
	}
    


	/**
	 * Main function for Extension Manager module.
	 *
	 * @return	void
	 */
	function main()	{
		global $BE_USER,$LANG,$TYPO3_CONF_VARS;

		if (empty($this->MOD_SETTINGS['mirrorListURL'])) $this->MOD_SETTINGS['mirrorListURL'] = $TYPO3_CONF_VARS['EXT']['em_mirrorListURL'];      
        
		// Starting page:
		$this->content.=$this->doc->startPage('Extension Manager');
		$this->content.=$this->doc->header('Extension Manager');
		$this->content.=$this->doc->spacer(5);
		$this->content.= '<script>
					/*
					Highlight Link script
					By JavaScript Kit (http://javascriptkit.com)
					Over 400+ free scripts here!
					Above notice MUST stay entact for use
					*/

					function highlight(which,color){
					if (document.all||document.getElementById)
						which.style.backgroundColor=color
					}
				</script>';
	
		// Commands given which is executed regardless of main menu setting:
		if ($this->CMD['showExt'])	{	// Show details for a single extension
			$this->showExtDetails($this->CMD['showExt']);
		} elseif ($this->CMD['requestInstallExtensions'])	{	// Show details for a single extension
				$this->requestInstallExtensions($this->CMD['requestInstallExtensions']);
		} elseif ($this->CMD['importExt'] || $this->CMD['uploadExt'])	{	// Imports an extension from online rep.
			$err = $this->importExtFromRep($this->CMD['importExt'],$this->CMD['extVersion'],$this->CMD['loc'],$this->CMD['uploadExt']);
			if ($err)	{
				$this->content.=$this->doc->section('',$GLOBALS['TBE_TEMPLATE']->rfw($err));
			}
			if(!$err && $this->CMD['importExt']) {
				$this->installTranslationsForExtension($this->CMD['importExt'], $this->getMirrorURL());
			}
		} elseif ($this->CMD['importExtInfo'])	{	// Gets detailed information of an extension from online rep.
			$this->importExtInfo($this->CMD['importExtInfo'],$this->CMD['extVersion']);
		} else {	// No command - we show what the menu setting tells us:
	
			if(t3lib_div::int_from_ver(TYPO3_version) < t3lib_div::int_from_ver('4.2.0')) {
				$menu = $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.menu').' '.
					t3lib_BEfunc::getFuncMenu(0,'SET[function]',$this->MOD_SETTINGS['function'],$this->MOD_MENU['function']);
			}
	
			if (t3lib_div::inList('2',$this->MOD_SETTINGS['function']) && t3lib_div::inList('state',$this->MOD_SETTINGS['listOrder']))	{
				$menu.='Category:&nbsp;&nbsp;'.t3lib_BEfunc::getFuncMenu(0,'SET[state]',$this->MOD_SETTINGS['state'],$this->MOD_MENU['state']).
				'&nbsp;&nbsp;Group by:&nbsp;'.t3lib_BEfunc::getFuncMenu(0,'SET[listOrder]',$this->MOD_SETTINGS['listOrder'],$this->MOD_MENU['listOrder']).
				'&nbsp;&nbsp;Show:&nbsp;'.t3lib_BEfunc::getFuncMenu(0,'SET[display_details]',$this->MOD_SETTINGS['display_details'],$this->MOD_MENU['display_details']).'<br />';
			}
	
			if (t3lib_div::inList('2',$this->MOD_SETTINGS['function']) && t3lib_div::inList('cat',$this->MOD_SETTINGS['listOrder'])) {
				$menu.='Category:&nbsp;&nbsp;'.t3lib_BEfunc::getFuncMenu(0,'SET[cat]',$this->MOD_SETTINGS['cat'],$this->MOD_MENU['cat']).
				'&nbsp;&nbsp;Group by:&nbsp;'.t3lib_BEfunc::getFuncMenu(0,'SET[listOrder]',$this->MOD_SETTINGS['listOrder'],$this->MOD_MENU['listOrder']).
				'&nbsp;&nbsp;Show:&nbsp;'.t3lib_BEfunc::getFuncMenu(0,'SET[display_details]',$this->MOD_SETTINGS['display_details'],$this->MOD_MENU['display_details']).'<br />'; 
			}
	
			if (t3lib_div::inList('2',$this->MOD_SETTINGS['function']) && t3lib_div::inList('author_company',$this->MOD_SETTINGS['listOrder'])) {
				$menu.='Group by:&nbsp;'.t3lib_BEfunc::getFuncMenu(0,'SET[listOrder]',$this->MOD_SETTINGS['listOrder'],$this->MOD_MENU['listOrder']).
					'&nbsp;&nbsp;Show:&nbsp;'.t3lib_BEfunc::getFuncMenu(0,'SET[display_details]',$this->MOD_SETTINGS['display_details'],$this->MOD_MENU['display_details']).'<br />';
			}
		
			if (t3lib_div::inList('0,1',$this->MOD_SETTINGS['function']))	{
				$menu.='Group by:&nbsp;'.t3lib_BEfunc::getFuncMenu(0,'SET[listOrder]',$this->MOD_SETTINGS['listOrder'],$this->MOD_MENU['listOrder']).
				'&nbsp;&nbsp;Show:&nbsp;'.t3lib_BEfunc::getFuncMenu(0,'SET[display_details]',$this->MOD_SETTINGS['display_details'],$this->MOD_MENU['display_details']).'<br />';
			}
			if (t3lib_div::inList('0,1',$this->MOD_SETTINGS['function']))	{
				$menu.='Display shy extensions:&nbsp;&nbsp;'.t3lib_BEfunc::getFuncCheck(0,'SET[display_shy]',$this->MOD_SETTINGS['display_shy']);
			}
			if (t3lib_div::inList('2',$this->MOD_SETTINGS['function']) && strlen($this->fe_user['username']))	{
				$menu.='Only my extensions:&nbsp;&nbsp;'.t3lib_BEfunc::getFuncCheck(0,'SET[display_own]',$this->MOD_SETTINGS['display_own']);
			}
			if (t3lib_div::inList('0,1,2',$this->MOD_SETTINGS['function']))	{
				$menu.='&nbsp;&nbsp;Show obsolete:&nbsp;&nbsp;'.t3lib_BEfunc::getFuncCheck(0,'SET[display_obsolete]',$this->MOD_SETTINGS['display_obsolete']);
			}
	
	
			if(t3lib_div::int_from_ver(TYPO3_version) < t3lib_div::int_from_ver('4.2.0')) {
				$this->content.=$this->doc->section('','<span class="nobr">'.$menu.'</span>');
				$this->content.=$this->doc->spacer(10);
			} else {
				$this->content.=$this->doc->section('','<form action="index.php" method="post" name="pageform"><span class="nobr">'.$menu.'</span></form>');
				$this->content.=$this->doc->spacer(10);
			}

			switch((string)$this->MOD_SETTINGS['function'])	{
				case '0':
					// Lists loaded (installed) extensions
					$this->extensionList_loaded();
					break;
				case '1':
					// Lists the installed (available) extensions
					$this->extensionList_installed();
					break;
				case '2':
					// Lists the extensions available from online rep.
					$this->extensionList_import();
					break;
				case '3':
					// Shows the settings screen
					$this->alterSettings();
					break;
				case '4':
					// Allows to set the translation preferences and check the status
					$this->translationHandling();
					break;
				default:                    
					$this->extObjContent();
					break;
			}
		}

		if(t3lib_div::int_from_ver(TYPO3_version) >= t3lib_div::int_from_ver('4.2.0')) {
			// closing any form?
			$formTags = substr_count($this->content, '<form') + substr_count($this->content, '</form');
			if ($formTags % 2 > 0) {
				$this->content .= '</form>';
			}
	
				// Setting up the buttons and markers for docheader
			$docHeaderButtons = $this->getButtons();
			$markers = array(
				'CSH' => $docHeaderButtons['csh'],
				'FUNC_MENU' => $this->getFuncMenu(),
				'CONTENT' => $this->content
			);
	
				// Build the <body> for the module
			$this->content = $this->doc->startPage('Extension Manager');
			$this->content.= $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $markers);
			$this->content.= $this->doc->endPage();
			$this->content = $this->doc->insertStylesAndJS($this->content);
		}

		// Shortcuts:
		if ($BE_USER->mayMakeShortcut())	{
			$this->content.=$this->doc->spacer(20).$this->doc->section('',$this->doc->makeShortcutIcon('CMD','function',$this->MCONF['name']));
		}
	}
   
     /**
     * Parses content of mirrors.xml into a suitable array
     *
     * @param       string          $string: XML data to parse
     * @return      string          HTLML output informing about result
     */
    function parseMirrorsXML($string) {
            global $TYPO3_CONF_VARS;

            // Create parser:
            $parser = xml_parser_create();
            $vals = array();
            $index = array();

            xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
            xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0);

            if ((double)phpversion()>=5)    {
                    $preg_result = array();
                    preg_match('/^[[:space:]]*<\?xml[^>]*encoding[[:space:]]*=[[:space:]]*"([^"]*)"/',substr($string,0,200),$preg_result);
                    $theCharset = $preg_result[1] ? $preg_result[1] : ($TYPO3_CONF_VARS['BE']['forceCharset'] ? $TYPO3_CONF_VARS['BE']['forceCharset'] : 'iso-8859-1');
                    xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $theCharset);  // us-ascii / utf-8 / iso-8859-1
            }

            // Parse content:
            xml_parse_into_struct($parser, $string, $vals, $index);

            // If error, return error message:
            if (xml_get_error_code($parser))        {
                    $line = xml_get_current_line_number($parser);
                    $error = xml_error_string(xml_get_error_code($parser));
                    xml_parser_free($parser);
                    return 'Error in XML parser while decoding mirrors XML file. Line '.$line.': '.$error;
            } else  {
                    // Init vars:
                    $stack = array(array());
                    $stacktop = 0;
                    $mirrornumber = 0;
                    $current=array();
                    $tagName = '';
                    $documentTag = '';

                    // Traverse the parsed XML structure:
                    foreach($vals as $val) {

                            // First, process the tag-name (which is used in both cases, whether "complete" or "close")
                            $tagName = ($val['tag']=='mirror' && $val['type']=='open') ? '__plh' : $val['tag'];
                            if (!$documentTag)      $documentTag = $tagName;

                            // Setting tag-values, manage stack:
                            switch($val['type'])    {
                                    case 'open':            // If open tag it means there is an array stored in sub-elements. Therefore increase the stackpointer and reset the accumulation array:
                                            $current[$tagName] = array();   // Setting blank place holder
                                            $stack[$stacktop++] = $current;
                                            $current = array();
                                            break;
                                    case 'close':   // If the tag is "close" then it is an array which is closing and we decrease the stack pointer.
                                    $oldCurrent = $current;
                                    $current = $stack[--$stacktop];
                                    end($current);  // Going to the end of array to get placeholder key, key($current), and fill in array next:
                                    if($tagName=='mirror') {
                                            unset($current['__plh']);
                                            $current[$oldCurrent['host']] = $oldCurrent;
                                    } else {
                                            $current[key($current)] = $oldCurrent;
                                    }
                                    unset($oldCurrent);
                                    break;
                                    case 'complete':        // If "complete", then it's a value. If the attribute "base64" is set, then decode the value, otherwise just set it.
                                    $current[$tagName] = (string)$val['value']; // Had to cast it as a string - otherwise it would be evaluate false if tested with isset()!!
                                    break;
                            }
                    }
                    return $current[$tagName];
            }
    }
    
    /**
     * Returns the base URL for the slected or a random mirror.
     *
     * @return      string          The URL for the selected or a random mirror
     */
    function getMirrorURL() {
            if(strlen($this->MOD_SETTINGS['rep_url'])) return $this->MOD_SETTINGS['rep_url'];

            $mirrors = unserialize($this->MOD_SETTINGS['extMirrors']);
            if(!is_array($mirrors)) {
                    $this->fetchMetaData('mirrors');
                    $mirrors = unserialize($this->MOD_SETTINGS['extMirrors']);
                    if(!is_array($mirrors)) return false;
            }
            if($this->MOD_SETTINGS['selectedMirror']=='') {
                    srand((float) microtime() * 10000000); // not needed after PHP 4.2.0...
                    $rand = array_rand($mirrors);
                    $url = 'http://'.$mirrors[$rand]['host'].$mirrors[$rand]['path'];
            }
            else {
                    $url = 'http://'.$mirrors[$this->MOD_SETTINGS['selectedMirror']]['host'].$mirrors[$this->MOD_SETTINGS['selectedMirror']]['path'];
            }

            return $url;
    }


        
	/**
	 * Imports an extensions from the online repository
	 * NOTICE: in version 4.0 this changed from "importExtFromRep_old($extRepUid,$loc,$uploadFlag=0,$directInput='',$recentTranslations=0,$incManual=0,$dontDelete=0)"
	 *
	 * @param	string		Extension key
	 * @param	string		Version
	 * @param	string		Install scope: "L" or "G" or "S"
	 * @param	boolean		If true, extension is uploaded as file
	 * @param	boolean		If true, extension directory+files will not be deleted before writing the new ones. That way custom files stored in the extension folder will be kept.
	 * @param	array		Direct input array (like from kickstarter)
	 * @return	string		Return false on success, returns error message if error.
	 */
	function importExtFromRep($extKey,$version,$loc,$uploadFlag=0,$dontDelete=0,$directInput='')	{

		$uploadSucceed = false;
		$uploadedTempFile = '';
		if (is_array($directInput))	{
			$fetchData = array($directInput,'');
			$loc = ($loc==='G'||$loc==='S') ? $loc : 'L';
		} elseif ($uploadFlag)	{
			if (($uploadedTempFile = $this->CMD['alreadyUploaded']) || $_FILES['upload_ext_file']['tmp_name'])	{

					// Read uploaded file:
				if (!$uploadedTempFile)	{
					if (!is_uploaded_file($_FILES['upload_ext_file']['tmp_name'])) {
 						t3lib_div::sysLog('Possible file upload attack: '.$_FILES['upload_ext_file']['tmp_name'], 'Extension Manager', 3);

						return 'File was not uploaded?!?';
					}

					$uploadedTempFile = t3lib_div::upload_to_tempfile($_FILES['upload_ext_file']['tmp_name']);
				}
				$fileContent = t3lib_div::getUrl($uploadedTempFile);

				if (!$fileContent)	return 'File is empty!';

					// Decode file data:
				$fetchData = $this->terConnection->decodeExchangeData($fileContent);

				if (is_array($fetchData))	{
					$extKey = $fetchData[0]['extKey'];
					if ($extKey)	{
						if (!$this->CMD['uploadOverwrite'])	{
							$loc = ($loc==='G'||$loc==='S') ? $loc : 'L';
							$comingExtPath = PATH_site.$this->typePaths[$loc].$extKey.'/';
							if (@is_dir($comingExtPath))	{
								return 'Extension was already present in "'.$comingExtPath.'" - and the overwrite flag was not set! So nothing done...';
							}	// ... else go on, install...
						}	// ... else go on, install...
					} else return 'No extension key in file. Strange...';
				} else return 'Wrong file format. No data recognized, '.$fetchData;
			} else return 'No file uploaded! Probably the file was too large for PHPs internal limit for uploadable files.';
		} else {       
   
            $this->xmlhandler->extensionsXML = array();
              
            // Make listing query, pass query to SQL database:
           $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*','tx_chlightem_extension','tx_chlightem_extension.extkey="'.$extKey.'"');
            
            while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
                $this->xmlhandler->extensionsXML[$row['extkey']]['extkey']=$row['extkey'];
                $this->xmlhandler->extensionsXML[$row['extkey']]['uid']=$row['uid'];
                $this->xmlhandler->extensionsXML[$row['extkey']]['downloadcounter']=$row['downloadcounter'];
                $this->xmlhandler->extensionsXML[$row['extkey']]['icon']=$row['icon'];
                $this->xmlhandler->extensionsXML[$row['extkey']]['type']=$row['type'];            
            }         
            mysql_free_result($res);
             
            foreach ($this->xmlhandler->extensionsXML as $k => $v) {
        
                $res = $GLOBALS['TYPO3_DB']->exec_SELECT_mm_query('*','tx_chlightem_extension','tx_chlightem_mm','tx_chlightem_version','AND tx_chlightem_extension.uid='.$v['uid']);
                                    
                while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {                    
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['version']=$row['version'];
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['title']=$row['title'];
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['description']=$row['description'];
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['state']=$row['extstate'];
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['reviewstate']=$row['reviewstate'];
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['lastuploaddate']=$row['lastuploaddate'];
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['constraints']=unserialize($row['dependencies']);
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['author']=$row['authorname'];
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['author_email']=$row['authoremail'];
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['author_company']=$row['authorcompany'];
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['ownerusername']=$row['ownerusername'];
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['t3xfilemd5']=$row['t3xfilemd5'];
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['category']=$row['category'];
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['uploadcomment']=$row['uploadcomment'];              
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['downloadcounter']=$row['downloadcounter'];                           
                }
            }
            mysql_free_result($res);
            
                // Fetch extension from TER:
            if(!strlen($version)) {
                $versions = array_keys($this->xmlhandler->extensionsXML[$extKey]['versions']);
                $version = ($version == '') ? end($versions) : $version;
            };  
            
			$fetchData = $this->terConnection->fetchExtension($extKey, $version, $this->xmlhandler->extensionsXML[$extKey]['versions'][$version]['EM_CONF']['t3xfilemd5'], $this->getMirrorURL());
		}

		// At this point the extension data should be present; so we want to write it to disc:
		if ($this->importAsType($loc))	{
			if (is_array($fetchData))	{	// There was some data successfully transferred
				if ($fetchData[0]['extKey'] && is_array($fetchData[0]['FILES']))	{
					$extKey = $fetchData[0]['extKey'];
					if(!isset($fetchData[0]['EM_CONF']['constraints'])) $fetchData[0]['EM_CONF']['constraints'] = $this->xmlhandler->extensionsXML[$extKey]['versions'][$version]['EM_CONF']['dependencies'];
					$EM_CONF = $this->fixEMCONF($fetchData[0]['EM_CONF']);
					if (!$EM_CONF['lockType'] || !strcmp($EM_CONF['lockType'],$loc))	{
							// check dependencies, act accordingly if ext is loaded
						list($instExtInfo,)=$this->getInstalledExtensions();
						$depStatus = $this->checkDependencies($extKey, $EM_CONF, $instExtInfo);
						if(t3lib_extMgm::isLoaded($extKey) && !$depStatus['returnCode']) {
							$this->content .= $depStatus['html'];
						} else {
							$res = $this->clearAndMakeExtensionDir($fetchData[0],$loc,$dontDelete);
							if (is_array($res))	{
								$extDirPath = trim($res[0]);
								if ($extDirPath && @is_dir($extDirPath) && substr($extDirPath,-1)=='/')	{

									$emConfFile = $this->construct_ext_emconf_file($extKey,$EM_CONF);
									$dirs = $this->extractDirsFromFileList(array_keys($fetchData[0]['FILES']));

									$res = $this->createDirsInPath($dirs,$extDirPath);
									if (!$res)	{
										$writeFiles = $fetchData[0]['FILES'];
										$writeFiles['ext_emconf.php']['content'] = $emConfFile;
										$writeFiles['ext_emconf.php']['content_md5'] = md5($emConfFile);

											// Write files:
										foreach($writeFiles as $theFile => $fileData)	{
											t3lib_div::writeFile($extDirPath.$theFile,$fileData['content']);
											if (!@is_file($extDirPath.$theFile))	{
												$content.='Error: File "'.$extDirPath.$theFile.'" could not be created!!!<br />';
											} elseif (md5(t3lib_div::getUrl($extDirPath.$theFile)) != $fileData['content_md5']) {
												$content.='Error: File "'.$extDirPath.$theFile.'" MD5 was different from the original files MD5 - so the file is corrupted!<br />';
											}
										}

											// No content, no errors. Create success output here:
										if (!$content)	{
											$content='SUCCESS: '.$extDirPath.'<br />';

												// Fix TYPO3_MOD_PATH for backend modules in extension:
											$modules = t3lib_div::trimExplode(',',$EM_CONF['module'],1);
											if (count($modules))	{
												foreach($modules as $mD)	{
													$confFileName = $extDirPath.$mD.'/conf.php';
													if (@is_file($confFileName))	{
														$content.= $this->writeTYPO3_MOD_PATH($confFileName,$loc,$extKey.'/'.$mD.'/').'<br />';
													} else $content.='Error: Couldn\'t find "'.$confFileName.'"<br />';
												}
											}
												// NOTICE: I used two hours trying to find out why a script, ext_emconf.php, written twice and in between included by PHP did not update correct the second time. Probably something with PHP-A cache and mtime-stamps.
												// But this order of the code works.... (using the empty Array with type, EMCONF and files hereunder).

												// Writing to ext_emconf.php:
											$sEMD5A = $this->serverExtensionMD5Array($extKey,array('type' => $loc, 'EM_CONF' => array(), 'files' => array()));
											$EM_CONF['_md5_values_when_last_written'] = serialize($sEMD5A);
											$emConfFile = $this->construct_ext_emconf_file($extKey,$EM_CONF);
											t3lib_div::writeFile($extDirPath.'ext_emconf.php',$emConfFile);

											$content.='ext_emconf.php: '.$extDirPath.'ext_emconf.php<br />';
											$content.='Type: '.$loc.'<br />';

												// Remove cache files:
											if (t3lib_extMgm::isLoaded($extKey))	{
												if ($this->removeCacheFiles())	{
													$content.='Cache-files are removed and will be re-written upon next hit<br />';
												}

												list($new_list)=$this->getInstalledExtensions();
												$content.=$this->updatesForm($extKey,$new_list[$extKey],1,'index.php?CMD[showExt]='.$extKey.'&SET[singleDetails]=info');
											}

												// Install / Uninstall:
											if(!$this->CMD['standAlone']) {
												$content = '<a href="index.php" class="typo3-goBack"><img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],'gfx/goback.gif','width="14" height="14"').' alt="" /> Go back</a><br />'.$content;
												$content.='<h3>Install / Uninstall Extension:</h3>';
												$content.= $new_list[$extKey] ?
													'<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[remove]=1&CMD[clrCmd]=1&SET[singleDetails]=info').'">'.$this->removeButton().' Uninstall extension</a>' :
													'<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[load]=1&CMD[clrCmd]=1&SET[singleDetails]=info').'">'.$this->installButton().' Install extension</a>';
											} else {
												$content = 'Extension has been imported.<br /><br /><a href="javascript:opener.top.content.document.forms[0].submit();window.close();">Close window and recheck dependencies</a>';
											}

										}
									} else $content = $res;
								} else $content = 'Error: The extension path "'.$extDirPath.'" was different than expected...';
							} else $content = $res;
						}
					} else $content = 'Error: The extension can only be installed in the path '.$this->typePaths[$EM_CONF['lockType']].' (lockType='.$EM_CONF['lockType'].')';
				} else $content = 'Error: No extension key!!! Why? - nobody knows... (Or no files in the file-array...)';
			}  else $content = 'Error: The datatransfer did not succeed. '.$fetchData;
		}  else $content = 'Error: Installation is not allowed in this path ('.$this->typePaths[$loc].')';

		$this->content.=$this->doc->section('Extension import results',$content,0,1);

		return false;
	}
    
	/**
	 * Returns detailed info about an extension in the online repository
	 *
	 * @param	string		Extension repository uid + optional "private key": [uid]-[key].
	 * @param	[type]		$version: ...
	 * @return	void
	 */
	function importExtInfo($extKey, $version='')	{

		if(t3lib_div::int_from_ver(TYPO3_version) < t3lib_div::int_from_ver('4.2.0')) {
				// "Go back" link
			$content = '<a href="index.php" class="typo3-goBack"><img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],'gfx/goback.gif','width="14" height="14"').' alt="" /> Go back</a>';
			$this->content.= $this->doc->section('',$content);
			$content = '';
  		} else {
			$content = '<form action="index.php" method="post" name="pageform">';
		}

        $this->xmlhandler->extensionsXML = array();
          
        // Make listing query, pass query to SQL database:
       $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*','tx_chlightem_extension','tx_chlightem_extension.extkey="'.$extKey.'"');
        
        while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
            $this->xmlhandler->extensionsXML[$row['extkey']]['extkey']=$row['extkey'];
            $this->xmlhandler->extensionsXML[$row['extkey']]['uid']=$row['uid'];
            $this->xmlhandler->extensionsXML[$row['extkey']]['downloadcounter']=$row['downloadcounter'];
            $this->xmlhandler->extensionsXML[$row['extkey']]['icon']=$row['icon'];
            $this->xmlhandler->extensionsXML[$row['extkey']]['type']=$row['type'];            
        }         
        mysql_free_result($res);
         
        foreach ($this->xmlhandler->extensionsXML as $k => $v) {
    
            $res = $GLOBALS['TYPO3_DB']->exec_SELECT_mm_query('*','tx_chlightem_extension','tx_chlightem_mm','tx_chlightem_version','AND tx_chlightem_extension.uid='.$v['uid']);
                                
            while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {                    
                $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['version']=$row['version'];
                $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['title']=$row['title'];
                $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['description']=$row['description'];
                $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['state']=$row['extstate'];
                $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['reviewstate']=$row['reviewstate'];
                $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['lastuploaddate']=$row['lastuploaddate'];
                $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['constraints']=unserialize($row['dependencies']);
                $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['author']=$row['authorname'];
                $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['author_email']=$row['authoremail'];
                $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['author_company']=$row['authorcompany'];
                $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['ownerusername']=$row['ownerusername'];
                $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['t3xfilemd5']=$row['t3xfilemd5'];
                $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['category']=$row['category'];
                $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['uploadcomment']=$row['uploadcomment'];              
                $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['downloadcounter']=$row['downloadcounter'];                           
            }
        }
        mysql_free_result($res);
         
		$versions = array_keys($this->xmlhandler->extensionsXML[$extKey]['versions']);
		$version = ($version == '') ? end($versions) : $version;

		$opt = array();
		foreach(array_keys($this->xmlhandler->extensionsXML[$extKey]['versions']) as $ver)	{
			$opt[]='<option value="'.$ver.'"'.(($version == $ver) ? ' selected="selected"' : '').'>'.$ver.'</option>';
		}

			// "Select version" box:
		$onClick = 'window.location.href=\'index.php?CMD[importExtInfo]='.$extKey.'&CMD[extVersion]=\'+document.pageform.extVersion.options[document.pageform.extVersion.selectedIndex].value; return false;';
		$select='<select name="extVersion">'.implode('',$opt).'</select> <input type="submit" value="Load details" onclick="'.htmlspecialchars($onClick).'" /> or<br /><br />';

		if ($this->importAtAll())	{
			$onClick = '
					window.location.href=\'index.php?CMD[importExt]='.$extKey.'\'
						+\'&CMD[extVersion]=\'+document.pageform.extVersion.options[document.pageform.extVersion.selectedIndex].value
						+\'&CMD[loc]=\'+document.pageform.loc.options[document.pageform.loc.selectedIndex].value;
						return false;';
			$select.='
				<input type="submit" value="Import/Update" onclick="'.htmlspecialchars($onClick).'"> to:
				<select name="loc">'.
				($this->importAsType('G',$this->xmlhandler->extensionsXML['emconf_lockType'])?'<option value="G">Global: '.$this->typePaths['G'].$extKey.'/'.(@is_dir(PATH_site.$this->typePaths['G'].$extKey)?' (OVERWRITE)':' (empty)').'</option>':'').
				($this->importAsType('L',$this->xmlhandler->extensionsXML['emconf_lockType'])?'<option value="L">Local: '.$this->typePaths['L'].$extKey.'/'.(@is_dir(PATH_site.$this->typePaths['L'].$extKey)?' (OVERWRITE)':' (empty)').'</option>':'').
				($this->importAsType('S',$this->xmlhandler->extensionsXML['emconf_lockType'])?'<option value="S">System: '.$this->typePaths['S'].$extKey.'/'.(@is_dir(PATH_site.$this->typePaths['S'].$extKey)?' (OVERWRITE)':' (empty)').'</option>':'').
				'</select>';
		} else $select.= $this->noImportMsg();
		$content.= $select;
		$this->content.= $this->doc->section('Select command',$content,0,1);

			// Details:
		$eInfo = $this->xmlhandler->extensionsXML[$extKey]['versions'][$version];
		$content='<strong>'.$this->xmlhandler->extensionsXML[$extKey]['_ICON'].' &nbsp;'.$eInfo['EM_CONF']['title'].' ('.$extKey.', '.$version.')</strong><br /><br />';
		$content.=$this->extInformationArray($extKey,$eInfo,1);
		$this->content.=$this->doc->spacer(10);
		$this->content.=$this->doc->section('Remote Extension Details',$content,0,1);
	}
    
	/**
	 * Listing remote extensions from online repository
	 *
	 * @return	void
	 */
	function extensionList_import()	{
		global $TYPO3_LOADED_EXT;        
       
		$content='';
        
 			// Listing from online repository:
		if ($this->listRemote)	{
        
			list($inst_list,) = $this->getInstalledExtensions();            
			$this->inst_keys = array_flip(array_keys($inst_list));
			$this->detailCols[1]+=6;
          
            $group = $this->MOD_SETTINGS['listOrder'];
            $cat = $this->MOD_SETTINGS[$group];            
         
            $lookup = array ('cat' => array (
                                            'be' => 'AND tx_chlightem_extension.category="be"',    
                                            'module' => 'AND tx_chlightem_extension.category="module"',
                                            'fe' => 'AND tx_chlightem_extension.category="fe"',
                                            'plugin' => 'AND tx_chlightem_extension.category="plugin"',
                                            'misc' => 'AND tx_chlightem_extension.category="misc"',
                                            'services' => 'AND tx_chlightem_extension.category="services"',
                                            'templates' => 'AND tx_chlightem_extension.category="templates"',
                                            'example' => 'AND tx_chlightem_extension.category="example"',
                                            'doc' => 'AND tx_chlightem_extension.category="doc"',
                                            '' => 'AND tx_chlightem_extension.category=""',
                                            'fab74.de' => 'AND tx_chlightem_extension.category="fab74.de extensions"',
                                            'lib' => 'AND tx_chlightem_extension.category="library"',
                                            'fe,be' => 'AND tx_chlightem_extension.category="fe,be"',
                                            'ICE Pack - Individual Content' => 'AND tx_chlightem_extension.category="ICE Pack - Individual Content"',
                                            'ABC T3Pack.org' => 'AND tx_chlightem_extension.category="ABC T3Pack.org"',
                                        ),
                            
                            'state' => array (                                            
                                            'alpha' => 'AND tx_chlightem_extension.extstate="alpha"',
                                            'beta' => 'AND tx_chlightem_extension.extstate="beta"',
                                            'stable' => 'AND tx_chlightem_extension.extstate="stable"',
                                            'experimental' => 'AND tx_chlightem_extension.extstate="experimental"',
                                            'test' => 'AND tx_chlightem_extension.extstate="test"',
                                            'obsolete' => 'AND tx_chlightem_extension.extstate="obsolete"',                                
                                        ), 
                                        
                           	 				'author_company' => array (
                                            'author_company' => '',    
                                        ),
                            );
            
            $cmd = $lookup[$group][$cat];               
            
            if (!$this->MOD_SETTINGS['display_obsolete']) {
                $cmd .= ' AND tx_chlightem_extension.extstate !="obsolete"';
            }            
            
            // display unsupported extension
            if ($this->MOD_SETTINGS['display_unchecked'] === 'on') {
                $cmd .= ' AND tx_chlightem_extension.reviewstate > 0';
            }            
            
            if ($this->listRemote_search) {
                $cmd .= ' AND tx_chlightem_extension.extkey LIKE "%'.$this->listRemote_search.'%"';
            }            
            
            if($this->MOD_SETTINGS['display_own'] && strlen($this->fe_user['username'])) {
                 $cmd .= ' AND tx_chlightem_extension.ownerusername="'.$this->fe_user['username'].'"';            
            }            
            
            $results_at_a_time = 15;            
            $piBase = t3lib_div::makeInstance('em_tslib_pibase');             
            $piBase->cObj = t3lib_div::makeInstance('tslib_cObj');   
            
            if (t3lib_div::_GP('ter_pointer') != t3lib_div::_GP('t9r_backup') ) {
                $piBase->ter_pointer = $_GET['t9r_backup'] = t3lib_div::_GP('ter_pointer');                
                $order = t3lib_div::_GP('ter_order');
                
            } else {
                
            	if (t3lib_div::_GP('ter_order')) {
                	$piBase->ter_pointer = t3lib_div::_GP('ter_pointer');                
                    $order = $this->order[t3lib_div::_GP('ter_order')];
                    $_GET['ter_order'] = $order;
                } else {
                    $order = 'DESC';
                }
            }
            
            if (t3lib_div::_GP('ter_sort')) {
                $sort = t3lib_div::_GP('ter_sort');     
            } else {
                $sort = 'lastuploaddate';
            }

            if ($group == 'author_company') {
                $sort = 'ownerusername';           
            }
            
                        
                // Initializing the query parameters:
			$piBase->internal["results_at_a_time"]=t3lib_div::intInRange($results_at_a_time,0,1000,9);		// Number of results to show in a listing.
            $pibase->internal['results_at_a_time'] = $results_at_a_time;
            
			$piBase->internal["maxPages"]=t3lib_div::intInRange(5,0,1000,2);		                        // The maximum number of "pages" in the browse-box: "Page 1", "Page 2", etc.
			$piBase->internal["searchFieldList"]='';
			$piBase->internal["orderByList"]= 'extkey,downloadcounter,category,extstate,version,title,ownerusername,lastuploaddate';
            $piBase->internal["orderBy"] = $sort;
            $piBase->internal["descFlag"] = $order;            
            $piBase->internal["currentTable"] = "tx_chlightem_extension";
            $piBase->internal['pagefloat'] = 'center';

			// Get number of records:
			$res = $piBase->pi_exec_query('tx_chlightem_extension',1,$cmd);
            list($piBase->internal['res_count']) =  $GLOBALS['TYPO3_DB']->sql_fetch_row($res);
            
            $lines=array();
            
            $lines[]=$this->extensionListRowHeader(' class="bgColor5"',array('<td><img src="clear.gif" width="18" height="1" alt="" /></td>'),1);                           
            $lines[]='<tr><td colspan="'.(3+$this->detailCols[$this->MOD_SETTINGS['display_details']]).'"><br /></td></tr>';
            $lines[]='<tr><td colspan="'.(3+$this->detailCols[$this->MOD_SETTINGS['display_details']]).'"><img src="'.$GLOBALS['BACK_PATH'].'gfx/i/sysf.gif" width="18" height="16" align="top" alt="" /><strong>'.$this->listOrderTitle($this->MOD_SETTINGS['listOrder'],$cat).'</strong></td></tr>';
         
            $this->xmlhandler->extensionsXML = array();            
            
            // Make listing query, pass query to SQL database:
	        $res = $piBase->pi_exec_query('tx_chlightem_extension','',$cmd);
            
            while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
                $this->xmlhandler->extensionsXML[$row['extkey']]['extkey']=$row['extkey'];
                $this->xmlhandler->extensionsXML[$row['extkey']]['uid']=$row['uid'];
                $this->xmlhandler->extensionsXML[$row['extkey']]['downloadcounter']=$row['downloadcounter'];
                $this->xmlhandler->extensionsXML[$row['extkey']]['icon']=$row['icon'];
                $this->xmlhandler->extensionsXML[$row['extkey']]['type']=$row['type'];            
                $this->xmlhandler->extensionsXML[$row['extkey']]['lastuploaddate']=$row['lastuploaddate'];            
            }
            mysql_free_result($res);            

            foreach ($this->xmlhandler->extensionsXML as $k => $v) {
        
                $res = $GLOBALS['TYPO3_DB']->exec_SELECT_mm_query('*','tx_chlightem_extension','tx_chlightem_mm','tx_chlightem_version','AND tx_chlightem_extension.uid='.$v['uid']);
                                    
                while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {                    
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['version']=$row['version'];
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['title']=$row['title'];
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['description']=$row['description'];
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['state']=$row['extstate'];
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['reviewstate']=$row['reviewstate'];
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['lastuploaddate']=$row['lastuploaddate'];
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['constraints']=unserialize($row['dependencies']);
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['author']=$row['authorname'];
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['author_email']=$row['authoremail'];
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['author_company']=$row['authorcompany'];
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['ownerusername']=$row['ownerusername'];
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['t3xfilemd5']=$row['t3xfilemd5'];
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['category']=$row['category'];
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['uploadcomment']=$row['uploadcomment'];              
                    $this->xmlhandler->extensionsXML[$v['extkey']]['versions'][$row['version']]['EM_CONF']['downloadcounter']=$row['downloadcounter'];                           
                }
                
                mysql_free_result($res);
            }
            
             
            if (count($this->xmlhandler->extensionsXML)) {
            
                foreach ($this->xmlhandler->extensionsXML as $k => $v) {
                    
                        // Unset extension key in installed keys array (for tracking)
                    if(isset($this->emObj->inst_keys[$k])) unset($this->emObj->inst_keys[$k]);
                
                    $version = end(array_keys($v['versions']));
                    $ext = $v['versions'][$version];
        
                    $ext['downloadcounter_all'] = $v['downloadcounter'];
                    $ext['downloadcounter'] = $ext['EM_CONF']['downloadcounter'];
                    $ext['_ICON'] = $v['icon'];                    
                 
                    $loadUnloadLink='';
                    if ($inst_list[$v['extkey']]['type']!='S' && (!isset($inst_list[$v['extkey']]) || $this->versionDifference($version,$inst_list[$v['extkey']]['EM_CONF']['version'],$this->versionDiffFactor)))	{
                        if (isset($inst_list[$v['extkey']]))	{
                                // update
                            $loc= ($inst_list[$v['extkey']]['type']=='G'?'G':'L');
                            $aUrl = 'index.php?CMD[importExt]='.$v['extkey'].'&CMD[extVersion]='.$version.'&CMD[loc]='.$loc;
                            $loadUnloadLink.= '<a href="'.htmlspecialchars($aUrl).'"><img src="'.$GLOBALS['BACK_PATH'].'gfx/import_update.gif" width="12" height="12" title="Update the extension in \''.($loc=='G'?'global':'local').'\' from online repository to server" alt="" /></a>';
                        } else {
                                // import
                            $aUrl = 'index.php?CMD[importExt]='.$v['extkey'].'&CMD[extVersion]='.$version.'&CMD[loc]=L';
                            $loadUnloadLink.= '<a href="'.htmlspecialchars($aUrl).'"><img src="'.$GLOBALS['BACK_PATH'].'gfx/import.gif" width="12" height="12" title="Import this extension to \'local\' dir typo3conf/ext/ from online repository." alt="" /></a>';
                        }
                    } else {
                        $loadUnloadLink = '&nbsp;';
                    }
    
                    if (isset($inst_list[$v['extkey']]))	{
                        $theRowClass = t3lib_extMgm::isLoaded($v['extkey']) ? 'em-listbg1' : 'em-listbg2';
                    } else {
                        $theRowClass = 'em-listbg3';
                    }              
    
                    $lines[]=$this->extensionListRow($v['extkey'],$ext,array('<td class="bgColor">'.$loadUnloadLink.'</td>'),$theRowClass,$inst_list,1,'index.php?CMD[importExtInfo]='.rawurlencode($v['extkey']));                
                }
                
            } else {
                $lines[] = '<strong>No matching extensions found.<strong><br>';
            }

                // CSH:
            $content.= t3lib_BEfunc::cshItem('_MOD_tools_em', 'import_ter', $GLOBALS['BACK_PATH'],'|<br/>');
            $onsubmit = "window.location.href='index.php?ter_connect=1&ter_search='+escape(this.elements['_lookUp'].value);return false;";
            $content.= '</form><form action="index.php" method="post" onsubmit="'.htmlspecialchars($onsubmit).'">List or look up extensions<br />
                    <input type="text" name="_lookUp" value="'.htmlspecialchars($this->listRemote_search).'" /> <input type="submit" value="Look up" /><br /><br />';

            $content.= '

            <!-- TER Extensions list -->
            <table border="0" cellpadding="2" cellspacing="1">'.implode(chr(10),$lines).'</table>';
                            
            unset($lines);            
           
            $content.=$piBase->pi_list_browseresults(1,'width="1%"',array ( 'activeLinkWrap' => '<td nowrap="nowrap"><p style="background-color:#FFFF00">|</p></td>',
                                                                            'showResultsWrap' => '<td width="99%" align="left" nowrap="nowrap"><p style="padding-left:20px">|</p></td></tr></table>',
                                                                            'browseLinksWrap' => '<table width="100%"><tr>|',
                                                                            )                                                                                
            
                                                    );
            
            $content.= '<br /><br /><strong>PRIVACY NOTICE:</strong><br /> '.$this->privacyNotice;
            $this->content.=$this->doc->section('Extensions in TYPO3 Extension Repository (online) - Grouped by: '.$this->MOD_MENU['listOrder'][$this->MOD_SETTINGS['listOrder']],$content,0,1);			

		} else {
				// CSH
			$content.= t3lib_BEfunc::cshItem('_MOD_tools_em', 'import', $GLOBALS['BACK_PATH'],'|<br/>');

			$onsubmit = "window.location.href='index.php?ter_connect=1&ter_search='+escape(this.elements['_lookUp'].value);return false;";
			$content.= '</form><form action="index.php" method="post" onsubmit="'.htmlspecialchars($onsubmit).'">List or look up extensions<br />
			<input type="text" name="_lookUp" value="" /> <input type="submit" value="Look up" /><br /><br />';

			if ($this->CMD['fetchMetaData'])	{	// fetches mirror/extension data from online rep.
				$content .= $this->fetchMetaData($this->CMD['fetchMetaData']);
			} else {
				$onCLick = "window.location.href='index.php?CMD[fetchMetaData]=extensions';return false;";
				$content.= 'Connect to the current mirror and retrieve the current list of available plugins from the TYPO3 Extension Repository.<br />
				<input type="submit" value="Retrieve/Update" onclick="'.htmlspecialchars($onCLick).'" />';
				if(is_file(PATH_site.'typo3temp/extensions.bin')) {
					$content .= ' (last update: '.date('Y-m-d H:i',filemtime(PATH_site.'typo3temp/extensions.bin')).')';
				}
			}

			$content.= '<br /><br /><strong>PRIVACY NOTICE:</strong><br />'.$this->privacyNotice;
            
			$output = $this->memory_get_usage();
			
            $content.= sprintf("<br><br><strong>PROCESSSTATUS:</strong><br>User: %s<br>Total virtual memory size: %d Mb<br>Total resident set size: %d Mb<br>Start: %s<br>Time: %s<br>pid: %d",$output[0],$output[3]/1024,$output[4]/1024,$output[5],$output[6],$output[7]);
            
            $content.= $this->monitor;
            
            $content.= '<br><br><strong>Please support the Light Extension Manager to keep it free!</strong>';
            
            $content.= '<br><table><tr><td><table><tr><td><a target="_blank" href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=chibo%40gmx%2ede&item_name=Typo3%20Extension%3a%20ch_lightem&amount=1%2e00&no_shipping=0&no_note=1&tax=0&currency_code=EUR&lc=DE&bn=PP%2dDonationsBF&charset=UTF%2d8"><img src="../../../../typo3conf/ext/ch_lightem/paypal_donate.gif"></a></td></tr><tr><td align="center">1 &#8364;</td></tr></table></td><td>';
            
            $content.= '<table><tr><td><a target="_blank" href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=chibo%40gmx%2ede&item_name=Typo3%20Extension%3a%20ch_lightem&amount=5%2e00&no_shipping=0&no_note=1&tax=0&currency_code=EUR&lc=DE&bn=PP%2dDonationsBF&charset=UTF%2d8"><img src="../../../../typo3conf/ext/ch_lightem/paypal_donate.gif"></a></td></tr><tr><td align="center">5 &#8364;</td></tr></table></td><td>';
            
            $content.= '<table><tr><td><a target="_blank" href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=chibo%40gmx%2ede&item_name=Typo3%20Extension%3a%20ch_lightem&amount=10%2e00&no_shipping=0&no_note=1&tax=0&currency_code=EUR&lc=DE&bn=PP%2dDonationsBF&charset=UTF%2d8"><img src="../../../../typo3conf/ext/ch_lightem/paypal_donate.gif"></a></td></tr><tr><td align="center">10 &#8364;</td></tr></table></td><td>';
            
            $content.= '<table><tr><td><a target="_blank" href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=chibo%40gmx%2ede&item_name=Typo3%20Extension%3a%20ch_lightem&amount=15%2e00&no_shipping=0&no_note=1&tax=0&currency_code=EUR&lc=DE&bn=PP%2dDonationsBF&charset=UTF%2d8"><img src="../../../../typo3conf/ext/ch_lightem/paypal_donate.gif"></a></td></tr><tr><td align="center">15 &#8364;</td></tr></table></td><td>';
            
            $content.= '<table><tr><td><a target="_blank" href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=chibo%40gmx%2ede&item_name=Typo3%20Extension%3a%20ch_lightem&amount=25%2e00&no_shipping=0&no_note=1&tax=0&currency_code=EUR&lc=DE&bn=PP%2dDonationsBF&charset=UTF%2d8"><img src="../../../../typo3conf/ext/ch_lightem/paypal_donate.gif"></a></td></tr><tr><td align="center">25 &#8364;</td></tr></table></td><td>';
            
            $content.= '<table><tr><td><a target="_blank" href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=chibo%40gmx%2ede&item_name=Typo3%20Extension%3a%20ch_lightem&amount=35%2e00&no_shipping=0&no_note=1&tax=0&currency_code=EUR&lc=DE&bn=PP%2dDonationsBF&charset=UTF%2d8"><img src="../../../../typo3conf/ext/ch_lightem/paypal_donate.gif"></a></td></tr><tr><td align="center">35 &#8364;</td></tr></table></td><td>';
            
            $content.= '</td></tr></table>';
 		
  	    $this->content.=$this->doc->section('Extensions in TYPO3 Extension Repository',$content,0,1);
	}

			// Upload:
		if ($this->importAtAll())	{
			$content= '</form><form action="index.php" enctype="'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['form_enctype'].'" method="post">
			Upload extension file (.t3x):<br />
				<input type="file" size="60" name="upload_ext_file" /><br />
				... to location:<br />
				<select name="CMD[loc]">';
			if ($this->importAsType('L'))	$content.='<option value="L">Local (../typo3conf/ext/)</option>';
			if ($this->importAsType('G'))	$content.='<option value="G">Global (typo3/ext/)</option>';
			if ($this->importAsType('S'))	$content.='<option value="S">System (typo3/sysext/)</option>';
			$content.='</select><br />
					<input type="checkbox" value="1" name="CMD[uploadOverwrite]" /> Overwrite any existing extension!<br />
					<input type="submit" name="CMD[uploadExt]" value="Upload extension file" /><br />
			';
		} else $content=$this->noImportMsg();

		$this->content.=$this->doc->spacer(20);
		$this->content.=$this->doc->section('Upload extension file directly (.t3x):',$content,0,1);
	}



	/**
	 * Fetches metadata and stores it to the corresponding place. This includes the mirror list,
	 * extension XML files.
	 *
	 * @param	string		Type of data to fetch: (mirrors)
	 * @param	boolean		If true the method doesn't produce any output
	 * @return	void
	 */
	function fetchMetaData($metaType)	{
		global $TYPO3_CONF_VARS;

		switch($metaType) {
			case 'mirrors':
				$mfile = t3lib_div::tempnam('mirrors');
				$mirrorsFile = t3lib_div::getURL($this->MOD_SETTINGS['mirrorListURL']);
				if($mirrorsFile===false) {
					t3lib_div::unlink_tempfile($mfile);
					$content = '<p>The mirror list was not updated, it could not be fetched from '.$this->MOD_SETTINGS['mirrorListURL'].'. Possible reasons: network problems, allow_url_fopen is off, curl is not enabled in Install tool.</p>';
				} else {
					t3lib_div::writeFile($mfile, $mirrorsFile);
                    $mirrors = implode(chr(10), gzfile($mfile));
                    t3lib_div::unlink_tempfile($mfile);

					$mirrors = $this->parseMirrorsXML($mirrors);
					if(is_array($mirrors) && count($mirrors)) {
						t3lib_BEfunc::getModuleData($this->MOD_MENU, array('extMirrors' => serialize($mirrors)), $this->MCONF['name'], '', 'extMirrors');
						$this->MOD_SETTINGS['extMirrors'] = serialize($mirrors);
						$content = '<p>The mirror list has been updated and now contains '.count($mirrors).' entries.</p>';
					}
					else {
						$content = '<p>'.$mirrors.'<br />The mirror list was not updated as it contained no entries.</p>';
					}
				}
				break;
			case 'extensions':
				$this->fetchMetaData('mirrors'); // if we fetch the extensions anyway, we can as well keep this up-to-date

				$mirror = $this->getMirrorURL();
				$extfile = $mirror.'extensions.xml.gz';
				$extmd5 = t3lib_div::getURL($mirror.'extensions.md5');
				if(is_file(PATH_site.'typo3temp/extensions.xml.gz')) $localmd5 = md5_file(PATH_site.'typo3temp/extensions.xml.gz');

				if($extmd5 === false) {
					$content .= '<p>Error: The extension MD5 sum could not be fetched from '.$mirror.'extensions.md5. Possible reasons: network problems, allow_url_fopen is off, curl is not enabled in Install tool.</p>';
				} elseif($extmd5 == $localmd5) {
					$content .= '<p>The extension list has not changed remotely, it has thus not been fetched.</p>';
				} else {
					$extXML = t3lib_div::getURL($extfile);
					if($extXML === false) {
						$content .= '<p>Error: The extension list could not be fetched from '.$extfile.'. Possible reasons: network problems, allow_url_fopen is off, curl is not enabled in Install tool.</p>';
					} else {

                        t3lib_div::writeFile(PATH_site.'typo3temp/extensions.xml.gz', $extXML);
                        $filepath = $this->getMirrorURL();
                        
                        //$this->monitor = "Total Memory (before Replication): " . $this->memory_get_usage() / 1024 . " KBytes <br/>";
                        $time_end = $this->microtime_float();
                        
                        $gz = gzopen(PATH_site.'typo3temp/extensions.xml.gz', 'rb');
                        
                        if ($gz) {             
                        
                            fseek($gz,51,SEEK_CUR);
                            
                            $res = $GLOBALS['TYPO3_DB']->sql('tx_chlightem_extension','truncate table tx_chlightem_extension');
                            $extC = 0;
                            
                            $res = $GLOBALS['TYPO3_DB']->sql('tx_chlightem_version','truncate table tx_chlightem_version');
                            $verC = 0;
                            
                            $res = $GLOBALS['TYPO3_DB']->sql('tx_chlightem_mm','truncate table tx_chlightem_mm');
                            
                            $char = '';
                            $pos = 0;
                            
                            while (!gzeof($gz)) {
                            
                                $char .= gzgets($gz, 4096);                       
                                $pos = strpos($char,"</extension>");
                             
                                if ($pos) {
                                
                                    $extC++;
                                    
                                    $buffer = substr($char,0,$pos+12);
                                    $char = substr($char,$pos+12);
        
                                    $result = $this->parseExtensionsXML($buffer);                                    
                                    $extKey = key($this->extXMLResult);
                                   
                                        // too be very sure extKey exists
                                    if (is_array($this->extXMLResult[$extKey])) {
                                    
                                        $version = array_keys($this->extXMLResult[$extKey]['versions']);
                                        $version = end($version);
            
                                        $res = $GLOBALS['TYPO3_DB']->exec_INSERTquery('tx_chlightem_extension', array (  	
                                                                                                                        'crdate' => time(),
                                                                                                                        'extkey' => $extKey,
                                                                                                                        'downloadcounter' => $this->extXMLResult[$extKey]['downloadcounter'],
                                                                                                                        'icon' => '<img alt="" src="'.$filepath.$extKey{0}.'/'.$extKey{1}.'/'.$extKey.'_'.$version.'.gif" />',
                                                                                                                        'category' => $this->extXMLResult[$extKey]['versions'][$version]['category'],
                                                                                                                        'extstate' => $this->extXMLResult[$extKey]['versions'][$version]['state'],
                                                                                                                        'version' => $version,
                                                                                                                        'title' => $this->extXMLResult[$extKey]['versions'][$version]['title'],
                                                                                                                        'reviewstate' => $this->extXMLResult[$extKey]['versions'][$version]['reviewstate'],
                                                                                                                        'ownerusername' => $this->extXMLResult[$extKey]['versions'][$version]['ownerusername'],
                                                                                                                        'lastuploaddate' => $this->extXMLResult[$extKey]['versions'][$version]['lastuploaddate'],
                                                                                                            )
                                                                                                );
                                        echo $GLOBALS['TYPO3_DB']->sql_error();
                                         
                                        $query1 = '';
                                        $q1str = array();
                                        
                                        $query2 = '';
                                        $q2str = array();
                                        
                                        foreach ($this->extXMLResult[$extKey]['versions'] as $k => $v) {                                        
                                            $verC++;
                                            
                                            $qArr = array(  $verC,
                                                            0,
                                                            time(),
                                                            $k,
                                                            $v['title'],
                                                            $v['description'],                                                            
                                                            $v['state'],
                                                            $v['reviewstate'],
                                                            $v['downloadcounter'],                                                            
                                                            $v['lastuploaddate'],                                                           
                                                            serialize($v['dependencies']),
                                                            $v['authorname'],
                                                            $v['authoremail'],
                                                            $v['authorcompany'],
                                                            $v['ownerusername'],
                                                            $v['t3xfilemd5'], 
                                                            $v['category'],                                                                                                                       
                                                            $v['uploadcomment'],
                                                            );
                                            
                                            $q1str[] = '\''.implode('\',\'',$qArr).'\'';
            
                                            $qArr = array (  $extC,
                                                             $verC,
                                                             '',
                                                             ''
                                                            );

                                            $q2str[] = '\''.implode('\',\'',$qArr).'\'';                                            
                                            
                                        }                
                                        
                                        $query1 = 'INSERT INTO `tx_chlightem_version` VALUES ('. implode('),(',$q1str).');';
                                        $query2 = 'INSERT INTO `tx_chlightem_mm` VALUES ('. implode('),(',$q2str).');';                                        

                                        $res = $GLOBALS['TYPO3_DB']->sql_query($query1);
                                        echo $GLOBALS['TYPO3_DB']->sql_error();
                                         
                                        $res = $GLOBALS['TYPO3_DB']->sql_query($query2);
                                        echo $GLOBALS['TYPO3_DB']->sql_error();
                                        
                                        $this->extXMLResult = array();
                                    }
                                }  
                            }                     
                            gzclose($gz);                           
                            
                            unset($this->extXMLResult);                            
                            unset($this->reviewStates);
                            
                            unset($buffer);
                            unset($char);
                            unset($query1);
                            unset($query2);
                            unset($pos);
                            unset($q1str);
                            unset($q2str);
                            unset($qArr);
                            
                            //$this->monitor.= "Total Memory (after Replication): " . $this->memory_get_usage() / 1024 . " KBytes <br/>";                            
                            $time_end = $this->microtime_float();
							$time = $time_end - $time_start;                            
                            $this->monitor .= "Runtime: $time sec<br>";
                            
                            $content.= "<p>The extensions list has been updated and now contains $extC extension entries.</p>";
                            
                        } else {
                            
                            $content.= "<p>Function gzopen fails!</p>";
                        }
                    }
                }
                break;
		}

		return $content;
	}

		/**
	 * ***************PARSING METHODS***********************
	 */
	/**
	 * Enter description here...
	 *
	 * @param	unknown_type		$parser
	 * @param	unknown_type		$name
	 * @param	unknown_type		$attrs
	 * @return	[type]		...
	 */
	function startElement($parser, $name, $attrs) {
		switch($name) {
			case 'extensions':
			break;
			case 'extension':
			$this->currentExt = $attrs['extensionkey'];
			break;
			case 'version':
			$this->currentVersion = $attrs['version'];
			$this->extXMLResult[$this->currentExt]['versions'][$this->currentVersion] = array();
			break;
			default:
			$this->currentTag = $name;
		}
	}

	/**
	 * Enter description here...
	 *
	 * @param	unknown_type		$parser
	 * @param	unknown_type		$name
	 * @return	[type]		...
	 */
	function endElement($parser, $name) {
		switch($name) {
			case 'extension':
			unset($this->currentExt);
			break;
			case 'version':
			unset($this->currentVersion);
			break;
			default:
			unset($this->currentTag);
		}
	}

	/**
	 * Enter description here...
	 *
	 * @param	unknown_type		$parser
	 * @param	unknown_type		$data
	 * @return	[type]		...
	 */
	function characterData($parser, $data) {
		if(isset($this->currentTag)) {
			if(!isset($this->currentVersion) && $this->currentTag == 'downloadcounter') {
				$this->extXMLResult[$this->currentExt]['downloadcounter'] = trim($data);
			} elseif($this->currentTag == 'dependencies') {
				$data = @unserialize($data);
				if(is_array($data)) {
					$dep = array();
					foreach($data as $v) {
						$dep[$v['kind']][$v['extensionKey']] = $v['versionRange'];
					}
					$this->extXMLResult[$this->currentExt]['versions'][$this->currentVersion]['dependencies'] = $dep;
				}
			} elseif($this->currentTag == 'reviewstate') {
					$this->reviewStates[$this->currentExt][$this->currentVersion] = (int)trim($data);
					$this->extXMLResult[$this->currentExt]['versions'][$this->currentVersion]['reviewstate'] = (int)trim($data);
			} else {
				$this->extXMLResult[$this->currentExt]['versions'][$this->currentVersion][$this->currentTag] .= trim($data);
			}
		}
	}
	
	/**
	 * Parses content of mirrors.xml into a suitable array
	 *
	 * @param	string		XML data file to parse
	 * @return	string		HTLML output informing about result
	 */
	function parseExtensionsXML($string) {
		global $TYPO3_CONF_VARS;

		$parser = xml_parser_create();
		xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
		xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0);
		xml_set_element_handler($parser, array(&$this,'startElement'), array(&$this,'endElement'));
		xml_set_character_data_handler($parser, array(&$this,'characterData'));

		if ((double)phpversion()>=5)	{
			$preg_result = array();
			preg_match('/^[[:space:]]*<\?xml[^>]*encoding[[:space:]]*=[[:space:]]*"([^"]*)"/',substr($string,0,200),$preg_result);
			$theCharset = $preg_result[1] ? $preg_result[1] : ($TYPO3_CONF_VARS['BE']['forceCharset'] ? $TYPO3_CONF_VARS['BE']['forceCharset'] : 'iso-8859-1');
			xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $theCharset);  // us-ascii / utf-8 / iso-8859-1
		}

		// Parse content:
		if (!xml_parse($parser, $string)) {
			$content.= 'Error in XML parser while decoding extensions XML file. Line '.xml_get_current_line_number($parser).': '.xml_error_string(xml_get_error_code($parser));
			$error = true;
		}
		xml_parser_free($parser);

		if(!$error) {
			$content.= '<p>The extensions list has been updated and now contains '.count($this->extXMLResult).' extension entries.</p>';
		}

		return $content;
	}

	
    function extensionListRowHeaderLink($str,$sort) {            

        $cmd = 'ter_connect='.t3lib_div::_GP('ter_connect').'&ter_search='.t3lib_div::_GP('ter_search').'&ter_sort='.$sort.'&ter_pointer='.t3lib_div::_GP('ter_pointer').'&t9r_backup='.t3lib_div::_GP('t9r_backup');        
        if (t3lib_div::_GP('ter_order')) {
            $cmd .= '&ter_order='.t3lib_div::_GP('ter_order');
        } else {
            $cmd .= '&ter_order=DESC';
        }
        return '<a onMouseover=highlight(this,\'yellow\') onMouseout="highlight(this,\'#c7cdd1\')" href="index.php?'.$cmd.'">'.$str.'</a>';
    }
   
	/**
	 * Prints the header row for the various listings
	 *
	 * @param	string		Attributes for the <tr> tag
	 * @param	array		Preset cells in the beginning of the row. Typically a blank cell with a clear-gif
	 * @param	boolean		If set, the list is coming from remote server.
	 * @return	string		HTML <tr> table row
	 */
	function extensionListRowHeader($trAttrib,$cells,$import=0)	{
		$cells[] = '<td></td>';
        
		if (!$this->MOD_SETTINGS['display_details'])	{
			$cells[] = '<td>'.$this->extensionListRowHeaderLink('Title:','title').'</td>';
            $cells[] = '<td>Description:</td>';
			$cells[] = '<td>'.$this->extensionListRowHeaderLink('Author:','ownerusername').'</td>';
		} elseif ($this->MOD_SETTINGS['display_details']==2)	{
			$cells[] = '<td>Title:</td>';
            $cells[] = '<td>Priority:</td>';
			$cells[] = '<td>Mod.Tables:</td>';
			$cells[] = '<td>Modules:</td>';
			$cells[] = '<td>Cl.Cache?</td>';
			$cells[] = '<td>Internal?</td>';
			$cells[] = '<td>Shy?</td>';
		} elseif ($this->MOD_SETTINGS['display_details']==3)	{
			$cells[] = '<td>Title:</td>';
            $cells[] = '<td>Tables/Fields:</td>';
			$cells[] = '<td>TS-files:</td>';
			$cells[] = '<td>Affects:</td>';
			$cells[] = '<td>Modules:</td>';
			$cells[] = '<td>Config?</td>';
			$cells[] = '<td>Code warnings:</td>';
		} elseif ($this->MOD_SETTINGS['display_details']==4)	{
			$cells[] = '<td>Title:</td>';
            $cells[] = '<td>locallang:</td>';
			$cells[] = '<td>Classes:</td>';
			$cells[] = '<td>Code warnings:</td>';
			$cells[] = '<td>Nameing annoyances:</td>';
		} elseif ($this->MOD_SETTINGS['display_details']==5)	{
			$cells[] = '<td>Title:</td>';
            $cells[] = '<td>Changed files:</td>';
		} elseif ($this->MOD_SETTINGS['display_details']==1 && t3lib_div::inList('2',$this->MOD_SETTINGS['function'])) {        
         
            $cells[] = '<td>'.$this->extensionListRowHeaderLink('Title:','title').'</td>';
            $cells[] = '<td>'.$this->extensionListRowHeaderLink('Extension key:','extkey').'</td>';
			$cells[] = '<td>'.$this->extensionListRowHeaderLink('Version:','version').'</td>';
            $cells[] = '<td class="bgColor6"'.$this->labelInfo('Current version of the extension on this server. If colored red there is a newer version in repository! Then you should upgrade.').'>'.$this->extensionListRowHeaderLink('Cur. Ver:','curver').'</td>';
            $cells[] = '<td class="bgColor6"'.$this->labelInfo('Current type of installation of the extension on this server.').'>'.$this->extensionListRowHeaderLink('Cur. Type:','curtype').'</td>';
            $cells[] = '<td'.$this->labelInfo('Number of downloads, all versions/this version').'>'.$this->extensionListRowHeaderLink('DL:','downloadcounter').'</td>';
            $cells[] = '<td>'.$this->extensionListRowHeaderLink('State:','extstate').'</td>';
            if (t3lib_div::inList('2',$this->MOD_SETTINGS['function'])) $cells[] = '<td>'.$this->extensionListRowHeaderLink('Lastuploaddate:','lastuploaddate').'</td>';
        
        } else {
        
            $cells[] = '<td>Title:</td>';
			$cells[] = '<td>Extension key:</td>';
			$cells[] = '<td>Version:</td>';
			if (!$import) {
				$cells[] = '<td>DL:</td>';
				$cells[] = '<td>Doc:</td>';
				$cells[] = '<td>Type:</td>';
			} else {
				$cells[] = '<td class="bgColor6"'.$this->labelInfo('Current version of the extension on this server. If colored red there is a newer version in repository! Then you should upgrade.').'>Cur. Ver:</td>';
				$cells[] = '<td class="bgColor6"'.$this->labelInfo('Current type of installation of the extension on this server.').'>Cur. Type:</td>';
				$cells[] = '<td'.$this->labelInfo('Number of downloads, all versions/this version').'>DL:</td>';
			}
			$cells[] = '<td>State:</td>';
		}
		return '
			<tr'.$trAttrib.'>
				'.implode('
				',$cells).'
			</tr>';
	}
    
    /**
	 * Prints a row with data for the various extension listings
	 *
	 * @param	string		Extension key
	 * @param	array		Extension information array
	 * @param	array		Preset table cells, eg. install/uninstall icons.
	 * @param	string		<tr> tag class
	 * @param	array		Array with installed extension keys (as keys)
	 * @param	boolean		If set, the list is coming from remote server.
	 * @param	string		Alternative link URL
	 * @return	string		HTML <tr> content
	 */
	function extensionListRow($extKey,$extInfo,$cells,$bgColorClass='',$inst_list=array(),$import=0,$altLinkUrl='')	{

			// Icon:
		$imgInfo = @getImageSize($this->getExtPath($extKey,$extInfo['type']).'/ext_icon.gif');
        
		if (is_array($imgInfo))	{
			$cells[] = '<td><img src="'.$GLOBALS['BACK_PATH'].$this->typeRelPaths[$extInfo['type']].$extKey.'/ext_icon.gif'.'" '.$imgInfo[3].' alt="" /></td>';
		} elseif ($extInfo['_ICON']) {
			$cells[] = '<td>'.$extInfo['_ICON'].'</td>';
		} else {
			$cells[] = '<td><img src="clear.gif" width="1" height="1" alt="" /></td>';
		}

			// Extension title:
		$cells[] = '<td nowrap="nowrap"><a onMouseover=highlight(this,\'yellow\') onMouseout="highlight(this,\'#ffdddd\')" href="'.htmlspecialchars($altLinkUrl?$altLinkUrl:'index.php?CMD[showExt]='.$extKey.'&SET[singleDetails]=info').'" title="'.$extKey.'">'.t3lib_div::fixed_lgd($extInfo['EM_CONF']['title']?$extInfo['EM_CONF']['title']:'<em>'.$extKey.'</em>',40).'</a></td>';

			// Based on which display mode you will see more or less details:
		if (!$this->MOD_SETTINGS['display_details'])	{
			
            		$cells[] = '<td><a onMouseover=highlight(this,\'yellow\') onMouseout="highlight(this,\'#ffdddd\')"  href="http://typo3.org/extensions/repository/view/'.$extKey.'/'.$extInfo['EM_CONF']['version'].'/">'.htmlspecialchars(t3lib_div::fixed_lgd($extInfo['EM_CONF']['description'],400)).'</a><br /><img src="clear.gif" width="300" height="1" alt="" /></td>';
			$cells[] = '<td nowrap="nowrap">'.($extInfo['EM_CONF']['author_email'] ? '<a href="mailto:'.htmlspecialchars($extInfo['EM_CONF']['author_email']).'">' : '').htmlspecialchars($extInfo['EM_CONF']['author']).($extInfo['EM_CONF']['author_email'] ? '</a>' : '').($extInfo['EM_CONF']['author_company'] ? '<br />'.htmlspecialchars($extInfo['EM_CONF']['author_company']) : '').'</td>';
		
        } elseif ($this->MOD_SETTINGS['display_details']==2)	{
			$cells[] = '<td nowrap="nowrap">'.$extInfo['EM_CONF']['priority'].'</td>';
			$cells[] = '<td nowrap="nowrap">'.implode('<br />',t3lib_div::trimExplode(',',$extInfo['EM_CONF']['modify_tables'],1)).'</td>';
			$cells[] = '<td nowrap="nowrap">'.$extInfo['EM_CONF']['module'].'</td>';
			$cells[] = '<td nowrap="nowrap">'.($extInfo['EM_CONF']['clearCacheOnLoad'] ? 'Yes' : '').'</td>';
			$cells[] = '<td nowrap="nowrap">'.($extInfo['EM_CONF']['internal'] ? 'Yes' : '').'</td>';
			$cells[] = '<td nowrap="nowrap">'.($extInfo['EM_CONF']['shy'] ? 'Yes' : '').'</td>';
		
        } elseif ($this->MOD_SETTINGS['display_details']==3)	{
			
            		$techInfo = $this->makeDetailedExtensionAnalysis($extKey,$extInfo);

			$cells[] = '<td>'.$this->extInformationArray_dbReq($techInfo).'</td>';
			$cells[] = '<td nowrap="nowrap">'.(is_array($techInfo['TSfiles']) ? implode('<br />',$techInfo['TSfiles']) : '').'</td>';
			$cells[] = '<td nowrap="nowrap">'.(is_array($techInfo['flags']) ? implode('<br />',$techInfo['flags']) : '').'</td>';
			$cells[] = '<td nowrap="nowrap">'.(is_array($techInfo['moduleNames']) ? implode('<br />',$techInfo['moduleNames']) : '').'</td>';
			$cells[] = '<td nowrap="nowrap">'.($techInfo['conf'] ? 'Yes' : '').'</td>';
			$cells[] = '<td>'.
			$GLOBALS['TBE_TEMPLATE']->rfw((t3lib_extMgm::isLoaded($extKey)&&$techInfo['tables_error']?'<strong>Table error!</strong><br />Probably one or more required fields/tables are missing in the database!':'').
			(t3lib_extMgm::isLoaded($extKey)&&$techInfo['static_error']?'<strong>Static table error!</strong><br />The static tables are missing or empty!':'')).
			'</td>';
		
        } elseif ($this->MOD_SETTINGS['display_details']==4)	{
        
			$techInfo=$this->makeDetailedExtensionAnalysis($extKey,$extInfo,1);

			$cells[] = '<td>'.(is_array($techInfo['locallang']) ? implode('<br />',$techInfo['locallang']) : '').'</td>';
			$cells[] = '<td>'.(is_array($techInfo['classes']) ? implode('<br />',$techInfo['classes']) : '').'</td>';
			$cells[] = '<td>'.(is_array($techInfo['errors']) ? $GLOBALS['TBE_TEMPLATE']->rfw(implode('<hr />',$techInfo['errors'])) : '').'</td>';
			$cells[] = '<td>'.(is_array($techInfo['NSerrors']) ? (!t3lib_div::inList($this->nameSpaceExceptions,$extKey) ? t3lib_div::view_array($techInfo['NSerrors']) : $GLOBALS['TBE_TEMPLATE']->dfw('[exception]')) :'').'</td>';
		
        } elseif ($this->MOD_SETTINGS['display_details']==5)	{
		
            $currentMd5Array = $this->serverExtensionMD5Array($extKey,$extInfo);
			$affectedFiles = '';
			$msgLines = array();
			$msgLines[] = 'Files: '.count($currentMd5Array);
			if (strcmp($extInfo['EM_CONF']['_md5_values_when_last_written'],serialize($currentMd5Array)))	{
				$msgLines[] = $GLOBALS['TBE_TEMPLATE']->rfw('<br /><strong>A difference between the originally installed version and the current was detected!</strong>');
				$affectedFiles = $this->findMD5ArrayDiff($currentMd5Array,unserialize($extInfo['EM_CONF']['_md5_values_when_last_written']));
				if (count($affectedFiles))	$msgLines[] = '<br /><strong>Modified files:</strong><br />'.$GLOBALS['TBE_TEMPLATE']->rfw(implode('<br />',$affectedFiles));
			}
			$cells[] = '<td>'.implode('<br />',$msgLines).'</td>';

        } else {
				// Default view:
			$verDiff = $inst_list[$extKey] && $this->versionDifference($extInfo['EM_CONF']['version'],$inst_list[$extKey]['EM_CONF']['version'],$this->versionDiffFactor);
            
			$cells[] = '<td nowrap="nowrap"><em><a onMouseover=highlight(this,\'yellow\') onMouseout="highlight(this,\'#ffdddd\')"  href="http://typo3.org/extensions/repository/view/'.$extKey.'/'.$extInfo['EM_CONF']['version'].'/">'.$extKey.'</a></em></td>';

            $cells[] = '<td nowrap="nowrap">'.($verDiff ? '<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw(htmlspecialchars($extInfo['EM_CONF']['version'])).'</strong>' : $extInfo['EM_CONF']['version']).'</td>';
            
			if (!$import) {		// Listing extenson on LOCAL server:
					// Extension Download:
				$cells[] = '<td nowrap="nowrap"><a href="'.htmlspecialchars('index.php?CMD[doBackup]=1&SET[singleDetails]=backup&CMD[showExt]='.$extKey).'"><img src="download.png" width="13" height="12" title="Download" alt="" /></a></td>';

					// Manual download
				$fileP = PATH_site.$this->typePaths[$extInfo['type']].$extKey.'/doc/manual.sxw';
				$cells[] = '<td nowrap="nowrap">'.
				($this->typePaths[$extInfo['type']] && @is_file($fileP)?'<a href="'.htmlspecialchars(t3lib_div::resolveBackPath($this->doc->backPath.'../'.$this->typePaths[$extInfo['type']].$extKey.'/doc/manual.sxw')).'" target="_blank"><img src="oodoc.gif" width="13" height="16" title="Local Open Office Manual" alt="" /></a>':'').
				'</td>';
				$cells[] = '<td nowrap="nowrap">'.$this->typeLabels[$extInfo['type']].(strlen($extInfo['doubleInstall'])>1?'<strong> '.$GLOBALS['TBE_TEMPLATE']->rfw($extInfo['doubleInstall']).'</strong>':'').'</td>';

            } else {	// Listing extensions from REMOTE repository:
				
                		$inst_curVer = $inst_list[$extKey]['EM_CONF']['version'];
				if (isset($inst_list[$extKey]))	{
					if ($verDiff)	$inst_curVer = '<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw($inst_curVer).'</strong>';
				}
				$cells[] = '<td nowrap="nowrap">'.$inst_curVer.'</td>';
				$cells[] = '<td nowrap="nowrap">'.$this->typeLabels[$inst_list[$extKey]['type']].(strlen($inst_list[$extKey]['doubleInstall'])>1?'<strong> '.$GLOBALS['TBE_TEMPLATE']->rfw($inst_list[$extKey]['doubleInstall']).'</strong>':'').'</td>';
				$cells[] = '<td nowrap="nowrap">'.($extInfo['downloadcounter_all']?$extInfo['downloadcounter_all']:'&nbsp;&nbsp;').'/'.($extInfo['downloadcounter']?$extInfo['downloadcounter']:'&nbsp;').'</td>';
			}
			$cells[] = '<td nowrap="nowrap" class="extstate" style="background-color:'.$this->stateColors[$extInfo['EM_CONF']['state']].';">'.$this->states[$extInfo['EM_CONF']['state']].'</td>';			
            
            if (t3lib_div::inList('2',$this->MOD_SETTINGS['function'])) $cells[] = '<td nowrap="nowrap">'.date('d.m.Y',$extInfo['EM_CONF']['lastuploaddate']).'</td>';
		}
      
		if($this->xmlhandler->extensionsXML[$extKey]['versions'][$extInfo['EM_CONF']['version']]['EM_CONF']['reviewstate']<1) {
			$bgclass = ' class="unsupported-ext"';
		} else {
			$bgclass = ' class="'.($bgColorClass?$bgColorClass:'bgColor4').'"';
		}
        
		return '
			<tr'.$bgclass.'>
				'.implode('
				',$cells).'
			</tr>';
	}
}

// Include extension?
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3conf/ext/ch_lightem/ux_index.php'])	{
	include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3conf/ext/ch_lightem/ux_index.php']);
}

?>
