"TYPO3 4.0.1: typo3_src-4.0.1/typo3/mod/tools/em/class.em_index.php Source File", "datetime" => "Sat Dec 2 19:22:21 2006", "date" => "2 Dec 2006", "doxygenversion" => "1.4.6", "projectname" => "TYPO3 4.0.1", "projectnumber" => "4.0.1" ); get_header($doxygen_vars); ?>

class.em_index.php

00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 1999-2005 Kasper Skaarhoj (kasperYYYY@typo3.com)
00006 *  (c) 2005-2006 Karsten Dambekalns <karsten@typo3.org>
00007 *  All rights reserved
00008 *
00009 *  This script is part of the TYPO3 project. The TYPO3 project is
00010 *  free software; you can redistribute it and/or modify
00011 *  it under the terms of the GNU General Public License as published by
00012 *  the Free Software Foundation; either version 2 of the License, or
00013 *  (at your option) any later version.
00014 *
00015 *  The GNU General Public License can be found at
00016 *  http://www.gnu.org/copyleft/gpl.html.
00017 *  A copy is found in the textfile GPL.txt and important notices to the license
00018 *  from the author is found in LICENSE.txt distributed with these scripts.
00019 *
00020 *
00021 *  This script is distributed in the hope that it will be useful,
00022 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00023 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00024 *  GNU General Public License for more details.
00025 *
00026 *  This copyright notice MUST APPEAR in all copies of the script!
00027 ***************************************************************/
00170         // Include classes needed:
00171 require_once(PATH_t3lib.'class.t3lib_tcemain.php');
00172 require_once(PATH_t3lib.'class.t3lib_install.php');
00173 require_once(PATH_t3lib.'class.t3lib_tsstyleconfig.php');
00174 require_once(PATH_t3lib.'class.t3lib_scbase.php');
00175 
00176 require_once('class.em_xmlhandler.php');
00177 require_once('class.em_terconnection.php');
00178 require_once('class.em_unzip.php');
00179 
00180         // from tx_ter by Robert Lemke
00181 define('TX_TER_RESULT_EXTENSIONSUCCESSFULLYUPLOADED', '10504');
00182 
00183 define('EM_INSTALL_VERSION_MIN', 1);
00184 define('EM_INSTALL_VERSION_MAX', 2);
00185 define('EM_INSTALL_VERSION_STRICT', 3);
00186 
00195 class SC_mod_tools_em_index extends t3lib_SCbase {
00196 
00197                 // Internal, static:
00198         var $versionDiffFactor = 1;             // This means that version difference testing for import is detected for sub-versions only, not dev-versions. Default: 1000
00199         var $systemInstall = 0;                         // If "1" then installs in the sysext directory is allowed. Default: 0
00200         var $requiredExt = '';                          // List of required extension (from TYPO3_CONF_VARS)
00201         var $maxUploadSize = 31457280;          // Max size in bytes of extension upload to repository
00202         var $kbMax = 500;                                       // Max size in kilobytes for files to be edited.
00203         var $doPrintContent = true;                     // If set (default), the function printContent() will echo the content which was collected in $this->content. You can set this to FALSE in order to echo content from elsewhere, fx. when using outbut buffering
00204 
00209         var $defaultCategories = Array(
00210                 'cat' => Array (
00211                         'be' => array(),
00212                         'module' => array(),
00213                         'fe' => array(),
00214                         'plugin' => array(),
00215                         'misc' => array(),
00216                         'services' => array(),
00217                         'templates' => array(),
00218                         'example' => array(),
00219                         'doc' => array()
00220                 )
00221         );
00222 
00227         var $categories = Array(
00228                 'be' => 'Backend',
00229                 'module' => 'Backend Modules',
00230                 'fe' => 'Frontend',
00231                 'plugin' => 'Frontend Plugins',
00232                 'misc' => 'Miscellaneous',
00233                 'services' => 'Services',
00234                 'templates' => 'Templates',
00235                 'example' => 'Examples',
00236                 'doc' => 'Documentation'
00237         );
00238 
00243         var $states = Array (
00244                 'alpha' => 'Alpha',
00245                 'beta' => 'Beta',
00246                 'stable' => 'Stable',
00247                 'experimental' => 'Experimental',
00248                 'test' => 'Test',
00249                 'obsolete' => 'Obsolete',
00250         );
00251 
00255         var $stateColors = Array (
00256                 'alpha' => '#d12438',
00257                 'beta' => '#97b17e',
00258                 'stable' => '#3bb65c',
00259                 'experimental' => '#007eba',
00260                 'test' => '#979797',
00261                 'obsolete' => '#000000',
00262         );
00263 
00267         var $typeLabels = Array (
00268                 'S' => 'System',
00269                 'G' => 'Global',
00270                 'L' => 'Local',
00271         );
00272         var $typeDescr = Array (
00273                 'S' => 'System extension (typo3/sysext/) - Always distributed with source code (Static).',
00274                 'G' => 'Global extensions (typo3/ext/) - Available for shared source on server (Dynamic).',
00275                 'L' => 'Local extensions (typo3conf/ext/) - Local for this TYPO3 installation only (Dynamic).',
00276         );
00277         var $typePaths = Array();                       // Also static, set in init()
00278         var $typeBackPaths = Array();           // Also static, set in init()
00279 
00280         var $typeRelPaths = Array (
00281                 'S' => 'sysext/',
00282                 'G' => 'ext/',
00283                 'L' => '../typo3conf/ext/',
00284         );
00285 
00286         var $detailCols = Array (
00287                 0 => 2,
00288                 1 => 5,
00289                 2 => 6,
00290                 3 => 6,
00291                 4 => 4,
00292                 5 => 1
00293         );
00294 
00295         var $fe_user = array(
00296                 'username' => '',
00297                 'password' => '',
00298         );
00299 
00300         var $privacyNotice = 'When you interact with the online repository, server information may be sent and stored in the repository for statistics.';
00301         var $editTextExtensions = 'html,htm,txt,css,tmpl,inc,php,sql,conf,cnf,pl,pm,sh,xml,ChangeLog';
00302         var $nameSpaceExceptions = 'beuser_tracking,design_components,impexp,static_file_edit,cms,freesite,quickhelp,classic_welcome,indexed_search,sys_action,sys_workflows,sys_todos,sys_messages,direct_mail,sys_stat,tt_address,tt_board,tt_calender,tt_guest,tt_links,tt_news,tt_poll,tt_rating,tt_products,setup,taskcenter,tsconfig_help,context_help,sys_note,tstemplate,lowlevel,install,belog,beuser,phpmyadmin,aboutmodules,imagelist,setup,taskcenter,sys_notepad,viewpage,adodb';
00303 
00304 
00305 
00306 
00307 
00308                 // Default variables for backend modules
00309         var $MCONF = array();                           // Module configuration
00310         var $MOD_MENU = array();                        // Module menu items
00311         var $MOD_SETTINGS = array();            // Module session settings
00312         var $doc;                                                       // Document Template Object
00313         var $content;                                           // Accumulated content
00314 
00315         var $inst_keys = array();                       // Storage of installed extensions
00316         var $gzcompress = 0;                            // Is set true, if system support compression.
00317 
00318         var $terConnection;                     // instance of TER connection handler
00319 
00320                 // GPvars:
00321         var $CMD = array();                                     // CMD array
00322         var $listRemote;                                        // If set, connects to remote repository
00323         var $lookUpStr;                                         // Search string when listing local extensions
00324 
00325 
00326 
00327 
00328         /*********************************
00329         *
00330         * Standard module initialization
00331         *
00332         *********************************/
00333 
00339         function init() {
00340                 global $BE_USER,$LANG,$BACK_PATH,$TYPO3_CONF_VARS;
00341 
00342                 // Setting paths of install scopes:
00343                 $this->typePaths = Array (
00344                         'S' => TYPO3_mainDir.'sysext/',
00345                         'G' => TYPO3_mainDir.'ext/',
00346                         'L' => 'typo3conf/ext/'
00347                 );
00348                 $this->typeBackPaths = Array (
00349                         'S' => '../../../',
00350                         'G' => '../../../',
00351                         'L' => '../../../../'.TYPO3_mainDir
00352                 );
00353 
00354                 // Setting module configuration:
00355                 $this->MCONF = $GLOBALS['MCONF'];
00356 
00357                 // Setting GPvars:
00358                 $this->CMD = t3lib_div::_GP('CMD');
00359                 $this->lookUpStr = t3lib_div::_GP('_lookUp');
00360                 $this->listRemote = t3lib_div::_GP('ter_connect');
00361                 $this->listRemote_search = t3lib_div::_GP('ter_search');
00362 
00363 
00364                         // Configure menu
00365                 $this->menuConfig();
00366 
00367                         // Setting internal static:
00368                 if ($TYPO3_CONF_VARS['EXT']['allowSystemInstall'])      $this->systemInstall = 1;
00369                 $this->requiredExt = t3lib_div::trimExplode(',',$TYPO3_CONF_VARS['EXT']['requiredExt'],1);
00370 
00371 
00372                         // Initialize helper object
00373                 $this->terConnection = t3lib_div::makeInstance('SC_mod_tools_em_terconnection');
00374                 $this->terConnection->emObj =& $this;
00375                 $this->terConnection->wsdlURL = $TYPO3_CONF_VARS['EXT']['em_wsdlURL'];
00376                 $this->xmlhandler = t3lib_div::makeInstance('SC_mod_tools_em_xmlhandler');
00377                 $this->xmlhandler->emObj =& $this;
00378                 $this->xmlhandler->useUnchecked = $this->MOD_SETTINGS['display_unchecked'];
00379                 $this->xmlhandler->useObsolete = $this->MOD_SETTINGS['display_obsolete'];
00380 
00381                         // Initialize Document Template object:
00382                 $this->doc = t3lib_div::makeInstance('noDoc');
00383                 $this->doc->backPath = $BACK_PATH;
00384                 $this->doc->docType = 'xhtml_trans';
00385 
00386                         // JavaScript
00387                 $this->doc->JScode = $this->doc->wrapScriptTags('
00388                         script_ended = 0;
00389                         function jumpToUrl(URL) {       //
00390                                 window.location.href = URL;
00391                         }
00392                 ');
00393                 $this->doc->form = '<form action="index.php" method="post" name="pageform">';
00394 
00395                 // Descriptions:
00396                 $this->descrTable = '_MOD_'.$this->MCONF['name'];
00397                 if ($BE_USER->uc['edit_showFieldHelp']) {
00398                         $LANG->loadSingleTableDescription($this->descrTable);
00399                 }
00400 
00401                 // Setting username/password etc. for upload-user:
00402                 $this->fe_user['username'] = $this->MOD_SETTINGS['fe_u'];
00403                 $this->fe_user['password'] = $this->MOD_SETTINGS['fe_p'];
00404                 parent::init();
00405                 $this->handleExternalFunctionValue('singleDetails');
00406         }
00407 
00419         function handleExternalFunctionValue($MM_key='function', $MS_value=NULL)        {
00420                 $MS_value = is_null($MS_value) ? $this->MOD_SETTINGS[$MM_key] : $MS_value;
00421                 $externalItems = $this->getExternalItemConfig($this->MCONF['name'],$MM_key,$MS_value);
00422                 if (is_array($externalItems))   $this->extClassConf = array_merge($externalItems,is_array($this->extClassConf)?$this->extClassConf:array());
00423                 if (is_array($this->extClassConf) && $this->extClassConf['path'])       {
00424                         $this->include_once[]=$this->extClassConf['path'];
00425                 }
00426         }
00427 
00433         function menuConfig()   {
00434                 global $BE_USER, $TYPO3_CONF_VARS;
00435 
00436                 // MENU-ITEMS:
00437                 $this->MOD_MENU = array(
00438                         'function' => array(
00439                                 0 => 'Loaded extensions',
00440                                 1 => 'Install extensions',
00441                                 2 => 'Import extensions',
00442                                 4 => 'Translation handling',
00443                                 3 => 'Settings',
00444                         ),
00445                         'listOrder' => array(
00446                                 'cat' => 'Category',
00447                                 'author_company' => 'Author',
00448                                 'state' => 'State',
00449                                 'type' => 'Type'
00450                         ),
00451                         'display_details' => array(
00452                                 1 => 'Details',
00453                                 0 => 'Description',
00454                                 2 => 'More details',
00455 
00456                                 3 => 'Technical (takes time!)',
00457                                 4 => 'Validating (takes time!)',
00458                                 5 => 'Changed? (takes time!)',
00459                         ),
00460                         'display_shy' => '',
00461                         'display_own' => '',
00462                         'display_unchecked' => '',
00463                         'display_obsolete' => '',
00464 
00465                         'singleDetails' => array(
00466                                 'info' => 'Information',
00467                                 'edit' => 'Edit files',
00468                                 'backup' => 'Backup/Delete',
00469                                 'dump' => 'Dump DB',
00470                                 'upload' => 'Upload to TER',
00471                                 'updateModule' => 'UPDATE!',
00472                         ),
00473                         'fe_u' => '',
00474                         'fe_p' => '',
00475 
00476                         'mirrorListURL' => '',
00477                         'rep_url' => '',
00478                         'extMirrors' => '',
00479                         'selectedMirror' => '',
00480 
00481                         'selectedLanguages' => ''
00482                 );
00483 
00484                 $this->MOD_MENU['singleDetails'] = $this->mergeExternalItems($this->MCONF['name'],'singleDetails',$this->MOD_MENU['singleDetails']);
00485 
00486                 // page/be_user TSconfig settings and blinding of menu-items
00487                 if (!$BE_USER->getTSConfigVal('mod.'.$this->MCONF['name'].'.allowTVlisting'))   {
00488                         unset($this->MOD_MENU['display_details'][3]);
00489                         unset($this->MOD_MENU['display_details'][4]);
00490                         unset($this->MOD_MENU['display_details'][5]);
00491                 }
00492 
00493                 // CLEANSE SETTINGS
00494                 $this->MOD_SETTINGS = t3lib_BEfunc::getModuleData($this->MOD_MENU, t3lib_div::_GP('SET'), $this->MCONF['name']);
00495 
00496                 if ($this->MOD_SETTINGS['function']==2) {
00497                         // If listing from online repository, certain items are removed though:
00498                         unset($this->MOD_MENU['listOrder']['type']);
00499                         unset($this->MOD_MENU['display_details'][2]);
00500                         unset($this->MOD_MENU['display_details'][3]);
00501                         unset($this->MOD_MENU['display_details'][4]);
00502                         unset($this->MOD_MENU['display_details'][5]);
00503                         $this->MOD_SETTINGS = t3lib_BEfunc::getModuleData($this->MOD_MENU, t3lib_div::_GP('SET'), $this->MCONF['name']);
00504                 }
00505                 parent::menuConfig();
00506         }
00507 
00513         function main() {
00514                 global $BE_USER,$LANG,$TYPO3_CONF_VARS;
00515 
00516                 if (empty($this->MOD_SETTINGS['mirrorListURL'])) $this->MOD_SETTINGS['mirrorListURL'] = $TYPO3_CONF_VARS['EXT']['em_mirrorListURL'];
00517 
00518                 // Starting page:
00519                 $this->content.=$this->doc->startPage('Extension Manager');
00520                 $this->content.=$this->doc->header('Extension Manager');
00521                 $this->content.=$this->doc->spacer(5);
00522 
00523                 // Commands given which is executed regardless of main menu setting:
00524                 if ($this->CMD['showExt'])      {       // Show details for a single extension
00525                         $this->showExtDetails($this->CMD['showExt']);
00526                 } elseif ($this->CMD['requestInstallExtensions'])       {       // Show details for a single extension
00527                                 $this->requestInstallExtensions($this->CMD['requestInstallExtensions']);
00528                 } elseif ($this->CMD['importExt'] || $this->CMD['uploadExt'])   {       // Imports an extension from online rep.
00529                         $err = $this->importExtFromRep($this->CMD['importExt'],$this->CMD['extVersion'],$this->CMD['loc'],$this->CMD['uploadExt']);
00530                         if ($err)       {
00531                                 $this->content.=$this->doc->section('',$GLOBALS['TBE_TEMPLATE']->rfw($err));
00532                         }
00533                         if(!$err && $this->CMD['importExt']) {
00534                                 $this->installTranslationsForExtension($this->CMD['importExt'], $this->getMirrorURL());
00535                         }
00536                 } elseif ($this->CMD['importExtInfo'])  {       // Gets detailed information of an extension from online rep.
00537                         $this->importExtInfo($this->CMD['importExtInfo'],$this->CMD['extVersion']);
00538                 } else {        // No command - we show what the menu setting tells us:
00539 
00540                         $menu = $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.menu').' '.
00541                         t3lib_BEfunc::getFuncMenu(0,'SET[function]',$this->MOD_SETTINGS['function'],$this->MOD_MENU['function']);
00542 
00543                         if (t3lib_div::inList('0,1,2',$this->MOD_SETTINGS['function'])) {
00544                                 $menu.='&nbsp;Group by:&nbsp;'.t3lib_BEfunc::getFuncMenu(0,'SET[listOrder]',$this->MOD_SETTINGS['listOrder'],$this->MOD_MENU['listOrder']).
00545                                 '&nbsp;&nbsp;Show:&nbsp;'.t3lib_BEfunc::getFuncMenu(0,'SET[display_details]',$this->MOD_SETTINGS['display_details'],$this->MOD_MENU['display_details']).'<br />';
00546                         }
00547                         if (t3lib_div::inList('0,1',$this->MOD_SETTINGS['function']))   {
00548                                 $menu.='Display shy extensions:&nbsp;&nbsp;'.t3lib_BEfunc::getFuncCheck(0,'SET[display_shy]',$this->MOD_SETTINGS['display_shy']);
00549                         }
00550                         if (t3lib_div::inList('2',$this->MOD_SETTINGS['function']) && strlen($this->fe_user['username']))       {
00551                                 $menu.='Only my extensions:&nbsp;&nbsp;'.t3lib_BEfunc::getFuncCheck(0,'SET[display_own]',$this->MOD_SETTINGS['display_own']);
00552                         }
00553                         if (t3lib_div::inList('0,1,2',$this->MOD_SETTINGS['function'])) {
00554                                 $menu.='&nbsp;&nbsp;Show obsolete:&nbsp;&nbsp;'.t3lib_BEfunc::getFuncCheck(0,'SET[display_obsolete]',$this->MOD_SETTINGS['display_obsolete']);
00555                         }
00556 
00557                         $this->content.=$this->doc->section('','<span class="nobr">'.$menu.'</span>');
00558                         $this->content.=$this->doc->spacer(10);
00559 
00560                         switch((string)$this->MOD_SETTINGS['function']) {
00561                                 case '0':
00562                                         // Lists loaded (installed) extensions
00563                                         $this->extensionList_loaded();
00564                                         break;
00565                                 case '1':
00566                                         // Lists the installed (available) extensions
00567                                         $this->extensionList_installed();
00568                                         break;
00569                                 case '2':
00570                                         // Lists the extensions available from online rep.
00571                                         $this->extensionList_import();
00572                                         break;
00573                                 case '3':
00574                                         // Shows the settings screen
00575                                         $this->alterSettings();
00576                                         break;
00577                                 case '4':
00578                                         // Allows to set the translation preferences and check the status
00579                                         $this->translationHandling();
00580                                         break;
00581                                 default:
00582                                         $this->extObjContent();
00583                                         break;
00584                         }
00585                 }
00586 
00587                 // Shortcuts:
00588                 if ($BE_USER->mayMakeShortcut())        {
00589                         $this->content.=$this->doc->spacer(20).$this->doc->section('',$this->doc->makeShortcutIcon('CMD','function',$this->MCONF['name']));
00590                 }
00591         }
00592 
00598         function printContent() {
00599                 if ($this->doPrintContent) {
00600                         $this->content.= $this->doc->endPage();
00601                         echo $this->content;
00602                 }
00603         }
00604 
00605 
00606 
00607 
00608 
00609 
00610 
00611 
00612 
00613 
00614         /*********************************
00615         *
00616         * Function Menu Applications
00617         *
00618         *********************************/
00619 
00625         function extensionList_loaded() {
00626                 global $TYPO3_LOADED_EXT;
00627 
00628                 list($list,$cat) = $this->getInstalledExtensions();
00629 
00630                 // Loaded extensions
00631                 $content = '';
00632                 $lines = array();
00633 
00634                 // Available extensions
00635                 if (is_array($cat[$this->MOD_SETTINGS['listOrder']]))   {
00636                         $content='';
00637                         $lines=array();
00638                         $lines[] = $this->extensionListRowHeader(' class="bgColor5"',array('<td><img src="clear.gif" width="1" height="1" alt="" /></td>'));
00639 
00640                         foreach($cat[$this->MOD_SETTINGS['listOrder']] as $catName => $extEkeys)        {
00641                                 natcasesort($extEkeys);
00642                                 reset($extEkeys);
00643                                 $extensions = array();
00644                                 while(list($extKey)=each($extEkeys))    {
00645                                         if (array_key_exists($extKey,$TYPO3_LOADED_EXT) && ($this->MOD_SETTINGS['display_shy'] || !$list[$extKey]['EM_CONF']['shy']) && $this->searchExtension($extKey,$list[$extKey])) {
00646                                                 if (in_array($extKey, $this->requiredExt))      {
00647                                                         $loadUnloadLink = '<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw('Rq').'</strong>';
00648                                                 } else {
00649                                                         $loadUnloadLink = '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[remove]=1').'">'.$this->removeButton().'</a>';
00650                                                 }
00651 
00652                                                 $extensions[] = $this->extensionListRow($extKey,$list[$extKey],array('<td class="bgColor">'.$loadUnloadLink.'</td>'));
00653                                         }
00654                                 }
00655                                 if(count($extensions)) {
00656                                         $lines[]='<tr><td colspan="'.(3+$this->detailCols[$this->MOD_SETTINGS['display_details']]).'"><br /></td></tr>';
00657                                         $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'],$catName).'</strong></td></tr>';
00658                                         $lines[] = implode(chr(10),$extensions);
00659                                 }
00660                         }
00661                 }
00662 
00663                 $content.= t3lib_BEfunc::cshItem('_MOD_tools_em', 'loaded', $GLOBALS['BACK_PATH'],'');
00664 
00665                 $content.= 'Look up: <input type="text" name="_lookUp" value="'.htmlspecialchars($this->lookUpStr).'" /><input type="submit" value="Search"/><br/><br/>';
00666 
00667                 $content.= '
00668 
00669                         <!-- Loaded Extensions List -->
00670                         <table border="0" cellpadding="2" cellspacing="1">'.implode('',$lines).'</table>';
00671 
00672                 $this->content.=$this->doc->section('Loaded Extensions',$content,0,1);
00673         }
00674 
00680         function extensionList_installed()      {
00681                 global $TYPO3_LOADED_EXT;
00682 
00683                 list($list,$cat)=$this->getInstalledExtensions();
00684 
00685                 // Available extensions
00686                 if (is_array($cat[$this->MOD_SETTINGS['listOrder']]))   {
00687                         $content='';
00688                         $lines=array();
00689                         $lines[]=$this->extensionListRowHeader(' class="bgColor5"',array('<td><img src="clear.gif" width="18" height="1" alt="" /></td>'));
00690 
00691                         $allKeys=array();
00692                         foreach($cat[$this->MOD_SETTINGS['listOrder']] as $catName => $extEkeys)        {
00693                                 if(!$this->MOD_SETTINGS['display_obsolete'] && $catName=='obsolete') continue;
00694 
00695                                 $allKeys[]='';
00696                                 $allKeys[]='TYPE: '.$catName;
00697 
00698                                 natcasesort($extEkeys);
00699                                 reset($extEkeys);
00700                                 $extensions = array();
00701                                 while(list($extKey)=each($extEkeys))    {
00702                                         $allKeys[]=$extKey;
00703                                         if ((!$list[$extKey]['EM_CONF']['shy'] || $this->MOD_SETTINGS['display_shy']) &&
00704                                                         ($list[$extKey]['EM_CONF']['state']!='obsolete' || $this->MOD_SETTINGS['display_obsolete'])
00705                                          && $this->searchExtension($extKey,$list[$extKey]))     {
00706                                                 $loadUnloadLink = t3lib_extMgm::isLoaded($extKey)?
00707                                                 '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[remove]=1&CMD[clrCmd]=1&SET[singleDetails]=info').'">'.$this->removeButton().'</a>':
00708                                                 '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[load]=1&CMD[clrCmd]=1&SET[singleDetails]=info').'">'.$this->installButton().'</a>';
00709                                                 if (in_array($extKey,$this->requiredExt))       {
00710                                                         $loadUnloadLink='<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw('Rq').'</strong>';
00711                                                 }
00712                                                 $theRowClass = t3lib_extMgm::isLoaded($extKey)? 'em-listbg1' : 'em-listbg2';
00713                                                 $extensions[]=$this->extensionListRow($extKey,$list[$extKey],array('<td class="bgColor">'.$loadUnloadLink.'</td>'),$theRowClass);
00714                                         }
00715                                 }
00716                                 if(count($extensions)) {
00717                                         $lines[]='<tr><td colspan="'.(3+$this->detailCols[$this->MOD_SETTINGS['display_details']]).'"><br /></td></tr>';
00718                                         $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'],$catName).'</strong></td></tr>';
00719                                         $lines[] = implode(chr(10),$extensions);
00720                                 }
00721                         }
00722 
00723                         $content.='
00724 
00725 
00726 <!--
00727 EXTENSION KEYS:
00728 
00729 '.trim(implode(chr(10),$allKeys)).'
00730 
00731 -->
00732 
00733 ';
00734 
00735                         $content.= t3lib_BEfunc::cshItem('_MOD_tools_em', 'avail', $GLOBALS['BACK_PATH'],'|<br/>');
00736                         $content.= 'If you want to use an extension in TYPO3, you should simply click the "plus" button '.$this->installButton().' . <br />
00737                                                 Installed extensions can also be removed again - just click the remove button '.$this->removeButton().' .<br /><br />';
00738 
00739                         $content.= 'Look up: <input type="text" name="_lookUp" value="'.htmlspecialchars($this->lookUpStr).'" /><input type="submit" value="Search"/><br/><br/>';
00740 
00741                         $content.= '<table border="0" cellpadding="2" cellspacing="1">'.implode('',$lines).'</table>';
00742 
00743                         $this->content.=$this->doc->section('Available Extensions - Grouped by: '.$this->MOD_MENU['listOrder'][$this->MOD_SETTINGS['listOrder']],$content,0,1);
00744                 }
00745         }
00746 
00752         function extensionList_import() {
00753                 global $TYPO3_LOADED_EXT;
00754                 $content='';
00755 
00756                         // Listing from online repository:
00757                 if ($this->listRemote)  {
00758                         list($inst_list,) = $this->getInstalledExtensions();
00759                         $this->inst_keys = array_flip(array_keys($inst_list));
00760 
00761                         $this->detailCols[1]+=6;
00762 
00763                                 // see if we have an extensionlist at all
00764                         $this->xmlhandler->loadExtensionsXML();
00765                         if (!count($this->xmlhandler->extensionsXML))   {
00766                                 $content .= $this->fetchMetaData('extensions');
00767                         }
00768 
00769                         if($this->MOD_SETTINGS['display_own'] && strlen($this->fe_user['username'])) {
00770                                 $this->xmlhandler->searchExtensionsXML($this->listRemote_search, $this->fe_user['username']);
00771                         } else {
00772                                 $this->xmlhandler->searchExtensionsXML($this->listRemote_search);
00773                         }
00774                         if (count($this->xmlhandler->extensionsXML))    {
00775                                 list($list,$cat) = $this->prepareImportExtList();
00776 
00777                                         // Available extensions
00778                                 if (is_array($cat[$this->MOD_SETTINGS['listOrder']]))   {
00779                                         $lines=array();
00780                                         $lines[]=$this->extensionListRowHeader(' class="bgColor5"',array('<td><img src="clear.gif" width="18" height="1" alt="" /></td>'),1);
00781 
00782                                         foreach($cat[$this->MOD_SETTINGS['listOrder']] as $catName => $extEkeys)        {
00783                                                 if (count($extEkeys))   {
00784                                                         $lines[]='<tr><td colspan="'.(3+$this->detailCols[$this->MOD_SETTINGS['display_details']]).'"><br /></td></tr>';
00785                                                         $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'],$catName).'</strong></td></tr>';
00786 
00787                                                         natcasesort($extEkeys);
00788                                                         reset($extEkeys);
00789                                                         while(list($extKey)=each($extEkeys))    {
00790                                                                 $version = array_keys($list[$extKey]['versions']);
00791                                                                 $version = end($version);
00792                                                                 $ext = $list[$extKey]['versions'][$version];
00793                                                                 $ext['downloadcounter_all'] = $list[$extKey]['downloadcounter'];
00794                                                                 $ext['_ICON'] = $list[$extKey]['_ICON'];
00795                                                                 $loadUnloadLink='';
00796                                                                 if ($inst_list[$extKey]['type']!='S' && (!isset($inst_list[$extKey]) || $this->versionDifference($version,$inst_list[$extKey]['EM_CONF']['version'],$this->versionDiffFactor))) {
00797                                                                         if (isset($inst_list[$extKey])) {
00798                                                                                         // update
00799                                                                                 $loc= ($inst_list[$extKey]['type']=='G'?'G':'L');
00800                                                                                 $aUrl = 'index.php?CMD[importExt]='.$extKey.'&CMD[extVersion]='.$version.'&CMD[loc]='.$loc;
00801                                                                                 $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>';
00802                                                                         } else {
00803                                                                                         // import
00804                                                                                 $aUrl = 'index.php?CMD[importExt]='.$extKey.'&CMD[extVersion]='.$version.'&CMD[loc]=L';
00805                                                                                 $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>';
00806                                                                         }
00807                                                                 } else {
00808                                                                         $loadUnloadLink = '&nbsp;';
00809                                                                 }
00810 
00811                                                                 if (isset($inst_list[$extKey])) {
00812                                                                         $theRowClass = t3lib_extMgm::isLoaded($extKey) ? 'em-listbg1' : 'em-listbg2';
00813                                                                 } else {
00814                                                                         $theRowClass = 'em-listbg3';
00815                                                                 }
00816 
00817                                                                 $lines[]=$this->extensionListRow($extKey,$ext,array('<td class="bgColor">'.$loadUnloadLink.'</td>'),$theRowClass,$inst_list,1,'index.php?CMD[importExtInfo]='.rawurlencode($extKey));
00818                                                         }
00819                                                 }
00820                                         }
00821 
00822                                                 // CSH:
00823                                         $content.= t3lib_BEfunc::cshItem('_MOD_tools_em', 'import_ter', $GLOBALS['BACK_PATH'],'|<br/>');
00824                                         $onsubmit = "window.location.href='index.php?ter_connect=1&ter_search='+escape(this.elements['_lookUp'].value);return false;";
00825                                         $content.= '</form><form action="index.php" method="post" onsubmit="'.htmlspecialchars($onsubmit).'">List or look up extensions<br />
00826                                                         <input type="text" name="_lookUp" value="'.htmlspecialchars($this->listRemote_search).'" /> <input type="submit" value="Look up" /><br /><br />';
00827 
00828                                         $content.= '
00829 
00830                                         <!-- TER Extensions list -->
00831                                         <table border="0" cellpadding="2" cellspacing="1">'.implode(chr(10),$lines).'</table>';
00832                                         $content.= '<br /><br /><strong>PRIVACY NOTICE:</strong><br /> '.$this->privacyNotice;
00833 
00834                                         $this->content.=$this->doc->section('Extensions in TYPO3 Extension Repository (online) - Grouped by: '.$this->MOD_MENU['listOrder'][$this->MOD_SETTINGS['listOrder']],$content,0,1);
00835 
00836                                                 // Plugins which are NOT uploaded to repository but present on this server.
00837                                         $content='';
00838                                         $lines=array();
00839                                         if (count($this->inst_keys))    {
00840                                                 reset($this->inst_keys);
00841                                                 while(list($extKey)=each($this->inst_keys))     {
00842                                                         if(strlen($this->listRemote_search) && !stristr($extKey,$this->listRemote_search)) continue;
00843 
00844                                                         $loadUnloadLink = t3lib_extMgm::isLoaded($extKey)?
00845                                                         '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[remove]=1&CMD[clrCmd]=1&SET[singleDetails]=info').'">'.$this->removeButton().'</a>':
00846                                                         '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[load]=1&CMD[clrCmd]=1&SET[singleDetails]=info').'">'.$this->installButton().'</a>';
00847                                                         if (in_array($extKey,$this->requiredExt))       $loadUnloadLink='<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw('Rq').'</strong>';
00848                                                         $lines[]=$this->extensionListRow($extKey,$inst_list[$extKey],array('<td class="bgColor">'.$loadUnloadLink.'</td>'),t3lib_extMgm::isLoaded($extKey)?'em-listbg1':'em-listbg2');
00849                                                 }
00850                                         }
00851                                         if(count($lines)) {
00852                                                 $content.= 'This is the list of extensions which are available locally, but not in the repository.<br />The might be user-defined and should be prepended user_ then.<br /><br />';
00853                                                 $content.= '<table border="0" cellpadding="2" cellspacing="1">'.
00854                                                         $this->extensionListRowHeader(' class="bgColor5"',array('<td><img src="clear.gif" width="18" height="1" alt="" /></td>')).
00855                                                         implode('',$lines).'</table>';
00856                                                 $this->content.=$this->doc->spacer(20);
00857                                                 $this->content.=$this->doc->section('Extensions found only on this server',$content,0,1);
00858                                         }
00859                                 }
00860                         } else {
00861                                 $content.= t3lib_BEfunc::cshItem('_MOD_tools_em', 'import_ter', $GLOBALS['BACK_PATH'],'|<br/>');
00862                                 $onsubmit = "window.location.href='index.php?ter_connect=1&ter_search='+escape(this.elements['_lookUp'].value);return false;";
00863                                 $content.= '</form><form action="index.php" method="post" onsubmit="'.htmlspecialchars($onsubmit).'">List or look up extensions<br />
00864                                         <input type="text" name="_lookUp" value="'.htmlspecialchars($this->listRemote_search).'" /> <input type="submit" value="Look up" /><br /><br />';
00865 
00866                                 $content.= '<p><strong>No matching extensions found.</strong></p>';
00867 
00868                                 $content.= '<br /><br /><strong>PRIVACY NOTICE:</strong><br /> '.$this->privacyNotice;
00869                                 $this->content.=$this->doc->section('Extensions in TYPO3 Extension Repository (online) - Grouped by: '.$this->MOD_MENU['listOrder'][$this->MOD_SETTINGS['listOrder']],$content,0,1);
00870                         }
00871                 } else {
00872                                 // CSH
00873                         $content.= t3lib_BEfunc::cshItem('_MOD_tools_em', 'import', $GLOBALS['BACK_PATH'],'|<br/>');
00874 
00875                         $onsubmit = "window.location.href='index.php?ter_connect=1&ter_search='+escape(this.elements['_lookUp'].value);return false;";
00876                         $content.= '</form><form action="index.php" method="post" onsubmit="'.htmlspecialchars($onsubmit).'">List or look up <strong'.($this->MOD_SETTINGS['display_unchecked']?' style="color:#900;">all':' style="color:#090;">reviewed').'</strong> extensions<br />
00877                         <input type="text" name="_lookUp" value="" /> <input type="submit" value="Look up" /><br /><br />';
00878 
00879                         if ($this->CMD['fetchMetaData'])        {       // fetches mirror/extension data from online rep.
00880                                 $content .= $this->fetchMetaData($this->CMD['fetchMetaData']);
00881                         } else {
00882                                 $onCLick = "window.location.href='index.php?CMD[fetchMetaData]=extensions';return false;";
00883                                 $content.= 'Connect to the current mirror and retrieve the current list of available plugins from the TYPO3 Extension Repository.<br />
00884                                 <input type="submit" value="Retrieve/Update" onclick="'.htmlspecialchars($onCLick).'" />';
00885                                 if(is_file(PATH_site.'typo3temp/extensions.bin')) {
00886                                         $content .= ' (last update: '.date('Y-m-d H:i',filemtime(PATH_site.'typo3temp/extensions.bin')).')';
00887                                 }
00888                         }
00889 
00890                         $content .= '<br /><br /><strong>PRIVACY NOTICE:</strong><br />'.$this->privacyNotice;
00891 
00892                         $this->content.=$this->doc->section('Extensions in TYPO3 Extension Repository',$content,0,1);
00893                 }
00894 
00895                         // Upload:
00896                 if ($this->importAtAll())       {
00897                         $content= '</form><form action="index.php" enctype="'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['form_enctype'].'" method="post">
00898                         Upload extension file (.t3x):<br />
00899                                 <input type="file" size="60" name="upload_ext_file" /><br />
00900                                 ... to location:<br />
00901                                 <select name="CMD[loc]">';
00902                         if ($this->importAsType('L'))   $content.='<option value="L">Local (../typo3conf/ext/)</option>';
00903                         if ($this->importAsType('G'))   $content.='<option value="G">Global (typo3/ext/)</option>';
00904                         if ($this->importAsType('S'))   $content.='<option value="S">System (typo3/sysext/)</option>';
00905                         $content.='</select><br />
00906         <input type="checkbox" value="1" name="CMD[uploadOverwrite]" /> Overwrite any existing extension!<br />
00907         <input type="submit" name="CMD[uploadExt]" value="Upload extension file" /><br />
00908                         ';
00909                 } else $content=$this->noImportMsg();
00910 
00911                 $this->content.=$this->doc->spacer(20);
00912                 $this->content.=$this->doc->section('Upload extension file directly (.t3x):',$content,0,1);
00913         }
00914 
00920         function alterSettings()        {
00921 
00922                         // Prepare the HTML output:
00923                 $content.= '
00924                         '.t3lib_BEfunc::cshItem('_MOD_tools_em', 'settings', $GLOBALS['BACK_PATH'],'|<br/>').'
00925                         <fieldset><legend>Security Settings</legend>
00926                         <table border="0" cellpadding="2" cellspacing="2">
00927                                 <tr class="bgColor4">
00928                                         <td>Enable extensions without review (basic security check):</td>
00929                                         <td>'.t3lib_BEfunc::getFuncCheck(0,'SET[display_unchecked]',$this->MOD_SETTINGS['display_unchecked']).'</td>
00930                                 </tr>
00931                         </table>
00932                         <strong>Notice:</strong> Make sure you know what consequences enabling this checkbox might have. Check the <a href="http://typo3.org/extensions/what-are-reviews/" target="_blank">information on typo3.org about security reviewing</a>!
00933                         </fieldset>
00934                         <br />
00935                         <br />
00936                         <fieldset><legend>User Settings</legend>
00937                         <table border="0" cellpadding="2" cellspacing="2">
00938                                 <tr class="bgColor4">
00939                                         <td>Enter repository username:</td>
00940                                         <td><input type="text" name="SET[fe_u]" value="'.htmlspecialchars($this->MOD_SETTINGS['fe_u']).'" /></td>
00941                                 </tr>
00942                                 <tr class="bgColor4">
00943                                         <td>Enter repository password:</td>
00944                                         <td><input type="password" name="SET[fe_p]" value="'.htmlspecialchars($this->MOD_SETTINGS['fe_p']).'" /></td>
00945                                 </tr>
00946                         </table>
00947                         <strong>Notice:</strong> This is <em>not</em> your password to the TYPO3 backend! This user information is what is needed to log in at typo3.org with your account there!
00948                         </fieldset>
00949                         <br />
00950                         <br />
00951                         <fieldset><legend>Mirror selection</legend>
00952                         <table border="0" cellpadding="2" cellspacing="2">
00953                                 <tr class="bgColor4">
00954                                         <td>Enter mirror list URL:</td>
00955                                         <td><input type="text" size="50" name="SET[mirrorListURL]" value="'.htmlspecialchars($this->MOD_SETTINGS['mirrorListURL']).'" /></td>
00956                                 </tr>
00957                         </table>
00958                         <br />
00959                         <p>Select a mirror from below. This list is built from the online mirror list retrieved from the URL above.<br /><br /></p>
00960                         <fieldset><legend>Mirror list</legend>';
00961                 if(!empty($this->MOD_SETTINGS['mirrorListURL'])) {
00962                         if ($this->CMD['fetchMetaData'])        {       // fetches mirror/extension data from online rep.
00963                                 $content .= $this->fetchMetaData($this->CMD['fetchMetaData']);
00964                         } else {
00965                                 $content.= '<a href="index.php?CMD[fetchMetaData]=mirrors">Click here to reload the list.</a>';
00966                         }
00967                 }
00968                 $content .= '<br />
00969                         <table cellspacing="4" style="text-align:left; vertical-alignment:top;">
00970                         <tr><td>Use</td><td>Name</td><td>URL</td><td>Country</td><td>Sponsored by</td></tr>
00971                 ';
00972 
00973                 if (!strlen($this->MOD_SETTINGS['extMirrors'])) $this->fetchMetaData('mirrors');
00974                 $extMirrors = unserialize($this->MOD_SETTINGS['extMirrors']);
00975                 $extMirrors[''] = array('title'=>'Random (recommended!)');
00976                 ksort($extMirrors);
00977                 if(is_array($extMirrors)) {
00978                         foreach($extMirrors as $k => $v) {
00979                                 if(isset($v['sponsor'])) {
00980                                         $sponsor = '<a href="'.htmlspecialchars($v['sponsor']['link']).'" target="_new"><img src="'.$v['sponsor']['logo'].'" title="'.htmlspecialchars($v['sponsor']['name']).'" alt="'.htmlspecialchars($v['sponsor']['name']).'" /></a>';
00981                                 }
00982                                 $selected = ($this->MOD_SETTINGS['selectedMirror']==$k) ? 'checked="checked"' : '';
00983                                 $content.='<tr class="bgColor4">
00984                         <td><input type="radio" name="SET[selectedMirror]" value="'.$k.'" '.$selected.'/></td><td>'.htmlspecialchars($v['title']).'</td><td>'.htmlspecialchars($v['host'].$v['path']).'</td><td>'.$v['country'].'</td><td>'.$sponsor.'</td></tr>';
00985                         }
00986                 }
00987                 $content.= '
00988                         </table>
00989                         </fieldset>
00990                         <br />
00991                         <table border="0" cellpadding="2" cellspacing="2">
00992                                 <tr class="bgColor4">
00993                                         <td>Enter repository URL:</td>
00994                                         <td><input type="text" size="50" name="SET[rep_url]" value="'.htmlspecialchars($this->MOD_SETTINGS['rep_url']).'" /></td>
00995                                 </tr>
00996                         </table>
00997 
00998                         If you set a repository URL, this overrides the use of a mirror. Use this to select a specific (private) repository.<br />
00999                         </fieldset>
01000                         <br />
01001                         <input type="submit" value="Update" />
01002                 ';
01003 
01004                 $this->content.=$this->doc->section('Repository settings',$content,0,1);
01005         }
01006 
01012         function translationHandling()  {
01013                 global $LANG, $TYPO3_LOADED_EXT;
01014                 $LANG->includeLLFile('EXT:setup/mod/locallang.xml');
01015 
01016                 $incoming = t3lib_div::_POST('SET');
01017                 if(isset($incoming['selectedLanguages']) && is_array($incoming['selectedLanguages'])) {
01018                         t3lib_BEfunc::getModuleData($this->MOD_MENU, array('selectedLanguages' => serialize($incoming['selectedLanguages'])), $this->MCONF['name'], '', 'selectedLanguages');
01019                         $this->MOD_SETTINGS['selectedLanguages'] = serialize($incoming['selectedLanguages']);
01020                 }
01021 
01022                 $selectedLanguages = unserialize($this->MOD_SETTINGS['selectedLanguages']);
01023                 if(count($selectedLanguages)==1 && empty($selectedLanguages[0])) $selectedLanguages = array();
01024                 $theLanguages = t3lib_div::trimExplode('|',TYPO3_languages);
01025                 foreach($theLanguages as $val)  {
01026                         if ($val!='default')    {
01027                                 $localLabel = '  -  ['.htmlspecialchars($GLOBALS['LOCAL_LANG']['default']['lang_'.$val]).']';
01028                                 $selected = (is_array($selectedLanguages) && in_array($val, $selectedLanguages)) ? ' selected="selected"' : '';
01029                                 $opt[$GLOBALS['LOCAL_LANG']['default']['lang_'.$val].'--'.$val]='
01030              <option value="'.$val.'"'.$selected.'>'.$LANG->getLL('lang_'.$val,1).$localLabel.'</option>';
01031                         }
01032                 }
01033                 ksort($opt);
01034 
01035                         // Prepare the HTML output:
01036                 $content.= '
01037                         '.t3lib_BEfunc::cshItem('_MOD_tools_em', 'translation', $GLOBALS['BACK_PATH'],'|<br/>').'
01038                         <fieldset><legend>Translation Settings</legend>
01039                         <table border="0" cellpadding="2" cellspacing="2">
01040                                 <tr class="bgColor4">
01041                                         <td>Languages to fetch:</td>
01042                                         <td>
01043                                           <select name="SET[selectedLanguages][]" multiple="multiple" size="10">
01044                                           <option></option>'.
01045             implode('',$opt).'
01046             </select>
01047           </td>
01048                                 </tr>
01049                         </table>
01050                         <br />
01051                         <p>For the selected languages the EM tries to download and install translation files if available, whenever an extension is installed. (This replaces the <code>csh_*</code> extensions that were used to install core translations before TYPO3 version 4!)<br />
01052                         <br />To request an update/install for already loaded extensions, see below.</p>
01053                         </fieldset>
01054                         <br />
01055                         <input type="submit" value="Save selection" />
01056                         <br />
01057                         </fieldset>';
01058 
01059                 $this->content.=$this->doc->section('Translation settings',$content,0,1);
01060 
01061                 if(count($selectedLanguages)>0) {
01062                         $mirrorURL = $this->getMirrorURL();
01063                         $content = '<input type="button" value="Check status against repository" onclick="document.location.href=\''.t3lib_div::linkThisScript(array('l10n'=>'check')).'\'" />&nbsp;<input type="button" value="Update from repository" onclick="document.location.href=\''.t3lib_div::linkThisScript(array('l10n'=>'update')).'\'" />';
01064 
01065                         if(t3lib_div::_GET('l10n') == 'check') {
01066                                 $loadedExtensions = array_keys($TYPO3_LOADED_EXT);
01067                                 $loadedExtensions = array_diff($loadedExtensions,array('_CACHEFILE'));
01068 
01069                                         // Override content output - we now do that ourself:
01070                                 echo ($this->content . $this->doc->section('Translation status',$content,0,1));
01071                                 $this->doPrintContent = FALSE;
01072                                 flush();
01073 
01074                                 echo '
01075                                 <br />
01076                                 <br />
01077                                 <p id="progress-message">
01078                                         Checking translation status, please wait ...
01079                                 </p>
01080                                 <br />
01081                                 <div style="width:100%; height:20px; border: 1px solid black;">
01082                                         <div id="progress-bar" style="float: left; width: 0%; height: 20px; background-color:green;">&nbsp;</div>
01083                                         <div id="transparent-bar" style="float: left; width: 100%; height: 20px; background-color:'.$this->doc->bgColor2.';">&nbsp;</div>
01084                                 </div>
01085                                 <br />
01086                                 <br /><p>This table shows the status of the loaded extension\'s translations.</p><br />
01087                                 <table border="0" cellpadding="2" cellspacing="2">
01088                                         <tr class="bgColor2"><td>Extension key</td>
01089                                 ';
01090 
01091                                 foreach($selectedLanguages as $lang) {
01092                                         echo ('<td>'.$LANG->getLL('lang_'.$lang,1).'</td>');
01093                                 }
01094                                 echo ('</tr>');
01095 
01096                                 $counter = 1;
01097                                 foreach($loadedExtensions as $extKey) {
01098 
01099                                         $percentDone = intval (($counter / count($loadedExtensions)) * 100);
01100                                         echo ('
01101                                         <script>
01102                                                 document.getElementById("progress-bar").style.width = "'.$percentDone.'%";
01103                                                 document.getElementById("transparent-bar").style.width = "'.(100-$percentDone).'%";
01104                                                 document.getElementById("progress-message").firstChild.data="Checking translation status for extension \"'.$extKey.'\" ...";
01105                                         </script>
01106                                         ');
01107 
01108                                         flush();
01109                                         $translationStatusArr = $this->terConnection->fetchTranslationStatus($extKey,$mirrorURL);
01110 
01111                                         echo ('<tr class="bgColor4"><td>'.$extKey.'</td>');
01112                                         foreach($selectedLanguages as $lang) {
01113                                                 // remote unknown -> keine l10n
01114                                                 if(!isset($translationStatusArr[$lang])) {
01115                                                         echo ('<td title="No translation available">N/A</td>');
01116                                                         continue;
01117                                                 }
01118                                                         // determine local md5 from zip
01119                                                 if(is_file(PATH_site.'typo3temp/'.$extKey.'-l10n-'.$lang.'.zip')) {
01120                                                         $localmd5 = md5_file(PATH_site.'typo3temp/'.$extKey.'-l10n-'.$lang.'.zip');
01121                                                 } else {
01122                                                         echo ('<td title="Not installed / Unknown" style="background-color:#ff0">???</td>');
01123                                                         continue;
01124                                                 }
01125                                                         // local!=remote -> needs update
01126                                                 if($localmd5 != $translationStatusArr[$lang]['md5']) {
01127                                                         echo ('<td title="Needs update" style="background-color:#ff0">UPD</td>');
01128                                                         continue;
01129                                                 }
01130                                                 echo ('<td title="Is up to date" style="background-color:#69a550">OK</td>');
01131                                         }
01132                                         echo ('</tr>');
01133 
01134                                         $counter ++;
01135                                 }
01136                                 echo '</table>
01137                                         <script>
01138                                                 document.getElementById("progress-message").firstChild.data="Check done.";
01139                                         </script>
01140                                 ';
01141                                 echo $this->doc->endPage();
01142                                 return '';
01143 
01144                         } elseif(t3lib_div::_GET('l10n') == 'update') {
01145                                 $loadedExtensions = array_keys($TYPO3_LOADED_EXT);
01146                                 $loadedExtensions = array_diff($loadedExtensions,array('_CACHEFILE'));
01147 
01148                                         // Override content output - we now do that ourself:
01149                                 echo ($this->content . $this->doc->section('Translation status',$content,0,1));
01150                                 $this->doPrintContent = FALSE;
01151                                 flush();
01152 
01153                                 echo ('
01154                                 <br />
01155                                 <br />
01156                                 <p id="progress-message">
01157                                         Updating translations, please wait ...
01158                                 </p>
01159                                 <br />
01160                                 <div style="width:100%; height:20px; border: 1px solid black;">
01161                                         <div id="progress-bar" style="float: left; width: 0%; height: 20px; background-color:green;">&nbsp;</div>
01162                                         <div id="transparent-bar" style="float: left; width: 100%; height: 20px; background-color:'.$this->doc->bgColor2.';">&nbsp;</div>
01163                                 </div>
01164                                 <br />
01165                                 <br /><p>This table shows the update results of the loaded extension\'s translations.<br />
01166                                 <em>If you want to force a full check/update, delete the l10n zip-files from the typo3temp folder.</em></p><br />
01167                                 <table border="0" cellpadding="2" cellspacing="2">
01168                                         <tr class="bgColor2"><td>Extension key</td>
01169                                 ');
01170 
01171                                 foreach($selectedLanguages as $lang) {
01172                                         echo '<td>'.$LANG->getLL('lang_'.$lang,1).'</td>';
01173                                 }
01174                                 echo '</tr>';
01175 
01176                                 $counter = 1;
01177                                 foreach($loadedExtensions as $extKey) {
01178                                         $percentDone = intval (($counter / count($loadedExtensions)) * 100);
01179                                         echo ('
01180                                         <script>
01181                                                 document.getElementById("progress-bar").style.width = "'.$percentDone.'%";
01182                                                 document.getElementById("transparent-bar").style.width = "'.(100-$percentDone).'%";
01183                                                 document.getElementById("progress-message").firstChild.data="Updating translation for extension \"'.$extKey.'\" ...";
01184                                         </script>
01185                                         ');
01186 
01187                                         flush();
01188                                         $translationStatusArr = $this->terConnection->fetchTranslationStatus($extKey,$mirrorURL);
01189 
01190                                         echo ('<tr class="bgColor4"><td>'.$extKey.'</td>');
01191                                         foreach($selectedLanguages as $lang) {
01192                                                         // remote unknown -> no l10n available
01193                                                 if(!isset($translationStatusArr[$lang])) {
01194                                                         echo ('<td title="No translation available">N/A</td>');
01195                                                         continue;
01196                                                 }
01197                                                 // determine local md5 from zip
01198                                                 if(is_file(PATH_site.'typo3temp/'.$extKey.'-l10n-'.$lang.'.zip')) {
01199                                                         $localmd5 = md5_file(PATH_site.'typo3temp/'.$extKey.'-l10n-'.$lang.'.zip');
01200                                                 } else {
01201                                                         $localmd5 = 'zzz';
01202                                                 }
01203                                                 // local!=remote or not installed -> needs update
01204                                                 if($localmd5 != $translationStatusArr[$lang]['md5']) {
01205                                                         $ret = $this->updateTranslation($extKey, $lang, $mirrorURL);
01206                                                         if($ret === true) {
01207                                                                 echo ('<td title="Has been updated" style="background-color:#69a550">UPD</td>');
01208                                                         } else {
01209                                                                 echo ('<td title="'.htmlspecialchars($ret).'" style="background-color:#cb3352">ERR</td>');
01210                                                         }
01211                                                         continue;
01212                                                 }
01213                                                 echo ('<td title="Is up to date" style="background-color:#69a550">OK</td>');
01214                                         }
01215                                         echo ('</tr>');
01216 
01217                                         $counter++;
01218                                 }
01219                                 echo '</table>
01220                                         <script>
01221                                                 document.getElementById("progress-message").firstChild.data="Update done.";
01222                                         </script>
01223                                 ';
01224                                 echo $this->doc->endPage();
01225                                 return '';
01226                         }
01227 
01228                         $this->content.=$this->doc->section('Translation status',$content,0,1);
01229                 }
01230         }
01231 
01240         function updateTranslation($extKey, $lang, $mirrorURL) {
01241                 $l10n = $this->terConnection->fetchTranslation($extKey, $lang, $mirrorURL);
01242                 if(is_array($l10n)) {
01243                         $file = PATH_site.'typo3temp/'.$extKey.'-l10n-'.$lang.'.zip';
01244                         $path = 'l10n/'.$lang.'/';
01245                         if(!is_dir(PATH_typo3conf.$path)) t3lib_div::mkdir_deep(PATH_typo3conf,$path);
01246                         t3lib_div::writeFile($file, $l10n[0]);
01247                         if($this->unzip($file, PATH_typo3conf.$path)) {
01248                                 return true;
01249                         } else {
01250                                 return 'Unpacking the language pack failed!';
01251                         }
01252                 } else {
01253                         return $l10n;
01254                 }
01255         }
01256 
01264         function installTranslationsForExtension($extKey, $mirrorURL) {
01265                 $selectedLanguages = unserialize($this->MOD_SETTINGS['selectedLanguages']);
01266                 if(!is_array($selectedLanguages)) $selectedLanguages = array();
01267                 foreach($selectedLanguages as $lang) {
01268                         $l10n = $this->terConnection->fetchTranslation($extKey, $lang, $mirrorURL);
01269                         if(is_array($l10n)) {
01270                                 $file = PATH_typo3conf.'l10n/'.$extKey.'-l10n-'.$lang.'.zip';
01271                                 $path = 'l10n/'.$lang.'/'.$extKey;
01272                                 t3lib_div::writeFile($file, $l10n[0]);
01273                                 if(!is_dir(PATH_typo3conf.$path)) t3lib_div::mkdir_deep(PATH_typo3conf,$path);
01274                                 if($this->unzip($file, PATH_typo3conf.$path)) {
01275                                         return true;
01276                                 } else {
01277                                         return 'Unpacking the language pack failed!';
01278                                 }
01279                         } else {
01280                                 return $l10n;
01281                         }
01282                 }
01283         }
01284 
01294         function unzip($file, $path) {
01295                 if(strlen($GLOBALS['TYPO3_CONF_VARS']['BE']['unzip_path'])) {
01296                         chdir($path);
01297                         $cmd = $GLOBALS['TYPO3_CONF_VARS']['BE']['unzip_path'].' -o '.escapeshellarg($file);
01298                         exec($cmd, $list, $ret);
01299                         return ($ret === 0);
01300                 } else {
01301                                 // we use a pure PHP unzip
01302                         $unzip = new em_unzip($file);
01303                         $ret = $unzip->extract(array('add_path'=>$path));
01304                         return (is_array($ret));
01305                 }
01306         }
01307 
01308 
01309 
01310         /*********************************
01311         *
01312         * Command Applications (triggered by GET var)
01313         *
01314         *********************************/
01315 
01323         function importExtInfo($extKey, $version='')    {
01324 
01325                         // "Go back" link
01326                 $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>';
01327                 $this->content.= $this->doc->section('',$content);
01328                 $content = '';
01329 
01330                         // Fetch remote data:
01331                 $this->xmlhandler->loadExtensionsXML();
01332                 $this->xmlhandler->extensionsXML = array($extKey => $this->xmlhandler->extensionsXML[$extKey]);
01333                 list($fetchData,) = $this->prepareImportExtList();
01334 
01335                 $versions = array_keys($fetchData[$extKey]['versions']);
01336                 $version = ($version == '') ? end($versions) : $version;
01337 
01338                 $opt = array();
01339                 foreach(array_keys($fetchData[$extKey]['versions']) as $ver)    {
01340                         $opt[]='<option value="'.$ver.'"'.(($version == $ver) ? ' selected="selected"' : '').'>'.$ver.'</option>';
01341                 }
01342 
01343                         // "Select version" box:
01344                 $onClick = 'window.location.href=\'index.php?CMD[importExtInfo]='.$extKey.'&CMD[extVersion]=\'+document.pageform.extVersion.options[document.pageform.extVersion.selectedIndex].value; return false;';
01345                 $select='<select name="extVersion">'.implode('',$opt).'</select> <input type="submit" value="Load details" onclick="'.htmlspecialchars($onClick).'" /> or<br /><br />';
01346 
01347                 if ($this->importAtAll())       {
01348                         $onClick = '
01349                                         window.location.href=\'index.php?CMD[importExt]='.$extKey.'\'
01350                                                 +\'&CMD[extVersion]=\'+document.pageform.extVersion.options[document.pageform.extVersion.selectedIndex].value
01351                                                 +\'&CMD[loc]=\'+document.pageform.loc.options[document.pageform.loc.selectedIndex].value;
01352                                                 return false;';
01353                         $select.='
01354                                 <input type="submit" value="Import/Update" onclick="'.htmlspecialchars($onClick).'"> to:
01355                                 <select name="loc">'.
01356                                 ($this->importAsType('G',$fetchData['emconf_lockType'])?'<option value="G">Global: '.$this->typePaths['G'].$extKey.'/'.(@is_dir(PATH_site.$this->typePaths['G'].$extKey)?' (OVERWRITE)':' (empty)').'</option>':'').
01357                                 ($this->importAsType('L',$fetchData['emconf_lockType'])?'<option value="L">Local: '.$this->typePaths['L'].$extKey.'/'.(@is_dir(PATH_site.$this->typePaths['L'].$extKey)?' (OVERWRITE)':' (empty)').'</option>':'').
01358                                 ($this->importAsType('S',$fetchData['emconf_lockType'])?'<option value="S">System: '.$this->typePaths['S'].$extKey.'/'.(@is_dir(PATH_site.$this->typePaths['S'].$extKey)?' (OVERWRITE)':' (empty)').'</option>':'').
01359                                 '</select>';
01360                 } else $select.= $this->noImportMsg();
01361                 $content.= $select;
01362                 $this->content.= $this->doc->section('Select command',$content,0,1);
01363 
01364                         // Details:
01365                 $eInfo = $fetchData[$extKey]['versions'][$version];
01366                 $content='<strong>'.$fetchData[$extKey]['_ICON'].' &nbsp;'.$eInfo['EM_CONF']['title'].' ('.$extKey.', '.$version.')</strong><br /><br />';
01367                 $content.=$this->extInformationArray($extKey,$eInfo,1);
01368                 $this->content.=$this->doc->spacer(10);
01369                 $this->content.=$this->doc->section('Remote Extension Details',$content,0,1);
01370         }
01371 
01380         function fetchMetaData($metaType)       {
01381                 global $TYPO3_CONF_VARS;
01382 
01383                 switch($metaType) {
01384                         case 'mirrors':
01385                                 $mfile = t3lib_div::tempnam('mirrors');
01386                                 $mirrorsFile = t3lib_div::getURL($this->MOD_SETTINGS['mirrorListURL']);
01387                                 if($mirrorsFile===false) {
01388                                         t3lib_div::unlink_tempfile($mfile);
01389                                         $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>';
01390                                 } else {
01391                                         t3lib_div::writeFile($mfile, $mirrorsFile);
01392                                         $mirrors = implode('',gzfile($mfile));
01393                                         t3lib_div::unlink_tempfile($mfile);
01394 
01395                                         $mirrors = $this->xmlhandler->parseMirrorsXML($mirrors);
01396                                         if(is_array($mirrors) && count($mirrors)) {
01397                                                 t3lib_BEfunc::getModuleData($this->MOD_MENU, array('extMirrors' => serialize($mirrors)), $this->MCONF['name'], '', 'extMirrors');
01398                                                 $this->MOD_SETTINGS['extMirrors'] = serialize($mirrors);
01399                                                 $content = '<p>The mirror list has been updated and now contains '.count($mirrors).' entries.</p>';
01400                                         }
01401                                         else {
01402                                                 $content = '<p>'.$mirrors.'<br />The mirror list was not updated as it contained no entries.</p>';
01403                                         }
01404                                 }
01405                                 break;
01406                         case 'extensions':
01407                                 $this->fetchMetaData('mirrors'); // if we fetch the extensions anyway, we can as well keep this up-to-date
01408 
01409                                 $mirror = $this->getMirrorURL();
01410                                 $extfile = $mirror.'extensions.xml.gz';
01411                                 $extmd5 = t3lib_div::getURL($mirror.'extensions.md5');
01412                                 if(is_file(PATH_site.'typo3temp/extensions.xml.gz')) $localmd5 = md5_file(PATH_site.'typo3temp/extensions.xml.gz');
01413 
01414                                 if($extmd5 === false) {
01415                                         $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>';
01416                                 } elseif($extmd5 == $localmd5) {
01417                                         $content .= '<p>The extension list has not changed remotely, it has thus not been fetched.</p>';
01418                                 } else {
01419                                         $extXML = t3lib_div::getURL($extfile);
01420                                         if($extXML === false) {
01421                                                 $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>';
01422                                         } else {
01423                                                 t3lib_div::writeFile(PATH_site.'typo3temp/extensions.xml.gz', $extXML);
01424                                                 $content .= $this->xmlhandler->parseExtensionsXML(implode('',gzfile(PATH_site.'typo3temp/extensions.xml.gz')));
01425                                                 $this->xmlhandler->saveExtensionsXML();
01426                                         }
01427                                 }
01428                                 break;
01429                 }
01430 
01431                 return $content;
01432         }
01433 
01439         function getMirrorURL() {
01440                 if(strlen($this->MOD_SETTINGS['rep_url'])) return $this->MOD_SETTINGS['rep_url'];
01441 
01442                 $mirrors = unserialize($this->MOD_SETTINGS['extMirrors']);
01443                 if(!is_array($mirrors)) {
01444                         $this->fetchMetaData('mirrors');
01445                         $mirrors = unserialize($this->MOD_SETTINGS['extMirrors']);
01446                         if(!is_array($mirrors)) return false;
01447                 }
01448                 if($this->MOD_SETTINGS['selectedMirror']=='') {
01449                         srand((float) microtime() * 10000000); // not needed after PHP 4.2.0...
01450                         $rand = array_rand($mirrors);
01451                         $url = 'http://'.$mirrors[$rand]['host'].$mirrors[$rand]['path'];
01452                 }
01453                 else {
01454                         $url = 'http://'.$mirrors[$this->MOD_SETTINGS['selectedMirror']]['host'].$mirrors[$this->MOD_SETTINGS['selectedMirror']]['path'];
01455                 }
01456 
01457                 return $url;
01458         }
01459 
01460 
01461 
01477         function installExtension($extKey, $version=null, $mode=EM_INSTALL_VERSION_MIN) {
01478                 list($inst_list,) = $this->getInstalledExtensions();
01479 
01480                         // check if it is already installed and loaded with sufficient version
01481                 if(isset($inst_list[$extKey])) {
01482                         $currentVersion = $inst_list[$extKey]['EM_CONF']['version'];
01483 
01484                         if(t3lib_extMgm::isLoaded($extKey)) {
01485                                 if($version===null) {
01486                                         return array(true, 'Extension already installed and loaded.');
01487                                 } else {
01488                                         switch($mode) {
01489                                                 case EM_INSTALL_VERSION_STRICT:
01490                                                         if($currentVersion == $version) {
01491                                                                 return array(true, 'Extension already installed and loaded.');
01492                                                         }
01493                                                         break;
01494                                                 case EM_INSTALL_VERSION_MIN:
01495                                                         if(version_compare($currentVersion, $version, '>=')) {
01496                                                                 return array(true, 'Extension already installed and loaded.');
01497                                                         }
01498                                                         break;
01499                                                 case EM_INSTALL_VERSION_MAX:
01500                                                         if(version_compare($currentVersion, $version, '<=')) {
01501                                                                 return array(true, 'Extension already installed and loaded.');
01502                                                         }
01503                                                         break;
01504                                         }
01505                                 }
01506                         } else {
01507                                 if (!t3lib_extMgm::isLocalconfWritable())       {
01508                                         return array(false, 'localconf.php is not writable!');
01509                                 }
01510                                 $newExtList = -1;
01511                                 switch($mode) {
01512                                         case EM_INSTALL_VERSION_STRICT:
01513                                                 if($currentVersion == $version) {
01514                                                         $newExtList = $this->addExtToList($extKey, $inst_list);
01515                                                 }
01516                                                 break;
01517                                         case EM_INSTALL_VERSION_MIN:
01518                                                 if(version_compare($currentVersion, $version, '>=')) {
01519                                                         $newExtList = $this->addExtToList($extKey, $inst_list);
01520                                                 }
01521                                                 break;
01522                                         case EM_INSTALL_VERSION_MAX:
01523                                                 if(version_compare($currentVersion, $version, '<=')) {
01524                                                         $newExtList = $this->addExtToList($extKey, $inst_list);
01525                                                 }
01526                                                 break;
01527                                 }
01528                                 if ($newExtList!=-1)    {
01529                                         $this->writeNewExtensionList($newExtList);
01530                                         $this->refreshGlobalExtList();
01531                                         $this->forceDBupdates($extKey, $inst_list[$extKey]);
01532                                         return array(true, 'Extension was already installed, it has been loaded.');
01533                                 }
01534                         }
01535                 }
01536 
01537                         // at this point we know we need to import (a matching version of) the extension from TER2
01538 
01539                         // see if we have an extensionlist at all
01540                 $this->xmlhandler->loadExtensionsXML();
01541                 if (!count($this->xmlhandler->extensionsXML))   {
01542                         $this->fetchMetaData('extensions');
01543                 }
01544 
01545                         // check if extension can be fetched
01546                 if(isset($this->xmlhandler->extensionsXML[$extKey])) {
01547                         $versions = array_keys($this->xmlhandler->extensionsXML[$extKey]['versions']);
01548                         $latestVersion = end($versions);
01549                         switch($mode) {
01550                                 case EM_INSTALL_VERSION_STRICT:
01551                                         if(!isset($this->xmlhandler->extensionsXML[$extKey]['versions'][$version])) {
01552                                                 return array(false, 'Extension not available in matching version');
01553                                         }
01554                                         break;
01555                                 case EM_INSTALL_VERSION_MIN:
01556                                         if(version_compare($latestVersion, $version, '>=')) {
01557                                                 $version = $latestVersion;
01558                                         } else {
01559                                                 return array(false, 'Extension not available in matching version');
01560                                         }
01561                                         break;
01562                                 case EM_INSTALL_VERSION_MAX:
01563                                         while(($v = array_pop($versions)) && version_compare($v, $version, '>=')) {}
01564                                         if($v !== null && version_compare($v, $version, '<=')) {
01565                                                 $version = $v;
01566                                         } else {
01567                                                 return array(false, 'Extension not available in matching version');
01568                                         }
01569                                         break;
01570                         }
01571                         $this->importExtFromRep($extKey, $version, 'L');
01572                         $newExtList = $this->addExtToList($extKey, $inst_list);
01573                         if ($newExtList!=-1)    {
01574                                 $this->writeNewExtensionList($newExtList);
01575                                 $this->refreshGlobalExtList();
01576                                 $this->forceDBupdates($extKey, $inst_list[$extKey]);
01577                                 $this->installTranslationsForExtension($extKey, $this->getMirrorURL());
01578                                 return array(true, 'Extension has been imported from repository and loaded.');
01579                         } else {
01580                                 return array(false, 'Extension is in repository, but could not be loaded.');
01581                         }
01582                 } else {
01583                         return array(false, 'Extension not available in repository');
01584                 }
01585         }
01586 
01587         function refreshGlobalExtList() {
01588                 global $TYPO3_LOADED_EXT;
01589 
01590                 $TYPO3_LOADED_EXT = t3lib_extMgm::typo3_loadExtensions();
01591                 if ($TYPO3_LOADED_EXT['_CACHEFILE'])    {
01592                         require(PATH_typo3conf.$TYPO3_LOADED_EXT['_CACHEFILE'].'_ext_localconf.php');
01593                 }
01594                 return;
01595 
01596                 $GLOBALS['TYPO3_LOADED_EXT'] = t3lib_extMgm::typo3_loadExtensions();
01597                 if ($TYPO3_LOADED_EXT['_CACHEFILE'])    {
01598                         require(PATH_typo3conf.$TYPO3_LOADED_EXT['_CACHEFILE'].'_ext_localconf.php');
01599                 } else {
01600                         $temp_TYPO3_LOADED_EXT = $TYPO3_LOADED_EXT;
01601                         reset($temp_TYPO3_LOADED_EXT);
01602                         while(list($_EXTKEY,$temp_lEDat)=each($temp_TYPO3_LOADED_EXT))  {
01603                                 if (is_array($temp_lEDat) && $temp_lEDat['ext_localconf.php'])  {
01604                                         $_EXTCONF = $TYPO3_CONF_VARS['EXT']['extConf'][$_EXTKEY];
01605                                         require($temp_lEDat['ext_localconf.php']);
01606                                 }
01607                         }
01608                 }
01609         }
01610 
01611 
01624         function importExtFromRep($extKey,$version,$loc,$uploadFlag=0,$dontDelete=0,$directInput='')    {
01625 
01626                 $uploadSucceed = false;
01627                 $uploadedTempFile = '';
01628                 if (is_array($directInput))     {
01629                         $fetchData = array($directInput,'');
01630                         $loc = ($loc==='G'||$loc==='S') ? $loc : 'L';
01631                 } elseif ($uploadFlag)  {
01632                         if (($uploadedTempFile = $this->CMD['alreadyUploaded']) || $_FILES['upload_ext_file']['tmp_name'])      {
01633 
01634                                         // Read uploaded file:
01635                                 if (!$uploadedTempFile) {
01636                                         if (!is_uploaded_file($_FILES['upload_ext_file']['tmp_name'])) {
01637                                                 t3lib_div::sysLog('Possible file upload attack: '.$_FILES['upload_ext_file']['tmp_name'], 'Extension Manager', 3);
01638 
01639                                                 return 'File was not uploaded?!?';
01640                                         }
01641 
01642                                         $uploadedTempFile = t3lib_div::upload_to_tempfile($_FILES['upload_ext_file']['tmp_name']);
01643                                 }
01644                                 $fileContent = t3lib_div::getUrl($uploadedTempFile);
01645 
01646                                 if (!$fileContent)      return 'File is empty!';
01647 
01648                                         // Decode file data:
01649                                 $fetchData = $this->terConnection->decodeExchangeData($fileContent);
01650 
01651                                 if (is_array($fetchData))       {
01652                                         $extKey = $fetchData[0]['extKey'];
01653                                         if ($extKey)    {
01654                                                 if (!$this->CMD['uploadOverwrite'])     {
01655                                                         $loc = ($loc==='G'||$loc==='S') ? $loc : 'L';
01656                                                         $comingExtPath = PATH_site.$this->typePaths[$loc].$extKey.'/';
01657                                                         if (@is_dir($comingExtPath))    {
01658                                                                 return 'Extension was already present in "'.$comingExtPath.'" - and the overwrite flag was not set! So nothing done...';
01659                                                         }       // ... else go on, install...
01660                                                 }       // ... else go on, install...
01661                                         } else return 'No extension key in file. Strange...';
01662                                 } else return 'Wrong file format. No data recognized, '.$fetchData;
01663                         } else return 'No file uploaded! Probably the file was too large for PHPs internal limit for uploadable files.';
01664                 } else {
01665                         $this->xmlhandler->loadExtensionsXML();
01666 
01667                                 // Fetch extension from TER:
01668                         if(!strlen($version)) {
01669                                 $versions = array_keys($this->xmlhandler->extensionsXML[$extKey]['versions']);
01670                                 $version = end($versions);
01671                         }
01672                         $fetchData = $this->terConnection->fetchExtension($extKey, $version, $this->xmlhandler->extensionsXML[$extKey]['versions'][$version]['t3xfilemd5'], $this->getMirrorURL());
01673                 }
01674 
01675                 // At this point the extension data should be present; so we want to write it to disc:
01676                 if ($this->importAsType($loc))  {
01677                         if (is_array($fetchData))       {       // There was some data successfully transferred
01678                                 if ($fetchData[0]['extKey'] && is_array($fetchData[0]['FILES']))        {
01679                                         $extKey = $fetchData[0]['extKey'];
01680                                         if(!isset($fetchData[0]['EM_CONF']['constraints'])) $fetchData[0]['EM_CONF']['constraints'] = $this->xmlhandler->extensionsXML[$extKey]['versions'][$version]['dependencies'];
01681                                         $EM_CONF = $this->fixEMCONF($fetchData[0]['EM_CONF']);
01682                                         if (!$EM_CONF['lockType'] || !strcmp($EM_CONF['lockType'],$loc))        {
01683                                                         // check dependencies, act accordingly if ext is loaded
01684                                                 list($instExtInfo,)=$this->getInstalledExtensions();
01685                                                 $depStatus = $this->checkDependencies($extKey, $EM_CONF, $instExtInfo);
01686                                                 if(t3lib_extMgm::isLoaded($extKey) && !$depStatus['returnCode']) {
01687                                                         $this->content .= $depStatus['html'];
01688                                                         if ($uploadedTempFile)  {
01689                                                                 $this->content .= '<input type="hidden" name="CMD[alreadyUploaded]" value="'.$uploadedTempFile.'" />';
01690                                                         }
01691                                                 } else {
01692                                                         $res = $this->clearAndMakeExtensionDir($fetchData[0],$loc,$dontDelete);
01693                                                         if (is_array($res))     {
01694                                                                 $extDirPath = trim($res[0]);
01695                                                                 if ($extDirPath && @is_dir($extDirPath) && substr($extDirPath,-1)=='/') {
01696 
01697                                                                         $emConfFile = $this->construct_ext_emconf_file($extKey,$EM_CONF);
01698                                                                         $dirs = $this->extractDirsFromFileList(array_keys($fetchData[0]['FILES']));
01699 
01700                                                                         $res = $this->createDirsInPath($dirs,$extDirPath);
01701                                                                         if (!$res)      {
01702                                                                                 $writeFiles = $fetchData[0]['FILES'];
01703                                                                                 $writeFiles['ext_emconf.php']['content'] = $emConfFile;
01704                                                                                 $writeFiles['ext_emconf.php']['content_md5'] = md5($emConfFile);
01705 
01706                                                                                         // Write files:
01707                                                                                 foreach($writeFiles as $theFile => $fileData)   {
01708                                                                                         t3lib_div::writeFile($extDirPath.$theFile,$fileData['content']);
01709                                                                                         if (!@is_file($extDirPath.$theFile))    {
01710                                                                                                 $content.='Error: File "'.$extDirPath.$theFile.'" could not be created!!!<br />';
01711                                                                                         } elseif (md5(t3lib_div::getUrl($extDirPath.$theFile)) != $fileData['content_md5']) {
01712                                                                                                 $content.='Error: File "'.$extDirPath.$theFile.'" MD5 was different from the original files MD5 - so the file is corrupted!<br />';
01713                                                                                         }
01714                                                                                 }
01715 
01716                                                                                         // No content, no errors. Create success output here:
01717                                                                                 if (!$content)  {
01718                                                                                         $content='SUCCESS: '.$extDirPath.'<br />';
01719 
01720                                                                                         $uploadSucceed = true;
01721 
01722                                                                                                 // Fix TYPO3_MOD_PATH for backend modules in extension:
01723                                                                                         $modules = t3lib_div::trimExplode(',',$EM_CONF['module'],1);
01724                                                                                         if (count($modules))    {
01725                                                                                                 foreach($modules as $mD)        {
01726                                                                                                         $confFileName = $extDirPath.$mD.'/conf.php';
01727                                                                                                         if (@is_file($confFileName))    {
01728                                                                                                                 $content.= $this->writeTYPO3_MOD_PATH($confFileName,$loc,$extKey.'/'.$mD.'/').'<br />';
01729                                                                                                         } else $content.='Error: Couldn\'t find "'.$confFileName.'"<br />';
01730                                                                                                 }
01731                                                                                         }
01732                                                                                                 // 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.
01733                                                                                                 // But this order of the code works.... (using the empty Array with type, EMCONF and files hereunder).
01734 
01735                                                                                                 // Writing to ext_emconf.php:
01736                                                                                         $sEMD5A = $this->serverExtensionMD5Array($extKey,array('type' => $loc, 'EM_CONF' => array(), 'files' => array()));
01737                                                                                         $EM_CONF['_md5_values_when_last_written'] = serialize($sEMD5A);
01738                                                                                         $emConfFile = $this->construct_ext_emconf_file($extKey,$EM_CONF);
01739                                                                                         t3lib_div::writeFile($extDirPath.'ext_emconf.php',$emConfFile);
01740 
01741                                                                                         $content.='ext_emconf.php: '.$extDirPath.'ext_emconf.php<br />';
01742                                                                                         $content.='Type: '.$loc.'<br />';
01743 
01744                                                                                                 // Remove cache files:
01745                                                                                         if (t3lib_extMgm::isLoaded($extKey))    {
01746                                                                                                 if ($this->removeCacheFiles())  {
01747                                                                                                         $content.='Cache-files are removed and will be re-written upon next hit<br />';
01748                                                                                                 }
01749 
01750                                                                                                 list($new_list)=$this->getInstalledExtensions();
01751                                                                                                 $content.=$this->updatesForm($extKey,$new_list[$extKey],1,'index.php?CMD[showExt]='.$extKey.'&SET[singleDetails]=info');
01752                                                                                         }
01753 
01754                                                                                                 // Install / Uninstall:
01755                                                                                         if(!$this->CMD['standAlone']) {
01756                                                                                                 $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;
01757                                                                                                 $content.='<h3>Install / Uninstall Extension:</h3>';
01758                                                                                                 $content.= $new_list[$extKey] ?
01759                                                                                                         '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[remove]=1&CMD[clrCmd]=1&SET[singleDetails]=info').'">'.$this->removeButton().' Uninstall extension</a>' :
01760                                                                                                         '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[load]=1&CMD[clrCmd]=1&SET[singleDetails]=info').'">'.$this->installButton().' Install extension</a>';
01761                                                                                         } else {
01762                                                                                                 $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>';
01763                                                                                         }
01764 
01765                                                                                 }
01766                                                                         } else $content = $res;
01767                                                                 } else $content = 'Error: The extension path "'.$extDirPath.'" was different than expected...';
01768                                                         } else $content = $res;
01769                                                 }
01770                                         } else $content = 'Error: The extension can only be installed in the path '.$this->typePaths[$EM_CONF['lockType']].' (lockType='.$EM_CONF['lockType'].')';
01771                                 } else $content = 'Error: No extension key!!! Why? - nobody knows... (Or no files in the file-array...)';
01772                         }  else $content = 'Error: The datatransfer did not succeed. '.$fetchData;
01773                 }  else $content = 'Error: Installation is not allowed in this path ('.$this->typePaths[$loc].')';
01774 
01775                 $this->content.=$this->doc->section('Extension import results',$content,0,1);
01776 
01777                 if ($uploadSucceed && $uploadedTempFile)        {
01778                         t3lib_div::unlink_tempfile($uploadedTempFile);
01779                 }
01780 
01781                 return false;
01782         }
01783 
01790         function showExtDetails($extKey)        {
01791                 global $TYPO3_LOADED_EXT;
01792 
01793                 list($list,)=$this->getInstalledExtensions();
01794                 $absPath = $this->getExtPath($extKey,$list[$extKey]['type']);
01795 
01796                 // Check updateModule:
01797                 if (@is_file($absPath.'class.ext_update.php'))  {
01798                         require_once($absPath.'class.ext_update.php');
01799                         $updateObj = new ext_update;
01800                         if (!$updateObj->access())      {
01801                                 unset($this->MOD_MENU['singleDetails']['updateModule']);
01802                         }
01803                 } else {
01804                         unset($this->MOD_MENU['singleDetails']['updateModule']);
01805                 }
01806 
01807                 if($this->CMD['doDelete']) {
01808                         $this->MOD_MENU['singleDetails'] = array();
01809                 }
01810 
01811                         // Function menu here:
01812                 if(!$this->CMD['standAlone'] && !t3lib_div::_GP('standAlone')) {
01813                         $content = '
01814                                 <table border="0" cellpadding="0" cellspacing="0" width="100%">
01815                                         <tr>
01816                                                 <td nowrap="nowrap">Extension:&nbsp;<strong>'.$this->extensionTitleIconHeader($extKey,$list[$extKey]).'</strong> ('.$extKey.')</td>
01817                                                 <td align="right" nowrap="nowrap">'.
01818                         t3lib_BEfunc::getFuncMenu(0,'SET[singleDetails]',$this->MOD_SETTINGS['singleDetails'],$this->MOD_MENU['singleDetails'],'','&CMD[showExt]='.$extKey).' &nbsp; &nbsp; '.
01819                         '<a href="index.php" class="typo3-goBack"><img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/goback.gif','width="14" height="14"').' class="absmiddle" alt="" /> Go back</a></td>
01820                                         </tr>
01821                                 </table>';
01822                         $this->content.=$this->doc->section('',$content);
01823                 }
01824 
01825                         // Show extension details:
01826                 if ($list[$extKey])     {
01827 
01828                                 // Checking if a command for install/uninstall is executed:
01829                         if (($this->CMD['remove'] || $this->CMD['load']) && !in_array($extKey,$this->requiredExt))      {
01830 
01831                                         // Install / Uninstall extension here:
01832                                 if (t3lib_extMgm::isLocalconfWritable())        {
01833                                                 // Check dependencies:
01834                                         $depStatus = $this->checkDependencies($extKey, $list[$extKey]['EM_CONF'], $list);
01835                                         if(!$this->CMD['remove'] && !$depStatus['returnCode']) {
01836                                                 $this->content .= $depStatus['html'];
01837                                                 $newExtList = -1;
01838                                         } elseif ($this->CMD['remove']) {
01839                                                 $newExtList = $this->removeExtFromList($extKey,$list);
01840                                         } else {
01841                                                 $newExtList = $this->addExtToList($extKey,$list);
01842                                         }
01843 
01844                                         // Success-installation:
01845                                         if ($newExtList!=-1)    {
01846                                                 $updates = '';
01847                                                 if ($this->CMD['load']) {
01848                                                         if($_SERVER['REQUEST_METHOD'] == 'POST') {
01849                                                                 $script = t3lib_div::linkThisScript(array('CMD[showExt]' => $extKey, 'CMD[load]' => 1, 'CMD[clrCmd]' => $this->CMD['clrCmd'], 'SET[singleDetails]' => 'info'));
01850                                                         } else {
01851                                                                 $script = '';
01852                                                         }
01853                                                         $updates = $this->updatesForm($extKey,$list[$extKey],1,$script,'<input type="hidden" name="_do_install" value="1" /><input type="hidden" name="_clrCmd" value="'.$this->CMD['clrCmd'].'" />');
01854                                                         if ($updates)   {
01855                                                                 $updates = 'Before the extension can be installed the database needs to be updated with new tables or fields. Please select which operations to perform:'.$updates;
01856                                                                 if($this->CMD['standAlone']) $updates .= '<input type="hidden" name="standAlone" value="1" />';
01857                                                                 $depsolver = t3lib_div::_POST('depsolver');
01858                                                                 if(is_array($depsolver['ignore'])) {
01859                                                                         foreach($depsolver['ignore'] as $depK => $depV) {
01860                                                                                 $updates .= '<input type="hidden" name="depsolver[ignore]['.$depK.']" value="1" />';
01861                                                                         }
01862                                                                 }
01863 
01864                                                                 $this->content.=$this->doc->section('Installing '.$this->extensionTitleIconHeader($extKey,$list[$extKey]).strtoupper(': Database needs to be updated'),$updates,1,1,1,1);
01865                                                         }
01866                                                 } elseif ($this->CMD['remove']) {
01867                                                         $updates.= $this->checkClearCache($list[$extKey]);
01868                                                         if ($updates)   {
01869                                                                 $updates = '
01870                                                                 </form><form action="'.t3lib_div::linkThisScript().'" method="post">'.$updates.'
01871                                                                 <br /><input type="submit" name="write" value="Remove extension" />
01872                                                                 <input type="hidden" name="_do_install" value="1" />
01873                                                                 <input type="hidden" name="_clrCmd" value="'.$this->CMD['clrCmd'].'" />
01874                                                                 <input type="hidden" name="standAlone" value="'.$this->CMD['standAlone'].'" />
01875                                                                 ';
01876                                                                 $this->content.=$this->doc->section('Removing '.$this->extensionTitleIconHeader($extKey,$list[$extKey]).strtoupper(': Database needs to be updated'),$updates,1,1,1,1);
01877                                                         }
01878                                                 }
01879                                                 if (!$updates || t3lib_div::_GP('_do_install')) {
01880                                                         $this->writeNewExtensionList($newExtList);
01881                                                         $GLOBALS['BE_USER']->writelog(5,1,0,0,'Extension list has been changed, extension %s has been %s',array($extKey,($this->CMD['load']?'installed':'removed')));
01882                                                         if ($this->CMD['clrCmd'] || t3lib_div::_GP('_clrCmd'))  {
01883                                                                 $vA = array('CMD'=>'');
01884                                                         } else {
01885                                                                 $vA = array('CMD'=>Array('showExt'=>$extKey));
01886                                                         }
01887                                                         if($this->CMD['standAlone'] || t3lib_div::_GP('standAlone')) {
01888                                                                 $this->content .= 'Extension has been '.($this->CMD['load'] ? 'installed' : 'removed').'.<br /><br /><a href="javascript:opener.top.content.document.forms[0].submit();window.close();">Close window and recheck dependencies</a>';
01889                                                         } else {
01890                                                                 header('Location: '.t3lib_div::linkThisScript($vA));
01891                                                         }
01892                                                 }
01893                                         }
01894                                 } else {
01895                                         $this->content.=$this->doc->section('Installing '.$this->extensionTitleIconHeader($extKey,$list[$extKey]).strtoupper(': Write access error'),'typo3conf/localconf.php seems not to be writable, so the extension cannot be installed automatically!',1,1,2,1);
01896                                 }
01897 
01898                         } elseif ($this->CMD['downloadFile'] && !in_array($extKey,$this->requiredExt))  {
01899 
01900                                 // Link for downloading extension has been clicked - deliver content stream:
01901                                 $dlFile = $this->CMD['downloadFile'];
01902                                 if (t3lib_div::isFirstPartOfStr($dlFile,PATH_site) && t3lib_div::isFirstPartOfStr($dlFile,$absPath) && @is_file($dlFile))       {
01903                                         $mimeType = 'application/octet-stream';
01904                                         Header('Content-Type: '.$mimeType);
01905                                         Header('Content-Disposition: attachment; filename='.basename($dlFile));
01906                                         echo t3lib_div::getUrl($dlFile);
01907                                         exit;
01908                                 } else die('Error while trying to download extension file...');
01909 
01910                         } elseif ($this->CMD['editFile'] && !in_array($extKey,$this->requiredExt))      {
01911 
01912                                 // Editing extension file:
01913                                 $editFile = $this->CMD['editFile'];
01914                                 if (t3lib_div::isFirstPartOfStr($editFile,PATH_site) && t3lib_div::isFirstPartOfStr($editFile,$absPath))        {       // Paranoia...
01915 
01916                                         $fI = t3lib_div::split_fileref($editFile);
01917                                         if (@is_file($editFile) && t3lib_div::inList($this->editTextExtensions,($fI['fileext']?$fI['fileext']:$fI['filebody'])))        {
01918                                                 if (filesize($editFile)<($this->kbMax*1024))    {
01919                                                         $outCode = '';
01920                                                         $info = '';
01921                                                         $submittedContent = t3lib_div::_POST('edit');
01922                                                         $saveFlag = 0;
01923 
01924                                                         if(isset($submittedContent['file']) && !$GLOBALS['TYPO3_CONF_VARS']['EXT']['noEdit'])   {               // Check referer here?
01925                                                                 $oldFileContent = t3lib_div::getUrl($editFile);
01926                                                                 if($oldFileContent != $submittedContent['file']) {
01927                                                                         $oldMD5 = md5(str_replace(chr(13),'',$oldFileContent));
01928                                                                         $info.= 'MD5: <b>'.$oldMD5.'</b> (Previous File)<br />';
01929                                                                         t3lib_div::writeFile($editFile,$submittedContent['file']);
01930                                                                         $saveFlag = 1;
01931                                                                 } else {
01932                                                                         $info .= 'No changes to the file detected!<br />';
01933                                                                 }
01934                                                         }
01935 
01936                                                         $fileContent = t3lib_div::getUrl($editFile);
01937 
01938                                                         $outCode.= 'File: <b>'.substr($editFile,strlen($absPath)).'</b> ('.t3lib_div::formatSize(filesize($editFile)).')<br />';
01939                                                         $fileMD5 = md5(str_replace(chr(13),'',$fileContent));
01940                                                         $info.= 'MD5: <b>'.$fileMD5.'</b> (Current File)<br />';
01941                                                         if($saveFlag)   {
01942                                                                 $saveMD5 = md5(str_replace(chr(13),'',$submittedContent['file']));
01943                                                                 $info.= 'MD5: <b>'.$saveMD5.'</b> (Submitted)<br />';
01944                                                                 if($fileMD5!=$saveMD5) $info .= $GLOBALS['TBE_TEMPLATE']->rfw('<br /><strong>Saving failed, the content was not correctly written to disk. Changes have been lost!</strong>').'<br />';
01945                                                                 else $info.= $GLOBALS['TBE_TEMPLATE']->rfw('<br /><strong>File saved.</strong>').'<br />';
01946                                                         }
01947 
01948                                                         $outCode.= '<textarea name="edit[file]" rows="35" wrap="off"'.$this->doc->formWidthText(48,'width:98%;height:70%','off').' class="fixed-font enable-tab">'.t3lib_div::formatForTextarea($fileContent).'</textarea>';
01949                                                         $outCode.= '<input type="hidden" name="edit[filename]" value="'.$editFile.'" />';
01950                                                         $outCode.= '<input type="hidden" name="CMD[editFile]" value="'.htmlspecialchars($editFile).'" />';
01951                                                         $outCode.= '<input type="hidden" name="CMD[showExt]" value="'.$extKey.'" />';
01952                                                         $outCode.= $info;
01953 
01954                                                         if (!$GLOBALS['TYPO3_CONF_VARS']['EXT']['noEdit'])      {
01955                                                                 $outCode.='<br /><input type="submit" name="save_file" value="Save file" />';
01956                                                         } else $outCode.=$GLOBALS['TBE_TEMPLATE']->rfw('<br />[SAVING IS DISABLED - can be enabled by the $TYPO3_CONF_VARS[\'EXT\'][\'noEdit\']-flag] ');
01957 
01958                                                         $onClick = 'window.location.href=\'index.php?CMD[showExt]='.$extKey.'\';return false;';
01959                                                         $outCode.='<input type="submit" name="cancel" value="Cancel" onclick="'.htmlspecialchars($onClick).'" />';
01960 
01961                                                         $theOutput.=$this->doc->spacer(15);
01962                                                         $theOutput.=$this->doc->section('Edit file:','',0,1);
01963                                                         $theOutput.=$this->doc->sectionEnd().$outCode;
01964                                                         $this->content.=$theOutput;
01965                                                 } else {
01966                                                         $theOutput.=$this->doc->spacer(15);
01967                                                         $theOutput.=$this->doc->section('Filesize exceeded '.$this->kbMax.' Kbytes','Files larger than '.$this->kbMax.' KBytes are not allowed to be edited.');
01968                                                 }
01969                                         }
01970                                 } else die('Fatal Edit error: File "'.$editFile.'" was not inside the correct path of the TYPO3 Extension!');
01971                         } else {
01972 
01973                                 // MAIN:
01974                                 switch((string)$this->MOD_SETTINGS['singleDetails'])    {
01975                                         case 'info':
01976                                                 // Loaded / Not loaded:
01977                                                 if (!in_array($extKey,$this->requiredExt))      {
01978                                                         if ($TYPO3_LOADED_EXT[$extKey]) {
01979                                                                 $content = '<strong>The extension is installed (loaded and running)!</strong><br />'.
01980                                                                 '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[remove]=1').'">Click here to remove the extension: '.$this->removeButton().'</a>';
01981                                                         } else {
01982                                                                 $content = 'The extension is <strong>not</strong> installed yet.<br />'.
01983                                                                 '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[load]=1').'">Click here to install the extension: '.$this->installButton().'</a>';
01984                                                         }
01985                                                 } else {
01986                                                         $content = 'This extension is entered in the TYPO3_CONF_VARS[SYS][requiredExt] list and is therefore always loaded.';
01987                                                 }
01988                                                 $this->content.=$this->doc->spacer(10);
01989                                                 $this->content.=$this->doc->section('Active status:',$content,0,1);
01990 
01991                                                 if (t3lib_extMgm::isLoaded($extKey))    {
01992                                                         $updates=$this->updatesForm($extKey,$list[$extKey]);
01993                                                         if ($updates)   {
01994                                                                 $this->content.=$this->doc->spacer(10);
01995                                                                 $this->content.=$this->doc->section('Update needed:',$updates.'<br /><br />Notice: "Static data" may not <em>need</em> to be updated. You will only have to import static data each time you upgrade the extension.',0,1);
01996                                                         }
01997                                                 }
01998 
01999                                                 // Config:
02000                                                 if (@is_file($absPath.'ext_conf_template.txt')) {
02001                                                         $this->content.=$this->doc->spacer(10);
02002                                                         $this->content.=$this->doc->section('Configuration:','(<em>Notice: You may need to clear the cache after configuration of the extension. This is required if the extension adds TypoScript depending on these settings.</em>)<br /><br />',0,1);
02003                                                         $this->tsStyleConfigForm($extKey,$list[$extKey]);
02004                                                 }
02005 
02006                                                 // Show details:
02007                                                 $content = t3lib_BEfunc::cshItem('_MOD_tools_em', 'info', $GLOBALS['BACK_PATH'],'|<br/>');
02008                                                 $content.= $this->extInformationArray($extKey,$list[$extKey]);
02009 
02010                                                 $this->content.=$this->doc->spacer(10);
02011                                                 $this->content.=$this->doc->section('Details:',$content,0,1);
02012                                                 break;
02013                                         case 'upload':
02014                                                 $em = t3lib_div::_POST('em');
02015                                                 if($em['action'] == 'doUpload') {
02016                                                         $em['extKey'] = $extKey;
02017                                                         $em['extInfo'] = $list[$extKey];
02018                                                         $content = $this->uploadExtensionToTER($em);
02019                                                         $content .= $this->doc->spacer(10);
02020                                                                 // Must reload this, because EM_CONF information has been updated!
02021                                                         list($list,)=$this->getInstalledExtensions();
02022                                                 } else {
02023                                                                 // CSH:
02024                                                         $content = t3lib_BEfunc::cshItem('_MOD_tools_em', 'upload', $GLOBALS['BACK_PATH'],'|<br/>');
02025 
02026                                                                 // Upload:
02027                                                         if (substr($extKey,0,5)!='user_')       {
02028                                                                 $content.= $this->getRepositoryUploadForm($extKey,$list[$extKey]);
02029                                                                 $eC=0;
02030                                                         } else {
02031                                                                 $content.='The extensions has an extension key prefixed "user_" which indicates that it is a user-defined extension with no official unique identification. Therefore it cannot be uploaded.';
02032                                                                 $eC=2;
02033                                                         }
02034                                                         if (!$this->fe_user['username'])        {
02035                                                                 $content.= '<br /><br /><img src="'.$GLOBALS['BACK_PATH'].'gfx/icon_note.gif" width="18" height="16" align="top" alt="" />You have not configured a default username/password yet. <a href="index.php?SET[function]=3">Go to "Settings"</a> if you want to do that.<br />';
02036                                                         }
02037                                                 }
02038                                                 $this->content.=$this->doc->section('Upload extension to repository',$content,0,1,$eC);
02039                                                 break;
02040                                         case 'backup':
02041                                                 if($this->CMD['doDelete']) {
02042                                                         $content = $this->extDelete($extKey,$list[$extKey]);
02043                                                         $this->content.=$this->doc->section('Delete',$content,0,1);
02044                                                 } else {
02045                                                         $content = t3lib_BEfunc::cshItem('_MOD_tools_em', 'backup_delete', $GLOBALS['BACK_PATH'],'|<br/>');
02046                                                         $content.= $this->extBackup($extKey,$list[$extKey]);
02047                                                         $this->content.=$this->doc->section('Backup',$content,0,1);
02048 
02049                                                         $content = $this->extDelete($extKey,$list[$extKey]);
02050                                                         $this->content.=$this->doc->section('Delete',$content,0,1);
02051 
02052                                                         $content = $this->extUpdateEMCONF($extKey,$list[$extKey]);
02053                                                         $this->content.=$this->doc->section('Update EM_CONF',$content,0,1);
02054                                                 }
02055                                                 break;
02056                                         case 'dump':
02057                                                 $this->extDumpTables($extKey,$list[$extKey]);
02058                                                 break;
02059                                         case 'edit':
02060                                                 $content = t3lib_BEfunc::cshItem('_MOD_tools_em', 'editfiles', $GLOBALS['BACK_PATH'],'|<br/>');
02061                                                 $content.= $this->getFileListOfExtension($extKey,$list[$extKey]);
02062 
02063                                                 $this->content.=$this->doc->section('Extension files',$content,0,1);
02064                                                 break;
02065                                         case 'updateModule':
02066                                                 $this->content.=$this->doc->section('Update:',is_object($updateObj) ? $updateObj->main() : 'No update object',0,1);
02067                                                 break;
02068                                         default:
02069                                                 $this->extObjContent();
02070                                                 break;
02071                                 }
02072                         }
02073                 }
02074         }
02075 
02083         function requestInstallExtensions($extList)     {
02084 
02085                         // Return URL:
02086                 $returnUrl = t3lib_div::_GP('returnUrl');
02087                 $installOrImportExtension = t3lib_div::_POST('installOrImportExtension');
02088 
02089                         // Extension List:
02090                 $extArray = explode(',',$extList);
02091                 $outputRow = array();
02092                 $outputRow[] = '
02093                         <tr class="bgColor5 tableheader">
02094                                 <td>Install/Import:</td>
02095                                 <td>Extension Key:</td>
02096                         </tr>
02097                 ';
02098 
02099                 foreach($extArray as $extKey)   {
02100 
02101                                 // Check for the request:
02102                         if ($installOrImportExtension[$extKey]) {
02103                                 $this->installExtension($extKey);
02104                         }
02105 
02106                                 // Display:
02107                         if (!t3lib_extMgm::isLoaded($extKey))   {
02108                                 $outputRow[] = '
02109                                 <tr class="bgColor4">
02110                                         <td><input type="checkbox" name="'.htmlspecialchars('installOrImportExtension['.$extKey.']').'" value="1" checked="checked" /></td>
02111                                         <td>'.htmlspecialchars($extKey).'</td>
02112                                 </tr>
02113                                 ';
02114                         }
02115                 }
02116 
02117                 if (count($outputRow)>1 || !$returnUrl) {
02118                         $content = '
02119                         </form> <!-- ending page form ... -->
02120                         <form action="'.htmlspecialchars(t3lib_div::getIndpEnv('REQUEST_URI')).'" method="post">
02121                                 <table border="0" cellpadding="1" cellspacing="1">'.implode('',$outputRow).'</table>
02122                         <input type="submit" name="_" value="Import and Install selected" />
02123                         </form>
02124                         <form>  <!-- continuing page form... -->';
02125 
02126                         if ($returnUrl) {
02127                                 $content.= '
02128                                 <br/>
02129                                 <br/>
02130                                 <a href="'.htmlspecialchars($returnUrl).'">Return</a>
02131                                 ';
02132                         }
02133 
02134                         $this->content.= $this->doc->section('Import/Install Extensions:',$content,0,1);
02135                 } else {
02136                         header('Location: '.t3lib_div::locationHeaderUrl($returnUrl));
02137                 }
02138         }
02139 
02140 
02141 
02142 
02143 
02144 
02145 
02146 
02147         /***********************************
02148         *
02149         * Application Sub-functions (HTML parts)
02150         *
02151         **********************************/
02152 
02164         function updatesForm($extKey,$extInfo,$notSilent=0,$script='',$addFields='')    {
02165                 $script = $script ? $script : t3lib_div::linkThisScript();
02166                 $updates.= $this->checkDBupdates($extKey,$extInfo);
02167                 $uCache = $this->checkClearCache($extInfo);
02168                 if ($notSilent) $updates.= $uCache;
02169                 $updates.= $this->checkUploadFolder($extKey,$extInfo);
02170 
02171                 $absPath = $this->getExtPath($extKey,$extInfo['type']);
02172                 if ($notSilent && @is_file($absPath.'ext_conf_template.txt'))   {
02173                         $cForm = $this->tsStyleConfigForm($extKey,$extInfo,1,$script,$updates.$addFields.'<br />');
02174                 }
02175 
02176                 if ($updates || $cForm) {
02177                         if ($cForm)     {
02178                                 $updates = '</form>'.$cForm.'<form>';
02179                         } else {
02180                                 $updates = '</form><form action="'.htmlspecialchars($script).'" method="post">'.$updates.$addFields.'
02181                                         <br /><input type="submit" name="write" value="Make updates" />
02182                                 ';
02183                         }
02184                 }
02185                 return $updates;
02186         }
02187 
02195         function extDumpTables($extKey,$extInfo)        {
02196 
02197                 // Get dbInfo which holds the structure known from the tables.sql file
02198                 $techInfo = $this->makeDetailedExtensionAnalysis($extKey,$extInfo);
02199                 $absPath = $this->getExtPath($extKey,$extInfo['type']);
02200 
02201                 // Static tables:
02202                 if (is_array($techInfo['static']))      {
02203                         if ($this->CMD['writeSTATICdump'])      {       // Writing static dump:
02204                                 $writeFile = $absPath.'ext_tables_static+adt.sql';
02205                                 if (@is_file($writeFile))       {
02206                                         $dump_static = $this->dumpStaticTables(implode(',',$techInfo['static']));
02207                                         t3lib_div::writeFile($writeFile,$dump_static);
02208                                         $this->content.=$this->doc->section('Table and field structure required',t3lib_div::formatSize(strlen($dump_static)).'bytes written to '.substr($writeFile,strlen(PATH_site)),0,1);
02209                                 }
02210                         } else {        // Showing info about what tables to dump - and giving the link to execute it.
02211                                 $msg = 'Dumping table content for static tables:<br />';
02212                                 $msg.= '<br />'.implode('<br />',$techInfo['static']).'<br />';
02213 
02214                                 // ... then feed that to this function which will make new CREATE statements of the same fields but based on the current database content.
02215                                 $this->content.=$this->doc->section('Static tables',$msg.'<hr /><strong><a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[writeSTATICdump]=1').'">Write current static table contents to ext_tables_static+adt.sql now!</a></strong>',0,1);
02216                                 $this->content.=$this->doc->spacer(20);
02217                         }
02218                 }
02219 
02220                 // Table and field definitions:
02221                 if (is_array($techInfo['dump_tf']))     {
02222                         $dump_tf_array = $this->getTableAndFieldStructure($techInfo['dump_tf']);
02223                         $dump_tf = $this->dumpTableAndFieldStructure($dump_tf_array);
02224                         if ($this->CMD['writeTFdump'])  {
02225                                 $writeFile = $absPath.'ext_tables.sql';
02226                                 if (@is_file($writeFile))       {
02227                                         t3lib_div::writeFile($writeFile,$dump_tf);
02228                                         $this->content.=$this->doc->section('Table and field structure required',t3lib_div::formatSize(strlen($dump_tf)).'bytes written to '.substr($writeFile,strlen(PATH_site)),0,1);
02229                                 }
02230                         } else {
02231                                 $msg = 'Dumping current database structure for:<br />';
02232                                 if (is_array($techInfo['tables']))      {
02233                                         $msg.= '<br /><strong>Tables:</strong><br />'.implode('<br />',$techInfo['tables']).'<br />';
02234                                 }
02235                                 if (is_array($techInfo['fields']))      {
02236                                         $msg.= '<br /><strong>Solo-fields:</strong><br />'.implode('<br />',$techInfo['fields']).'<br />';
02237                                 }
02238 
02239                                 // ... then feed that to this function which will make new CREATE statements of the same fields but based on the current database content.
02240                                 $this->content.=$this->doc->section('Table and field structure required',$msg.'<hr /><strong><a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[writeTFdump]=1').'">Write this dump to ext_tables.sql now!</a></strong><hr />
02241                                 <pre>'.htmlspecialchars($dump_tf).'</pre>',0,1);
02242 
02243 
02244                                 $details = '                                                    This dump is based on two factors:<br />
02245                                 <ul>
02246                                 <li>1) All tablenames in ext_tables.sql which are <em>not</em> found in the "modify_tables" list in ext_emconf.php are dumped with the current database structure.</li>
02247                                 <li>2) For any tablenames which <em>are</em> listed in "modify_tables" all fields and keys found for the table in ext_tables.sql will be re-dumped with the fresh equalents from the database.</li>
02248                                 </ul>
02249                                 Bottomline is: Whole tables are dumped from database with no regard to which fields and keys are defined in ext_tables.sql. But for tables which are only modified, any NEW fields added to the database must in some form or the other exist in the ext_tables.sql file as well.<br />';
02250                                 $this->content.=$this->doc->section('',$details);
02251                         }
02252                 }
02253         }
02254 
02262         function getFileListOfExtension($extKey,$conf)  {
02263                 $content = '';
02264                 $extPath = $this->getExtPath($extKey,$conf['type']);
02265 
02266                 if ($extPath)   {
02267                         // Read files:
02268                         $fileArr = array();
02269                         $fileArr = t3lib_div::getAllFilesAndFoldersInPath($fileArr,$extPath);
02270 
02271                         // Start table:
02272                         $lines = array();
02273                         $totalSize = 0;
02274 
02275                         // Header:
02276                         $lines[] = '
02277                                 <tr class="bgColor5">
02278                                         <td>File:</td>
02279                                         <td>Size:</td>
02280                                         <td>Edit:</td>
02281                                 </tr>';
02282 
02283                         foreach($fileArr as $file)      {
02284                                 $fI = t3lib_div::split_fileref($file);
02285                                 $lines[] = '
02286                                 <tr class="bgColor4">
02287                                         <td><a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[downloadFile]='.rawurlencode($file)).'" title="Download...">'.substr($file,strlen($extPath)).'</a></td>
02288                                         <td>'.t3lib_div::formatSize(filesize($file)).'</td>
02289                                         <td>'.(!in_array($extKey,$this->requiredExt)&&t3lib_div::inList($this->editTextExtensions,($fI['fileext']?$fI['fileext']:$fI['filebody']))?'<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[editFile]='.rawurlencode($file)).'">Edit file</a>':'').'</td>
02290                                 </tr>';
02291                                 $totalSize+=filesize($file);
02292                         }
02293 
02294                         $lines[] = '
02295                                 <tr class="bgColor6">
02296                                         <td><strong>Total:</strong></td>
02297                                         <td><strong>'.t3lib_div::formatSize($totalSize).'</strong></td>
02298                                         <td>&nbsp;</td>
02299                                 </tr>';
02300 
02301                         $content = '
02302                         Path: '.$extPath.'<br /><br />
02303                         <table border="0" cellpadding="1" cellspacing="2">'.implode('',$lines).'</table>';
02304                 }
02305 
02306                 return $content;
02307         }
02308 
02316         function extDelete($extKey,$extInfo)    {
02317                 $absPath = $this->getExtPath($extKey,$extInfo['type']);
02318                 if (t3lib_extMgm::isLoaded($extKey))    {
02319                         return 'This extension is currently installed (loaded and active) and so cannot be deleted!';
02320                 } elseif (!$this->deleteAsType($extInfo['type'])) {
02321                         return 'You cannot delete (and install/update) extensions in the '.$this->typeLabels[$extInfo['type']].' scope.';
02322                 } elseif (t3lib_div::inList('G,L',$extInfo['type'])) {
02323                         if ($this->CMD['doDelete'] && !strcmp($absPath,$this->CMD['absPath'])) {
02324                                 $res = $this->removeExtDirectory($absPath);
02325                                 if ($res) {
02326                                         return 'ERROR: Could not remove extension directory "'.$absPath.'". Had the following errors:<br /><br />'.
02327                                         nl2br($res);
02328                                 } else {
02329                                         return 'Removed extension in path "'.$absPath.'"!';
02330                                 }
02331                         } else {
02332                                 $onClick = "if (confirm('Are you sure you want to delete this extension from the server?')) {window.location.href='index.php?CMD[showExt]=".$extKey.'&CMD[doDelete]=1&CMD[absPath]='.rawurlencode($absPath)."';}";
02333                                 $content.= '<a href="#" onclick="'.htmlspecialchars($onClick).' return false;"><strong>DELETE EXTENSION FROM SERVER</strong> (in the "'.$this->typeLabels[$extInfo['type']].'" location "'.substr($absPath,strlen(PATH_site)).'")!</a>';
02334                                 $content.= '<br /><br />(Maybe you should make a backup first, see above.)';
02335                                 return $content;
02336                         }
02337                 } else return 'Extension is not a global or local extension and cannot be removed.';
02338         }
02339 
02347         function extUpdateEMCONF($extKey,$extInfo)      {
02348                 $absPath = $this->getExtPath($extKey,$extInfo['type']);
02349                 if ($this->CMD['doUpdateEMCONF']) {
02350                         return $this->updateLocalEM_CONF($extKey,$extInfo);
02351                 } else {
02352                         $onClick = "if (confirm('Are you sure you want to update EM_CONF?')) {window.location.href='index.php?CMD[showExt]=".$extKey."&CMD[doUpdateEMCONF]=1';}";
02353                         $content.= '<a href="#" onclick="'.htmlspecialchars($onClick).' return false;"><strong>Update extension EM_CONF file</strong> (in the "'.$this->typeLabels[$extInfo['type']].'" location "'.substr($absPath,strlen(PATH_site)).'")!</a>';
02354                         $content.= '<br /><br />If files are changed, added or removed to an extension this is normally detected and displayed so you know that this extension has been locally altered and may need to be uploaded or at least not overridden.<br />
02355                                                 Updating this file will first of all reset this registration.';
02356                         return $content;
02357                 }
02358         }
02359 
02367         function extBackup($extKey,$extInfo)    {
02368                 $uArr = $this->makeUploadArray($extKey,$extInfo);
02369                 if (is_array($uArr))    {
02370                         $backUpData = $this->terConnection->makeUploadDataFromArray($uArr);
02371                         $filename = 'T3X_'.$extKey.'-'.str_replace('.','_',$extInfo['EM_CONF']['version']).'-z-'.date('YmdHi').'.t3x';
02372                         if (intval($this->CMD['doBackup'])==1)  {
02373                                 header('Content-Type: application/octet-stream');
02374                                 header('Content-Disposition: attachment; filename='.$filename);
02375                                 echo $backUpData;
02376                                 exit;
02377                         } elseif ($this->CMD['dumpTables'])     {
02378                                 $filename='T3X_'.$extKey;
02379                                 $cTables = count(explode(',',$this->CMD['dumpTables']));
02380                                 if ($cTables>1) {
02381                                         $filename.='-'.$cTables.'tables';
02382                                 } else {
02383                                         $filename.='-'.$this->CMD['dumpTables'];
02384                                 }
02385                                 $filename.='+adt.sql';
02386 
02387                                 header('Content-Type: application/octet-stream');
02388                                 header('Content-Disposition: attachment; filename='.$filename);
02389                                 echo $this->dumpStaticTables($this->CMD['dumpTables']);
02390                                 exit;
02391                         } else {
02392                                 $techInfo = $this->makeDetailedExtensionAnalysis($extKey,$extInfo);
02393                                 $lines=array();
02394                                 $lines[]='<tr class="bgColor5"><td colspan="2"><strong>Make selection:</strong></td></tr>';
02395                                 $lines[]='<tr class="bgColor4"><td><strong>Extension files:</strong></td><td>'.
02396                                 '<a href="'.htmlspecialchars('index.php?CMD[doBackup]=1&CMD[showExt]='.$extKey).'">Download extension "'.$extKey.'" as a file</a><br />('.$filename.', '.t3lib_div::formatSize(strlen($backUpData)).', MD5: '.md5($backUpData).')<br /></td></tr>';
02397 
02398                                 if (is_array($techInfo['tables']))      {       $lines[]='<tr class="bgColor4"><td><strong>Data tables:</strong></td><td>'.$this->extBackup_dumpDataTablesLine($techInfo['tables'],$extKey).'</td></tr>';       }
02399                                 if (is_array($techInfo['static']))      {       $lines[]='<tr class="bgColor4"><td><strong>Static tables:</strong></td><td>'.$this->extBackup_dumpDataTablesLine($techInfo['static'],$extKey).'</td></tr>';     }
02400 
02401                                 $content = '<table border="0" cellpadding="2" cellspacing="2">'.implode('',$lines).'</table>';
02402                                 return $content;
02403                         }
02404                 } else die('Error...');
02405         }
02406 
02414         function extBackup_dumpDataTablesLine($tablesArray,$extKey)     {
02415                 $tables = array();
02416                 $tablesNA = array();
02417 
02418                 foreach($tablesArray as $tN)    {
02419                         $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('count(*)', $tN, '');
02420                         if (!$GLOBALS['TYPO3_DB']->sql_error()) {
02421                                 $row = $GLOBALS['TYPO3_DB']->sql_fetch_row($res);
02422                                 $tables[$tN]='<tr><td>&nbsp;</td><td><a href="'.htmlspecialchars('index.php?CMD[dumpTables]='.rawurlencode($tN).'&CMD[showExt]='.$extKey).'" title="Dump table \''.$tN.'\'">'.$tN.'</a></td><td>&nbsp;&nbsp;&nbsp;</td><td>'.$row[0].' records</td></tr>';
02423                         } else {
02424                                 $tablesNA[$tN]='<tr><td>&nbsp;</td><td>'.$tN.'</td><td>&nbsp;</td><td>Did not exist.</td></tr>';
02425                         }
02426                 }
02427                 $label = '<table border="0" cellpadding="0" cellspacing="0">'.implode('',array_merge($tables,$tablesNA)).'</table>';// Candidate for t3lib_div::array_merge() if integer-keys will some day make trouble...
02428                 if (count($tables))     {
02429                         $label = '<a href="'.htmlspecialchars('index.php?CMD[dumpTables]='.rawurlencode(implode(',',array_keys($tables))).'&CMD[showExt]='.$extKey).'" title="Dump all existing tables.">Download all data from:</a><br /><br />'.$label;
02430                 } else $label = 'Nothing to dump...<br /><br />'.$label;
02431                 return $label;
02432         }
02433 
02442         function extInformationArray($extKey,$extInfo,$remote=0)        {
02443                 $lines=array();
02444                 $lines[]='<tr class="bgColor5"><td colspan="2"><strong>General information:</strong></td>'.$this->helpCol('').'</tr>';
02445                 $lines[]='<tr class="bgColor4"><td>Title:</td><td>'.$extInfo['EM_CONF']['_icon'].$extInfo['EM_CONF']['title'].'</td>'.$this->helpCol('title').'</tr>';
02446                 $lines[]='<tr class="bgColor4"><td>Description:</td><td>'.nl2br(htmlspecialchars($extInfo['EM_CONF']['description'])).'</td>'.$this->helpCol('description').'</tr>';
02447                 $lines[]='<tr class="bgColor4"><td>Author:</td><td>'.$this->wrapEmail($extInfo['EM_CONF']['author'].($extInfo['EM_CONF']['author_email'] ? ' <'.$extInfo['EM_CONF']['author_email'].'>' : ''),$extInfo['EM_CONF']['author_email']).($extInfo['EM_CONF']['author_company']?', '.$extInfo['EM_CONF']['author_company']:'').
02448                 '</td>'.$this->helpCol('description').'</tr>';
02449 
02450                 $lines[]='<tr class="bgColor4"><td>Version:</td><td>'.$extInfo['EM_CONF']['version'].'</td>'.$this->helpCol('version').'</tr>';
02451                 $lines[]='<tr class="bgColor4"><td>Category:</td><td>'.$this->categories[$extInfo['EM_CONF']['category']].'</td>'.$this->helpCol('category').'</tr>';
02452                 $lines[]='<tr class="bgColor4"><td>State:</td><td>'.$this->states[$extInfo['EM_CONF']['state']].'</td>'.$this->helpCol('state').'</tr>';
02453                 $lines[]='<tr class="bgColor4"><td>Shy?</td><td>'.($extInfo['EM_CONF']['shy']?'Yes':'').'</td>'.$this->helpCol('shy').'</tr>';
02454                 $lines[]='<tr class="bgColor4"><td>Internal?</td><td>'.($extInfo['EM_CONF']['internal']?'Yes':'').'</td>'.$this->helpCol('internal').'</tr>';
02455 
02456                 $lines[]='<tr class="bgColor4"><td>Depends on:</td><td>'.$this->depToString($extInfo['EM_CONF']['constraints']).'</td>'.$this->helpCol('dependencies').'</tr>';
02457                 $lines[]='<tr class="bgColor4"><td>Conflicts with:</td><td>'.$this->depToString($extInfo['EM_CONF']['constraints'],'conflicts').'</td>'.$this->helpCol('dependencies').'</tr>';
02458                 $lines[]='<tr class="bgColor4"><td>Suggests:</td><td>'.$this->depToString($extInfo['EM_CONF']['constraints'],'suggests').'</td>'.$this->helpCol('dependencies').'</tr>';
02459                 if (!$remote)   {
02460                         $lines[]='<tr class="bgColor4"><td>Priority:</td><td>'.$extInfo['EM_CONF']['priority'].'</td>'.$this->helpCol('priority').'</tr>';
02461                         $lines[]='<tr class="bgColor4"><td>Clear cache?</td><td>'.($extInfo['EM_CONF']['clearCacheOnLoad']?'Yes':'').'</td>'.$this->helpCol('clearCacheOnLoad').'</tr>';
02462                         $lines[]='<tr class="bgColor4"><td>Includes modules:</td><td>'.$extInfo['EM_CONF']['module'].'</td>'.$this->helpCol('module').'</tr>';
02463                         $lines[]='<tr class="bgColor4"><td>Lock Type?</td><td>'.($extInfo['EM_CONF']['lockType']?$extInfo['EM_CONF']['lockType']:'').'</td>'.$this->helpCol('lockType').'</tr>';
02464                         $lines[]='<tr class="bgColor4"><td>Modifies tables:</td><td>'.$extInfo['EM_CONF']['modify_tables'].'</td>'.$this->helpCol('modify_tables').'</tr>';
02465 
02466                         // Installation status:
02467                         $techInfo = $this->makeDetailedExtensionAnalysis($extKey,$extInfo,1);
02468                         $lines[]='<tr><td>&nbsp;</td><td></td>'.$this->helpCol('').'</tr>';
02469                         $lines[]='<tr class="bgColor5"><td colspan="2"><strong>Installation status:</strong></td>'.$this->helpCol('').'</tr>';
02470                         $lines[]='<tr class="bgColor4"><td>Type of install:</td><td>'.$this->typeLabels[$extInfo['type']].' - <em>'.$this->typeDescr[$extInfo['type']].'</em></td>'.$this->helpCol('type').'</tr>';
02471                         $lines[]='<tr class="bgColor4"><td>Double installs?</td><td>'.$this->extInformationArray_dbInst($extInfo['doubleInstall'],$extInfo['type']).'</td>'.$this->helpCol('doubleInstall').'</tr>';
02472                         if (is_array($extInfo['files']))        {
02473                                 sort($extInfo['files']);
02474                                 $lines[]='<tr class="bgColor4"><td>Root files:</td><td>'.implode('<br />',$extInfo['files']).'</td>'.$this->helpCol('rootfiles').'</tr>';
02475                         }
02476 
02477                         if ($techInfo['tables']||$techInfo['static']||$techInfo['fields'])      {
02478                                 if (!$remote && t3lib_extMgm::isLoaded($extKey))        {
02479                                         $tableStatus = $GLOBALS['TBE_TEMPLATE']->rfw(($techInfo['tables_error']?'<strong>Table error!</strong><br />Probably one or more required fields/tables are missing in the database!':'').
02480                                         ($techInfo['static_error']?'<strong>Static table error!</strong><br />The static tables are missing or empty!':''));
02481                                 } else {
02482                                         $tableStatus = $techInfo['tables_error']||$techInfo['static_error'] ? 'The database will need to be updated when this extension is installed.' : 'All required tables are already in the database!';
02483                                 }
02484                         }
02485 
02486                         $lines[]='<tr class="bgColor4"><td>Database requirements:</td><td>'.$this->extInformationArray_dbReq($techInfo,1).'</td>'.$this->helpCol('dbReq').'</tr>';
02487                         $lines[]='<tr class="bgColor4"><td>Database status:</td><td>'.$tableStatus.'</td>'.$this->helpCol('dbStatus').'</tr>';
02488                         $lines[]='<tr class="bgColor4"><td>Flags:</td><td>'.(is_array($techInfo['flags'])?implode('<br />',$techInfo['flags']):'').'</td>'.$this->helpCol('flags').'</tr>';
02489                         $lines[]='<tr class="bgColor4"><td>Config template?</td><td>'.($techInfo['conf']?'Yes':'').'</td>'.$this->helpCol('conf').'</tr>';
02490                         $lines[]='<tr class="bgColor4"><td>TypoScript files:</td><td>'.(is_array($techInfo['TSfiles'])?implode('<br />',$techInfo['TSfiles']):'').'</td>'.$this->helpCol('TSfiles').'</tr>';
02491                         $lines[]='<tr class="bgColor4"><td>Language files:</td><td>'.(is_array($techInfo['locallang'])?implode('<br />',$techInfo['locallang']):'').'</td>'.$this->helpCol('locallang').'</tr>';
02492                         $lines[]='<tr class="bgColor4"><td>Upload folder:</td><td>'.($techInfo['uploadfolder']?$techInfo['uploadfolder']:'').'</td>'.$this->helpCol('uploadfolder').'</tr>';
02493                         $lines[]='<tr class="bgColor4"><td>Create directories:</td><td>'.(is_array($techInfo['createDirs'])?implode('<br />',$techInfo['createDirs']):'').'</td>'.$this->helpCol('createDirs').'</tr>';
02494                         $lines[]='<tr class="bgColor4"><td>Module names:</td><td>'.(is_array($techInfo['moduleNames'])?implode('<br />',$techInfo['moduleNames']):'').'</td>'.$this->helpCol('moduleNames').'</tr>';
02495                         $lines[]='<tr class="bgColor4"><td>Class names:</td><td>'.(is_array($techInfo['classes'])?implode('<br />',$techInfo['classes']):'').'</td>'.$this->helpCol('classNames').'</tr>';
02496                         $lines[]='<tr class="bgColor4"><td>Code warnings:<br />(developer-relevant)</td><td>'.(is_array($techInfo['errors'])?$GLOBALS['TBE_TEMPLATE']->rfw(implode('<br />',$techInfo['errors'])):'').'</td>'.$this->helpCol('errors').'</tr>';
02497                         $lines[]='<tr class="bgColor4"><td>Naming annoyances:<br />(developer-relevant)</td><td>'.(is_array($techInfo['NSerrors']) ? (!t3lib_div::inList($this->nameSpaceExceptions,$extKey)?t3lib_div::view_array($techInfo['NSerrors']):$GLOBALS['TBE_TEMPLATE']->dfw('[exception]')) : '').'</td>'.$this->helpCol('NSerrors').'</tr>';
02498 
02499                         $currentMd5Array = $this->serverExtensionMD5Array($extKey,$extInfo);
02500                         $affectedFiles='';
02501 
02502                         $msgLines=array();
02503                         if (strcmp($extInfo['EM_CONF']['_md5_values_when_last_written'],serialize($currentMd5Array)))   {
02504                                 $msgLines[] = $GLOBALS['TBE_TEMPLATE']->rfw('<br /><strong>A difference between the originally installed version and the current was detected!</strong>');
02505                                 $affectedFiles = $this->findMD5ArrayDiff($currentMd5Array,unserialize($extInfo['EM_CONF']['_md5_values_when_last_written']));
02506                                 if (count($affectedFiles))      $msgLines[] = '<br /><strong>Modified files:</strong><br />'.$GLOBALS['TBE_TEMPLATE']->rfw(implode('<br />',$affectedFiles));
02507                         }
02508                         $lines[]='<tr class="bgColor4"><td>Files changed?</td><td>'.implode('<br />',$msgLines).'</td>'.$this->helpCol('filesChanged').'</tr>';
02509                 }
02510 
02511                 return '<table border="0" cellpadding="1" cellspacing="2">
02512                                         '.implode('
02513                                         ',$lines).'
02514                                 </table>';
02515         }
02516 
02524         function extInformationArray_dbReq($techInfo,$tableHeader=0)    {
02525                 return nl2br(trim((is_array($techInfo['tables'])?($tableHeader?"\n\n<strong>Tables:</strong>\n":'').implode(chr(10),$techInfo['tables']):'').
02526                 (is_array($techInfo['static'])?"\n\n<strong>Static tables:</strong>\n".implode(chr(10),$techInfo['static']):'').
02527                 (is_array($techInfo['fields'])?"\n\n<strong>Additional fields:</strong>\n".implode('<hr />',$techInfo['fields']):'')));
02528         }
02529 
02537         function extInformationArray_dbInst($dbInst,$current)   {
02538                 if (strlen($dbInst)>1)  {
02539                         $others = array();
02540                         for($a=0;$a<strlen($dbInst);$a++)       {
02541                                 if (substr($dbInst,$a,1)!=$current)     {
02542                                         $others[]='"'.$this->typeLabels[substr($dbInst,$a,1)].'"';
02543                                 }
02544                         }
02545                         return $GLOBALS['TBE_TEMPLATE']->rfw('A '.implode(' and ',$others).' extension with this key is also available on the server, but cannot be loaded because the "'.$this->typeLabels[$current].'" version takes precedence.');
02546                 } else return '';
02547         }
02548 
02556         function getRepositoryUploadForm($extKey,$extInfo)      {
02557                 $content.='
02558                         <input type="hidden" name="CMD[showExt]" value="'.$extKey.'" />
02559                         <input type="hidden" name="em[action]" value="doUpload" />
02560                         <table border="0" cellpadding="2" cellspacing="1">
02561                                 <tr class="bgColor4">
02562                                         <td>Repository Username:</td>
02563                                         <td><input'.$this->doc->formWidth(20).' type="text" name="em[user][fe_u]" value="'.$this->fe_user['username'].'" /></td>
02564                                 </tr>
02565                                 <tr class="bgColor4">
02566                                         <td>Repository Password:</td>
02567                                         <td><input'.$this->doc->formWidth(20).' type="password" name="em[user][fe_p]" value="'.$this->fe_user['password'].'" /></td>
02568                                 </tr>
02569                                 <tr class="bgColor4">
02570                                         <td>Changelog for upload:</td>
02571                                         <td><textarea'.$this->doc->formWidth(30,1).' rows="5" name="em[upload][comment]"></textarea></td>
02572                                 </tr>
02573                                 <tr class="bgColor4">
02574                                         <td>Upload command:</td>
02575                                         <td nowrap="nowrap">
02576                                                 <input type="radio" name="em[upload][mode]" value="new_dev" checked="checked" /> New development version (latest x.x.<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw('x+1').'</strong>)<br />
02577                                                 <input type="radio" name="em[upload][mode]" value="latest" /> Override <em>this</em> development version ('.$extInfo['EM_CONF']['version'].')<br />
02578                                                 <input type="radio" name="em[upload][mode]" value="new_sub" /> New sub version (latest x.<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw('x+1').'</strong>.0)<br />
02579                                                 <input type="radio" name="em[upload][mode]" value="new_main" /> New main version (latest <strong>'.$GLOBALS['TBE_TEMPLATE']->rfw('x+1').'</strong>.0.0)<br />
02580                                                 <input type="radio" name="em[upload][mode]" value="custom" /> This version: <input type="text" name="em[upload][version]" /><br />
02581                                         </td>
02582                                 </tr>
02583                                 <tr class="bgColor4">
02584                                         <td>&nbsp;</td>
02585                                         <td><input type="submit" name="submit" value="Upload extension" />
02586                                         </td>
02587                                 </tr>
02588                         </table>
02589                         ';
02590 
02591                 return $content;
02592         }
02593 
02594 
02595 
02596 
02597 
02598 
02599 
02600 
02601 
02602 
02603         /***********************************
02604         *
02605         * Extension list rendering
02606         *
02607         **********************************/
02608 
02617         function extensionListRowHeader($trAttrib,$cells,$import=0)     {
02618                 $cells[] = '<td></td>';
02619                 $cells[] = '<td>Title:</td>';
02620 
02621                 if (!$this->MOD_SETTINGS['display_details'])    {
02622                         $cells[] = '<td>Description:</td>';
02623                         $cells[] = '<td>Author:</td>';
02624                 } elseif ($this->MOD_SETTINGS['display_details']==2)    {
02625                         $cells[] = '<td>Priority:</td>';
02626                         $cells[] = '<td>Mod.Tables:</td>';
02627                         $cells[] = '<td>Modules:</td>';
02628                         $cells[] = '<td>Cl.Cache?</td>';
02629                         $cells[] = '<td>Internal?</td>';
02630                         $cells[] = '<td>Shy?</td>';
02631                 } elseif ($this->MOD_SETTINGS['display_details']==3)    {
02632                         $cells[] = '<td>Tables/Fields:</td>';
02633                         $cells[] = '<td>TS-files:</td>';
02634                         $cells[] = '<td>Affects:</td>';
02635                         $cells[] = '<td>Modules:</td>';
02636                         $cells[] = '<td>Config?</td>';
02637                         $cells[] = '<td>Code warnings:</td>';
02638                 } elseif ($this->MOD_SETTINGS['display_details']==4)    {
02639                         $cells[] = '<td>locallang:</td>';
02640                         $cells[] = '<td>Classes:</td>';
02641                         $cells[] = '<td>Code warnings:</td>';
02642                         $cells[] = '<td>Nameing annoyances:</td>';
02643                 } elseif ($this->MOD_SETTINGS['display_details']==5)    {
02644                         $cells[] = '<td>Changed files:</td>';
02645                 } else {
02646                         $cells[] = '<td>Extension key:</td>';
02647                         $cells[] = '<td>Version:</td>';
02648                         if (!$import) {
02649                                 $cells[] = '<td>DL:</td>';
02650                                 $cells[] = '<td>Doc:</td>';
02651                                 $cells[] = '<td>Type:</td>';
02652                         } else {
02653                                 $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>';
02654                                 $cells[] = '<td class="bgColor6"'.$this->labelInfo('Current type of installation of the extension on this server.').'>Cur. Type:</td>';
02655                                 $cells[] = '<td'.$this->labelInfo('Number of downloads, all versions/this version').'>DL:</td>';
02656                         }
02657                         $cells[] = '<td>State:</td>';
02658                 }
02659                 return '
02660                         <tr'.$trAttrib.'>
02661                                 '.implode('
02662                                 ',$cells).'
02663                         </tr>';
02664         }
02665 
02678         function extensionListRow($extKey,$extInfo,$cells,$bgColorClass='',$inst_list=array(),$import=0,$altLinkUrl='') {
02679 
02680                         // Icon:
02681                 $imgInfo = @getImageSize($this->getExtPath($extKey,$extInfo['type']).'/ext_icon.gif');
02682                 if (is_array($imgInfo)) {
02683                         $cells[] = '<td><img src="'.$GLOBALS['BACK_PATH'].$this->typeRelPaths[$extInfo['type']].$extKey.'/ext_icon.gif'.'" '.$imgInfo[3].' alt="" /></td>';
02684                 } elseif ($extInfo['_ICON']) {
02685                         $cells[] = '<td>'.$extInfo['_ICON'].'</td>';
02686                 } else {
02687                         $cells[] = '<td><img src="clear.gif" width="1" height="1" alt="" /></td>';
02688                 }
02689 
02690                         // Extension title:
02691                 $cells[] = '<td nowrap="nowrap"><a href="'.htmlspecialchars($altLinkUrl?$altLinkUrl:'index.php?CMD[showExt]='.$extKey.'&SET[singleDetails]=info').'" title="'.$extKey.'"'/*.($extInfo['EM_CONF']['shy'] ? ' style="color:#666;" ' : '')*/.'>'.t3lib_div::fixed_lgd($extInfo['EM_CONF']['title']?$extInfo['EM_CONF']['title']:'<em>'.$extKey.'</em>',40).'</a></td>';
02692 
02693                         // Based on which display mode you will see more or less details:
02694                 if (!$this->MOD_SETTINGS['display_details'])    {
02695                         $cells[] = '<td>'.htmlspecialchars(t3lib_div::fixed_lgd($extInfo['EM_CONF']['description'],400)).'<br /><img src="clear.gif" width="300" height="1" alt="" /></td>';
02696                         $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>';
02697                 } elseif ($this->MOD_SETTINGS['display_details']==2)    {
02698                         $cells[] = '<td nowrap="nowrap">'.$extInfo['EM_CONF']['priority'].'</td>';
02699                         $cells[] = '<td nowrap="nowrap">'.implode('<br />',t3lib_div::trimExplode(',',$extInfo['EM_CONF']['modify_tables'],1)).'</td>';
02700                         $cells[] = '<td nowrap="nowrap">'.$extInfo['EM_CONF']['module'].'</td>';
02701                         $cells[] = '<td nowrap="nowrap">'.($extInfo['EM_CONF']['clearCacheOnLoad'] ? 'Yes' : '').'</td>';
02702                         $cells[] = '<td nowrap="nowrap">'.($extInfo['EM_CONF']['internal'] ? 'Yes' : '').'</td>';
02703                         $cells[] = '<td nowrap="nowrap">'.($extInfo['EM_CONF']['shy'] ? 'Yes' : '').'</td>';
02704                 } elseif ($this->MOD_SETTINGS['display_details']==3)    {
02705                         $techInfo = $this->makeDetailedExtensionAnalysis($extKey,$extInfo);
02706 
02707                         $cells[] = '<td>'.$this->extInformationArray_dbReq($techInfo).
02708                         '</td>';
02709                         $cells[] = '<td nowrap="nowrap">'.(is_array($techInfo['TSfiles']) ? implode('<br />',$techInfo['TSfiles']) : '').'</td>';
02710                         $cells[] = '<td nowrap="nowrap">'.(is_array($techInfo['flags']) ? implode('<br />',$techInfo['flags']) : '').'</td>';
02711                         $cells[] = '<td nowrap="nowrap">'.(is_array($techInfo['moduleNames']) ? implode('<br />',$techInfo['moduleNames']) : '').'</td>';
02712                         $cells[] = '<td nowrap="nowrap">'.($techInfo['conf'] ? 'Yes' : '').'</td>';
02713                         $cells[] = '<td>'.
02714                         $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!':'').
02715                         (t3lib_extMgm::isLoaded($extKey)&&$techInfo['static_error']?'<strong>Static table error!</strong><br />The static tables are missing or empty!':'')).
02716                         '</td>';
02717                 } elseif ($this->MOD_SETTINGS['display_details']==4)    {
02718                         $techInfo=$this->makeDetailedExtensionAnalysis($extKey,$extInfo,1);
02719 
02720                         $cells[] = '<td>'.(is_array($techInfo['locallang']) ? implode('<br />',$techInfo['locallang']) : '').'</td>';
02721                         $cells[] = '<td>'.(is_array($techInfo['classes']) ? implode('<br />',$techInfo['classes']) : '').'</td>';
02722                         $cells[] = '<td>'.(is_array($techInfo['errors']) ? $GLOBALS['TBE_TEMPLATE']->rfw(implode('<hr />',$techInfo['errors'])) : '').'</td>';
02723                         $cells[] = '<td>'.(is_array($techInfo['NSerrors']) ? (!t3lib_div::inList($this->nameSpaceExceptions,$extKey) ? t3lib_div::view_array($techInfo['NSerrors']) : $GLOBALS['TBE_TEMPLATE']->dfw('[exception]')) :'').'</td>';
02724                 } elseif ($this->MOD_SETTINGS['display_details']==5)    {
02725                         $currentMd5Array = $this->serverExtensionMD5Array($extKey,$extInfo);
02726                         $affectedFiles = '';
02727                         $msgLines = array();
02728                         $msgLines[] = 'Files: '.count($currentMd5Array);
02729                         if (strcmp($extInfo['EM_CONF']['_md5_values_when_last_written'],serialize($currentMd5Array)))   {
02730                                 $msgLines[] = $GLOBALS['TBE_TEMPLATE']->rfw('<br /><strong>A difference between the originally installed version and the current was detected!</strong>');
02731                                 $affectedFiles = $this->findMD5ArrayDiff($currentMd5Array,unserialize($extInfo['EM_CONF']['_md5_values_when_last_written']));
02732                                 if (count($affectedFiles))      $msgLines[] = '<br /><strong>Modified files:</strong><br />'.$GLOBALS['TBE_TEMPLATE']->rfw(implode('<br />',$affectedFiles));
02733                         }
02734                         $cells[] = '<td>'.implode('<br />',$msgLines).'</td>';
02735                 } else {
02736                                 // Default view:
02737                         $verDiff = $inst_list[$extKey] && $this->versionDifference($extInfo['EM_CONF']['version'],$inst_list[$extKey]['EM_CONF']['version'],$this->versionDiffFactor);
02738 
02739                         $cells[] = '<td nowrap="nowrap"><em>'.$extKey.'</em></td>';
02740                         $cells[] = '<td nowrap="nowrap">'.($verDiff ? '<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw(htmlspecialchars($extInfo['EM_CONF']['version'])).'</strong>' : $extInfo['EM_CONF']['version']).'</td>';
02741                         if (!$import) {         // Listing extenson on LOCAL server:
02742                                         // Extension Download:
02743                                 $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>';
02744 
02745                                         // Manual download
02746                                 $fileP = PATH_site.$this->typePaths[$extInfo['type']].$extKey.'/doc/manual.sxw';
02747                                 $cells[] = '<td nowrap="nowrap">'.
02748                                 ($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>':'').
02749                                 '</td>';
02750                                 $cells[] = '<td nowrap="nowrap">'.$this->typeLabels[$extInfo['type']].(strlen($extInfo['doubleInstall'])>1?'<strong> '.$GLOBALS['TBE_TEMPLATE']->rfw($extInfo['doubleInstall']).'</strong>':'').'</td>';
02751                         } else {        // Listing extensions from REMOTE repository:
02752                                 $inst_curVer = $inst_list[$extKey]['EM_CONF']['version'];
02753                                 if (isset($inst_list[$extKey])) {
02754                                         if ($verDiff)   $inst_curVer = '<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw($inst_curVer).'</strong>';
02755                                 }
02756                                 $cells[] = '<td nowrap="nowrap">'.$inst_curVer.'</td>';
02757                                 $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>';
02758                                 $cells[] = '<td nowrap="nowrap">'.($extInfo['downloadcounter_all']?$extInfo['downloadcounter_all']:'&nbsp;&nbsp;').'/'.($extInfo['downloadcounter']?$extInfo['downloadcounter']:'&nbsp;').'</td>';
02759                         }
02760                         $cells[] = '<td nowrap="nowrap" class="extstate" style="background-color:'.$this->stateColors[$extInfo['EM_CONF']['state']].';">'.$this->states[$extInfo['EM_CONF']['state']].'</td>';
02761                 }
02762 
02763                 if($this->xmlhandler->getReviewState($extKey,$extInfo['EM_CONF']['version'])<1) {
02764                         $bgclass = ' class="unsupported-ext"';
02765                 } else {
02766                         $bgclass = ' class="'.($bgColorClass?$bgColorClass:'bgColor4').'"';
02767                 }
02768 
02769                 return '
02770                         <tr'.$bgclass.'>
02771                                 '.implode('
02772                                 ',$cells).'
02773                         </tr>';
02774         }
02775 
02776 
02777 
02778 
02779 
02780 
02781         /************************************
02782         *
02783         * Output helper functions
02784         *
02785         ************************************/
02786 
02794         function wrapEmail($str,$email) {
02795                 if ($email)     {
02796                         $str = '<a href="mailto:'.htmlspecialchars($email).'">'.htmlspecialchars($str).'</a>';
02797                 }
02798                 return $str;
02799         }
02800 
02807         function helpCol($key)  {
02808                 global $BE_USER;
02809                 if ($BE_USER->uc['edit_showFieldHelp']) {
02810                         $hT = trim(t3lib_BEfunc::helpText($this->descrTable,'emconf_'.$key,$this->doc->backPath));
02811                         return '<td>'.($hT?$hT:t3lib_BEfunc::helpTextIcon($this->descrTable,'emconf_'.$key,$this->doc->backPath)).'</td>';
02812                 } else {
02813                         return '';
02814                 }
02815         }
02816 
02823         function labelInfo($str)        {
02824                 return ' title="'.htmlspecialchars($str).'" style="cursor:help;"';
02825         }
02826 
02835         function extensionTitleIconHeader($extKey,$extInfo,$align='top')        {
02836                 $imgInfo = @getImageSize($this->getExtPath($extKey,$extInfo['type']).'/ext_icon.gif');
02837                 $out = '';
02838                 if (is_array($imgInfo)) {
02839                         $out.= '<img src="'.$GLOBALS['BACK_PATH'].$this->typeRelPaths[$extInfo['type']].$extKey.'/ext_icon.gif" '.$imgInfo[3].' align="'.$align.'" alt="" />';
02840                 }
02841                 $out.= $extInfo['EM_CONF']['title'] ? htmlspecialchars(t3lib_div::fixed_lgd($extInfo['EM_CONF']['title'],40)) : '<em>'.$extKey.'</em>';
02842                 return $out;
02843         }
02844 
02850         function removeButton() {
02851                 return '<img src="uninstall.gif" width="16" height="16" title="Remove extension" align="top" alt="" />';
02852         }
02853 
02859         function installButton()        {
02860                 return '<img src="install.gif" width="16" height="16" title="Install extension..." align="top" alt="" />';
02861         }
02862 
02868         function noImportMsg()  {
02869                 return '<img src="'.$this->doc->backPath.'gfx/icon_warning2.gif" width="18" height="16" align="top" alt="" /><strong>Import to both local and global path is disabled in TYPO3_CONF_VARS!</strong>';
02870         }
02871 
02881         function depToString($dep,$type='depends') {
02882                 if(is_array($dep)) {
02883                         unset($dep[$type]['php']);
02884                         unset($dep[$type]['typo3']);
02885                         $s = (count($dep[$type])) ? implode(',', array_keys($dep[$type])) : '';
02886                         return $s;
02887                 }
02888                 return '';
02889         }
02890 
02900         function stringToDep($dep) {
02901                 $constraint = array();
02902                 if(is_string($dep) && strlen($dep)) {
02903                         $dep = explode(',',$dep);
02904                         foreach($dep as $v) {
02905                                 $constraint[$v] = '';
02906                         }
02907                 }
02908                 return $constraint;
02909         }
02910 
02911 
02912 
02913 
02914 
02915 
02916 
02917 
02918         /********************************
02919         *
02920         * Read information about all available extensions
02921         *
02922         *******************************/
02923 
02930         function getInstalledExtensions()       {
02931                 $list = array();
02932                 $cat = $this->defaultCategories;
02933 
02934                 $path = PATH_site.TYPO3_mainDir.'sysext/';
02935                 $this->getInstExtList($path,$list,$cat,'S');
02936 
02937                 $path = PATH_site.TYPO3_mainDir.'ext/';
02938                 $this->getInstExtList($path,$list,$cat,'G');
02939 
02940                 $path = PATH_site.'typo3conf/ext/';
02941                 $this->getInstExtList($path,$list,$cat,'L');
02942 
02943                 return array($list,$cat);
02944         }
02945 
02957         function getInstExtList($path,&$list,&$cat,$type)       {
02958 
02959                 if (@is_dir($path))     {
02960                         $extList = t3lib_div::get_dirs($path);
02961                         if (is_array($extList)) {
02962                                 foreach($extList as $extKey)    {
02963                                         if (@is_file($path.$extKey.'/ext_emconf.php'))  {
02964                                                 $emConf = $this->includeEMCONF($path.$extKey.'/ext_emconf.php', $extKey);
02965                                                 if (is_array($emConf))  {
02966                                                         if (is_array($list[$extKey]))   {
02967                                                                 $list[$extKey]=array('doubleInstall'=>$list[$extKey]['doubleInstall']);
02968                                                         }
02969                                                         $list[$extKey]['doubleInstall'].= $type;
02970                                                         $list[$extKey]['type'] = $type;
02971                                                         $list[$extKey]['EM_CONF'] = $emConf;
02972                                                         $list[$extKey]['files'] = t3lib_div::getFilesInDir($path.$extKey);
02973 
02974                                                         $this->setCat($cat,$list[$extKey], $extKey);
02975                                                 }
02976                                         }
02977                                 }
02978                         }
02979                 }
02980         }
02981 
02988         function fixEMCONF($emConf) {
02989                 if(!isset($emConf['constraints']) || !isset($emConf['constraints']['depends']) || !isset($emConf['constraints']['conflicts']) || !isset($emConf['constraints']['suggests'])) {
02990                         if(!isset($emConf['constraints']) || !isset($emConf['constraints']['depends'])) {
02991                                 $emConf['constraints']['depends'] = $this->stringToDep($emConf['dependencies']);
02992                                 if(strlen($emConf['PHP_version'])) {
02993                                         $versionRange = $this->splitVersionRange($emConf['PHP_version']);
02994                                         if(version_compare($versionRange[0],'3.0.0','<')) $versionRange[0] = '3.0.0';
02995                                         if(version_compare($versionRange[1],'3.0.0','<')) $versionRange[1] = '';
02996                                         $emConf['constraints']['depends']['php'] = implode('-',$versionRange);
02997                                 }
02998                                 if(strlen($emConf['TYPO3_version'])) {
02999                                         $versionRange = $this->splitVersionRange($emConf['TYPO3_version']);
03000                                         if(version_compare($versionRange[0],'3.5.0','<')) $versionRange[0] = '3.5.0';
03001                                         if(version_compare($versionRange[1],'3.5.0','<')) $versionRange[1] = '';
03002                                         $emConf['constraints']['depends']['typo3'] = implode('-',$versionRange);
03003                                 }
03004                         }
03005                         if(!isset($emConf['constraints']) || !isset($emConf['constraints']['conflicts'])) {
03006                                 $emConf['constraints']['conflicts'] = $this->stringToDep($emConf['conflicts']);
03007                         }
03008                         if(!isset($emConf['constraints']) || !isset($emConf['constraints']['suggests'])) {
03009                                 $emConf['constraints']['suggests'] = array();
03010                         }
03011                 } elseif (isset($emConf['constraints']) && isset($emConf['dependencies'])) {
03012                         $emConf['suggests'] = isset($emConf['suggests']) ? $emConf['suggests'] : array();
03013                         $emConf['dependencies'] = $this->depToString($emConf['constraints']);
03014                         $emConf['conflicts'] = $this->depToString($emConf['constraints'], 'conflicts');
03015                 }
03016 
03017                         // sanity check for version numbers, intentionally only checks php and typo3
03018                 if(isset($emConf['constraints']['depends']) && isset($emConf['constraints']['depends']['php'])) {
03019                         $versionRange = $this->splitVersionRange($emConf['constraints']['depends']['php']);
03020                         if(version_compare($versionRange[0],'3.0.0','<')) $versionRange[0] = '3.0.0';
03021                         if(version_compare($versionRange[1],'3.0.0','<')) $versionRange[1] = '';
03022                         $emConf['constraints']['depends']['php'] = implode('-',$versionRange);
03023                 }
03024                 if(isset($emConf['constraints']['depends']) && isset($emConf['constraints']['depends']['typo3'])) {
03025                         $versionRange = $this->splitVersionRange($emConf['constraints']['depends']['typo3']);
03026                         if(version_compare($versionRange[0],'3.5.0','<')) $versionRange[0] = '3.0.0';
03027                         if(version_compare($versionRange[1],'3.5.0','<')) $versionRange[1] = '';
03028                         $emConf['constraints']['depends']['typo3'] = implode('-',$versionRange);
03029                 }
03030 
03031                 unset($emConf['private']);
03032                 unset($emConf['download_password']);
03033                 unset($emConf['TYPO3_version']);
03034                 unset($emConf['PHP_version']);
03035 
03036                 return $emConf;
03037         }
03038 
03048         function splitVersionRange($ver) {
03049                 $versionRange = array();
03050                 if(strstr($ver, '-')) $versionRange = explode('-', $ver, 2);
03051                 else {
03052                         $versionRange[0] = $ver;
03053                         $versionRange[1] = '';
03054                 }
03055 
03056                 return $versionRange;
03057         }
03058 
03064         function prepareImportExtList() {
03065                 $list = array();
03066                 $cat = $this->defaultCategories;
03067                 $filepath = $this->getMirrorURL();
03068 
03069                 reset($this->xmlhandler->extensionsXML);
03070                 while (list($extKey, $data) = each($this->xmlhandler->extensionsXML)) {
03071                         $GLOBALS['LANG']->csConvObj->convArray($data,'utf-8',$GLOBALS['LANG']->charSet); // is there a better place for conversion?
03072                         $list[$extKey]['type'] = '_';
03073                         $version = array_keys($data['versions']);
03074                         $list[$extKey]['_ICON'] = '<img alt="" src="'.$filepath.$extKey{0}.'/'.$extKey{1}.'/'.$extKey.'_'.end($version).'.gif" />';
03075                         $list[$extKey]['downloadcounter'] = $data['downloadcounter'];
03076 
03077                         foreach(array_keys($data['versions']) as $version) {
03078                                 $list[$extKey]['versions'][$version]['downloadcounter'] = $data['versions'][$version]['downloadcounter'];
03079 
03080                                 $list[$extKey]['versions'][$version]['EM_CONF'] = array(
03081                                 'version' => $version,
03082                                 'title' => $data['versions'][$version]['title'],
03083                                 'description' => $data['versions'][$version]['description'],
03084                                 'category' => $data['versions'][$version]['category'],
03085                                 'constraints' => $data['versions'][$version]['dependencies'],
03086                                 'state' => $data['versions'][$version]['state'],
03087                                 'reviewstate' => $data['versions'][$version]['reviewstate'],
03088                                 'lastuploaddate' => $data['versions'][$version]['lastuploaddate'],
03089                                 'author' => $data['versions'][$version]['authorname'],
03090                                 'author_email' => $data['versions'][$version]['authoremail'],
03091                                 'author_company' => $data['versions'][$version]['authorcompany'],
03092                                 );
03093                         }
03094                         $this->setCat($cat, $list[$extKey]['versions'][$version], $extKey);
03095                 }
03096 
03097                 return array($list,$cat);
03098         }
03099 
03108         function setCat(&$cat,$listArrayPart,$extKey)   {
03109 
03110                 // Getting extension title:
03111                 $extTitle = $listArrayPart['EM_CONF']['title'];
03112 
03113                 // Category index:
03114                 $index = $listArrayPart['EM_CONF']['category'];
03115                 $cat['cat'][$index][$extKey] = $extTitle;
03116 
03117                 // Author index:
03118                 $index = $listArrayPart['EM_CONF']['author'].($listArrayPart['EM_CONF']['author_company']?', '.$listArrayPart['EM_CONF']['author_company']:'');
03119                 $cat['author_company'][$index][$extKey] = $extTitle;
03120 
03121                 // State index:
03122                 $index = $listArrayPart['EM_CONF']['state'];
03123                 $cat['state'][$index][$extKey] = $extTitle;
03124 
03125                 // Type index:
03126                 $index = $listArrayPart['type'];
03127                 $cat['type'][$index][$extKey] = $extTitle;
03128 
03129                 // Return categories:
03130                 return $cat;
03131         }
03132 
03133 
03134 
03135 
03136 
03137 
03138 
03139 
03140 
03141 
03142         /*******************************
03143         *
03144         * Extension analyzing (detailed information)
03145         *
03146         ******************************/
03147 
03158         function makeDetailedExtensionAnalysis($extKey,$extInfo,$validity=0)    {
03159 
03160                 // Get absolute path of the extension
03161                 $absPath = $this->getExtPath($extKey,$extInfo['type']);
03162 
03163                 $infoArray = array();
03164 
03165                 $table_class_prefix = substr($extKey,0,5)=='user_' ? 'user_' : 'tx_'.str_replace('_','',$extKey).'_';
03166                 $module_prefix = substr($extKey,0,5)=='user_' ? 'u' : 'tx'.str_replace('_','',$extKey);
03167 
03168                 // Database status:
03169                 $dbInfo = $this->checkDBupdates($extKey,$extInfo,1);
03170 
03171                 // Database structure required:
03172                 if (is_array($dbInfo['structure']['tables_fields']))    {
03173                         $modify_tables = t3lib_div::trimExplode(',',$extInfo['EM_CONF']['modify_tables'],1);
03174                         $infoArray['dump_tf'] = array();
03175 
03176                         foreach($dbInfo['structure']['tables_fields'] as $tN => $d)     {
03177                                 if (in_array($tN,$modify_tables))       {
03178                                         $infoArray['fields'][] = $tN.': <i>'.
03179                                         (is_array($d['fields']) ? implode(', ',array_keys($d['fields'])) : '').
03180                                         (is_array($d['keys']) ? ' + '.count($d['keys']).' keys' : '').
03181                                         '</i>';
03182                                         if (is_array($d['fields']))     {
03183                                                 reset($d['fields']);
03184                                                 while(list($fN) = each($d['fields']))   {
03185                                                         $infoArray['dump_tf'][] = $tN.'.'.$fN;
03186                                                         if (!t3lib_div::isFirstPartOfStr($fN,$table_class_prefix))      {
03187                                                                 $infoArray['NSerrors']['fields'][$fN] = $fN;
03188                                                         } else {
03189                                                                 $infoArray['NSok']['fields'][$fN] = $fN;
03190                                                         }
03191                                                 }
03192                                         }
03193                                         if (is_array($d['keys']))       {
03194                                                 reset($d['keys']);
03195                                                 while(list($fN)=each($d['keys']))       {
03196                                                         $infoArray['dump_tf'][] = $tN.'.KEY:'.$fN;
03197                                                 }
03198                                         }
03199                                 } else {
03200                                         $infoArray['dump_tf'][] = $tN;
03201                                         $infoArray['tables'][] = $tN;
03202                                         if (!t3lib_div::isFirstPartOfStr($tN,$table_class_prefix))      {
03203                                                 $infoArray['NSerrors']['tables'][$tN] = $tN;
03204                                         } else $infoArray['NSok']['tables'][$tN] = $tN;
03205                                 }
03206                         }
03207                         if (count($dbInfo['structure']['diff']['diff']) || count($dbInfo['structure']['diff']['extra']))        {
03208                                 $msg = array();
03209                                 if (count($dbInfo['structure']['diff']['diff']))        $msg[] = 'missing';
03210                                 if (count($dbInfo['structure']['diff']['extra']))       $msg[] = 'of wrong type';
03211                                 $infoArray['tables_error'] = 1;
03212                                 if (t3lib_extMgm::isLoaded($extKey))    $infoArray['errors'][] = 'Some tables or fields are '.implode(' and ',$msg).'!';
03213                         }
03214                 }
03215 
03216                 // Static tables?
03217                 if (is_array($dbInfo['static']))        {
03218                         $infoArray['static'] = array_keys($dbInfo['static']);
03219 
03220                         foreach($dbInfo['static'] as $tN => $d) {
03221                                 if (!$d['exists'])      {
03222                                         $infoArray['static_error'] = 1;
03223                                         if (t3lib_extMgm::isLoaded($extKey))    $infoArray['errors'][] = 'Static table(s) missing!';
03224                                         if (!t3lib_div::isFirstPartOfStr($tN,$table_class_prefix))      {
03225                                                 $infoArray['NSerrors']['tables'][$tN] = $tN;
03226                                         } else $infoArray['NSok']['tables'][$tN] = $tN;
03227                                 }
03228                         }
03229                 }
03230 
03231                 // Backend Module-check:
03232                 $knownModuleList = t3lib_div::trimExplode(',',$extInfo['EM_CONF']['module'],1);
03233                 foreach($knownModuleList as $mod)       {
03234                         if (@is_dir($absPath.$mod))     {
03235                                 if (@is_file($absPath.$mod.'/conf.php'))        {
03236                                         $confFileInfo = $this->modConfFileAnalysis($absPath.$mod.'/conf.php');
03237                                         if (is_array($confFileInfo['TYPO3_MOD_PATH']))  {
03238                                                 $shouldBePath = $this->typeRelPaths[$extInfo['type']].$extKey.'/'.$mod.'/';
03239                                                 if (strcmp($confFileInfo['TYPO3_MOD_PATH'][1][1],$shouldBePath))        {
03240                                                         $infoArray['errors'][] = 'Configured TYPO3_MOD_PATH "'.$confFileInfo['TYPO3_MOD_PATH'][1][1].'" different from "'.$shouldBePath.'"';
03241                                                 }
03242                                         } else $infoArray['errors'][] = 'No definition of TYPO3_MOD_PATH constant found inside!';
03243                                         if (is_array($confFileInfo['MCONF_name']))      {
03244                                                 $mName = $confFileInfo['MCONF_name'][1][1];
03245                                                 $mNameParts = explode('_',$mName);
03246                                                 $infoArray['moduleNames'][] = $mName;
03247                                                 if (!t3lib_div::isFirstPartOfStr($mNameParts[0],$module_prefix) &&
03248                                                 (!$mNameParts[1] || !t3lib_div::isFirstPartOfStr($mNameParts[1],$module_prefix)))       {
03249                                                         $infoArray['NSerrors']['modname'][] = $mName;
03250                                                 } else $infoArray['NSok']['modname'][] = $mName;
03251                                         } else $infoArray['errors'][] = 'No definition of MCONF[name] variable found inside!';
03252                                 } else  $infoArray['errors'][] = 'Backend module conf file "'.$mod.'/conf.php" should exist but does not!';
03253                         } else $infoArray['errors'][] = 'Backend module folder "'.$mod.'/" should exist but does not!';
03254                 }
03255                 $dirs = t3lib_div::get_dirs($absPath);
03256                 if (is_array($dirs))    {
03257                         reset($dirs);
03258                         while(list(,$mod) = each($dirs))        {
03259                                 if (!in_array($mod,$knownModuleList) && @is_file($absPath.$mod.'/conf.php'))    {
03260                                         $confFileInfo = $this->modConfFileAnalysis($absPath.$mod.'/conf.php');
03261                                         if (is_array($confFileInfo))    {
03262                                                 $infoArray['errors'][] = 'It seems like there is a backend module in "'.$mod.'/conf.php" which is not configured in ext_emconf.php';
03263                                         }
03264                                 }
03265                         }
03266                 }
03267 
03268                 // ext_tables.php:
03269                 if (@is_file($absPath.'ext_tables.php'))        {
03270                         $content = t3lib_div::getUrl($absPath.'ext_tables.php');
03271                         if (stristr($content,'t3lib_extMgm::addModule'))        $infoArray['flags'][] = 'Module';
03272                         if (stristr($content,'t3lib_extMgm::insertModuleFunction'))     $infoArray['flags'][] = 'Module+';
03273                         if (stristr($content,'t3lib_div::loadTCA'))     $infoArray['flags'][] = 'loadTCA';
03274                         if (stristr($content,'$TCA['))  $infoArray['flags'][] = 'TCA';
03275                         if (stristr($content,'t3lib_extMgm::addPlugin'))        $infoArray['flags'][] = 'Plugin';
03276                 }
03277 
03278                 // ext_localconf.php:
03279                 if (@is_file($absPath.'ext_localconf.php'))     {
03280                         $content = t3lib_div::getUrl($absPath.'ext_localconf.php');
03281                         if (stristr($content,'t3lib_extMgm::addPItoST43'))      $infoArray['flags'][]='Plugin/ST43';
03282                         if (stristr($content,'t3lib_extMgm::addPageTSConfig'))  $infoArray['flags'][]='Page-TSconfig';
03283                         if (stristr($content,'t3lib_extMgm::addUserTSConfig'))  $infoArray['flags'][]='User-TSconfig';
03284                         if (stristr($content,'t3lib_extMgm::addTypoScriptSetup'))       $infoArray['flags'][]='TS/Setup';
03285                         if (stristr($content,'t3lib_extMgm::addTypoScriptConstants'))   $infoArray['flags'][]='TS/Constants';
03286                 }
03287 
03288                 if (@is_file($absPath.'ext_typoscript_constants.txt'))  {
03289                         $infoArray['TSfiles'][] = 'Constants';
03290                 }
03291                 if (@is_file($absPath.'ext_typoscript_setup.txt'))      {
03292                         $infoArray['TSfiles'][] = 'Setup';
03293                 }
03294                 if (@is_file($absPath.'ext_conf_template.txt')) {
03295                         $infoArray['conf'] = 1;
03296                 }
03297 
03298                 // Classes:
03299                 if ($validity)  {
03300                         $filesInside = $this->getClassIndexLocallangFiles($absPath,$table_class_prefix,$extKey);
03301                         if (is_array($filesInside['errors']))   $infoArray['errors'] = array_merge((array)$infoArray['errors'],$filesInside['errors']);
03302                         if (is_array($filesInside['NSerrors'])) $infoArray['NSerrors'] = array_merge((array)$infoArray['NSerrors'],$filesInside['NSerrors']);
03303                         if (is_array($filesInside['NSok']))     $infoArray['NSok'] = array_merge((array)$infoArray['NSok'],$filesInside['NSok']);
03304                         $infoArray['locallang'] = $filesInside['locallang'];
03305                         $infoArray['classes'] = $filesInside['classes'];
03306                 }
03307 
03308                 // Upload folders
03309                 if ($extInfo['EM_CONF']['uploadfolder'])        {
03310                         $infoArray['uploadfolder'] = $this->ulFolder($extKey);
03311                         if (!@is_dir(PATH_site.$infoArray['uploadfolder']))     {
03312                                 $infoArray['errors'][] = 'Error: Upload folder "'.$infoArray['uploadfolder'].'" did not exist!';
03313                                 $infoArray['uploadfolder'] = '';
03314                         }
03315                 }
03316 
03317                 // Create directories:
03318                 if ($extInfo['EM_CONF']['createDirs'])  {
03319                         $infoArray['createDirs'] = array_unique(t3lib_div::trimExplode(',',$extInfo['EM_CONF']['createDirs'],1));
03320                         foreach($infoArray['createDirs'] as $crDir)     {
03321                                 if (!@is_dir(PATH_site.$crDir)) {
03322                                         $infoArray['errors'][]='Error: Upload folder "'.$crDir.'" did not exist!';
03323                                 }
03324                         }
03325                 }
03326 
03327                 // Return result array:
03328                 return $infoArray;
03329         }
03330 
03340         function getClassIndexLocallangFiles($absPath,$table_class_prefix,$extKey)      {
03341                 $filesInside = t3lib_div::removePrefixPathFromList(t3lib_div::getAllFilesAndFoldersInPath(array(),$absPath,'php,inc'),$absPath);
03342                 $out = array();
03343 
03344                 foreach($filesInside as $fileName)      {
03345                         if (substr($fileName,0,4)!='ext_' && substr($fileName,0,6)!='tests/')   {       // ignore supposed-to-be unit tests as well
03346                                 $baseName = basename($fileName);
03347                                 if (substr($baseName,0,9)=='locallang' && substr($baseName,-4)=='.php') {
03348                                         $out['locallang'][] = $fileName;
03349                                 } elseif ($baseName!='conf.php')        {
03350                                         if (filesize($absPath.$fileName)<500*1024)      {
03351                                                 $fContent = t3lib_div::getUrl($absPath.$fileName);
03352                                                 unset($reg);
03353                                                 if (preg_match('/\n[[:space:]]*class[[:space:]]*([[:alnum:]_]+)([[:alnum:][:space:]_]*)/',$fContent,$reg))      {
03354 
03355                                                         // Find classes:
03356                                                         $lines = explode(chr(10),$fContent);
03357                                                         foreach($lines as $l)   {
03358                                                                 $line = trim($l);
03359                                                                 unset($reg);
03360                                                                 if (preg_match('/^class[[:space:]]*([[:alnum:]_]+)([[:alnum:][:space:]_]*)/',$line,$reg))       {
03361                                                                         $out['classes'][] = $reg[1];
03362                                                                         $out['files'][$fileName]['classes'][] = $reg[1];
03363                                                                         if ($reg[1]!=='ext_update' && substr($reg[1],0,3)!='ux_' && !t3lib_div::isFirstPartOfStr($reg[1],$table_class_prefix) && strcmp(substr($table_class_prefix,0,-1),$reg[1]))      {
03364                                                                                 $out['NSerrors']['classname'][] = $reg[1];
03365                                                                         } else $out['NSok']['classname'][] = $reg[1];
03366                                                                 }
03367                                                         }
03368                                                         // If class file prefixed 'class.'....
03369                                                         if (substr($baseName,0,6)=='class.')    {
03370                                                                 $fI = pathinfo($baseName);
03371                                                                 $testName=substr($baseName,6,-(1+strlen($fI['extension'])));
03372                                                                 if ($testName!=='ext_update' && substr($testName,0,3)!='ux_' && !t3lib_div::isFirstPartOfStr($testName,$table_class_prefix) && strcmp(substr($table_class_prefix,0,-1),$testName))      {
03373                                                                         $out['NSerrors']['classfilename'][] = $baseName;
03374                                                                 } else {
03375                                                                         $out['NSok']['classfilename'][] = $baseName;
03376                                                                         if (is_array($out['files'][$fileName]['classes']) && $this->first_in_array($testName,$out['files'][$fileName]['classes'],1))    {
03377                                                                                 $out['msg'][] = 'Class filename "'.$fileName.'" did contain the class "'.$testName.'" just as it should.';
03378                                                                         } else $out['errors'][] = 'Class filename "'.$fileName.'" did NOT contain the class "'.$testName.'"!';
03379                                                                 }
03380                                                         }
03381                                                         //
03382                                                         $XclassParts = split('if \(defined\([\'"]TYPO3_MODE[\'"]\) && \$TYPO3_CONF_VARS\[TYPO3_MODE\]\[[\'"]XCLASS[\'"]\]',$fContent,2);
03383                                                         if (count($XclassParts)==2)     {
03384                                                                 unset($reg);
03385                                                                 preg_match('/^\[[\'"]([[:alnum:]_\/\.]*)[\'"]\]/',$XclassParts[1],$reg);
03386                                                                 if ($reg[1]) {
03387                                                                         $cmpF = 'ext/'.$extKey.'/'.$fileName;
03388                                                                         if (!strcmp($reg[1],$cmpF))     {
03389                                                                                 if (preg_match('/_once[[:space:]]*\(\$TYPO3_.ONF_VARS\[TYPO3_MODE\]\[[\'"]XCLASS[\'"]\]\[[\'"]'.preg_quote($cmpF,'/').'[\'"]\]\);/', $XclassParts[1]))  {
03390                                                                                         $out['msg'][] = 'XCLASS OK in '.$fileName;
03391                                                                                 } else $out['errors'][] = 'Couldn\'t find the include_once statement for XCLASS!';
03392                                                                         } else $out['errors'][] = 'The XCLASS filename-key "'.$reg[1].'" was different from "'.$cmpF.'" which it should have been!';
03393                                                                 } else $out['errors'][] = 'No XCLASS filename-key found in file "'.$fileName.'". Maybe a regex coding error here...';
03394                                                         } elseif (!$this->first_in_array('ux_',$out['files'][$fileName]['classes'])) $out['errors'][] = 'No XCLASS inclusion code found in file "'.$fileName.'"';
03395                                                 }
03396                                         }
03397                                 }
03398                         }
03399                 }
03400                 return $out;
03401         }
03402 
03410         function modConfFileAnalysis($confFilePath)     {
03411                 $lines = explode(chr(10),t3lib_div::getUrl($confFilePath));
03412                 $confFileInfo = array();
03413                 $confFileInfo['lines'] = $lines;
03414 
03415                 foreach($lines as $k => $l)     {
03416                         $line = trim($l);
03417 
03418                         unset($reg);
03419                         if (preg_match('/^define[[:space:]]*\([[:space:]]*["\']TYPO3_MOD_PATH["\'][[:space:]]*,[[:space:]]*["\']([[:alnum:]_\/\.]+)["\'][[:space:]]*\)[[:space:]]*;/',$line,$reg))      {
03420                                 $confFileInfo['TYPO3_MOD_PATH'] = array($k,$reg);
03421                         }
03422 
03423                         unset($reg);
03424                         if (preg_match('/^\$MCONF\[["\']?name["\']?\][[:space:]]*=[[:space:]]*["\']([[:alnum:]_]+)["\'];/',$line,$reg)) {
03425                                 $confFileInfo['MCONF_name'] = array($k,$reg);
03426                         }
03427                 }
03428                 return $confFileInfo;
03429         }
03430 
03438         function serverExtensionMD5Array($extKey,$conf) {
03439 
03440                 // Creates upload-array - including filelist.
03441                 $mUA = $this->makeUploadArray($extKey,$conf);
03442 
03443                 $md5Array = array();
03444                 if (is_array($mUA['FILES']))    {
03445 
03446                         // Traverse files.
03447                         foreach($mUA['FILES'] as $fN => $d)     {
03448                                 if ($fN!='ext_emconf.php')      {
03449                                         $md5Array[$fN] = substr($d['content_md5'],0,4);
03450                                 }
03451                         }
03452                 } else debug($mUA);
03453                 return $md5Array;
03454         }
03455 
03463         function findMD5ArrayDiff($current,$past)       {
03464                 if (!is_array($current))        $current = array();
03465                 if (!is_array($past))           $past = array();
03466                 $filesInCommon = array_intersect($current,$past);
03467                 $diff1 =  array_keys(array_diff($past,$filesInCommon));
03468                 $diff2 =  array_keys(array_diff($current,$filesInCommon));
03469                 $affectedFiles = array_unique(array_merge($diff1,$diff2));
03470                 return $affectedFiles;
03471         }
03472 
03473 
03474 
03475 
03476 
03477 
03478 
03479 
03480 
03481 
03482         /***********************************
03483         *
03484         * File system operations
03485         *
03486         **********************************/
03487 
03495         function createDirsInPath($dirs,$extDirPath)    {
03496                 if (is_array($dirs))    {
03497                         foreach($dirs as $dir)  {
03498                                 $error = t3lib_div::mkdir_deep($extDirPath,$dir);
03499                                 if ($error)     return $error;
03500                         }
03501                 }
03502 
03503                 return false;
03504         }
03505 
03513         function removeExtDirectory($removePath,$removeContentOnly=0)   {
03514                 $errors = array();
03515                 if (@is_dir($removePath) && substr($removePath,-1)=='/' && (
03516                 t3lib_div::isFirstPartOfStr($removePath,PATH_site.$this->typePaths['G']) ||
03517                 t3lib_div::isFirstPartOfStr($removePath,PATH_site.$this->typePaths['L']) ||
03518                 (t3lib_div::isFirstPartOfStr($removePath,PATH_site.$this->typePaths['S']) && $this->systemInstall) ||
03519                 t3lib_div::isFirstPartOfStr($removePath,PATH_site.'fileadmin/_temp_/'))         // Playing-around directory...
03520                 ) {
03521 
03522                         // All files in extension directory:
03523                         $fileArr = t3lib_div::getAllFilesAndFoldersInPath(array(),$removePath,'',1);
03524                         if (is_array($fileArr)) {
03525 
03526                                 // Remove files in dirs:
03527                                 foreach($fileArr as $removeFile)        {
03528                                         if (!@is_dir($removeFile))      {
03529                                                 if (@is_file($removeFile) && t3lib_div::isFirstPartOfStr($removeFile,$removePath) && strcmp($removeFile,$removePath))   {       // ... we are very paranoid, so we check what cannot go wrong: that the file is in fact within the prefix path!
03530                                                         @unlink($removeFile);
03531                                                         clearstatcache();
03532                                                         if (@is_file($removeFile))      {
03533                                                                 $errors[] = 'Error: "'.$removeFile.'" could not be deleted!';
03534                                                         }
03535                                                 } else $errors[] = 'Error: "'.$removeFile.'" was either not a file, or it was equal to the removed directory or simply outside the removed directory "'.$removePath.'"!';
03536                                         }
03537                                 }
03538 
03539                                 // Remove directories:
03540                                 $remDirs = $this->extractDirsFromFileList(t3lib_div::removePrefixPathFromList($fileArr,$removePath));
03541                                 $remDirs = array_reverse($remDirs);     // Must delete outer directories first...
03542                                 foreach($remDirs as $removeRelDir)      {
03543                                         $removeDir = $removePath.$removeRelDir;
03544                                         if (@is_dir($removeDir))        {
03545                                                 rmdir($removeDir);
03546                                                 clearstatcache();
03547                                                 if (@is_dir($removeDir))        {
03548                                                         $errors[] = 'Error: "'.$removeDir.'" could not be removed (are there files left?)';
03549                                                 }
03550                                         } else $errors[] = 'Error: "'.$removeDir.'" was not a directory!';
03551                                 }
03552 
03553                                 // If extension dir should also be removed:
03554                                 if (!$removeContentOnly)        {
03555                                         rmdir($removePath);
03556                                         clearstatcache();
03557                                         if (@is_dir($removePath))       {
03558                                                 $errors[] = 'Error: Extension directory "'.$removePath.'" could not be removed (are there files or folders left?)';
03559                                         }
03560                                 }
03561                         } else $errors[] = 'Error: '.$fileArr;
03562                 } else $errors[] = 'Error: Unallowed path to remove: '.$removePath;
03563 
03564                 // Return errors if any:
03565                 return implode(chr(10),$errors);
03566         }
03567 
03576         function clearAndMakeExtensionDir($importedData,$type,$dontDelete=0)    {
03577                 if (!$importedData['extKey'])   return 'FATAL ERROR: Extension key was not set for some VERY strange reason. Nothing done...';
03578 
03579                 // Setting install path (L, G, S or fileadmin/_temp_/)
03580                 $path = '';
03581                 switch((string)$type)   {
03582                         case 'G':
03583                         case 'L':
03584                                 $path = PATH_site.$this->typePaths[$type];
03585                                 $suffix = '';
03586 
03587                                 // Creates the typo3conf/ext/ directory if it does NOT already exist:
03588                                 if ((string)$type=='L' && !@is_dir($path))      {
03589                                         t3lib_div::mkdir($path);
03590                                 }
03591                                 break;
03592                         default:
03593                                 if ($this->systemInstall && (string)$type=='S') {
03594                                         $path = PATH_site.$this->typePaths[$type];
03595                                         $suffix = '';
03596                                 } else {
03597                                         $path = PATH_site.'fileadmin/_temp_/';
03598                                         $suffix = '_'.date('dmy-His');
03599                                 }
03600                                 break;
03601                 }
03602 
03603                 // If the install path is OK...
03604                 if ($path && @is_dir($path))    {
03605 
03606                         // Set extension directory:
03607                         $extDirPath = $path.$importedData['extKey'].$suffix.'/';
03608 
03609                         // Install dir was found, remove it then:
03610                         if (@is_dir($extDirPath))       {
03611                                 if($dontDelete) return array($extDirPath);
03612                                 $res = $this->removeExtDirectory($extDirPath);
03613                                 if ($res) {
03614                                         return 'ERROR: Could not remove extension directory "'.$extDirPath.'". Reasons:<br /><br />'.nl2br($res);
03615                                 }
03616                         }
03617 
03618                         // We go create...
03619                         t3lib_div::mkdir($extDirPath);
03620                         if (!is_dir($extDirPath))       return 'ERROR: Could not create extension directory "'.$extDirPath.'"';
03621                         return array($extDirPath);
03622                 } else return 'ERROR: The extension install path "'.$path.'" was not a directory.';
03623         }
03624 
03630         function removeCacheFiles()     {
03631                 return t3lib_extMgm::removeCacheFiles();
03632         }
03633 
03640         function extractDirsFromFileList($files)        {
03641                 $dirs = array();
03642 
03643                 if (is_array($files))   {
03644                         // Traverse files / directories array:
03645                         foreach($files as $file)        {
03646                                 if (substr($file,-1)=='/')      {
03647                                         $dirs[$file] = $file;
03648                                 } else {
03649                                         $pI = pathinfo($file);
03650                                         if (strcmp($pI['dirname'],'') && strcmp($pI['dirname'],'.'))    {
03651                                                 $dirs[$pI['dirname'].'/'] = $pI['dirname'].'/';
03652                                         }
03653                                 }
03654                         }
03655                 }
03656                 return $dirs;
03657         }
03658 
03666         function getExtPath($extKey,$type)      {
03667                 $typeP = $this->typePaths[$type];
03668                 if ($typeP)     {
03669                         $path = PATH_site.$typeP.$extKey.'/';
03670                         return @is_dir($path) ? $path : '';
03671                 } else {
03672                         return '';
03673                 }
03674         }
03675 
03676 
03677 
03678 
03679 
03680 
03681 
03682 
03683 
03684 
03685         /*******************************
03686         *
03687         * Writing to "conf.php" and "localconf.php" files
03688         *
03689         ******************************/
03690 
03700         function writeTYPO3_MOD_PATH($confFilePath,$type,$mP)   {
03701                 $lines = explode(chr(10),t3lib_div::getUrl($confFilePath));
03702                 $confFileInfo = array();
03703                 $confFileInfo['lines'] = $lines;
03704 
03705                 $flag_M = 0;
03706                 $flag_B = 0;
03707 
03708                 foreach($lines as $k => $l)     {
03709                         $line = trim($l);
03710 
03711                         unset($reg);
03712                         if (preg_match('/^define[[:space:]]*\([[:space:]]*["\']TYPO3_MOD_PATH["\'][[:space:]]*,[[:space:]]*["\']([[:alnum:]_\/\.]+)["\'][[:space:]]*\)[[:space:]]*;/',$line,$reg))      {
03713                                 $lines[$k] = str_replace($reg[0], 'define(\'TYPO3_MOD_PATH\', \''.$this->typeRelPaths[$type].$mP.'\');', $lines[$k]);
03714                                 $flag_M = $k+1;
03715                         }
03716 
03717                         unset($reg);
03718                         if (preg_match('/^\$BACK_PATH[[:space:]]*=[[:space:]]*["\']([[:alnum:]_\/\.]+)["\'][[:space:]]*;/',$line,$reg)) {
03719                                 $lines[$k] = str_replace($reg[0], '$BACK_PATH=\''.$this->typeBackPaths[$type].'\';', $lines[$k]);
03720                                 $flag_B = $k+1;
03721                         }
03722                 }
03723 
03724                 if ($flag_B && $flag_M) {
03725                         t3lib_div::writeFile($confFilePath,implode(chr(10),$lines));
03726                         return 'TYPO3_MOD_PATH and $BACK_PATH was updated in "'.substr($confFilePath,strlen(PATH_site)).'"';
03727                 } else return 'Error: Either TYPO3_MOD_PATH or $BACK_PATH was not found in the "'.$confFilePath.'" file. You must manually configure that!';
03728         }
03729 
03737         function writeNewExtensionList($newExtList)     {
03738                 global $TYPO3_CONF_VARS;
03739 
03740                 // Instance of install tool
03741                 $instObj = new t3lib_install;
03742                 $instObj->allowUpdateLocalConf =1;
03743                 $instObj->updateIdentity = 'TYPO3 Extension Manager';
03744 
03745                 // Get lines from localconf file
03746                 $lines = $instObj->writeToLocalconf_control();
03747                 $instObj->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'EXT\'][\'extList\']', $newExtList);
03748                 $instObj->writeToLocalconf_control($lines);
03749 
03750                 $TYPO3_CONF_VARS['EXT']['extList'] = $newExtList;
03751                 $this->removeCacheFiles();
03752         }
03753 
03762         function writeTsStyleConfig($extKey,$arr)       {
03763 
03764                 // Instance of install tool
03765                 $instObj = new t3lib_install;
03766                 $instObj->allowUpdateLocalConf =1;
03767                 $instObj->updateIdentity = 'TYPO3 Extension Manager';
03768 
03769                 // Get lines from localconf file
03770                 $lines = $instObj->writeToLocalconf_control();
03771                 $instObj->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'EXT\'][\'extConf\'][\''.$extKey.'\']', serialize($arr));  // This will be saved only if there are no linebreaks in it !
03772                 $instObj->writeToLocalconf_control($lines);
03773 
03774                 $this->removeCacheFiles();
03775         }
03776 
03784         function updateLocalEM_CONF($extKey,$extInfo)   {
03785                 $extInfo['EM_CONF']['_md5_values_when_last_written'] = serialize($this->serverExtensionMD5Array($extKey,$extInfo));
03786                 $emConfFileContent = $this->construct_ext_emconf_file($extKey,$extInfo['EM_CONF']);
03787 
03788                 if($emConfFileContent)  {
03789                         $absPath = $this->getExtPath($extKey,$extInfo['type']);
03790                         $emConfFileName = $absPath.'ext_emconf.php';
03791 
03792                         if(@is_file($emConfFileName))   {
03793                                 if(t3lib_div::writeFile($emConfFileName,$emConfFileContent) === true) {
03794                                         return '"'.substr($emConfFileName,strlen($absPath)).'" was updated with a cleaned up EM_CONF array.';
03795                                 } else {
03796                                         return '<strong>Error: "'.$emConfFileName.'" was not writable!</strong>';
03797                                 }
03798                         } else return('<strong>Error: No file "'.$emConfFileName.'" found. DON\'T PANIC!</strong>');
03799                 } else {
03800                         return 'No content to write to "'.substr($emConfFileName,strlen($absPath)).'"!';
03801                 }
03802         }
03803 
03804 
03805 
03806 
03807 
03808 
03809 
03810 
03811 
03812 
03813         /*******************************************
03814         *
03815         * Compiling upload information, emconf-file etc.
03816         *
03817         *******************************************/
03818 
03826         function construct_ext_emconf_file($extKey,$EM_CONF)    {
03827 
03828                         // clean version number:
03829                 $vDat = $this->renderVersion($EM_CONF['version']);
03830                 $EM_CONF['version']=$vDat['version'];
03831 
03832                 return '<?php
03833 
03834 ########################################################################
03835 # Extension Manager/Repository config file for ext: "'.$extKey.'"
03836 #
03837 # Auto generated '.date('d-m-Y H:i').'
03838 #
03839 # Manual updates:
03840 # Only the data in the array - anything else is removed by next write.
03841 # "version" and "dependencies" must not be touched!
03842 ########################################################################
03843 
03844 $EM_CONF[$_EXTKEY] = '.$this->arrayToCode($EM_CONF, 0).';
03845 
03846 ?>';
03847         }
03848 
03857         function arrayToCode($array, $level=0) {
03858                 $lines = 'array('.chr(10);
03859                 $level++;
03860                 foreach($array as $k => $v)     {
03861                         if(strlen($k) && is_array($v)) {
03862                                 $lines .= str_repeat(chr(9),$level)."'".$k."' => ".$this->arrayToCode($v, $level);
03863                         } elseif(strlen($k)) {
03864                                 $lines .= str_repeat(chr(9),$level)."'".$k."' => ".(t3lib_div::testInt($v) ? intval($v) : "'".t3lib_div::slashJS(trim($v),1)."'").','.chr(10);
03865                         }
03866                 }
03867 
03868                 $lines .= str_repeat(chr(9),$level-1).')'.($level-1==0 ? '':','.chr(10));
03869                 return $lines;
03870         }
03871 
03879         function makeUploadArray($extKey,$conf) {
03880                 $extPath = $this->getExtPath($extKey,$conf['type']);
03881 
03882                 if ($extPath)   {
03883 
03884                         // Get files for extension:
03885                         $fileArr = array();
03886                         $fileArr = t3lib_div::getAllFilesAndFoldersInPath($fileArr,$extPath);
03887 
03888                         // Calculate the total size of those files:
03889                         $totalSize = 0;
03890                         foreach($fileArr as $file)      {
03891                                 $totalSize+=filesize($file);
03892                         }
03893 
03894                         // If the total size is less than the upper limit, proceed:
03895                         if ($totalSize < $this->maxUploadSize)  {
03896 
03897                                 // Initialize output array:
03898                                 $uploadArray = array();
03899                                 $uploadArray['extKey'] = $extKey;
03900                                 $uploadArray['EM_CONF'] = $conf['EM_CONF'];
03901                                 $uploadArray['misc']['codelines'] = 0;
03902                                 $uploadArray['misc']['codebytes'] = 0;
03903 
03904                                 $uploadArray['techInfo'] = $this->makeDetailedExtensionAnalysis($extKey,$conf,1);
03905 
03906                                 // Read all files:
03907                                 foreach($fileArr as $file)      {
03908                                         $relFileName = substr($file,strlen($extPath));
03909                                         $fI = pathinfo($relFileName);
03910                                         if ($relFileName!='ext_emconf.php')     {               // This file should be dynamically written...
03911                                                 $uploadArray['FILES'][$relFileName] = array(
03912                                                 'name' => $relFileName,
03913                                                 'size' => filesize($file),
03914                                                 'mtime' => filemtime($file),
03915                                                 'is_executable' => (TYPO3_OS=='WIN' ? 0 : is_executable($file)),
03916                                                 'content' => t3lib_div::getUrl($file)
03917                                                 );
03918                                                 if (t3lib_div::inList('php,inc',strtolower($fI['extension'])))  {
03919                                                         $uploadArray['FILES'][$relFileName]['codelines']=count(explode(chr(10),$uploadArray['FILES'][$relFileName]['content']));
03920                                                         $uploadArray['misc']['codelines']+=$uploadArray['FILES'][$relFileName]['codelines'];
03921                                                         $uploadArray['misc']['codebytes']+=$uploadArray['FILES'][$relFileName]['size'];
03922 
03923                                                         // locallang*.php files:
03924                                                         if (substr($fI['basename'],0,9)=='locallang' && strstr($uploadArray['FILES'][$relFileName]['content'],'$LOCAL_LANG'))   {
03925                                                                 $uploadArray['FILES'][$relFileName]['LOCAL_LANG']=$this->getSerializedLocalLang($file,$uploadArray['FILES'][$relFileName]['content']);
03926                                                         }
03927                                                 }
03928                                                 $uploadArray['FILES'][$relFileName]['content_md5'] = md5($uploadArray['FILES'][$relFileName]['content']);
03929                                         }
03930                                 }
03931 
03932                                 // Return upload-array:
03933                                 return $uploadArray;
03934                         } else return 'Error: Total size of uncompressed upload ('.$totalSize.') exceeds '.t3lib_div::formatSize($this->maxUploadSize);
03935                 } else {
03936                         return 'Error: Extension path for extension "'.$extKey.'" not found';
03937                 }
03938         }
03939 
03948         function getSerializedLocalLang($file,$content) {
03949                 $returnParts = explode('$LOCAL_LANG',$content,2);
03950 
03951                 include($file);
03952                 if (is_array($LOCAL_LANG))      {
03953                         $returnParts[1] = serialize($LOCAL_LANG);
03954                         return $returnParts;
03955                 } else {
03956                         return array();
03957                 }
03958         }
03959 
03960 
03961 
03962 
03963 
03964 
03965 
03966 
03967 
03968 
03969         /********************************
03970         *
03971         * Managing dependencies, conflicts, priorities, load order of extension keys
03972         *
03973         *******************************/
03974 
03984         function addExtToList($extKey,$instExtInfo)     {
03985                 global $TYPO3_LOADED_EXT;
03986 
03987                         // ext_emconf.php information:
03988                 $conf = $instExtInfo[$extKey]['EM_CONF'];
03989 
03990                         // Get list of installed extensions and add this one.
03991                 $listArr = array_keys($TYPO3_LOADED_EXT);
03992                 if ($conf['priority']=='top')   {
03993                         array_unshift($listArr,$extKey);
03994                 } else {
03995                         $listArr[]=$extKey;
03996                 }
03997 
03998                         // Manage other circumstances:
03999                 $listArr = $this->managesPriorities($listArr,$instExtInfo);
04000                 $listArr = $this->removeRequiredExtFromListArr($listArr);
04001 
04002                         // Implode unique list of extensions to load and return:
04003                 $list = implode(',',array_unique($listArr));
04004                 return $list;
04005         }
04006 
04015         function checkDependencies($extKey, $conf, $instExtInfo) {
04016                 $content = '';
04017                 $depError = false;
04018                 $msg = array();
04019                 $depsolver = t3lib_div::_POST('depsolver');
04020 
04021                 foreach($conf['constraints']['depends'] as $depK => $depV)      {
04022                         if($depsolver['ignore'][$depK]) {
04023                                 $msg[] = '<br />Dependency on '.$depK.' ignored as requested.
04024                                 <input type="hidden" value="1" name="depsolver[ignore]['.$depK.']" />';
04025                                 continue;
04026                         }
04027                         if($depK == 'php') {
04028                                 if(!$depV) continue;
04029                                 $versionRange = $this->splitVersionRange($depV);
04030                                 $phpv = strstr(PHP_VERSION,'-') ? substr(PHP_VERSION,0,strpos(PHP_VERSION,'-')) : PHP_VERSION; // Linux distributors like to add suffixes, like in 5.1.2-1. Those must be ignored!
04031                                 if($versionRange[0] && version_compare($phpv,$versionRange[0],'<')) {
04032                                         $msg[] = '<br />The running PHP version ('.$phpv.') is lower than required ('.$versionRange[0].')';
04033                                         $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore]['.$depK.']" /> Ignore this version requirement';
04034                                         $depError = true;
04035                                         continue;
04036                                 } elseif($versionRange[1] && version_compare($phpv,$versionRange[1],'>')) {
04037                                         $msg[] = '<br />The running PHP version ('.$phpv.') is higher than allowed ('.$versionRange[1].')';
04038                                         $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore]['.$depK.']" /> Ignore this version requirement';
04039                                         $depError = true;
04040                                         continue;
04041                                 }
04042                         } elseif($depK == 'typo3') {
04043                                 if(!$depV) continue;
04044                                 $versionRange = $this->splitVersionRange($depV);
04045                                 if($versionRange[0] && version_compare(TYPO3_version,$versionRange[0],'<')) {
04046                                         $msg[] = '<br />The running TYPO3 version ('.TYPO3_version.') is lower than required ('.$versionRange[0].')';
04047                                         $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore]['.$depK.']" /> Ignore this version requirement';
04048                                         $depError = true;
04049                                         continue;
04050                                 } elseif($versionRange[1] && version_compare(TYPO3_version,$versionRange[1],'>')) {
04051                                         $msg[] = '<br />The running TYPO3 version ('.TYPO3_version.') is higher than allowed ('.$versionRange[1].')';
04052                                         $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore]['.$depK.']" /> Ignore this version requirement';
04053                                         $depError = true;
04054                                         continue;
04055                                 }
04056                         } elseif (strlen($depK) && !t3lib_extMgm::isLoaded($depK))      { // strlen check for braindead empty dependencies coming from extensions...
04057                                 if(!isset($instExtInfo[$depK])) {
04058                                         $msg[] = '<br />Extension "'.$depK.'" was not available in the system. Please import it from the TYPO3 Extension Repository.';
04059                                         $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<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="" />&nbsp;<a href="index.php?CMD[importExt]='.$depK.'&CMD[loc]=L&CMD[standAlone]=1" target="_blank">Import now (opens a new window)</a>';
04060                                         $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore]['.$depK.']" /> Ignore this extension requirement';
04061                                 } else {
04062                                         $msg[] = '<br />Extension "'.$depK.'" ('.$instExtInfo[$depK]['EM_CONF']['title'].') was not installed. Please install it first.';
04063                                         $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;'.$this->installButton().'&nbsp;<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$depK.'&CMD[load]=1&CMD[clrCmd]=1&CMD[standAlone]=1&SET[singleDetails]=info').'" target="_blank">Install now (opens a new window)</a>';
04064                                         $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore]['.$depK.']" /> Ignore this extension requirement';
04065                                 }
04066                                 $depError = true;
04067                         } else {
04068                                 $versionRange = $this->splitVersionRange($depV);
04069                                 if($versionRange[0] && version_compare($instExtInfo[$depK]['EM_CONF']['version'],$versionRange[0],'<')) {
04070                                         $msg[] = '<br />The running version of extension "'.$depK.'" ('.$instExtInfo[$depK]['EM_CONF']['version'].') is lower than required ('.$versionRange[0].')';
04071                                         $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore]['.$depK.']" /> Ignore this version requirement';
04072                                         $depError = true;
04073                                         continue;
04074                                 } elseif($versionRange[1] && version_compare($instExtInfo[$depK]['EM_CONF']['version'],$versionRange[1],'>')) {
04075                                         $msg[] = '<br />The running version of extension "'.$depK.'" ('.$instExtInfo[$depK]['EM_CONF']['version'].') is higher than allowed ('.$versionRange[1].')';
04076                                         $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore]['.$depK.']" /> Ignore this version requirement';
04077                                         $depError = true;
04078                                         continue;
04079                                 }
04080                         }
04081                 }
04082                 if($depError) {
04083                         $content .= $this->doc->section('Dependency Error',implode('<br />',$msg),0,1,2);
04084                 }
04085 
04086                         // Check conflicts with other extensions:
04087                 $conflictError = false;
04088                 $msg = array();
04089                 foreach((array)$conf['constraints']['conflicts'] as $conflictK => $conflictV)   {
04090                         if($depsolver['ignore'][$conflictK]) {
04091                                 $msg[] = '<br />Conflict with '.$conflictK.' ignored as requested.
04092                                 <input type="hidden" value="1" name="depsolver[ignore]['.$conflictK.']" />';
04093                                 continue;
04094                         }
04095                         if (t3lib_extMgm::isLoaded($conflictK)) {
04096                                 $msg[] = 'The extensions "'.$extKey.'" and "'.$conflictK.'" ('.$instExtInfo[$conflictK]['EM_CONF']['title'].') will conflict with each other. Please remove "'.$conflictK.'" if you want to install "'.$extKey.'".';
04097                                 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;'.$this->removeButton().'&nbsp;<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$conflictK.'&CMD[remove]=1&CMD[clrCmd]=1&CMD[standAlone]=1&SET[singleDetails]=info').'" target="_blank">Remove now (opens a new window)</a>';
04098                                 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore]['.$conflictK.']" /> Ignore this conflict error';
04099                                 $conflictError = true;
04100                         }
04101                 }
04102                 if($conflictError) {
04103                         $content .= $this->doc->section('Conflict Error',implode('<br />',$msg),0,1,2);
04104                 }
04105 
04106                         // Check suggests on other extensions:
04107                 if(is_array($conf['constraints']['suggests'])) {
04108                         $suggestion = false;
04109                         $msg = array();
04110                         foreach($conf['constraints']['suggests'] as $suggestK => $suggestV)     {
04111                                 if($depsolver['ignore'][$suggestK]) {
04112                                         $msg[] = '<br />Suggestion of '.$suggestK.' acknowledged.
04113                                 <input type="hidden" value="1" name="depsolver[ignore]['.$suggestK.']" />';
04114                                         continue;
04115                                 }
04116                                 if (!t3lib_extMgm::isLoaded($suggestK)) {
04117                                         if (!isset($instExtInfo[$suggestK]))    {
04118                                                 $msg[] = 'Extension "'.$suggestK.'" was not available in the system. You may want to import it from the TYPO3 Extension Repository.';
04119                                                 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<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="" />&nbsp;<a href="index.php?CMD[importExt]='.$depK.'&CMD[loc]=L&CMD[standAlone]=1" target="_blank">Import now (opens a new window)</a>';
04120                                                 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore]['.$suggestK.']" /> Ignore this suggestion';
04121                                         } else {
04122                                                 $msg[] = 'Extension "'.$suggestK.'" ('.$instExtInfo[$suggestK]['EM_CONF']['title'].') was not installed. You may want to install it.';
04123                                                 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;'.$this->installButton().'&nbsp;<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$suggestK.'&CMD[load]=1&CMD[clrCmd]=1&CMD[standAlone]=1&SET[singleDetails]=info').'" target="_blank">Install now (opens a new window)</a>';
04124                                                 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore]['.$suggestK.']" /> Ignore this suggestion';
04125                                         }
04126                                         $suggestion = true;
04127                                 }
04128                         }
04129                         if($suggestion) {
04130                                 $content .= $this->doc->section('Extensions suggested by extension "'.$extKey.'"',implode('<br />',$msg),0,1,1);
04131                         }
04132                 }
04133 
04134                 if($depError || $conflictError || $suggestion) {
04135                         foreach($this->CMD as $k => $v) {
04136                                 $content .= '<input type="hidden" name="CMD['.$k.']" value="'.$v.'" />';
04137                         }
04138                         $content .= '<br /><br /><input type="submit" value="Try again" />';
04139 
04140                         return array('returnCode' => false, 'html' => $content);
04141                 }
04142 
04143                 return array('returnCode' => true);
04144         }
04145 
04155         function removeExtFromList($extKey,$instExtInfo)        {
04156                 global $TYPO3_LOADED_EXT;
04157 
04158                         // Initialize:
04159                 $depList = array();
04160                 $listArr = array_keys($TYPO3_LOADED_EXT);
04161 
04162                         // Traverse all installed extensions to check if any of them have this extension as dependency since if that is the case it will not work out!
04163                 foreach($listArr as $k => $ext) {
04164                         if ($instExtInfo[$ext]['EM_CONF']['dependencies'])      {
04165                                 $dep = t3lib_div::trimExplode(',',$instExtInfo[$ext]['EM_CONF']['dependencies'],1);
04166                                 if (in_array($extKey,$dep))     {
04167                                         $depList[] = $ext;
04168                                 }
04169                         }
04170                         if (!strcmp($ext,$extKey))      unset($listArr[$k]);
04171                 }
04172 
04173                         // Returns either error or the new list
04174                 if (count($depList))    {
04175                         $msg = 'The extension(s) "'.implode(', ',$depList).'" depends on the extension you are trying to remove. The operation was not completed.';
04176                         $this->content.=$this->doc->section('Dependency Error',$msg,0,1,2);
04177                         return -1;
04178                 } else {
04179                         $listArr = $this->removeRequiredExtFromListArr($listArr);
04180                         $list = implode(',',array_unique($listArr));
04181                         return $list;
04182                 }
04183         }
04184 
04192         function removeRequiredExtFromListArr($listArr) {
04193                 foreach($listArr as $k => $ext) {
04194                         if (in_array($ext,$this->requiredExt) || !strcmp($ext,'_CACHEFILE'))    unset($listArr[$k]);
04195                 }
04196                 return $listArr;
04197         }
04198 
04207         function managesPriorities($listArr,$instExtInfo)       {
04208 
04209                         // Initialize:
04210                 $levels = array(
04211                         'top' => array(),
04212                         'middle' => array(),
04213                         'bottom' => array(),
04214                 );
04215 
04216                         // Traverse list of extensions:
04217                 foreach($listArr as $ext)       {
04218                         $prio = trim($instExtInfo[$ext]['EM_CONF']['priority']);
04219                         switch((string)$prio)   {
04220                                 case 'top':
04221                                 case 'bottom':
04222                                         $levels[$prio][] = $ext;
04223                                         break;
04224                                 default:
04225                                         $levels['middle'][] = $ext;
04226                                         break;
04227                         }
04228                 }
04229                 return array_merge(
04230                         $levels['top'],
04231                         $levels['middle'],
04232                         $levels['bottom']
04233                 );
04234         }
04235 
04236 
04237 
04238 
04239 
04240 
04241 
04242 
04243 
04244 
04245         /*******************************
04246         *
04247         * System Update functions (based on extension requirements)
04248         *
04249         ******************************/
04250 
04259         function checkClearCache($extInfo)      {
04260                 if ($extInfo['EM_CONF']['clearCacheOnLoad'])    {
04261                         if (t3lib_div::_POST('_clear_all_cache'))       {               // Action: Clearing the cache
04262                                 $tce = t3lib_div::makeInstance('t3lib_TCEmain');
04263                                 $tce->stripslashes_values = 0;
04264                                 $tce->start(Array(),Array());
04265                                 $tce->clear_cacheCmd('all');
04266                         } else {        // Show checkbox for clearing cache:
04267                                 $content.= '
04268                                         <br />
04269                                         <h3>Clear cache</h3>
04270                                         <p>This extension requests the cache to be cleared when it is installed/removed.<br />
04271                                                 Clear all cache: <input type="checkbox" name="_clear_all_cache" checked="checked" value="1" /><br />
04272                                                 </p>
04273                                 ';
04274                         }
04275                 }
04276                 return $content;
04277         }
04278 
04286         function checkUploadFolder($extKey,$extInfo)    {
04287 
04288                         // Checking for upload folder:
04289                 $uploadFolder = PATH_site.$this->ulFolder($extKey);
04290                 if ($extInfo['EM_CONF']['uploadfolder'] && !@is_dir($uploadFolder))     {
04291                         if (t3lib_div::_POST('_uploadfolder'))  {       // CREATE dir:
04292                                 t3lib_div::mkdir($uploadFolder);
04293                                 $indexContent = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
04294 <HTML>
04295 <HEAD>
04296         <TITLE></TITLE>
04297 <META http-equiv=Refresh Content="0; Url=../../">
04298 </HEAD>
04299 </HTML>';
04300                                 t3lib_div::writeFile($uploadFolder.'index.html',$indexContent);
04301                         } else {        // Show checkbox / HTML for creation:
04302                                 $content.='
04303                                         <br /><h3>Create upload folder</h3>
04304                                         <p>The extension requires the upload folder "'.$this->ulFolder($extKey).'" to exist.<br />
04305                                 Create directory "'.$this->ulFolder($extKey).'": <input type="checkbox" name="_uploadfolder" checked="checked" value="1" /><br />
04306                                 </p>
04307                                 ';
04308                         }
04309                 }
04310 
04311                         // Additional directories that should be created:
04312                 if ($extInfo['EM_CONF']['createDirs'])  {
04313                         $createDirs = array_unique(t3lib_div::trimExplode(',',$extInfo['EM_CONF']['createDirs'],1));
04314 
04315                         foreach($createDirs as $crDir)  {
04316                                 if (!@is_dir(PATH_site.$crDir)) {
04317                                         if (t3lib_div::_POST('_createDir_'.md5($crDir)))        {       // CREATE dir:
04318 
04319                                                         // Initialize:
04320                                                 $crDirStart = '';
04321                                                 $dirs_in_path = explode('/',preg_replace('/\/$/','',$crDir));
04322 
04323                                                         // Traverse each part of the dir path and create it one-by-one:
04324                                                 foreach($dirs_in_path as $dirP) {
04325                                                         if (strcmp($dirP,''))   {
04326                                                                 $crDirStart.= $dirP.'/';
04327                                                                 if (!@is_dir(PATH_site.$crDirStart))    {
04328                                                                         t3lib_div::mkdir(PATH_site.$crDirStart);
04329                                                                         $finalDir = PATH_site.$crDirStart;
04330                                                                 }
04331                                                         } else {
04332                                                                 die('ERROR: The path "'.PATH_site.$crDir.'" could not be created.');
04333                                                         }
04334                                                 }
04335                                                 if ($finalDir)  {
04336                                                         $indexContent = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
04337 <HTML>
04338 <HEAD>
04339         <TITLE></TITLE>
04340 <META http-equiv=Refresh Content="0; Url=/">
04341 </HEAD>
04342 </HTML>';
04343                                                         t3lib_div::writeFile($finalDir.'index.html',$indexContent);
04344                                                 }
04345                                         } else {        // Show checkbox / HTML for creation:
04346                                                 $content.='
04347                                                         <br />
04348                                                         <h3>Create folder</h3>
04349                                                         <p>The extension requires the folder "'.$crDir.'" to exist.<br />
04350                                                 Create directory "'.$crDir.'": <input type="checkbox" name="_createDir_'.md5($crDir).'" checked="checked" value="1" /><br />
04351                                                 </p>
04352                                                 ';
04353                                         }
04354                                 }
04355                         }
04356                 }
04357 
04358                 return $content;
04359         }
04360 
04371         function checkDBupdates($extKey,$extInfo,$infoOnly=0)   {
04372 
04373                         // Initializing Install Tool object:
04374                 $instObj = new t3lib_install;
04375                 $instObj->INSTALL = t3lib_div::_GP('TYPO3_INSTALL');
04376                 $dbStatus = array();
04377 
04378                         // Updating tables and fields?
04379                 if (is_array($extInfo['files']) && in_array('ext_tables.sql',$extInfo['files']))        {
04380                         $fileContent = t3lib_div::getUrl($this->getExtPath($extKey,$extInfo['type']).'ext_tables.sql');
04381 
04382                         $FDfile = $instObj->getFieldDefinitions_sqlContent($fileContent);
04383                         if (count($FDfile))     {
04384                                 $FDdb = $instObj->getFieldDefinitions_database(TYPO3_db);
04385                                 $diff = $instObj->getDatabaseExtra($FDfile, $FDdb);
04386                                 $update_statements = $instObj->getUpdateSuggestions($diff);
04387 
04388                                 $dbStatus['structure']['tables_fields'] = $FDfile;
04389                                 $dbStatus['structure']['diff'] = $diff;
04390 
04391                                         // Updating database...
04392                                 if (!$infoOnly && is_array($instObj->INSTALL['database_update']))       {
04393                                         $instObj->performUpdateQueries($update_statements['add'],$instObj->INSTALL['database_update']);
04394                                         $instObj->performUpdateQueries($update_statements['change'],$instObj->INSTALL['database_update']);
04395                                         $instObj->performUpdateQueries($update_statements['create_table'],$instObj->INSTALL['database_update']);
04396                                 } else {
04397                                         $content.=$instObj->generateUpdateDatabaseForm_checkboxes($update_statements['add'],'Add fields');
04398                                         $content.=$instObj->generateUpdateDatabaseForm_checkboxes($update_statements['change'],'Changing fields',1,0,$update_statements['change_currentValue']);
04399                                         $content.=$instObj->generateUpdateDatabaseForm_checkboxes($update_statements['create_table'],'Add tables');
04400                                 }
04401                         }
04402                 }
04403 
04404                         // Importing static tables?
04405                 if (is_array($extInfo['files']) && in_array('ext_tables_static+adt.sql',$extInfo['files']))     {
04406                         $fileContent = t3lib_div::getUrl($this->getExtPath($extKey,$extInfo['type']).'ext_tables_static+adt.sql');
04407 
04408                         $statements = $instObj->getStatementArray($fileContent,1);
04409                         list($statements_table, $insertCount) = $instObj->getCreateTables($statements,1);
04410 
04411                                 // Execute import of static table content:
04412                         if (!$infoOnly && is_array($instObj->INSTALL['database_import']))       {
04413 
04414                                         // Traverse the tables
04415                                 foreach($instObj->INSTALL['database_import'] as $table => $md5str)      {
04416                                         if ($md5str == md5($statements_table[$table]))  {
04417                                                 $GLOBALS['TYPO3_DB']->admin_query('DROP TABLE IF EXISTS '.$table);
04418                                                 $GLOBALS['TYPO3_DB']->admin_query($statements_table[$table]);
04419 
04420                                                 if ($insertCount[$table])       {
04421                                                         $statements_insert = $instObj->getTableInsertStatements($statements, $table);
04422 
04423                                                         foreach($statements_insert as $v)       {
04424                                                                 $GLOBALS['TYPO3_DB']->admin_query($v);
04425                                                         }
04426                                                 }
04427                                         }
04428                                 }
04429                         } else {
04430                                 $whichTables = $instObj->getListOfTables();
04431                                 if (count($statements_table))   {
04432                                         $out = '';
04433                                         foreach($statements_table as $table => $definition)     {
04434                                                 $exist = isset($whichTables[$table]);
04435 
04436                                                 $dbStatus['static'][$table]['exists'] = $exist;
04437                                                 $dbStatus['static'][$table]['count'] = $insertCount[$table];
04438 
04439                                                 $out.= '<tr>
04440                                                         <td><input type="checkbox" name="TYPO3_INSTALL[database_import]['.$table.']" checked="checked" value="'.md5($definition).'" /></td>
04441                                                         <td><strong>'.$table.'</strong></td>
04442                                                         <td><img src="clear.gif" width="10" height="1" alt="" /></td>
04443                                                         <td nowrap="nowrap">'.($insertCount[$table]?'Rows: '.$insertCount[$table]:'').'</td>
04444                                                         <td><img src="clear.gif" width="10" height="1" alt="" /></td>
04445                                                         <td nowrap="nowrap">'.($exist?'<img src="'.$GLOBALS['BACK_PATH'].'gfx/icon_warning.gif" width="18" height="16" align="top" alt="" />Table exists!':'').'</td>
04446                                                         </tr>';
04447                                         }
04448                                         $content.= '
04449                                                 <br />
04450                                                 <h3>Import static data</h3>
04451                                                 <table border="0" cellpadding="0" cellspacing="0">'.$out.'</table>';
04452                                 }
04453                         }
04454                 }
04455 
04456                         // Return array of information if $infoOnly, otherwise content.
04457                 return $infoOnly ? $dbStatus : $content;
04458         }
04459 
04468         function forceDBupdates($extKey, $extInfo)      {
04469                 $instObj = new t3lib_install;
04470 
04471                         // Updating tables and fields?
04472                 if (is_array($extInfo['files']) && in_array('ext_tables.sql',$extInfo['files']))        {
04473                         $fileContent = t3lib_div::getUrl($this->getExtPath($extKey,$extInfo['type']).'ext_tables.sql');
04474 
04475                         $FDfile = $instObj->getFieldDefinitions_sqlContent($fileContent);
04476                         if (count($FDfile))     {
04477                                 $FDdb = $instObj->getFieldDefinitions_database(TYPO3_db);
04478                                 $diff = $instObj->getDatabaseExtra($FDfile, $FDdb);
04479                                 $update_statements = $instObj->getUpdateSuggestions($diff);
04480 
04481                                 foreach((array)$update_statements['add'] as $string)    {
04482                                         $GLOBALS['TYPO3_DB']->admin_query($string);
04483                                 }
04484                                 foreach((array)$update_statements['change'] as $string) {
04485                                         $GLOBALS['TYPO3_DB']->admin_query($string);
04486                                 }
04487                                 foreach((array)$update_statements['create_table'] as $string)   {
04488                                         $GLOBALS['TYPO3_DB']->admin_query($string);
04489                                 }
04490                         }
04491                 }
04492 
04493                         // Importing static tables?
04494                 if (is_array($extInfo['files']) && in_array('ext_tables_static+adt.sql',$extInfo['files']))     {
04495                         $fileContent = t3lib_div::getUrl($this->getExtPath($extKey,$extInfo['type']).'ext_tables_static+adt.sql');
04496 
04497                         $statements = $instObj->getStatementArray($fileContent,1);
04498                         list($statements_table, $insertCount) = $instObj->getCreateTables($statements,1);
04499 
04500                                 // Traverse the tables
04501                         foreach($statements_table as $table => $query)  {
04502                                 $GLOBALS['TYPO3_DB']->admin_query('DROP TABLE IF EXISTS '.$table);
04503                                 $GLOBALS['TYPO3_DB']->admin_query($query);
04504 
04505                                 if ($insertCount[$table])       {
04506                                         $statements_insert = $instObj->getTableInsertStatements($statements, $table);
04507 
04508                                         foreach($statements_insert as $v)       {
04509                                                 $GLOBALS['TYPO3_DB']->admin_query($v);
04510                                         }
04511                                 }
04512                         }
04513                 }
04514         }
04515 
04526         function tsStyleConfigForm($extKey,$extInfo,$output=0,$script='',$addFields='') {
04527                 global $TYPO3_CONF_VARS;
04528 
04529                         // Initialize:
04530                 $absPath = $this->getExtPath($extKey,$extInfo['type']);
04531                 $relPath = $this->typeRelPaths[$extInfo['type']].$extKey.'/';
04532 
04533                         // Look for template file for form:
04534                 if (@is_file($absPath.'ext_conf_template.txt')) {
04535 
04536                                 // Load tsStyleConfig class and parse configuration template:
04537                         $tsStyleConfig = t3lib_div::makeInstance('t3lib_tsStyleConfig');
04538                         $tsStyleConfig->doNotSortCategoriesBeforeMakingForm = TRUE;
04539                         $theConstants = $tsStyleConfig->ext_initTSstyleConfig(
04540                         t3lib_div::getUrl($absPath.'ext_conf_template.txt'),
04541                         $relPath,
04542                         $absPath,
04543                         $GLOBALS['BACK_PATH']
04544                         );
04545 
04546                                 // Load the list of resources.
04547                         $tsStyleConfig->ext_loadResources($absPath.'res/');
04548 
04549                                 // Load current value:
04550                         $arr = unserialize($TYPO3_CONF_VARS['EXT']['extConf'][$extKey]);
04551                         $arr = is_array($arr) ? $arr : array();
04552 
04553                                 // Call processing function for constants config and data before write and form rendering:
04554                         if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/mod/tools/em/index.php']['tsStyleConfigForm']))      {
04555                                 $_params = array('fields' => &$theConstants, 'data' => &$arr, 'extKey' => $extKey);
04556                                 foreach($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/mod/tools/em/index.php']['tsStyleConfigForm'] as $_funcRef)       {
04557                                         t3lib_div::callUserFunction($_funcRef,$_params,$this);
04558                                 }
04559                                 unset($_params);
04560                         }
04561 
04562                                 // If saving operation is done:
04563                         if (t3lib_div::_POST('submit')) {
04564                                 $tsStyleConfig->ext_procesInput(t3lib_div::_POST(),array(),$theConstants,array());
04565                                 $arr = $tsStyleConfig->ext_mergeIncomingWithExisting($arr);
04566                                 $this->writeTsStyleConfig($extKey,$arr);
04567                         }
04568 
04569                                 // Setting value array
04570                         $tsStyleConfig->ext_setValueArray($theConstants,$arr);
04571 
04572                                 // Getting session data:
04573                         $MOD_MENU = array();
04574                         $MOD_MENU['constant_editor_cat'] = $tsStyleConfig->ext_getCategoriesForModMenu();
04575                         $MOD_SETTINGS = t3lib_BEfunc::getModuleData($MOD_MENU, t3lib_div::_GP('SET'), 'xMod_test');
04576 
04577                                 // Resetting the menu (stop)
04578                         if (count($MOD_MENU)>1) {
04579                                 $menu = 'Category: '.t3lib_BEfunc::getFuncMenu(0,'SET[constant_editor_cat]',$MOD_SETTINGS['constant_editor_cat'],$MOD_MENU['constant_editor_cat'],'','&CMD[showExt]='.$extKey);
04580                                 $this->content.=$this->doc->section('','<span class="nobr">'.$menu.'</span>');
04581                                 $this->content.=$this->doc->spacer(10);
04582                         }
04583 
04584                                 // Category and constant editor config:
04585                         $form = '
04586                                 <table border="0" cellpadding="0" cellspacing="0" width="600">
04587                                         <tr>
04588                                                 <td>'.$tsStyleConfig->ext_getForm($MOD_SETTINGS['constant_editor_cat'],$theConstants,$script,$addFields).'</td>
04589                                         </tr>
04590                                 </table>';
04591                         if ($output)    {
04592                                 return $form;
04593                         } else {
04594                                 $this->content.=$this->doc->section('','</form>'.$form.'<form>');
04595                         }
04596                 }
04597         }
04598 
04599 
04600 
04601 
04602 
04603 
04604 
04605 
04606 
04607 
04608         /*******************************
04609         *
04610         * Dumping database (MySQL compliant)
04611         *
04612         ******************************/
04613 
04621         function dumpTableAndFieldStructure($arr)       {
04622                 $tables = array();
04623 
04624                 if (count($arr))        {
04625 
04626                         // Get file header comment:
04627                         $tables[] = $this->dumpHeader();
04628 
04629                         // Traverse tables, write each table/field definition:
04630                         foreach($arr as $table => $fieldKeyInfo)        {
04631                                 $tables[] = $this->dumpTableHeader($table,$fieldKeyInfo);
04632                         }
04633                 }
04634 
04635                 // Return result:
04636                 return implode(chr(10).chr(10).chr(10),$tables);
04637         }
04638 
04646         function dumpStaticTables($tableList)   {
04647                 $instObj = new t3lib_install;
04648                 $dbFields = $instObj->getFieldDefinitions_database(TYPO3_db);
04649 
04650                 $out = '';
04651                 $parts = t3lib_div::trimExplode(',',$tableList,1);
04652 
04653                 // Traverse the table list and dump each:
04654                 foreach($parts as $table)       {
04655                         if (is_array($dbFields[$table]['fields']))      {
04656                                 $dHeader = $this->dumpHeader();
04657                                 $header = $this->dumpTableHeader($table,$dbFields[$table],1);
04658                                 $insertStatements = $this->dumpTableContent($table,$dbFields[$table]['fields']);
04659 
04660                                 $out.= $dHeader.chr(10).chr(10).chr(10).
04661                                 $header.chr(10).chr(10).chr(10).
04662                                 $insertStatements.chr(10).chr(10).chr(10);
04663                         } else {
04664                                 die('Fatal error: Table for dump not found in database...');
04665                         }
04666                 }
04667                 return $out;
04668         }
04669 
04675         function dumpHeader()   {
04676                 return trim('
04677 # TYPO3 Extension Manager dump 1.1
04678 #
04679 # Host: '.TYPO3_db_host.'    Database: '.TYPO3_db.'
04680 #--------------------------------------------------------
04681 ');
04682         }
04683 
04692         function dumpTableHeader($table,$fieldKeyInfo,$dropTableIfExists=0)     {
04693                 $lines = array();
04694                 $dump = '';
04695 
04696                 // Create field definitions
04697                 if (is_array($fieldKeyInfo['fields']))  {
04698                         foreach($fieldKeyInfo['fields'] as $fieldN => $data)    {
04699                                 $lines[]='  '.$fieldN.' '.$data;
04700                         }
04701                 }
04702 
04703                 // Create index key definitions
04704                 if (is_array($fieldKeyInfo['keys']))    {
04705                         foreach($fieldKeyInfo['keys'] as $fieldN => $data)      {
04706                                 $lines[]='  '.$data;
04707                         }
04708                 }
04709 
04710                 // Compile final output:
04711                 if (count($lines))      {
04712                         $dump = trim('
04713 #
04714 # Table structure for table "'.$table.'"
04715 #
04716 '.($dropTableIfExists ? 'DROP TABLE IF EXISTS '.$table.';
04717 ' : '').'CREATE TABLE '.$table.' (
04718 '.implode(','.chr(10),$lines).'
04719 );'
04720 );
04721                 }
04722 
04723                 return $dump;
04724         }
04725 
04734         function dumpTableContent($table,$fieldStructure)       {
04735 
04736                 // Substitution of certain characters (borrowed from phpMySQL):
04737                 $search = array('\\', '\'', "\x00", "\x0a", "\x0d", "\x1a");
04738                 $replace = array('\\\\', '\\\'', '\0', '\n', '\r', '\Z');
04739 
04740                 $lines = array();
04741 
04742                 // Select all rows from the table:
04743                 $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, '');
04744 
04745                 // Traverse the selected rows and dump each row as a line in the file:
04746                 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
04747                         $values = array();
04748                         reset($fieldStructure);
04749                         while(list($field) = each($fieldStructure))     {
04750                                 $values[] = isset($row[$field]) ? "'".str_replace($search, $replace, $row[$field])."'" : 'NULL';
04751                         }
04752                         $lines[] = 'INSERT INTO '.$table.' VALUES ('.implode(', ',$values).');';
04753                 }
04754 
04755                 // Free DB result:
04756                 $GLOBALS['TYPO3_DB']->sql_free_result($result);
04757 
04758                 // Implode lines and return:
04759                 return implode(chr(10),$lines);
04760         }
04761 
04769         function getTableAndFieldStructure($parts)      {
04770                 // Instance of install tool
04771                 $instObj = new t3lib_install;
04772                 $dbFields = $instObj->getFieldDefinitions_database(TYPO3_db);
04773 
04774 
04775                 $outTables = array();
04776                 foreach($parts as $table)       {
04777                         $tP = explode('.',$table);
04778                         if ($tP[0] && isset($dbFields[$tP[0]])) {
04779                                 if ($tP[1])     {
04780                                         $kfP = explode('KEY:',$tP[1],2);
04781                                         if (count($kfP)==2 && !$kfP[0]) {       // key:
04782                                                 if (isset($dbFields[$tP[0]]['keys'][$kfP[1]]))  $outTables[$tP[0]]['keys'][$kfP[1]] = $dbFields[$tP[0]]['keys'][$kfP[1]];
04783                                         } else {
04784                                                 if (isset($dbFields[$tP[0]]['fields'][$tP[1]])) $outTables[$tP[0]]['fields'][$tP[1]] = $dbFields[$tP[0]]['fields'][$tP[1]];
04785                                         }
04786                                 } else {
04787                                         $outTables[$tP[0]] = $dbFields[$tP[0]];
04788                                 }
04789                         }
04790                 }
04791 
04792                 return $outTables;
04793         }
04794 
04795 
04796 
04797 
04798 
04799 
04800 
04801 
04802 
04803 
04804         /*******************************
04805         *
04806         * TER Communication functions
04807         *
04808         ******************************/
04809 
04810 
04811 
04819         function uploadExtensionToTER($em)      {
04820                 $msg = '';
04821                 $response = $this->terConnection->uploadToTER($em);
04822 
04823                 if(!is_array($response)) return $response;
04824 
04825                 if($response['resultCode']==TX_TER_RESULT_EXTENSIONSUCCESSFULLYUPLOADED) {
04826                         $em['extInfo']['EM_CONF']['version'] = $response['version'];
04827                         $response['resultMessages'][] = 'The extension is now version: '.$response['version'];
04828                         $response['resultMessages'][] = $this->updateLocalEM_CONF($em['extKey'],$em['extInfo']);
04829                 }
04830 
04831                 $msg = '<ul><li>'.implode('</li><li>',$response['resultMessages']).'</li></ul>';
04832                 return $msg;
04833         }
04834 
04835 
04836 
04837 
04838 
04839 
04840 
04841 
04842 
04843 
04844         /************************************
04845         *
04846         * Various helper functions
04847         *
04848         ************************************/
04849 
04857         function listOrderTitle($listOrder,$key)        {
04858                 switch($listOrder)      {
04859                         case 'cat':
04860                                 return isset($this->categories[$key])?$this->categories[$key]:'<em>['.$key.']</em>';
04861                                 break;
04862                         case 'author_company':
04863                                 return $key;
04864                                 break;
04865                         case 'state':
04866                                 return $this->states[$key];
04867                                 break;
04868                         case 'type':
04869                                 return $this->typeDescr[$key];
04870                                 break;
04871                 }
04872         }
04873 
04882         function makeVersion($v,$mode)  {
04883                 $vDat = $this->renderVersion($v);
04884                 return $vDat['version_'.$mode];
04885         }
04886 
04894         function renderVersion($v,$raise='')    {
04895                 $parts = t3lib_div::intExplode('.',$v.'..');
04896                 $parts[0] = t3lib_div::intInRange($parts[0],0,999);
04897                 $parts[1] = t3lib_div::intInRange($parts[1],0,999);
04898                 $parts[2] = t3lib_div::intInRange($parts[2],0,999);
04899 
04900                 switch((string)$raise)  {
04901                         case 'main':
04902                                 $parts[0]++;
04903                                 $parts[1]=0;
04904                                 $parts[2]=0;
04905                                 break;
04906                         case 'sub':
04907                                 $parts[1]++;
04908                                 $parts[2]=0;
04909                                 break;
04910                         case 'dev':
04911                                 $parts[2]++;
04912                                 break;
04913                 }
04914 
04915                 $res = array();
04916                 $res['version'] = $parts[0].'.'.$parts[1].'.'.$parts[2];
04917                 $res['version_int'] = intval(str_pad($parts[0],3,'0',STR_PAD_LEFT).str_pad($parts[1],3,'0',STR_PAD_LEFT).str_pad($parts[2],3,'0',STR_PAD_LEFT));
04918                 $res['version_main'] = $parts[0];
04919                 $res['version_sub'] = $parts[1];
04920                 $res['version_dev'] = $parts[2];
04921 
04922                 return $res;
04923         }
04924 
04931         function ulFolder($extKey)      {
04932                 return 'uploads/tx_'.str_replace('_','',$extKey).'/';
04933         }
04934 
04940         function importAtAll()  {
04941                 return ($GLOBALS['TYPO3_CONF_VARS']['EXT']['allowGlobalInstall'] || $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowLocalInstall']);
04942         }
04943 
04951         function importAsType($type,$lockType='')       {
04952                 switch($type)   {
04953                         case 'G':
04954                                 return $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowGlobalInstall'] && (!$lockType || !strcmp($lockType,$type));
04955                                 break;
04956                         case 'L':
04957                                 return $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowLocalInstall'] && (!$lockType || !strcmp($lockType,$type));
04958                                 break;
04959                         case 'S':
04960                                 return $this->systemInstall;
04961                                 break;
04962                         default:
04963                                 return false;
04964                 }
04965         }
04966 
04973         function deleteAsType($type)    {
04974                 switch($type)   {
04975                         case 'G':
04976                                 return $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowGlobalInstall'];
04977                                 break;
04978                         case 'L':
04979                                 return $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowLocalInstall'];
04980                                 break;
04981                         default:
04982                                 return false;
04983                 }
04984         }
04985 
04994         function versionDifference($v1,$v2,$div=1)      {
04995                 return floor($this->makeVersion($v1,'int')/$div) > floor($this->makeVersion($v2,'int')/$div);
04996         }
04997 
05006         function first_in_array($str,$array,$caseInsensitive=FALSE)     {
05007                 if ($caseInsensitive)   $str = strtolower($str);
05008                 if (is_array($array))   {
05009                         foreach($array as $cl)  {
05010                                 if ($caseInsensitive)   $cl = strtolower($cl);
05011                                 if (t3lib_div::isFirstPartOfStr($cl,$str))      return true;
05012                         }
05013                 }
05014                 return false;
05015         }
05016 
05024         function includeEMCONF($path,$_EXTKEY)  {
05025                 @include($path);
05026                 if(is_array($EM_CONF[$_EXTKEY])) {
05027                         return $this->fixEMCONF($EM_CONF[$_EXTKEY]);
05028                 }
05029                 return false;
05030         }
05031 
05039         function searchExtension($extKey,$row) {
05040                 if ($this->lookUpStr)   {
05041                         return (
05042                         stristr($extKey,$this->lookUpStr) ||
05043                         stristr($row['EM_CONF']['title'],$this->lookUpStr) ||
05044                         stristr($row['EM_CONF']['description'],$this->lookUpStr) ||
05045                         stristr($row['EM_CONF']['author'],$this->lookUpStr) ||
05046                         stristr($row['EM_CONF']['author_company'],$this->lookUpStr)
05047                         );
05048                 } else return true;
05049         }
05050 }
05051 
05052 // Include extension?
05053 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/mod/tools/em/index.php'])    {
05054         include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/mod/tools/em/index.php']);
05055 }
05056 
05057 ?>