Documentation TYPO3 par Ameos

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         var $listingLimit = 500;                // List that many extension maximally at one time (fixing memory problems)
00205         var $listingLimitAuthor = 250;          // List that many extension maximally at one time (fixing memory problems)
00206 
00211         var $defaultCategories = Array(
00212                 'cat' => Array (
00213                         'be' => array(),
00214                         'module' => array(),
00215                         'fe' => array(),
00216                         'plugin' => array(),
00217                         'misc' => array(),
00218                         'services' => array(),
00219                         'templates' => array(),
00220                         'example' => array(),
00221                         'doc' => array()
00222                 )
00223         );
00224 
00229         var $categories = Array(
00230                 'be' => 'Backend',
00231                 'module' => 'Backend Modules',
00232                 'fe' => 'Frontend',
00233                 'plugin' => 'Frontend Plugins',
00234                 'misc' => 'Miscellaneous',
00235                 'services' => 'Services',
00236                 'templates' => 'Templates',
00237                 'example' => 'Examples',
00238                 'doc' => 'Documentation'
00239         );
00240 
00245         var $states = Array (
00246                 'alpha' => 'Alpha',
00247                 'beta' => 'Beta',
00248                 'stable' => 'Stable',
00249                 'experimental' => 'Experimental',
00250                 'test' => 'Test',
00251                 'obsolete' => 'Obsolete',
00252         );
00253 
00257         var $stateColors = Array (
00258                 'alpha' => '#d12438',
00259                 'beta' => '#97b17e',
00260                 'stable' => '#3bb65c',
00261                 'experimental' => '#007eba',
00262                 'test' => '#979797',
00263                 'obsolete' => '#000000',
00264         );
00265 
00269         var $typeLabels = Array (
00270                 'S' => 'System',
00271                 'G' => 'Global',
00272                 'L' => 'Local',
00273         );
00274         var $typeDescr = Array (
00275                 'S' => 'System extension (typo3/sysext/) - Always distributed with source code (Static).',
00276                 'G' => 'Global extensions (typo3/ext/) - Available for shared source on server (Dynamic).',
00277                 'L' => 'Local extensions (typo3conf/ext/) - Local for this TYPO3 installation only (Dynamic).',
00278         );
00279         var $typePaths = Array();                       // Also static, set in init()
00280         var $typeBackPaths = Array();           // Also static, set in init()
00281 
00282         var $typeRelPaths = Array (
00283                 'S' => 'sysext/',
00284                 'G' => 'ext/',
00285                 'L' => '../typo3conf/ext/',
00286         );
00287 
00288         var $detailCols = Array (
00289                 0 => 2,
00290                 1 => 5,
00291                 2 => 6,
00292                 3 => 6,
00293                 4 => 4,
00294                 5 => 1
00295         );
00296 
00297         var $fe_user = array(
00298                 'username' => '',
00299                 'password' => '',
00300         );
00301 
00302         var $privacyNotice = 'When you interact with the online repository, server information may be sent and stored in the repository for statistics.';
00303         var $securityHint = '<strong>Found a security problem? Please get in touch with us!</strong><br />If you think you have found a security issue in TYPO3 or an extension, please contact the <a href="http://typo3.org/teams/security/" target="_blank">TYPO3 security team</a>! Thank you!';
00304         var $editTextExtensions = 'html,htm,txt,css,tmpl,inc,php,sql,conf,cnf,pl,pm,sh,xml,ChangeLog';
00305         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';
00306 
00307 
00308 
00309 
00310 
00311                 // Default variables for backend modules
00312         var $MCONF = array();                           // Module configuration
00313         var $MOD_MENU = array();                        // Module menu items
00314         var $MOD_SETTINGS = array();            // Module session settings
00315         var $doc;                                                       // Document Template Object
00316         var $content;                                           // Accumulated content
00317 
00318         var $inst_keys = array();                       // Storage of installed extensions
00319         var $gzcompress = 0;                            // Is set true, if system support compression.
00320 
00321         var $terConnection;                     // instance of TER connection handler
00322 
00323                 // GPvars:
00324         var $CMD = array();                                     // CMD array
00325         var $listRemote;                                        // If set, connects to remote repository
00326         var $lookUpStr;                                         // Search string when listing local extensions
00327 
00328 
00329 
00330 
00331         /*********************************
00332         *
00333         * Standard module initialization
00334         *
00335         *********************************/
00336 
00342         function init() {
00343                 global $BE_USER,$LANG,$BACK_PATH,$TYPO3_CONF_VARS;
00344 
00345                         // Setting paths of install scopes:
00346                 $this->typePaths = Array (
00347                         'S' => TYPO3_mainDir.'sysext/',
00348                         'G' => TYPO3_mainDir.'ext/',
00349                         'L' => 'typo3conf/ext/'
00350                 );
00351                 $this->typeBackPaths = Array (
00352                         'S' => '../../../',
00353                         'G' => '../../../',
00354                         'L' => '../../../../'.TYPO3_mainDir
00355                 );
00356 
00357                 $this->excludeForPackaging = $GLOBALS['TYPO3_CONF_VARS']['EXT']['excludeForPackaging'];
00358 
00359                         // Setting module configuration:
00360                 $this->MCONF = $GLOBALS['MCONF'];
00361 
00362                         // Setting GPvars:
00363                 $this->CMD = t3lib_div::_GP('CMD');
00364                 $this->lookUpStr = trim(t3lib_div::_GP('_lookUp'));
00365                 $this->listRemote = t3lib_div::_GP('ter_connect');
00366                 $this->listRemote_search = trim(t3lib_div::_GP('ter_search'));
00367 
00368 
00369                         // Configure menu
00370                 $this->menuConfig();
00371 
00372                         // Setting internal static:
00373                 if ($TYPO3_CONF_VARS['EXT']['allowSystemInstall'])      $this->systemInstall = 1;
00374                 $this->requiredExt = t3lib_div::trimExplode(',',$TYPO3_CONF_VARS['EXT']['requiredExt'],1);
00375 
00376 
00377                         // Initialize helper object
00378                 $this->terConnection = t3lib_div::makeInstance('SC_mod_tools_em_terconnection');
00379                 $this->terConnection->emObj =& $this;
00380                 $this->terConnection->wsdlURL = $TYPO3_CONF_VARS['EXT']['em_wsdlURL'];
00381                 $this->xmlhandler = t3lib_div::makeInstance('SC_mod_tools_em_xmlhandler');
00382                 $this->xmlhandler->emObj =& $this;
00383                 $this->xmlhandler->useUnchecked = $this->MOD_SETTINGS['display_unchecked'];
00384                 $this->xmlhandler->useObsolete = $this->MOD_SETTINGS['display_obsolete'];
00385 
00386                         // Initialize Document Template object:
00387                 $this->doc = t3lib_div::makeInstance('noDoc');
00388                 $this->doc->backPath = $BACK_PATH;
00389                 $this->doc->docType = 'xhtml_trans';
00390 
00391                         // JavaScript
00392                 $this->doc->JScode = $this->doc->wrapScriptTags('
00393                         script_ended = 0;
00394                         function jumpToUrl(URL) {       //
00395                                 window.location.href = URL;
00396                         }
00397                 ');
00398                 $this->doc->form = '<form action="index.php" method="post" name="pageform">';
00399 
00400                 // Descriptions:
00401                 $this->descrTable = '_MOD_'.$this->MCONF['name'];
00402                 if ($BE_USER->uc['edit_showFieldHelp']) {
00403                         $LANG->loadSingleTableDescription($this->descrTable);
00404                 }
00405 
00406                 // Setting username/password etc. for upload-user:
00407                 $this->fe_user['username'] = $this->MOD_SETTINGS['fe_u'];
00408                 $this->fe_user['password'] = $this->MOD_SETTINGS['fe_p'];
00409                 parent::init();
00410                 $this->handleExternalFunctionValue('singleDetails');
00411         }
00412 
00424         function handleExternalFunctionValue($MM_key='function', $MS_value=NULL)        {
00425                 $MS_value = is_null($MS_value) ? $this->MOD_SETTINGS[$MM_key] : $MS_value;
00426                 $externalItems = $this->getExternalItemConfig($this->MCONF['name'],$MM_key,$MS_value);
00427                 if (is_array($externalItems))   $this->extClassConf = array_merge($externalItems,is_array($this->extClassConf)?$this->extClassConf:array());
00428                 if (is_array($this->extClassConf) && $this->extClassConf['path'])       {
00429                         $this->include_once[]=$this->extClassConf['path'];
00430                 }
00431         }
00432 
00438         function menuConfig()   {
00439                 global $BE_USER, $TYPO3_CONF_VARS;
00440 
00441                 // MENU-ITEMS:
00442                 $this->MOD_MENU = array(
00443                         'function' => array(
00444                                 0 => 'Loaded extensions',
00445                                 1 => 'Install extensions',
00446                                 2 => 'Import extensions',
00447                                 4 => 'Translation handling',
00448                                 3 => 'Settings',
00449                         ),
00450                         'listOrder' => array(
00451                                 'cat' => 'Category',
00452                                 'author_company' => 'Author',
00453                                 'state' => 'State',
00454                                 'type' => 'Type'
00455                         ),
00456                         'display_details' => array(
00457                                 1 => 'Details',
00458                                 0 => 'Description',
00459                                 2 => 'More details',
00460 
00461                                 3 => 'Technical (takes time!)',
00462                                 4 => 'Validating (takes time!)',
00463                                 5 => 'Changed? (takes time!)',
00464                         ),
00465                         'display_shy' => '',
00466                         'display_own' => '',
00467                         'display_unchecked' => '',
00468                         'display_obsolete' => '',
00469 
00470                         'singleDetails' => array(
00471                                 'info' => 'Information',
00472                                 'edit' => 'Edit files',
00473                                 'backup' => 'Backup/Delete',
00474                                 'dump' => 'Dump DB',
00475                                 'upload' => 'Upload to TER',
00476                                 'updateModule' => 'UPDATE!',
00477                         ),
00478                         'fe_u' => '',
00479                         'fe_p' => '',
00480 
00481                         'mirrorListURL' => '',
00482                         'rep_url' => '',
00483                         'extMirrors' => '',
00484                         'selectedMirror' => '',
00485 
00486                         'selectedLanguages' => ''
00487                 );
00488 
00489                 $this->MOD_MENU['singleDetails'] = $this->mergeExternalItems($this->MCONF['name'],'singleDetails',$this->MOD_MENU['singleDetails']);
00490 
00491                 // page/be_user TSconfig settings and blinding of menu-items
00492                 if (!$BE_USER->getTSConfigVal('mod.'.$this->MCONF['name'].'.allowTVlisting'))   {
00493                         unset($this->MOD_MENU['display_details'][3]);
00494                         unset($this->MOD_MENU['display_details'][4]);
00495                         unset($this->MOD_MENU['display_details'][5]);
00496                 }
00497 
00498                 // CLEANSE SETTINGS
00499                 $this->MOD_SETTINGS = t3lib_BEfunc::getModuleData($this->MOD_MENU, t3lib_div::_GP('SET'), $this->MCONF['name']);
00500 
00501                 if ($this->MOD_SETTINGS['function']==2) {
00502                         // If listing from online repository, certain items are removed though:
00503                         unset($this->MOD_MENU['listOrder']['type']);
00504                         unset($this->MOD_MENU['display_details'][2]);
00505                         unset($this->MOD_MENU['display_details'][3]);
00506                         unset($this->MOD_MENU['display_details'][4]);
00507                         unset($this->MOD_MENU['display_details'][5]);
00508                         $this->MOD_SETTINGS = t3lib_BEfunc::getModuleData($this->MOD_MENU, t3lib_div::_GP('SET'), $this->MCONF['name']);
00509                 }
00510                 parent::menuConfig();
00511         }
00512 
00518         function main() {
00519                 global $BE_USER,$LANG,$TYPO3_CONF_VARS;
00520 
00521                 if (empty($this->MOD_SETTINGS['mirrorListURL'])) $this->MOD_SETTINGS['mirrorListURL'] = $TYPO3_CONF_VARS['EXT']['em_mirrorListURL'];
00522 
00523                 // Starting page:
00524                 $this->content.=$this->doc->startPage('Extension Manager');
00525                 $this->content.=$this->doc->header('Extension Manager');
00526                 $this->content.=$this->doc->spacer(5);
00527 
00528                 // Commands given which is executed regardless of main menu setting:
00529                 if ($this->CMD['showExt'])      {       // Show details for a single extension
00530                         $this->showExtDetails($this->CMD['showExt']);
00531                 } elseif ($this->CMD['requestInstallExtensions'])       {       // Show details for a single extension
00532                                 $this->requestInstallExtensions($this->CMD['requestInstallExtensions']);
00533                 } elseif ($this->CMD['importExt'] || $this->CMD['uploadExt'])   {       // Imports an extension from online rep.
00534                         $err = $this->importExtFromRep($this->CMD['importExt'],$this->CMD['extVersion'],$this->CMD['loc'],$this->CMD['uploadExt']);
00535                         if ($err)       {
00536                                 $this->content.=$this->doc->section('',$GLOBALS['TBE_TEMPLATE']->rfw($err));
00537                         }
00538                         if(!$err && $this->CMD['importExt']) {
00539                                 $this->installTranslationsForExtension($this->CMD['importExt'], $this->getMirrorURL());
00540                         }
00541                 } elseif ($this->CMD['importExtInfo'])  {       // Gets detailed information of an extension from online rep.
00542                         $this->importExtInfo($this->CMD['importExtInfo'],$this->CMD['extVersion']);
00543                 } else {        // No command - we show what the menu setting tells us:
00544 
00545                         $menu = $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.menu').' '.
00546                         t3lib_BEfunc::getFuncMenu(0,'SET[function]',$this->MOD_SETTINGS['function'],$this->MOD_MENU['function']);
00547 
00548                         if (t3lib_div::inList('0,1,2',$this->MOD_SETTINGS['function'])) {
00549                                 $menu.='&nbsp;Group by:&nbsp;'.t3lib_BEfunc::getFuncMenu(0,'SET[listOrder]',$this->MOD_SETTINGS['listOrder'],$this->MOD_MENU['listOrder']).
00550                                 '&nbsp;&nbsp;Show:&nbsp;'.t3lib_BEfunc::getFuncMenu(0,'SET[display_details]',$this->MOD_SETTINGS['display_details'],$this->MOD_MENU['display_details']).'<br />';
00551                         }
00552                         if (t3lib_div::inList('0,1',$this->MOD_SETTINGS['function']))   {
00553                                 $menu.='<label for="checkDisplayShy">Display shy extensions:</label>&nbsp;&nbsp;'.t3lib_BEfunc::getFuncCheck(0,'SET[display_shy]',$this->MOD_SETTINGS['display_shy'],'','','id="checkDisplayShy"');
00554                         }
00555                         if (t3lib_div::inList('2',$this->MOD_SETTINGS['function']) && strlen($this->fe_user['username']))       {
00556                                 $menu.='<label for="checkDisplayOwn">Only my extensions:</label>&nbsp;&nbsp;'.t3lib_BEfunc::getFuncCheck(0,'SET[display_own]',$this->MOD_SETTINGS['display_own'],'','','id="checkDisplayOwn"');
00557                         }
00558                         if (t3lib_div::inList('0,1,2',$this->MOD_SETTINGS['function'])) {
00559                                 $menu.='&nbsp;&nbsp;<label for="checkDisplayObsolete">Show obsolete:</label>&nbsp;&nbsp;'.t3lib_BEfunc::getFuncCheck(0,'SET[display_obsolete]',$this->MOD_SETTINGS['display_obsolete'],'','','id="checkDisplayObsolete"');
00560                         }
00561 
00562                         $this->content.=$this->doc->section('','<span class="nobr">'.$menu.'</span>');
00563                         $this->content.=$this->doc->spacer(10);
00564 
00565                         switch((string)$this->MOD_SETTINGS['function']) {
00566                                 case '0':
00567                                         // Lists loaded (installed) extensions
00568                                         $this->extensionList_loaded();
00569                                         break;
00570                                 case '1':
00571                                         // Lists the installed (available) extensions
00572                                         $this->extensionList_installed();
00573                                         break;
00574                                 case '2':
00575                                         // Lists the extensions available from online rep.
00576                                         $this->extensionList_import();
00577                                         break;
00578                                 case '3':
00579                                         // Shows the settings screen
00580                                         $this->alterSettings();
00581                                         break;
00582                                 case '4':
00583                                         // Allows to set the translation preferences and check the status
00584                                         $this->translationHandling();
00585                                         break;
00586                                 default:
00587                                         $this->extObjContent();
00588                                         break;
00589                         }
00590                 }
00591 
00592                 // Shortcuts:
00593                 if ($BE_USER->mayMakeShortcut())        {
00594                         $this->content.=$this->doc->spacer(20).$this->doc->section('',$this->doc->makeShortcutIcon('CMD','function',$this->MCONF['name']));
00595                 }
00596         }
00597 
00603         function printContent() {
00604                 if ($this->doPrintContent) {
00605                         $this->content.= $this->doc->endPage();
00606                         echo $this->content;
00607                 }
00608         }
00609 
00610 
00611 
00612 
00613 
00614 
00615 
00616 
00617 
00618 
00619         /*********************************
00620         *
00621         * Function Menu Applications
00622         *
00623         *********************************/
00624 
00630         function extensionList_loaded() {
00631                 global $TYPO3_LOADED_EXT;
00632 
00633                 list($list,$cat) = $this->getInstalledExtensions();
00634 
00635                 // Loaded extensions
00636                 $content = '';
00637                 $lines = array();
00638 
00639                 // Available extensions
00640                 if (is_array($cat[$this->MOD_SETTINGS['listOrder']]))   {
00641                         $content='';
00642                         $lines=array();
00643                         $lines[] = $this->extensionListRowHeader(' class="bgColor5"',array('<td><img src="clear.gif" width="1" height="1" alt="" /></td>'));
00644 
00645                         foreach($cat[$this->MOD_SETTINGS['listOrder']] as $catName => $extEkeys)        {
00646                                 natcasesort($extEkeys);
00647                                 reset($extEkeys);
00648                                 $extensions = array();
00649                                 while(list($extKey)=each($extEkeys))    {
00650                                         if (array_key_exists($extKey,$TYPO3_LOADED_EXT) && ($this->MOD_SETTINGS['display_shy'] || !$list[$extKey]['EM_CONF']['shy']) && $this->searchExtension($extKey,$list[$extKey])) {
00651                                                 if (in_array($extKey, $this->requiredExt))      {
00652                                                         $loadUnloadLink = '<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw('Rq').'</strong>';
00653                                                 } else {
00654                                                         $loadUnloadLink = '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[remove]=1').'">'.$this->removeButton().'</a>';
00655                                                 }
00656 
00657                                                 $extensions[] = $this->extensionListRow($extKey,$list[$extKey],array('<td class="bgColor">'.$loadUnloadLink.'</td>'));
00658                                         }
00659                                 }
00660                                 if(count($extensions)) {
00661                                         $lines[]='<tr><td colspan="'.(3+$this->detailCols[$this->MOD_SETTINGS['display_details']]).'"><br /></td></tr>';
00662                                         $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>';
00663                                         $lines[] = implode(chr(10),$extensions);
00664                                 }
00665                         }
00666                 }
00667 
00668                 $content.= t3lib_BEfunc::cshItem('_MOD_tools_em', 'loaded', $GLOBALS['BACK_PATH'],'');
00669 
00670                 $content.= 'Look up: <input type="text" name="_lookUp" value="'.htmlspecialchars($this->lookUpStr).'" /><input type="submit" value="Search"/><br/><br/>';
00671 
00672                 $content.= '
00673 
00674                         <!-- Loaded Extensions List -->
00675                         <table border="0" cellpadding="2" cellspacing="1">'.implode('',$lines).'</table>';
00676 
00677                 $this->content.=$this->doc->section('Loaded Extensions',$content,0,1);
00678         }
00679 
00685         function extensionList_installed()      {
00686                 global $TYPO3_LOADED_EXT;
00687 
00688                 list($list,$cat)=$this->getInstalledExtensions();
00689 
00690                 // Available extensions
00691                 if (is_array($cat[$this->MOD_SETTINGS['listOrder']]))   {
00692                         $content='';
00693                         $lines=array();
00694                         $lines[]=$this->extensionListRowHeader(' class="bgColor5"',array('<td><img src="clear.gif" width="18" height="1" alt="" /></td>'));
00695 
00696                         $allKeys=array();
00697                         foreach($cat[$this->MOD_SETTINGS['listOrder']] as $catName => $extEkeys)        {
00698                                 if(!$this->MOD_SETTINGS['display_obsolete'] && $catName=='obsolete') continue;
00699 
00700                                 $allKeys[]='';
00701                                 $allKeys[]='TYPE: '.$catName;
00702 
00703                                 natcasesort($extEkeys);
00704                                 reset($extEkeys);
00705                                 $extensions = array();
00706                                 while(list($extKey)=each($extEkeys))    {
00707                                         $allKeys[]=$extKey;
00708                                         if ((!$list[$extKey]['EM_CONF']['shy'] || $this->MOD_SETTINGS['display_shy']) &&
00709                                                         ($list[$extKey]['EM_CONF']['state']!='obsolete' || $this->MOD_SETTINGS['display_obsolete'])
00710                                          && $this->searchExtension($extKey,$list[$extKey]))     {
00711                                                 $loadUnloadLink = t3lib_extMgm::isLoaded($extKey)?
00712                                                 '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[remove]=1&CMD[clrCmd]=1&SET[singleDetails]=info').'">'.$this->removeButton().'</a>':
00713                                                 '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[load]=1&CMD[clrCmd]=1&SET[singleDetails]=info').'">'.$this->installButton().'</a>';
00714                                                 if (in_array($extKey,$this->requiredExt))       {
00715                                                         $loadUnloadLink='<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw('Rq').'</strong>';
00716                                                 }
00717                                                 $theRowClass = t3lib_extMgm::isLoaded($extKey)? 'em-listbg1' : 'em-listbg2';
00718                                                 $extensions[]=$this->extensionListRow($extKey,$list[$extKey],array('<td class="bgColor">'.$loadUnloadLink.'</td>'),$theRowClass);
00719                                         }
00720                                 }
00721                                 if(count($extensions)) {
00722                                         $lines[]='<tr><td colspan="'.(3+$this->detailCols[$this->MOD_SETTINGS['display_details']]).'"><br /></td></tr>';
00723                                         $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>';
00724                                         $lines[] = implode(chr(10),$extensions);
00725                                 }
00726                         }
00727 
00728                         $content.='
00729 
00730 
00731 <!--
00732 EXTENSION KEYS:
00733 
00734 '.trim(implode(chr(10),$allKeys)).'
00735 
00736 -->
00737 
00738 ';
00739 
00740                         $content.= t3lib_BEfunc::cshItem('_MOD_tools_em', 'avail', $GLOBALS['BACK_PATH'],'|<br/>');
00741                         $content.= 'If you want to use an extension in TYPO3, you should simply click the "plus" button '.$this->installButton().' . <br />
00742                                                 Installed extensions can also be removed again - just click the remove button '.$this->removeButton().' .<br /><br />';
00743 
00744                         $content.= 'Look up: <input type="text" name="_lookUp" value="'.htmlspecialchars($this->lookUpStr).'" /><input type="submit" value="Search"/><br/><br/>';
00745                         $content.= $this->securityHint.'<br /><br />';
00746 
00747                         $content.= '<table border="0" cellpadding="2" cellspacing="1">'.implode('',$lines).'</table>';
00748 
00749                         $this->content.=$this->doc->section('Available Extensions - Grouped by: '.$this->MOD_MENU['listOrder'][$this->MOD_SETTINGS['listOrder']],$content,0,1);
00750                 }
00751         }
00752 
00758         function extensionList_import() {
00759                 global $TYPO3_LOADED_EXT;
00760                 $content='';
00761 
00762                         // Listing from online repository:
00763                 if ($this->listRemote)  {
00764                         list($inst_list,) = $this->getInstalledExtensions();
00765                         $this->inst_keys = array_flip(array_keys($inst_list));
00766 
00767                         $this->detailCols[1]+=6;
00768 
00769                                 // see if we have an extensionlist at all
00770                         $this->extensionCount = $this->xmlhandler->countExtensions();
00771                         if (!$this->extensionCount)     {
00772                                 $content .= $this->fetchMetaData('extensions');
00773                         }
00774 
00775                         if($this->MOD_SETTINGS['listOrder']=='author_company') {
00776                                 $this->listingLimit = $this->listingLimitAuthor;
00777                         }
00778 
00779                         $this->pointer = intval(t3lib_div::_GP('pointer'));
00780                         $offset = $this->listingLimit*$this->pointer;
00781 
00782                         if($this->MOD_SETTINGS['display_own'] && strlen($this->fe_user['username'])) {
00783                                 $this->xmlhandler->searchExtensionsXML($this->listRemote_search, $this->fe_user['username'], $this->MOD_SETTINGS['listOrder']);
00784                         } else {
00785                                 $this->xmlhandler->searchExtensionsXML($this->listRemote_search, '', $this->MOD_SETTINGS['listOrder'], false, false, $offset, $this->listingLimit);
00786                         }
00787                         if (count($this->xmlhandler->extensionsXML))    {
00788                                 list($list,$cat) = $this->prepareImportExtList(true);
00789 
00790                                         // Available extensions
00791                                 if (is_array($cat[$this->MOD_SETTINGS['listOrder']]))   {
00792                                         $lines=array();
00793                                         $lines[]=$this->extensionListRowHeader(' class="bgColor5"',array('<td><img src="clear.gif" width="18" height="1" alt="" /></td>'),1);
00794 
00795                                         foreach($cat[$this->MOD_SETTINGS['listOrder']] as $catName => $extEkeys)        {
00796                                                 if (count($extEkeys))   {
00797                                                         $lines[]='<tr><td colspan="'.(3+$this->detailCols[$this->MOD_SETTINGS['display_details']]).'"><br /></td></tr>';
00798                                                         $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>';
00799 
00800                                                         natcasesort($extEkeys);
00801                                                         reset($extEkeys);
00802                                                         while(list($extKey)=each($extEkeys))    {
00803                                                                 $version = array_keys($list[$extKey]['versions']);
00804                                                                 $version = end($version);
00805                                                                 $ext = $list[$extKey]['versions'][$version];
00806                                                                 $ext['downloadcounter_all'] = $list[$extKey]['downloadcounter'];
00807                                                                 $ext['_ICON'] = $list[$extKey]['_ICON'];
00808                                                                 $loadUnloadLink='';
00809                                                                 if ($inst_list[$extKey]['type']!='S' && (!isset($inst_list[$extKey]) || $this->versionDifference($version,$inst_list[$extKey]['EM_CONF']['version'],$this->versionDiffFactor))) {
00810                                                                         if (isset($inst_list[$extKey])) {
00811                                                                                         // update
00812                                                                                 $loc= ($inst_list[$extKey]['type']=='G'?'G':'L');
00813                                                                                 $aUrl = 'index.php?CMD[importExt]='.$extKey.'&CMD[extVersion]='.$version.'&CMD[loc]='.$loc;
00814                                                                                 $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>';
00815                                                                         } else {
00816                                                                                         // import
00817                                                                                 $aUrl = 'index.php?CMD[importExt]='.$extKey.'&CMD[extVersion]='.$version.'&CMD[loc]=L';
00818                                                                                 $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>';
00819                                                                         }
00820                                                                 } else {
00821                                                                         $loadUnloadLink = '&nbsp;';
00822                                                                 }
00823 
00824                                                                 if (isset($inst_list[$extKey])) {
00825                                                                         $theRowClass = t3lib_extMgm::isLoaded($extKey) ? 'em-listbg1' : 'em-listbg2';
00826                                                                 } else {
00827                                                                         $theRowClass = 'em-listbg3';
00828                                                                 }
00829 
00830                                                                 $lines[]=$this->extensionListRow($extKey,$ext,array('<td class="bgColor">'.$loadUnloadLink.'</td>'),$theRowClass,$inst_list,1,'index.php?CMD[importExtInfo]='.rawurlencode($extKey));
00831                                                                 unset($list[$extKey]);
00832                                                         }
00833                                                 }
00834                                         }
00835                                         unset($list);
00836 
00837                                                 // CSH:
00838                                         $content.= t3lib_BEfunc::cshItem('_MOD_tools_em', 'import_ter', $GLOBALS['BACK_PATH'],'|<br/>');
00839                                         $onsubmit = "window.location.href='index.php?ter_connect=1&ter_search='+escape(this.elements['_lookUp'].value);return false;";
00840                                         $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 />
00841                                                         <input type="text" name="_lookUp" value="'.htmlspecialchars($this->listRemote_search).'" /> <input type="submit" value="Look up" /><br /><br />';
00842 
00843                                         $content .= $this->browseLinks();
00844 
00845                                         $content.= '
00846 
00847                                         <!-- TER Extensions list -->
00848                                         <table border="0" cellpadding="2" cellspacing="1">'.implode(chr(10),$lines).'</table>';
00849                                         $content .= '<br />'.$this->browseLinks();
00850                                         $content.= '<br /><br />'.$this->securityHint;
00851                                         $content.= '<br /><br /><strong>PRIVACY NOTICE:</strong><br /> '.$this->privacyNotice;
00852 
00853                                         $this->content.=$this->doc->section('Extensions in TYPO3 Extension Repository (online) - Grouped by: '.$this->MOD_MENU['listOrder'][$this->MOD_SETTINGS['listOrder']],$content,0,1);
00854 
00855                                                 // Plugins which are NOT uploaded to repository but present on this server.
00856                                         $content='';
00857                                         $lines=array();
00858                                         if (count($this->inst_keys))    {
00859                                                 reset($this->inst_keys);
00860                                                 while(list($extKey)=each($this->inst_keys))     {
00861                                                         $this->xmlhandler->searchExtensionsXML($extKey, '', '', true);
00862                                                         if((strlen($this->listRemote_search) && !stristr($extKey,$this->listRemote_search)) || isset($this->xmlhandler->extensionsXML[$extKey])) continue;
00863 
00864                                                         $loadUnloadLink = t3lib_extMgm::isLoaded($extKey)?
00865                                                         '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[remove]=1&CMD[clrCmd]=1&SET[singleDetails]=info').'">'.$this->removeButton().'</a>':
00866                                                         '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[load]=1&CMD[clrCmd]=1&SET[singleDetails]=info').'">'.$this->installButton().'</a>';
00867                                                         if (in_array($extKey,$this->requiredExt))       $loadUnloadLink='<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw('Rq').'</strong>';
00868                                                         $lines[]=$this->extensionListRow($extKey,$inst_list[$extKey],array('<td class="bgColor">'.$loadUnloadLink.'</td>'),t3lib_extMgm::isLoaded($extKey)?'em-listbg1':'em-listbg2');
00869                                                 }
00870                                         }
00871                                         if(count($lines)) {
00872                                                 $content.= 'This is the list of extensions which are available locally, but not in the repository.<br />They might be user-defined and should be prepended user_ then.<br /><br />';
00873                                                 $content.= '<table border="0" cellpadding="2" cellspacing="1">'.
00874                                                         $this->extensionListRowHeader(' class="bgColor5"',array('<td><img src="clear.gif" width="18" height="1" alt="" /></td>')).
00875                                                         implode('',$lines).'</table>';
00876                                                 $this->content.=$this->doc->spacer(20);
00877                                                 $this->content.=$this->doc->section('Extensions found only on this server',$content,0,1);
00878                                         }
00879                                 }
00880                         } else {
00881                                 $content.= t3lib_BEfunc::cshItem('_MOD_tools_em', 'import_ter', $GLOBALS['BACK_PATH'],'|<br/>');
00882                                 $onsubmit = "window.location.href='index.php?ter_connect=1&ter_search='+escape(this.elements['_lookUp'].value);return false;";
00883                                 $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 />
00884                                         <input type="text" name="_lookUp" value="'.htmlspecialchars($this->listRemote_search).'" /> <input type="submit" value="Look up" /><br /><br />';
00885 
00886                                 $content.= '<p><strong>No matching extensions found.</strong></p>';
00887 
00888                                 $content.= '<br /><br /><strong>PRIVACY NOTICE:</strong><br /> '.$this->privacyNotice;
00889                                 $this->content.=$this->doc->section('Extensions in TYPO3 Extension Repository (online) - Grouped by: '.$this->MOD_MENU['listOrder'][$this->MOD_SETTINGS['listOrder']],$content,0,1);
00890                         }
00891                 } else {
00892                                 // CSH
00893                         $content.= t3lib_BEfunc::cshItem('_MOD_tools_em', 'import', $GLOBALS['BACK_PATH'],'|<br/>');
00894 
00895                         $onsubmit = "window.location.href='index.php?ter_connect=1&ter_search='+escape(this.elements['_lookUp'].value);return false;";
00896                         $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 />
00897                         <input type="text" name="_lookUp" value="" /> <input type="submit" value="Look up" /><br /><br />';
00898 
00899                         if ($this->CMD['fetchMetaData'])        {       // fetches mirror/extension data from online rep.
00900                                 $content .= $this->fetchMetaData($this->CMD['fetchMetaData']);
00901                         } else {
00902                                 $onCLick = "window.location.href='index.php?CMD[fetchMetaData]=extensions';return false;";
00903                                 $content.= 'Connect to the current mirror and retrieve the current list of available plugins from the TYPO3 Extension Repository.<br />
00904                                 <input type="submit" value="Retrieve/Update" onclick="'.htmlspecialchars($onCLick).'" />';
00905                                 if (is_file(PATH_site.'typo3temp/extensions.xml.gz'))   {
00906                                         $dateFormat = $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'];
00907                                         $timeFormat = $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'];
00908                                         $content.= ' (last update: '.date($dateFormat.' '.$timeFormat,filemtime(PATH_site.'typo3temp/extensions.xml.gz')).')';
00909                                 }
00910                         }
00911                         $content.= '<br /><br />'.$this->securityHint;
00912                         $content.= '<br /><br /><strong>PRIVACY NOTICE:</strong><br />'.$this->privacyNotice;
00913 
00914                         $this->content.=$this->doc->section('Extensions in TYPO3 Extension Repository',$content,0,1);
00915                 }
00916 
00917                         // Upload:
00918                 if ($this->importAtAll())       {
00919                         $content= '</form><form action="index.php" enctype="'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['form_enctype'].'" method="post">
00920                         Upload extension file (.t3x):<br />
00921                                 <input type="file" size="60" name="upload_ext_file" /><br />
00922                                 ... to location:<br />
00923                                 <select name="CMD[loc]">';
00924                         if ($this->importAsType('L'))   $content.='<option value="L">Local (../typo3conf/ext/)</option>';
00925                         if ($this->importAsType('G'))   $content.='<option value="G">Global (typo3/ext/)</option>';
00926                         if ($this->importAsType('S'))   $content.='<option value="S">System (typo3/sysext/)</option>';
00927                         $content.='</select><br />
00928         <input type="checkbox" value="1" name="CMD[uploadOverwrite]" id="checkUploadOverwrite" /> <label for="checkUploadOverwrite">Overwrite any existing extension!</label><br />
00929         <input type="submit" name="CMD[uploadExt]" value="Upload extension file" /><br />
00930                         ';
00931                 } else $content=$this->noImportMsg();
00932 
00933                 $this->content.=$this->doc->spacer(20);
00934                 $this->content.=$this->doc->section('Upload extension file directly (.t3x):',$content,0,1);
00935         }
00936 
00942         function browseLinks()  {
00943                 $content = '';
00944                 if ($this->pointer)     {
00945                         $content .= '<a href="'.t3lib_div::linkThisScript(array('pointer' => $this->pointer-1)).'" class="typo3-prevPage"><img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],'gfx/pilleft_n.gif','width="14" height="14"').' alt="Prev page" /> Prev page</a>';
00946                 }
00947                 if ($content) $content .= '&nbsp;&nbsp;&nbsp;';
00948                 if (intval($this->xmlhandler->matchingCount/$this->listingLimit)>$this->pointer)        {
00949                         $content .= '<a href="'.t3lib_div::linkThisScript(array('pointer' => $this->pointer+1)).'" class="typo3-nextPage"><img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],'gfx/pilright_n.gif','width="14" height="14"').' alt="Next page" /> Next page</a>';
00950                 }
00951                 $upper = (($this->pointer+1)*$this->listingLimit);
00952                 if ($upper>$this->xmlhandler->matchingCount)    {
00953                         $upper = $this->xmlhandler->matchingCount;
00954                 }
00955                 if ($content) $content .= '<br /><br />Showing extensions <strong>'.($this->pointer*$this->listingLimit+1).'</strong> to <strong>'.$upper.'</strong>';
00956                 if ($content) $content .= '<br /><br />';
00957                 return $content;
00958         }
00959 
00965         function alterSettings()        {
00966 
00967                         // Prepare the HTML output:
00968                 $content.= '
00969                         '.t3lib_BEfunc::cshItem('_MOD_tools_em', 'settings', $GLOBALS['BACK_PATH'],'|<br/>').'
00970                         <fieldset><legend>Security Settings</legend>
00971                         <table border="0" cellpadding="2" cellspacing="2">
00972                                 <tr class="bgColor4">
00973                                         <td><label for="display_unchecked">Enable extensions without review (basic security check):</label></td>
00974                                         <td>'.t3lib_BEfunc::getFuncCheck(0,'SET[display_unchecked]',$this->MOD_SETTINGS['display_unchecked'],'','','id="display_unchecked"').'</td>
00975                                 </tr>
00976                         </table>
00977                         <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>!
00978                         </fieldset>
00979                         <br />
00980                         <br />
00981                         <fieldset><legend>User Settings</legend>
00982                         <table border="0" cellpadding="2" cellspacing="2">
00983                                 <tr class="bgColor4">
00984                                         <td>Enter repository username:</td>
00985                                         <td><input type="text" name="SET[fe_u]" value="'.htmlspecialchars($this->MOD_SETTINGS['fe_u']).'" /></td>
00986                                 </tr>
00987                                 <tr class="bgColor4">
00988                                         <td>Enter repository password:</td>
00989                                         <td><input type="password" name="SET[fe_p]" value="'.htmlspecialchars($this->MOD_SETTINGS['fe_p']).'" /></td>
00990                                 </tr>
00991                         </table>
00992                         <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!
00993                         </fieldset>
00994                         <br />
00995                         <br />
00996                         <fieldset><legend>Mirror selection</legend>
00997                         <table border="0" cellpadding="2" cellspacing="2">
00998                                 <tr class="bgColor4">
00999                                         <td>Enter mirror list URL:</td>
01000                                         <td><input type="text" size="50" name="SET[mirrorListURL]" value="'.htmlspecialchars($this->MOD_SETTINGS['mirrorListURL']).'" /></td>
01001                                 </tr>
01002                         </table>
01003                         <br />
01004                         <p>Select a mirror from below. This list is built from the online mirror list retrieved from the URL above.<br /><br /></p>
01005                         <fieldset><legend>Mirror list</legend>';
01006                 if(!empty($this->MOD_SETTINGS['mirrorListURL'])) {
01007                         if ($this->CMD['fetchMetaData'])        {       // fetches mirror/extension data from online rep.
01008                                 $content .= $this->fetchMetaData($this->CMD['fetchMetaData']);
01009                         } else {
01010                                 $content.= '<a href="index.php?CMD[fetchMetaData]=mirrors">Click here to reload the list.</a>';
01011                         }
01012                 }
01013                 $content .= '<br />
01014                         <table cellspacing="4" style="text-align:left; vertical-alignment:top;">
01015                         <tr><td>Use</td><td>Name</td><td>URL</td><td>Country</td><td>Sponsored by</td></tr>
01016                 ';
01017 
01018                 if (!strlen($this->MOD_SETTINGS['extMirrors'])) $this->fetchMetaData('mirrors');
01019                 $extMirrors = unserialize($this->MOD_SETTINGS['extMirrors']);
01020                 $extMirrors[''] = array('title'=>'Random (recommended!)');
01021                 ksort($extMirrors);
01022                 if(is_array($extMirrors)) {
01023                         foreach($extMirrors as $k => $v) {
01024                                 if(isset($v['sponsor'])) {
01025                                         $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>';
01026                                 }
01027                                 $selected = ($this->MOD_SETTINGS['selectedMirror']==$k) ? 'checked="checked"' : '';
01028                                 $content.='<tr class="bgColor4">
01029                         <td><input type="radio" name="SET[selectedMirror]" id="selectedMirror'.$k.'" value="'.$k.'" '.$selected.'/></td><td><label for="selectedMirror'.$k.'">'.htmlspecialchars($v['title']).'</label></td><td>'.htmlspecialchars($v['host'].$v['path']).'</td><td>'.$v['country'].'</td><td>'.$sponsor.'</td></tr>';
01030                         }
01031                 }
01032                 $content.= '
01033                         </table>
01034                         </fieldset>
01035                         <br />
01036                         <table border="0" cellpadding="2" cellspacing="2">
01037                                 <tr class="bgColor4">
01038                                         <td>Enter repository URL:</td>
01039                                         <td><input type="text" size="50" name="SET[rep_url]" value="'.htmlspecialchars($this->MOD_SETTINGS['rep_url']).'" /></td>
01040                                 </tr>
01041                         </table>
01042 
01043                         If you set a repository URL, this overrides the use of a mirror. Use this to select a specific (private) repository.<br />
01044                         </fieldset>
01045                         <br />
01046                         <input type="submit" value="Update" />
01047                 ';
01048 
01049                 $this->content.=$this->doc->section('Repository settings',$content,0,1);
01050         }
01051 
01057         function translationHandling()  {
01058                 global $LANG, $TYPO3_LOADED_EXT;
01059                 $LANG->includeLLFile('EXT:setup/mod/locallang.xml');
01060 
01061                 $incoming = t3lib_div::_POST('SET');
01062                 if(isset($incoming['selectedLanguages']) && is_array($incoming['selectedLanguages'])) {
01063                         t3lib_BEfunc::getModuleData($this->MOD_MENU, array('selectedLanguages' => serialize($incoming['selectedLanguages'])), $this->MCONF['name'], '', 'selectedLanguages');
01064                         $this->MOD_SETTINGS['selectedLanguages'] = serialize($incoming['selectedLanguages']);
01065                 }
01066 
01067                 $selectedLanguages = unserialize($this->MOD_SETTINGS['selectedLanguages']);
01068                 if(count($selectedLanguages)==1 && empty($selectedLanguages[0])) $selectedLanguages = array();
01069                 $theLanguages = t3lib_div::trimExplode('|',TYPO3_languages);
01070                 foreach($theLanguages as $val)  {
01071                         if ($val!='default')    {
01072                                 $localLabel = '  -  ['.htmlspecialchars($GLOBALS['LOCAL_LANG']['default']['lang_'.$val]).']';
01073                                 $selected = (is_array($selectedLanguages) && in_array($val, $selectedLanguages)) ? ' selected="selected"' : '';
01074                                 $opt[$GLOBALS['LOCAL_LANG']['default']['lang_'.$val].'--'.$val]='
01075              <option value="'.$val.'"'.$selected.'>'.$LANG->getLL('lang_'.$val,1).$localLabel.'</option>';
01076                         }
01077                 }
01078                 ksort($opt);
01079 
01080                         // Prepare the HTML output:
01081                 $content.= '
01082                         '.t3lib_BEfunc::cshItem('_MOD_tools_em', 'translation', $GLOBALS['BACK_PATH'],'|<br/>').'
01083                         <fieldset><legend>Translation Settings</legend>
01084                         <table border="0" cellpadding="2" cellspacing="2">
01085                                 <tr class="bgColor4">
01086                                         <td>Languages to fetch:</td>
01087                                         <td>
01088                                           <select name="SET[selectedLanguages][]" multiple="multiple" size="10">
01089                                           <option></option>'.
01090             implode('',$opt).'
01091             </select>
01092           </td>
01093                                 </tr>
01094                         </table>
01095                         <br />
01096                         <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 />
01097                         <br />To request an update/install for already loaded extensions, see below.</p>
01098                         </fieldset>
01099                         <br />
01100                         <input type="submit" value="Save selection" />
01101                         <br />
01102                         </fieldset>';
01103 
01104                 $this->content.=$this->doc->section('Translation settings',$content,0,1);
01105 
01106                 if(count($selectedLanguages)>0) {
01107                         $mirrorURL = $this->getMirrorURL();
01108                         $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')).'\'" />';
01109 
01110                         if(t3lib_div::_GET('l10n') == 'check') {
01111                                 $loadedExtensions = array_keys($TYPO3_LOADED_EXT);
01112                                 $loadedExtensions = array_diff($loadedExtensions,array('_CACHEFILE'));
01113 
01114                                         // Override content output - we now do that ourself:
01115                                 echo ($this->content . $this->doc->section('Translation status',$content,0,1));
01116                                 $this->doPrintContent = FALSE;
01117                                 flush();
01118 
01119                                 echo '
01120                                 <br />
01121                                 <br />
01122                                 <p id="progress-message">
01123                                         Checking translation status, please wait ...
01124                                 </p>
01125                                 <br />
01126                                 <div style="width:100%; height:20px; border: 1px solid black;">
01127                                         <div id="progress-bar" style="float: left; width: 0%; height: 20px; background-color:green;">&nbsp;</div>
01128                                         <div id="transparent-bar" style="float: left; width: 100%; height: 20px; background-color:'.$this->doc->bgColor2.';">&nbsp;</div>
01129                                 </div>
01130                                 <br />
01131                                 <br /><p>This table shows the status of the loaded extension\'s translations.</p><br />
01132                                 <table border="0" cellpadding="2" cellspacing="2">
01133                                         <tr class="bgColor2"><td>Extension key</td>
01134                                 ';
01135 
01136                                 foreach($selectedLanguages as $lang) {
01137                                         echo ('<td>'.$LANG->getLL('lang_'.$lang,1).'</td>');
01138                                 }
01139                                 echo ('</tr>');
01140 
01141                                 $counter = 1;
01142                                 foreach($loadedExtensions as $extKey) {
01143 
01144                                         $percentDone = intval (($counter / count($loadedExtensions)) * 100);
01145                                         echo ('
01146                                         <script>
01147                                                 document.getElementById("progress-bar").style.width = "'.$percentDone.'%";
01148                                                 document.getElementById("transparent-bar").style.width = "'.(100-$percentDone).'%";
01149                                                 document.getElementById("progress-message").firstChild.data="Checking translation status for extension \"'.$extKey.'\" ...";
01150                                         </script>
01151                                         ');
01152 
01153                                         flush();
01154                                         $translationStatusArr = $this->terConnection->fetchTranslationStatus($extKey,$mirrorURL);
01155 
01156                                         echo ('<tr class="bgColor4"><td>'.$extKey.'</td>');
01157                                         foreach($selectedLanguages as $lang) {
01158                                                 // remote unknown -> keine l10n
01159                                                 if(!isset($translationStatusArr[$lang])) {
01160                                                         echo ('<td title="No translation available">N/A</td>');
01161                                                         continue;
01162                                                 }
01163                                                         // determine local md5 from zip
01164                                                 if(is_file(PATH_site.'typo3temp/'.$extKey.'-l10n-'.$lang.'.zip')) {
01165                                                         $localmd5 = md5_file(PATH_site.'typo3temp/'.$extKey.'-l10n-'.$lang.'.zip');
01166                                                 } else {
01167                                                         echo ('<td title="Not installed / Unknown" style="background-color:#ff0">???</td>');
01168                                                         continue;
01169                                                 }
01170                                                         // local!=remote -> needs update
01171                                                 if($localmd5 != $translationStatusArr[$lang]['md5']) {
01172                                                         echo ('<td title="Needs update" style="background-color:#ff0">UPD</td>');
01173                                                         continue;
01174                                                 }
01175                                                 echo ('<td title="Is up to date" style="background-color:#69a550">OK</td>');
01176                                         }
01177                                         echo ('</tr>');
01178 
01179                                         $counter ++;
01180                                 }
01181                                 echo '</table>
01182                                         <script>
01183                                                 document.getElementById("progress-message").firstChild.data="Check done.";
01184                                         </script>
01185                                 ';
01186                                 echo $this->doc->endPage();
01187                                 return '';
01188 
01189                         } elseif(t3lib_div::_GET('l10n') == 'update') {
01190                                 $loadedExtensions = array_keys($TYPO3_LOADED_EXT);
01191                                 $loadedExtensions = array_diff($loadedExtensions,array('_CACHEFILE'));
01192 
01193                                         // Override content output - we now do that ourself:
01194                                 echo ($this->content . $this->doc->section('Translation status',$content,0,1));
01195                                 $this->doPrintContent = FALSE;
01196                                 flush();
01197 
01198                                 echo ('
01199                                 <br />
01200                                 <br />
01201                                 <p id="progress-message">
01202                                         Updating translations, please wait ...
01203                                 </p>
01204                                 <br />
01205                                 <div style="width:100%; height:20px; border: 1px solid black;">
01206                                         <div id="progress-bar" style="float: left; width: 0%; height: 20px; background-color:green;">&nbsp;</div>
01207                                         <div id="transparent-bar" style="float: left; width: 100%; height: 20px; background-color:'.$this->doc->bgColor2.';">&nbsp;</div>
01208                                 </div>
01209                                 <br />
01210                                 <br /><p>This table shows the update results of the loaded extension\'s translations.<br />
01211                                 <em>If you want to force a full check/update, delete the l10n zip-files from the typo3temp folder.</em></p><br />
01212                                 <table border="0" cellpadding="2" cellspacing="2">
01213                                         <tr class="bgColor2"><td>Extension key</td>
01214                                 ');
01215 
01216                                 foreach($selectedLanguages as $lang) {
01217                                         echo '<td>'.$LANG->getLL('lang_'.$lang,1).'</td>';
01218                                 }
01219                                 echo '</tr>';
01220 
01221                                 $counter = 1;
01222                                 foreach($loadedExtensions as $extKey) {
01223                                         $percentDone = intval (($counter / count($loadedExtensions)) * 100);
01224                                         echo ('
01225                                         <script>
01226                                                 document.getElementById("progress-bar").style.width = "'.$percentDone.'%";
01227                                                 document.getElementById("transparent-bar").style.width = "'.(100-$percentDone).'%";
01228                                                 document.getElementById("progress-message").firstChild.data="Updating translation for extension \"'.$extKey.'\" ...";
01229                                         </script>
01230                                         ');
01231 
01232                                         flush();
01233                                         $translationStatusArr = $this->terConnection->fetchTranslationStatus($extKey,$mirrorURL);
01234 
01235                                         echo ('<tr class="bgColor4"><td>'.$extKey.'</td>');
01236                                         if(is_array($translationStatusArr)) {
01237                                                 foreach($selectedLanguages as $lang) {
01238                                                                 // remote unknown -> no l10n available
01239                                                         if(!isset($translationStatusArr[$lang])) {
01240                                                                 echo ('<td title="No translation available">N/A</td>');
01241                                                                 continue;
01242                                                         }
01243                                                                 // determine local md5 from zip
01244                                                         if(is_file(PATH_site.'typo3temp/'.$extKey.'-l10n-'.$lang.'.zip')) {
01245                                                                 $localmd5 = md5_file(PATH_site.'typo3temp/'.$extKey.'-l10n-'.$lang.'.zip');
01246                                                         } else {
01247                                                                 $localmd5 = 'zzz';
01248                                                         }
01249                                                                 // local!=remote or not installed -> needs update
01250                                                         if($localmd5 != $translationStatusArr[$lang]['md5']) {
01251                                                                 $ret = $this->updateTranslation($extKey, $lang, $mirrorURL);
01252                                                                 if($ret === true) {
01253                                                                         echo ('<td title="Has been updated" style="background-color:#69a550">UPD</td>');
01254                                                                 } else {
01255                                                                         echo ('<td title="'.htmlspecialchars($ret).'" style="background-color:#cb3352">ERR</td>');
01256                                                                 }
01257                                                                 continue;
01258                                                         }
01259                                                         echo ('<td title="Is up to date" style="background-color:#69a550">OK</td>');
01260                                                 }
01261                                         } else {
01262                                                 echo ('<td colspan="'.count($selectedLanguages).'" title="Possible reasons: network problems, allow_url_fopen off, curl not enabled in Install tool.">Could not fetch translation status</td>');
01263                                         }
01264                                         echo ('</tr>');
01265                                         $counter++;
01266                                 }
01267                                 echo '</table>
01268                                         <script>
01269                                                 document.getElementById("progress-message").firstChild.data="Update done.";
01270                                         </script>
01271                                 ';
01272                                 echo $this->doc->endPage();
01273                                 return '';
01274                         }
01275 
01276                         $this->content.=$this->doc->section('Translation status',$content,0,1);
01277                 }
01278         }
01279 
01288         function updateTranslation($extKey, $lang, $mirrorURL) {
01289                 $l10n = $this->terConnection->fetchTranslation($extKey, $lang, $mirrorURL);
01290                 if(is_array($l10n)) {
01291                         $file = PATH_site.'typo3temp/'.$extKey.'-l10n-'.$lang.'.zip';
01292                         $path = 'l10n/'.$lang.'/';
01293                         if(!is_dir(PATH_typo3conf.$path)) t3lib_div::mkdir_deep(PATH_typo3conf,$path);
01294                         t3lib_div::writeFile($file, $l10n[0]);
01295                         if($this->unzip($file, PATH_typo3conf.$path)) {
01296                                 return true;
01297                         } else {
01298                                 return 'Unpacking the language pack failed!';
01299                         }
01300                 } else {
01301                         return $l10n;
01302                 }
01303         }
01304 
01312         function installTranslationsForExtension($extKey, $mirrorURL) {
01313                 $selectedLanguages = unserialize($this->MOD_SETTINGS['selectedLanguages']);
01314                 if(!is_array($selectedLanguages)) $selectedLanguages = array();
01315                 foreach($selectedLanguages as $lang) {
01316                         $l10n = $this->terConnection->fetchTranslation($extKey, $lang, $mirrorURL);
01317                         if(is_array($l10n)) {
01318                                 $file = PATH_typo3conf.'l10n/'.$extKey.'-l10n-'.$lang.'.zip';
01319                                 $path = 'l10n/'.$lang.'/'.$extKey;
01320                                 t3lib_div::writeFile($file, $l10n[0]);
01321                                 if(!is_dir(PATH_typo3conf.$path)) t3lib_div::mkdir_deep(PATH_typo3conf,$path);
01322                                 if($this->unzip($file, PATH_typo3conf.$path)) {
01323                                         return true;
01324                                 } else {
01325                                         return 'Unpacking the language pack failed!';
01326                                 }
01327                         } else {
01328                                 return $l10n;
01329                         }
01330                 }
01331         }
01332 
01342         function unzip($file, $path) {
01343                 if(strlen($GLOBALS['TYPO3_CONF_VARS']['BE']['unzip_path'])) {
01344                         chdir($path);
01345                         $cmd = $GLOBALS['TYPO3_CONF_VARS']['BE']['unzip_path'].' -o '.escapeshellarg($file);
01346                         exec($cmd, $list, $ret);
01347                         return ($ret === 0);
01348                 } else {
01349                                 // we use a pure PHP unzip
01350                         $unzip = new em_unzip($file);
01351                         $ret = $unzip->extract(array('add_path'=>$path));
01352                         return (is_array($ret));
01353                 }
01354         }
01355 
01356 
01357 
01358         /*********************************
01359         *
01360         * Command Applications (triggered by GET var)
01361         *
01362         *********************************/
01363 
01371         function importExtInfo($extKey, $version='')    {
01372 
01373                         // "Go back" link
01374                 $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>';
01375                 $this->content.= $this->doc->section('',$content);
01376                 $content = '';
01377 
01378                         // Fetch remote data:
01379                 $this->xmlhandler->searchExtensionsXML($extKey, '', '', true, true);
01380                 list($fetchData,) = $this->prepareImportExtList(true);
01381 
01382                 $versions = array_keys($fetchData[$extKey]['versions']);
01383                 $version = ($version == '') ? end($versions) : $version;
01384 
01385                 $opt = array();
01386                 foreach(array_keys($fetchData[$extKey]['versions']) as $ver)    {
01387                         $opt[]='<option value="'.$ver.'"'.(($version == $ver) ? ' selected="selected"' : '').'>'.$ver.'</option>';
01388                 }
01389 
01390                         // "Select version" box:
01391                 $onClick = 'window.location.href=\'index.php?CMD[importExtInfo]='.$extKey.'&CMD[extVersion]=\'+document.pageform.extVersion.options[document.pageform.extVersion.selectedIndex].value; return false;';
01392                 $select='<select name="extVersion">'.implode('',$opt).'</select> <input type="submit" value="Load details" onclick="'.htmlspecialchars($onClick).'" /> or<br /><br />';
01393 
01394                 if ($this->importAtAll())       {
01395                         $onClick = '
01396                                         window.location.href=\'index.php?CMD[importExt]='.$extKey.'\'
01397                                                 +\'&CMD[extVersion]=\'+document.pageform.extVersion.options[document.pageform.extVersion.selectedIndex].value
01398                                                 +\'&CMD[loc]=\'+document.pageform.loc.options[document.pageform.loc.selectedIndex].value;
01399                                                 return false;';
01400                         $select.='
01401                                 <input type="submit" value="Import/Update" onclick="'.htmlspecialchars($onClick).'"> to:
01402                                 <select name="loc">'.
01403                                 ($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>':'').
01404                                 ($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>':'').
01405                                 ($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>':'').
01406                                 '</select>';
01407                 } else $select.= $this->noImportMsg();
01408                 $content.= $select;
01409                 $this->content.= $this->doc->section('Select command',$content,0,1);
01410 
01411                         // Details:
01412                 $eInfo = $fetchData[$extKey]['versions'][$version];
01413                 $content='<strong>'.$fetchData[$extKey]['_ICON'].' &nbsp;'.$eInfo['EM_CONF']['title'].' ('.$extKey.', '.$version.')</strong><br /><br />';
01414                 $content.=$this->extInformationArray($extKey,$eInfo,1);
01415                 $this->content.=$this->doc->spacer(10);
01416                 $this->content.=$this->doc->section('Remote Extension Details',$content,0,1);
01417         }
01418 
01427         function fetchMetaData($metaType)       {
01428                 global $TYPO3_CONF_VARS;
01429 
01430                 switch($metaType) {
01431                         case 'mirrors':
01432                                 $mfile = t3lib_div::tempnam('mirrors');
01433                                 $mirrorsFile = t3lib_div::getURL($this->MOD_SETTINGS['mirrorListURL']);
01434                                 if($mirrorsFile===false) {
01435                                         t3lib_div::unlink_tempfile($mfile);
01436                                         $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>';
01437                                 } else {
01438                                         t3lib_div::writeFile($mfile, $mirrorsFile);
01439                                         $mirrors = implode('',gzfile($mfile));
01440                                         t3lib_div::unlink_tempfile($mfile);
01441 
01442                                         $mirrors = $this->xmlhandler->parseMirrorsXML($mirrors);
01443                                         if(is_array($mirrors) && count($mirrors)) {
01444                                                 t3lib_BEfunc::getModuleData($this->MOD_MENU, array('extMirrors' => serialize($mirrors)), $this->MCONF['name'], '', 'extMirrors');
01445                                                 $this->MOD_SETTINGS['extMirrors'] = serialize($mirrors);
01446                                                 $content = '<p>The mirror list has been updated and now contains '.count($mirrors).' entries.</p>';
01447                                         }
01448                                         else {
01449                                                 $content = '<p>'.$mirrors.'<br />The mirror list was not updated as it contained no entries.</p>';
01450                                         }
01451                                 }
01452                                 break;
01453                         case 'extensions':
01454                                 $this->fetchMetaData('mirrors'); // if we fetch the extensions anyway, we can as well keep this up-to-date
01455 
01456                                 $mirror = $this->getMirrorURL();
01457                                 $extfile = $mirror.'extensions.xml.gz';
01458                                 $extmd5 = t3lib_div::getURL($mirror.'extensions.md5');
01459                                 if(is_file(PATH_site.'typo3temp/extensions.xml.gz')) $localmd5 = md5_file(PATH_site.'typo3temp/extensions.xml.gz');
01460 
01461                                 if($extmd5 === false) {
01462                                         $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>';
01463                                 } elseif($extmd5 == $localmd5) {
01464                                         $content .= '<p>The extension list has not changed remotely, it has thus not been fetched.</p>';
01465                                 } else {
01466                                         $extXML = t3lib_div::getURL($extfile);
01467                                         if($extXML === false) {
01468                                                 $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>';
01469                                         } else {
01470                                                 t3lib_div::writeFile(PATH_site.'typo3temp/extensions.xml.gz', $extXML);
01471                                                 $content .= $this->xmlhandler->parseExtensionsXML(PATH_site.'typo3temp/extensions.xml.gz');
01472                                         }
01473                                 }
01474                                 break;
01475                 }
01476 
01477                 return $content;
01478         }
01479 
01485         function getMirrorURL() {
01486                 if(strlen($this->MOD_SETTINGS['rep_url'])) return $this->MOD_SETTINGS['rep_url'];
01487 
01488                 $mirrors = unserialize($this->MOD_SETTINGS['extMirrors']);
01489                 if(!is_array($mirrors)) {
01490                         $this->fetchMetaData('mirrors');
01491                         $mirrors = unserialize($this->MOD_SETTINGS['extMirrors']);
01492                         if(!is_array($mirrors)) return false;
01493                 }
01494                 if($this->MOD_SETTINGS['selectedMirror']=='') {
01495                         srand((float) microtime() * 10000000); // not needed after PHP 4.2.0...
01496                         $rand = array_rand($mirrors);
01497                         $url = 'http://'.$mirrors[$rand]['host'].$mirrors[$rand]['path'];
01498                 }
01499                 else {
01500                         $url = 'http://'.$mirrors[$this->MOD_SETTINGS['selectedMirror']]['host'].$mirrors[$this->MOD_SETTINGS['selectedMirror']]['path'];
01501                 }
01502 
01503                 return $url;
01504         }
01505 
01506 
01507 
01523         function installExtension($extKey, $version=null, $mode=EM_INSTALL_VERSION_MIN) {
01524                 list($inst_list,) = $this->getInstalledExtensions();
01525 
01526                         // check if it is already installed and loaded with sufficient version
01527                 if(isset($inst_list[$extKey])) {
01528                         $currentVersion = $inst_list[$extKey]['EM_CONF']['version'];
01529 
01530                         if(t3lib_extMgm::isLoaded($extKey)) {
01531                                 if($version===null) {
01532                                         return array(true, 'Extension already installed and loaded.');
01533                                 } else {
01534                                         switch($mode) {
01535                                                 case EM_INSTALL_VERSION_STRICT:
01536                                                         if ($currentVersion == $version)        {
01537                                                                 return array(true, 'Extension already installed and loaded.');
01538                                                         }
01539                                                         break;
01540                                                 case EM_INSTALL_VERSION_MIN:
01541                                                         if (version_compare($currentVersion, $version, '>='))   {
01542                                                                 return array(true, 'Extension already installed and loaded.');
01543                                                         }
01544                                                         break;
01545                                                 case EM_INSTALL_VERSION_MAX:
01546                                                         if (version_compare($currentVersion, $version, '<='))   {
01547                                                                 return array(true, 'Extension already installed and loaded.');
01548                                                         }
01549                                                         break;
01550                                         }
01551                                 }
01552                         } else {
01553                                 if (!t3lib_extMgm::isLocalconfWritable())       {
01554                                         return array(false, 'localconf.php is not writable!');
01555                                 }
01556                                 $newExtList = -1;
01557                                 switch($mode) {
01558                                         case EM_INSTALL_VERSION_STRICT:
01559                                                 if ($currentVersion == $version)        {
01560                                                         $newExtList = $this->addExtToList($extKey, $inst_list);
01561                                                 }
01562                                                 break;
01563                                         case EM_INSTALL_VERSION_MIN:
01564                                                 if (version_compare($currentVersion, $version, '>='))   {
01565                                                         $newExtList = $this->addExtToList($extKey, $inst_list);
01566                                                 }
01567                                                 break;
01568                                         case EM_INSTALL_VERSION_MAX:
01569                                                 if (version_compare($currentVersion, $version, '<='))   {
01570                                                         $newExtList = $this->addExtToList($extKey, $inst_list);
01571                                                 }
01572                                                 break;
01573                                 }
01574                                 if ($newExtList!=-1)    {
01575                                         $this->writeNewExtensionList($newExtList);
01576                                         $this->refreshGlobalExtList();
01577                                         $this->forceDBupdates($extKey, $inst_list[$extKey]);
01578                                         return array(true, 'Extension was already installed, it has been loaded.');
01579                                 }
01580                         }
01581                 }
01582 
01583                         // at this point we know we need to import (a matching version of) the extension from TER2
01584 
01585                         // see if we have an extensionlist at all
01586                 if (!$this->xmlhandler->countExtensions())      {
01587                         $this->fetchMetaData('extensions');
01588                 }
01589                 $this->xmlhandler->searchExtensionsXML($extKey, '', '', true);
01590 
01591                         // check if extension can be fetched
01592                 if(isset($this->xmlhandler->extensionsXML[$extKey])) {
01593                         $versions = array_keys($this->xmlhandler->extensionsXML[$extKey]['versions']);
01594                         $latestVersion = end($versions);
01595                         switch($mode) {
01596                                 case EM_INSTALL_VERSION_STRICT:
01597                                         if(!isset($this->xmlhandler->extensionsXML[$extKey]['versions'][$version])) {
01598                                                 return array(false, 'Extension not available in matching version');
01599                                         }
01600                                         break;
01601                                 case EM_INSTALL_VERSION_MIN:
01602                                         if (version_compare($latestVersion, $version, '>='))    {
01603                                                 $version = $latestVersion;
01604                                         } else {
01605                                                 return array(false, 'Extension not available in matching version');
01606                                         }
01607                                         break;
01608                                 case EM_INSTALL_VERSION_MAX:
01609                                         while (($v = array_pop($versions)) && version_compare($v, $version, '>='))      {
01610                                                 // Loop until a version is found
01611                                         }
01612 
01613                                         if ($v !== null && version_compare($v, $version, '<=')) {
01614                                                 $version = $v;
01615                                         } else {
01616                                                 return array(false, 'Extension not available in matching version');
01617                                         }
01618                                         break;
01619                         }
01620                         $this->importExtFromRep($extKey, $version, 'L');
01621                         $newExtList = $this->addExtToList($extKey, $inst_list);
01622                         if ($newExtList!=-1)    {
01623                                 $this->writeNewExtensionList($newExtList);
01624                                 $this->refreshGlobalExtList();
01625                                 $this->forceDBupdates($extKey, $inst_list[$extKey]);
01626                                 $this->installTranslationsForExtension($extKey, $this->getMirrorURL());
01627                                 return array(true, 'Extension has been imported from repository and loaded.');
01628                         } else {
01629                                 return array(false, 'Extension is in repository, but could not be loaded.');
01630                         }
01631                 } else {
01632                         return array(false, 'Extension not available in repository');
01633                 }
01634         }
01635 
01636         function refreshGlobalExtList() {
01637                 global $TYPO3_LOADED_EXT;
01638 
01639                 $TYPO3_LOADED_EXT = t3lib_extMgm::typo3_loadExtensions();
01640                 if ($TYPO3_LOADED_EXT['_CACHEFILE'])    {
01641                         require(PATH_typo3conf.$TYPO3_LOADED_EXT['_CACHEFILE'].'_ext_localconf.php');
01642                 }
01643                 return;
01644 
01645                 $GLOBALS['TYPO3_LOADED_EXT'] = t3lib_extMgm::typo3_loadExtensions();
01646                 if ($TYPO3_LOADED_EXT['_CACHEFILE'])    {
01647                         require(PATH_typo3conf.$TYPO3_LOADED_EXT['_CACHEFILE'].'_ext_localconf.php');
01648                 } else {
01649                         $temp_TYPO3_LOADED_EXT = $TYPO3_LOADED_EXT;
01650                         reset($temp_TYPO3_LOADED_EXT);
01651                         while(list($_EXTKEY,$temp_lEDat)=each($temp_TYPO3_LOADED_EXT))  {
01652                                 if (is_array($temp_lEDat) && $temp_lEDat['ext_localconf.php'])  {
01653                                         $_EXTCONF = $TYPO3_CONF_VARS['EXT']['extConf'][$_EXTKEY];
01654                                         require($temp_lEDat['ext_localconf.php']);
01655                                 }
01656                         }
01657                 }
01658         }
01659 
01660 
01673         function importExtFromRep($extKey,$version,$loc,$uploadFlag=0,$dontDelete=0,$directInput='')    {
01674 
01675                 $uploadSucceed = false;
01676                 $uploadedTempFile = '';
01677                 if (is_array($directInput))     {
01678                         $fetchData = array($directInput,'');
01679                         $loc = ($loc==='G'||$loc==='S') ? $loc : 'L';
01680                 } elseif ($uploadFlag)  {
01681                         if (($uploadedTempFile = $this->CMD['alreadyUploaded']) || $_FILES['upload_ext_file']['tmp_name'])      {
01682 
01683                                         // Read uploaded file:
01684                                 if (!$uploadedTempFile) {
01685                                         if (!is_uploaded_file($_FILES['upload_ext_file']['tmp_name'])) {
01686                                                 t3lib_div::sysLog('Possible file upload attack: '.$_FILES['upload_ext_file']['tmp_name'], 'Extension Manager', 3);
01687 
01688                                                 return 'File was not uploaded?!?';
01689                                         }
01690 
01691                                         $uploadedTempFile = t3lib_div::upload_to_tempfile($_FILES['upload_ext_file']['tmp_name']);
01692                                 }
01693                                 $fileContent = t3lib_div::getUrl($uploadedTempFile);
01694 
01695                                 if (!$fileContent)      return 'File is empty!';
01696 
01697                                         // Decode file data:
01698                                 $fetchData = $this->terConnection->decodeExchangeData($fileContent);
01699 
01700                                 if (is_array($fetchData))       {
01701                                         $extKey = $fetchData[0]['extKey'];
01702                                         if ($extKey)    {
01703                                                 if (!$this->CMD['uploadOverwrite'])     {
01704                                                         $loc = ($loc==='G'||$loc==='S') ? $loc : 'L';
01705                                                         $comingExtPath = PATH_site.$this->typePaths[$loc].$extKey.'/';
01706                                                         if (@is_dir($comingExtPath))    {
01707                                                                 return 'Extension was already present in "'.$comingExtPath.'" - and the overwrite flag was not set! So nothing done...';
01708                                                         }       // ... else go on, install...
01709                                                 }       // ... else go on, install...
01710                                         } else return 'No extension key in file. Strange...';
01711                                 } else return 'Wrong file format. No data recognized, '.$fetchData;
01712                         } else return 'No file uploaded! Probably the file was too large for PHPs internal limit for uploadable files.';
01713                 } else {
01714                         $this->xmlhandler->searchExtensionsXML($extKey, '', '', true);
01715 
01716                                 // Fetch extension from TER:
01717                         if(!strlen($version)) {
01718                                 $versions = array_keys($this->xmlhandler->extensionsXML[$extKey]['versions']);
01719                                 $version = end($versions);
01720                         }
01721                         $fetchData = $this->terConnection->fetchExtension($extKey, $version, $this->xmlhandler->extensionsXML[$extKey]['versions'][$version]['t3xfilemd5'], $this->getMirrorURL());
01722                 }
01723 
01724                 // At this point the extension data should be present; so we want to write it to disc:
01725                 if ($this->importAsType($loc))  {
01726                         if (is_array($fetchData))       {       // There was some data successfully transferred
01727                                 if ($fetchData[0]['extKey'] && is_array($fetchData[0]['FILES']))        {
01728                                         $extKey = $fetchData[0]['extKey'];
01729                                         if(!isset($fetchData[0]['EM_CONF']['constraints'])) $fetchData[0]['EM_CONF']['constraints'] = $this->xmlhandler->extensionsXML[$extKey]['versions'][$version]['dependencies'];
01730                                         $EM_CONF = $this->fixEMCONF($fetchData[0]['EM_CONF']);
01731                                         if (!$EM_CONF['lockType'] || !strcmp($EM_CONF['lockType'],$loc))        {
01732                                                         // check dependencies, act accordingly if ext is loaded
01733                                                 list($instExtInfo,)=$this->getInstalledExtensions();
01734                                                 $depStatus = $this->checkDependencies($extKey, $EM_CONF, $instExtInfo);
01735                                                 if(t3lib_extMgm::isLoaded($extKey) && !$depStatus['returnCode']) {
01736                                                         $this->content .= $depStatus['html'];
01737                                                         if ($uploadedTempFile)  {
01738                                                                 $this->content .= '<input type="hidden" name="CMD[alreadyUploaded]" value="'.$uploadedTempFile.'" />';
01739                                                         }
01740                                                 } else {
01741                                                         $res = $this->clearAndMakeExtensionDir($fetchData[0],$loc,$dontDelete);
01742                                                         if (is_array($res))     {
01743                                                                 $extDirPath = trim($res[0]);
01744                                                                 if ($extDirPath && @is_dir($extDirPath) && substr($extDirPath,-1)=='/') {
01745 
01746                                                                         $emConfFile = $this->construct_ext_emconf_file($extKey,$EM_CONF);
01747                                                                         $dirs = $this->extractDirsFromFileList(array_keys($fetchData[0]['FILES']));
01748 
01749                                                                         $res = $this->createDirsInPath($dirs,$extDirPath);
01750                                                                         if (!$res)      {
01751                                                                                 $writeFiles = $fetchData[0]['FILES'];
01752                                                                                 $writeFiles['ext_emconf.php']['content'] = $emConfFile;
01753                                                                                 $writeFiles['ext_emconf.php']['content_md5'] = md5($emConfFile);
01754 
01755                                                                                         // Write files:
01756                                                                                 foreach($writeFiles as $theFile => $fileData)   {
01757                                                                                         t3lib_div::writeFile($extDirPath.$theFile,$fileData['content']);
01758                                                                                         if (!@is_file($extDirPath.$theFile))    {
01759                                                                                                 $content.='Error: File "'.$extDirPath.$theFile.'" could not be created!!!<br />';
01760                                                                                         } elseif (md5(t3lib_div::getUrl($extDirPath.$theFile)) != $fileData['content_md5']) {
01761                                                                                                 $content.='Error: File "'.$extDirPath.$theFile.'" MD5 was different from the original files MD5 - so the file is corrupted!<br />';
01762                                                                                         }
01763                                                                                 }
01764 
01765                                                                                         // No content, no errors. Create success output here:
01766                                                                                 if (!$content)  {
01767                                                                                         $content='SUCCESS: '.$extDirPath.'<br />';
01768 
01769                                                                                         $uploadSucceed = true;
01770 
01771                                                                                                 // Fix TYPO3_MOD_PATH for backend modules in extension:
01772                                                                                         $modules = t3lib_div::trimExplode(',',$EM_CONF['module'],1);
01773                                                                                         if (count($modules))    {
01774                                                                                                 foreach($modules as $mD)        {
01775                                                                                                         $confFileName = $extDirPath.$mD.'/conf.php';
01776                                                                                                         if (@is_file($confFileName))    {
01777                                                                                                                 $content.= $this->writeTYPO3_MOD_PATH($confFileName,$loc,$extKey.'/'.$mD.'/').'<br />';
01778                                                                                                         } else $content.='Error: Couldn\'t find "'.$confFileName.'"<br />';
01779                                                                                                 }
01780                                                                                         }
01781                                                                                                 // 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.
01782                                                                                                 // But this order of the code works.... (using the empty Array with type, EMCONF and files hereunder).
01783 
01784                                                                                                 // Writing to ext_emconf.php:
01785                                                                                         $sEMD5A = $this->serverExtensionMD5Array($extKey,array('type' => $loc, 'EM_CONF' => array(), 'files' => array()));
01786                                                                                         $EM_CONF['_md5_values_when_last_written'] = serialize($sEMD5A);
01787                                                                                         $emConfFile = $this->construct_ext_emconf_file($extKey,$EM_CONF);
01788                                                                                         t3lib_div::writeFile($extDirPath.'ext_emconf.php',$emConfFile);
01789 
01790                                                                                         $content.='ext_emconf.php: '.$extDirPath.'ext_emconf.php<br />';
01791                                                                                         $content.='Type: '.$loc.'<br />';
01792 
01793                                                                                                 // Remove cache files:
01794                                                                                         if (t3lib_extMgm::isLoaded($extKey))    {
01795                                                                                                 if ($this->removeCacheFiles())  {
01796                                                                                                         $content.='Cache-files are removed and will be re-written upon next hit<br />';
01797                                                                                                 }
01798 
01799                                                                                                 list($new_list)=$this->getInstalledExtensions();
01800                                                                                                 $content.=$this->updatesForm($extKey,$new_list[$extKey],1,'index.php?CMD[showExt]='.$extKey.'&SET[singleDetails]=info');
01801                                                                                         }
01802 
01803                                                                                                 // Install / Uninstall:
01804                                                                                         if(!$this->CMD['standAlone']) {
01805                                                                                                 $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;
01806                                                                                                 $content.='<h3>Install / Uninstall Extension:</h3>';
01807                                                                                                 $content.= $new_list[$extKey] ?
01808                                                                                                         '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[remove]=1&CMD[clrCmd]=1&SET[singleDetails]=info').'">'.$this->removeButton().' Uninstall extension</a>' :
01809                                                                                                         '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[load]=1&CMD[clrCmd]=1&SET[singleDetails]=info').'">'.$this->installButton().' Install extension</a>';
01810                                                                                         } else {
01811                                                                                                 $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>';
01812                                                                                         }
01813 
01814                                                                                 }
01815                                                                         } else $content = $res;
01816                                                                 } else $content = 'Error: The extension path "'.$extDirPath.'" was different than expected...';
01817                                                         } else $content = $res;
01818                                                 }
01819                                         } else $content = 'Error: The extension can only be installed in the path '.$this->typePaths[$EM_CONF['lockType']].' (lockType='.$EM_CONF['lockType'].')';
01820                                 } else $content = 'Error: No extension key!!! Why? - nobody knows... (Or no files in the file-array...)';
01821                         }  else $content = 'Error: The datatransfer did not succeed. '.$fetchData;
01822                 }  else $content = 'Error: Installation is not allowed in this path ('.$this->typePaths[$loc].')';
01823 
01824                 $this->content.=$this->doc->section('Extension import results',$content,0,1);
01825 
01826                 if ($uploadSucceed && $uploadedTempFile)        {
01827                         t3lib_div::unlink_tempfile($uploadedTempFile);
01828                 }
01829 
01830                 return false;
01831         }
01832 
01839         function showExtDetails($extKey)        {
01840                 global $TYPO3_LOADED_EXT;
01841 
01842                 list($list,)=$this->getInstalledExtensions();
01843                 $absPath = $this->getExtPath($extKey,$list[$extKey]['type']);
01844 
01845                 // Check updateModule:
01846                 if (@is_file($absPath.'class.ext_update.php'))  {
01847                         require_once($absPath.'class.ext_update.php');
01848                         $updateObj = new ext_update;
01849                         if (!$updateObj->access())      {
01850                                 unset($this->MOD_MENU['singleDetails']['updateModule']);
01851                         }
01852                 } else {
01853                         unset($this->MOD_MENU['singleDetails']['updateModule']);
01854                 }
01855 
01856                 if($this->CMD['doDelete']) {
01857                         $this->MOD_MENU['singleDetails'] = array();
01858                 }
01859 
01860                         // Function menu here:
01861                 if(!$this->CMD['standAlone'] && !t3lib_div::_GP('standAlone')) {
01862                         $content = '
01863                                 <table border="0" cellpadding="0" cellspacing="0" width="100%">
01864                                         <tr>
01865                                                 <td nowrap="nowrap">Extension:&nbsp;<strong>'.$this->extensionTitleIconHeader($extKey,$list[$extKey]).'</strong> ('.$extKey.')</td>
01866                                                 <td align="right" nowrap="nowrap">'.
01867                         t3lib_BEfunc::getFuncMenu(0,'SET[singleDetails]',$this->MOD_SETTINGS['singleDetails'],$this->MOD_MENU['singleDetails'],'','&CMD[showExt]='.$extKey).' &nbsp; &nbsp; '.
01868                         '<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>
01869                                         </tr>
01870                                 </table>';
01871                         $this->content.=$this->doc->section('',$content);
01872                 }
01873 
01874                         // Show extension details:
01875                 if ($list[$extKey])     {
01876 
01877                                 // Checking if a command for install/uninstall is executed:
01878                         if (($this->CMD['remove'] || $this->CMD['load']) && !in_array($extKey,$this->requiredExt))      {
01879 
01880                                         // Install / Uninstall extension here:
01881                                 if (t3lib_extMgm::isLocalconfWritable())        {
01882                                                 // Check dependencies:
01883                                         $depStatus = $this->checkDependencies($extKey, $list[$extKey]['EM_CONF'], $list);
01884                                         if(!$this->CMD['remove'] && !$depStatus['returnCode']) {
01885                                                 $this->content .= $depStatus['html'];
01886                                                 $newExtList = -1;
01887                                         } elseif ($this->CMD['remove']) {
01888                                                 $newExtList = $this->removeExtFromList($extKey,$list);
01889                                         } else {
01890                                                 $newExtList = $this->addExtToList($extKey,$list);
01891                                         }
01892 
01893                                         // Success-installation:
01894                                         if ($newExtList!=-1)    {
01895                                                 $updates = '';
01896                                                 if ($this->CMD['load']) {
01897                                                         if($_SERVER['REQUEST_METHOD'] == 'POST') {
01898                                                                 $script = t3lib_div::linkThisScript(array('CMD[showExt]' => $extKey, 'CMD[load]' => 1, 'CMD[clrCmd]' => $this->CMD['clrCmd'], 'SET[singleDetails]' => 'info'));
01899                                                         } else {
01900                                                                 $script = '';
01901                                                         }
01902                                                         $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'].'" />');
01903                                                         if ($updates)   {
01904                                                                 $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;
01905                                                                 if($this->CMD['standAlone']) $updates .= '<input type="hidden" name="standAlone" value="1" />';
01906                                                                 $depsolver = t3lib_div::_POST('depsolver');
01907                                                                 if(is_array($depsolver['ignore'])) {
01908                                                                         foreach($depsolver['ignore'] as $depK => $depV) {
01909                                                                                 $updates .= '<input type="hidden" name="depsolver[ignore]['.$depK.']" value="1" />';
01910                                                                         }
01911                                                                 }
01912 
01913                                                                 $this->content.=$this->doc->section('Installing '.$this->extensionTitleIconHeader($extKey,$list[$extKey]).strtoupper(': Database needs to be updated'),$updates,1,1,1,1);
01914                                                         }
01915                                                 } elseif ($this->CMD['remove']) {
01916                                                         $updates.= $this->checkClearCache($list[$extKey]);
01917                                                         if ($updates)   {
01918                                                                 $updates = '
01919                                                                 </form><form action="'.t3lib_div::linkThisScript().'" method="post">'.$updates.'
01920                                                                 <br /><input type="submit" name="write" value="Remove extension" />
01921                                                                 <input type="hidden" name="_do_install" value="1" />
01922                                                                 <input type="hidden" name="_clrCmd" value="'.$this->CMD['clrCmd'].'" />
01923                                                                 <input type="hidden" name="standAlone" value="'.$this->CMD['standAlone'].'" />
01924                                                                 ';
01925                                                                 $this->content.=$this->doc->section('Removing '.$this->extensionTitleIconHeader($extKey,$list[$extKey]).strtoupper(': Database needs to be updated'),$updates,1,1,1,1);
01926                                                         }
01927                                                 }
01928                                                 if (!$updates || t3lib_div::_GP('_do_install')) {
01929                                                         $this->writeNewExtensionList($newExtList);
01930                                                         $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')));
01931                                                         if ($this->CMD['clrCmd'] || t3lib_div::_GP('_clrCmd'))  {
01932                                                                 $vA = array('CMD'=>'');
01933                                                         } else {
01934                                                                 $vA = array('CMD'=>Array('showExt'=>$extKey));
01935                                                         }
01936                                                         if($this->CMD['standAlone'] || t3lib_div::_GP('standAlone')) {
01937                                                                 $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>';
01938                                                         } else {
01939                                                                 header('Location: '.t3lib_div::linkThisScript($vA));
01940                                                         }
01941                                                 }
01942                                         }
01943                                 } else {
01944                                         $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);
01945                                 }
01946 
01947                         } elseif ($this->CMD['downloadFile'] && !in_array($extKey,$this->requiredExt))  {
01948 
01949                                 // Link for downloading extension has been clicked - deliver content stream:
01950                                 $dlFile = $this->CMD['downloadFile'];
01951                                 if (t3lib_div::isFirstPartOfStr($dlFile,PATH_site) && t3lib_div::isFirstPartOfStr($dlFile,$absPath) && @is_file($dlFile))       {
01952                                         $mimeType = 'application/octet-stream';
01953                                         Header('Content-Type: '.$mimeType);
01954                                         Header('Content-Disposition: attachment; filename='.basename($dlFile));
01955                                         echo t3lib_div::getUrl($dlFile);
01956                                         exit;
01957                                 } else die('Error while trying to download extension file...');
01958 
01959                         } elseif ($this->CMD['editFile'] && !in_array($extKey,$this->requiredExt))      {
01960 
01961                                 // Editing extension file:
01962                                 $editFile = $this->CMD['editFile'];
01963                                 if (t3lib_div::isFirstPartOfStr($editFile,PATH_site) && t3lib_div::isFirstPartOfStr($editFile,$absPath))        {       // Paranoia...
01964 
01965                                         $fI = t3lib_div::split_fileref($editFile);
01966                                         if (@is_file($editFile) && t3lib_div::inList($this->editTextExtensions,($fI['fileext']?$fI['fileext']:$fI['filebody'])))        {
01967                                                 if (filesize($editFile)<($this->kbMax*1024))    {
01968                                                         $outCode = '';
01969                                                         $info = '';
01970                                                         $submittedContent = t3lib_div::_POST('edit');
01971                                                         $saveFlag = 0;
01972 
01973                                                         if(isset($submittedContent['file']) && !$GLOBALS['TYPO3_CONF_VARS']['EXT']['noEdit'])   {               // Check referer here?
01974                                                                 $oldFileContent = t3lib_div::getUrl($editFile);
01975                                                                 if($oldFileContent != $submittedContent['file']) {
01976                                                                         $oldMD5 = md5(str_replace(chr(13),'',$oldFileContent));
01977                                                                         $info.= 'MD5: <b>'.$oldMD5.'</b> (Previous File)<br />';
01978                                                                         t3lib_div::writeFile($editFile,$submittedContent['file']);
01979                                                                         $saveFlag = 1;
01980                                                                 } else {
01981                                                                         $info .= 'No changes to the file detected!<br />';
01982                                                                 }
01983                                                         }
01984 
01985                                                         $fileContent = t3lib_div::getUrl($editFile);
01986 
01987                                                         $outCode.= 'File: <b>'.substr($editFile,strlen($absPath)).'</b> ('.t3lib_div::formatSize(filesize($editFile)).')<br />';
01988                                                         $fileMD5 = md5(str_replace(chr(13),'',$fileContent));
01989                                                         $info.= 'MD5: <b>'.$fileMD5.'</b> (Current File)<br />';
01990                                                         if($saveFlag)   {
01991                                                                 $saveMD5 = md5(str_replace(chr(13),'',$submittedContent['file']));
01992                                                                 $info.= 'MD5: <b>'.$saveMD5.'</b> (Submitted)<br />';
01993                                                                 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 />';
01994                                                                 else $info.= $GLOBALS['TBE_TEMPLATE']->rfw('<br /><strong>File saved.</strong>').'<br />';
01995                                                         }
01996 
01997                                                         $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>';
01998                                                         $outCode.= '<input type="hidden" name="edit[filename]" value="'.$editFile.'" />';
01999                                                         $outCode.= '<input type="hidden" name="CMD[editFile]" value="'.htmlspecialchars($editFile).'" />';
02000                                                         $outCode.= '<input type="hidden" name="CMD[showExt]" value="'.$extKey.'" />';
02001                                                         $outCode.= $info;
02002 
02003                                                         if (!$GLOBALS['TYPO3_CONF_VARS']['EXT']['noEdit'])      {
02004                                                                 $outCode.='<br /><input type="submit" name="save_file" value="Save file" />';
02005                                                         } else $outCode.=$GLOBALS['TBE_TEMPLATE']->rfw('<br />[SAVING IS DISABLED - can be enabled by the $TYPO3_CONF_VARS[\'EXT\'][\'noEdit\']-flag] ');
02006 
02007                                                         $onClick = 'window.location.href=\'index.php?CMD[showExt]='.$extKey.'\';return false;';
02008                                                         $outCode.='<input type="submit" name="cancel" value="Cancel" onclick="'.htmlspecialchars($onClick).'" />';
02009 
02010                                                         $theOutput.=$this->doc->spacer(15);
02011                                                         $theOutput.=$this->doc->section('Edit file:','',0,1);
02012                                                         $theOutput.=$this->doc->sectionEnd().$outCode;
02013                                                         $this->content.=$theOutput;
02014                                                 } else {
02015                                                         $theOutput.=$this->doc->spacer(15);
02016                                                         $theOutput.=$this->doc->section('Filesize exceeded '.$this->kbMax.' Kbytes','Files larger than '.$this->kbMax.' KBytes are not allowed to be edited.');
02017                                                 }
02018                                         }
02019                                 } else die('Fatal Edit error: File "'.$editFile.'" was not inside the correct path of the TYPO3 Extension!');
02020                         } else {
02021 
02022                                 // MAIN:
02023                                 switch((string)$this->MOD_SETTINGS['singleDetails'])    {
02024                                         case 'info':
02025                                                 // Loaded / Not loaded:
02026                                                 if (!in_array($extKey,$this->requiredExt))      {
02027                                                         if ($TYPO3_LOADED_EXT[$extKey]) {
02028                                                                 $content = '<strong>The extension is installed (loaded and running)!</strong><br />'.
02029                                                                 '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[remove]=1').'">Click here to remove the extension: '.$this->removeButton().'</a>';
02030                                                         } else {
02031                                                                 $content = 'The extension is <strong>not</strong> installed yet.<br />'.
02032                                                                 '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[load]=1').'">Click here to install the extension: '.$this->installButton().'</a>';
02033                                                         }
02034                                                 } else {
02035                                                         $content = 'This extension is entered in the TYPO3_CONF_VARS[SYS][requiredExt] list and is therefore always loaded.';
02036                                                 }
02037                                                 $this->content.=$this->doc->spacer(10);
02038                                                 $this->content.=$this->doc->section('Active status:',$content,0,1);
02039 
02040                                                 if (t3lib_extMgm::isLoaded($extKey))    {
02041                                                         $updates=$this->updatesForm($extKey,$list[$extKey]);
02042                                                         if ($updates)   {
02043                                                                 $this->content.=$this->doc->spacer(10);
02044                                                                 $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);
02045                                                         }
02046                                                 }
02047 
02048                                                 // Config:
02049                                                 if (@is_file($absPath.'ext_conf_template.txt')) {
02050                                                         $this->content.=$this->doc->spacer(10);
02051                                                         $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);
02052                                                         $this->tsStyleConfigForm($extKey,$list[$extKey]);
02053                                                 }
02054 
02055                                                 // Show details:
02056                                                 $content = t3lib_BEfunc::cshItem('_MOD_tools_em', 'info', $GLOBALS['BACK_PATH'],'|<br/>');
02057                                                 $content.= $this->extInformationArray($extKey,$list[$extKey]);
02058 
02059                                                 $this->content.=$this->doc->spacer(10);
02060                                                 $this->content.=$this->doc->section('Details:',$content,0,1);
02061                                                 break;
02062                                         case 'upload':
02063                                                 $em = t3lib_div::_POST('em');
02064                                                 if($em['action'] == 'doUpload') {
02065                                                         $em['extKey'] = $extKey;
02066                                                         $em['extInfo'] = $list[$extKey];
02067                                                         $content = $this->uploadExtensionToTER($em);
02068                                                         $content .= $this->doc->spacer(10);
02069                                                                 // Must reload this, because EM_CONF information has been updated!
02070                                                         list($list,)=$this->getInstalledExtensions();
02071                                                 } else {
02072                                                                 // CSH:
02073                                                         $content = t3lib_BEfunc::cshItem('_MOD_tools_em', 'upload', $GLOBALS['BACK_PATH'],'|<br/>');
02074 
02075                                                                 // Upload:
02076                                                         if (substr($extKey,0,5)!='user_')       {
02077                                                                 $content.= $this->getRepositoryUploadForm($extKey,$list[$extKey]);
02078                                                                 $eC=0;
02079                                                         } else {
02080                                                                 $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.';
02081                                                                 $eC=2;
02082                                                         }
02083                                                         if (!$this->fe_user['username'])        {
02084                                                                 $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 />';
02085                                                         }
02086                                                 }
02087                                                 $this->content.=$this->doc->section('Upload extension to repository',$content,0,1,$eC);
02088                                                 break;
02089                                         case 'backup':
02090                                                 if($this->CMD['doDelete']) {
02091                                                         $content = $this->extDelete($extKey,$list[$extKey]);
02092                                                         $this->content.=$this->doc->section('Delete',$content,0,1);
02093                                                 } else {
02094                                                         $content = t3lib_BEfunc::cshItem('_MOD_tools_em', 'backup_delete', $GLOBALS['BACK_PATH'],'|<br/>');
02095                                                         $content.= $this->extBackup($extKey,$list[$extKey]);
02096                                                         $this->content.=$this->doc->section('Backup',$content,0,1);
02097 
02098                                                         $content = $this->extDelete($extKey,$list[$extKey]);
02099                                                         $this->content.=$this->doc->section('Delete',$content,0,1);
02100 
02101                                                         $content = $this->extUpdateEMCONF($extKey,$list[$extKey]);
02102                                                         $this->content.=$this->doc->section('Update EM_CONF',$content,0,1);
02103                                                 }
02104                                                 break;
02105                                         case 'dump':
02106                                                 $this->extDumpTables($extKey,$list[$extKey]);
02107                                                 break;
02108                                         case 'edit':
02109                                                 $content = t3lib_BEfunc::cshItem('_MOD_tools_em', 'editfiles', $GLOBALS['BACK_PATH'],'|<br/>');
02110                                                 $content.= $this->getFileListOfExtension($extKey,$list[$extKey]);
02111 
02112                                                 $this->content.=$this->doc->section('Extension files',$content,0,1);
02113                                                 break;
02114                                         case 'updateModule':
02115                                                 $this->content.=$this->doc->section('Update:',is_object($updateObj) ? $updateObj->main() : 'No update object',0,1);
02116                                                 break;
02117                                         default:
02118                                                 $this->extObjContent();
02119                                                 break;
02120                                 }
02121                         }
02122                 }
02123         }
02124 
02132         function requestInstallExtensions($extList)     {
02133 
02134                         // Return URL:
02135                 $returnUrl = t3lib_div::_GP('returnUrl');
02136                 $installOrImportExtension = t3lib_div::_POST('installOrImportExtension');
02137 
02138                         // Extension List:
02139                 $extArray = explode(',',$extList);
02140                 $outputRow = array();
02141                 $outputRow[] = '
02142                         <tr class="bgColor5 tableheader">
02143                                 <td>Install/Import:</td>
02144                                 <td>Extension Key:</td>
02145                         </tr>
02146                 ';
02147 
02148                 foreach($extArray as $extKey)   {
02149 
02150                                 // Check for the request:
02151                         if ($installOrImportExtension[$extKey]) {
02152                                 $this->installExtension($extKey);
02153                         }
02154 
02155                                 // Display:
02156                         if (!t3lib_extMgm::isLoaded($extKey))   {
02157                                 $outputRow[] = '
02158                                 <tr class="bgColor4">
02159                                         <td><input type="checkbox" name="'.htmlspecialchars('installOrImportExtension['.$extKey.']').'" value="1" checked="checked" id="check_'.$extKey.'" /></td>
02160                                         <td><label for="check_'.$extKey.'">'.htmlspecialchars($extKey).'</label></td>
02161                                 </tr>
02162                                 ';
02163                         }
02164                 }
02165 
02166                 if (count($outputRow)>1 || !$returnUrl) {
02167                         $content = '
02168                         </form> <!-- ending page form ... -->
02169                         <form action="'.htmlspecialchars(t3lib_div::getIndpEnv('REQUEST_URI')).'" method="post">
02170                                 <table border="0" cellpadding="1" cellspacing="1">'.implode('',$outputRow).'</table>
02171                         <input type="submit" name="_" value="Import and Install selected" />
02172                         </form>
02173                         <form>  <!-- continuing page form... -->';
02174 
02175                         if ($returnUrl) {
02176                                 $content.= '
02177                                 <br/>
02178                                 <br/>
02179                                 <a href="'.htmlspecialchars($returnUrl).'">Return</a>
02180                                 ';
02181                         }
02182 
02183                         $this->content.= $this->doc->section('Import/Install Extensions:',$content,0,1);
02184                 } else {
02185                         header('Location: '.t3lib_div::locationHeaderUrl($returnUrl));
02186                 }
02187         }
02188 
02189 
02190 
02191 
02192 
02193 
02194 
02195 
02196         /***********************************
02197         *
02198         * Application Sub-functions (HTML parts)
02199         *
02200         **********************************/
02201 
02213         function updatesForm($extKey,$extInfo,$notSilent=0,$script='',$addFields='')    {
02214                 $script = $script ? $script : t3lib_div::linkThisScript();
02215                 $updates.= $this->checkDBupdates($extKey,$extInfo);
02216                 $uCache = $this->checkClearCache($extInfo);
02217                 if ($notSilent) $updates.= $uCache;
02218                 $updates.= $this->checkUploadFolder($extKey,$extInfo);
02219 
02220                 $absPath = $this->getExtPath($extKey,$extInfo['type']);
02221                 if ($notSilent && @is_file($absPath.'ext_conf_template.txt'))   {
02222                         $cForm = $this->tsStyleConfigForm($extKey,$extInfo,1,$script,$updates.$addFields.'<br />');
02223                 }
02224 
02225                 if ($updates || $cForm) {
02226                         if ($cForm)     {
02227                                 $updates = '</form>'.$cForm.'<form>';
02228                         } else {
02229                                 $updates = '</form><form action="'.htmlspecialchars($script).'" method="post">'.$updates.$addFields.'
02230                                         <br /><input type="submit" name="write" value="Make updates" />
02231                                 ';
02232                         }
02233                 }
02234                 return $updates;
02235         }
02236 
02244         function extDumpTables($extKey,$extInfo)        {
02245 
02246                 // Get dbInfo which holds the structure known from the tables.sql file
02247                 $techInfo = $this->makeDetailedExtensionAnalysis($extKey,$extInfo);
02248                 $absPath = $this->getExtPath($extKey,$extInfo['type']);
02249 
02250                 // Static tables:
02251                 if (is_array($techInfo['static']))      {
02252                         if ($this->CMD['writeSTATICdump'])      {       // Writing static dump:
02253                                 $writeFile = $absPath.'ext_tables_static+adt.sql';
02254                                 if (@is_file($writeFile))       {
02255                                         $dump_static = $this->dumpStaticTables(implode(',',$techInfo['static']));
02256                                         t3lib_div::writeFile($writeFile,$dump_static);
02257                                         $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);
02258                                 }
02259                         } else {        // Showing info about what tables to dump - and giving the link to execute it.
02260                                 $msg = 'Dumping table content for static tables:<br />';
02261                                 $msg.= '<br />'.implode('<br />',$techInfo['static']).'<br />';
02262 
02263                                 // ... then feed that to this function which will make new CREATE statements of the same fields but based on the current database content.
02264                                 $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);
02265                                 $this->content.=$this->doc->spacer(20);
02266                         }
02267                 }
02268 
02269                 // Table and field definitions:
02270                 if (is_array($techInfo['dump_tf']))     {
02271                         $dump_tf_array = $this->getTableAndFieldStructure($techInfo['dump_tf']);
02272                         $dump_tf = $this->dumpTableAndFieldStructure($dump_tf_array);
02273                         if ($this->CMD['writeTFdump'])  {
02274                                 $writeFile = $absPath.'ext_tables.sql';
02275                                 if (@is_file($writeFile))       {
02276                                         t3lib_div::writeFile($writeFile,$dump_tf);
02277                                         $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);
02278                                 }
02279                         } else {
02280                                 $msg = 'Dumping current database structure for:<br />';
02281                                 if (is_array($techInfo['tables']))      {
02282                                         $msg.= '<br /><strong>Tables:</strong><br />'.implode('<br />',$techInfo['tables']).'<br />';
02283                                 }
02284                                 if (is_array($techInfo['fields']))      {
02285                                         $msg.= '<br /><strong>Solo-fields:</strong><br />'.implode('<br />',$techInfo['fields']).'<br />';
02286                                 }
02287 
02288                                 // ... then feed that to this function which will make new CREATE statements of the same fields but based on the current database content.
02289                                 $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 />
02290                                 <pre>'.htmlspecialchars($dump_tf).'</pre>',0,1);
02291 
02292 
02293                                 $details = '                                                    This dump is based on two factors:<br />
02294                                 <ul>
02295                                 <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>
02296                                 <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>
02297                                 </ul>
02298                                 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 />';
02299                                 $this->content.=$this->doc->section('',$details);
02300                         }
02301                 }
02302         }
02303 
02311         function getFileListOfExtension($extKey,$conf)  {
02312                 $content = '';
02313                 $extPath = $this->getExtPath($extKey,$conf['type']);
02314 
02315                 if ($extPath)   {
02316                         // Read files:
02317                         $fileArr = array();
02318                         $fileArr = t3lib_div::getAllFilesAndFoldersInPath($fileArr,$extPath,'',0,99,$this->excludeForPackaging);
02319 
02320                         // Start table:
02321                         $lines = array();
02322                         $totalSize = 0;
02323 
02324                         // Header:
02325                         $lines[] = '
02326                                 <tr class="bgColor5">
02327                                         <td>File:</td>
02328                                         <td>Size:</td>
02329                                         <td>Edit:</td>
02330                                 </tr>';
02331 
02332                         foreach($fileArr as $file)      {
02333                                 $fI = t3lib_div::split_fileref($file);
02334                                 $lines[] = '
02335                                 <tr class="bgColor4">
02336                                         <td><a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[downloadFile]='.rawurlencode($file)).'" title="Download...">'.substr($file,strlen($extPath)).'</a></td>
02337                                         <td>'.t3lib_div::formatSize(filesize($file)).'</td>
02338                                         <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>
02339                                 </tr>';
02340                                 $totalSize+=filesize($file);
02341                         }
02342 
02343                         $lines[] = '
02344                                 <tr class="bgColor6">
02345                                         <td><strong>Total:</strong></td>
02346                                         <td><strong>'.t3lib_div::formatSize($totalSize).'</strong></td>
02347                                         <td>&nbsp;</td>
02348                                 </tr>';
02349 
02350                         $content = '
02351                         Path: '.$extPath.'<br /><br />
02352                         <table border="0" cellpadding="1" cellspacing="2">'.implode('',$lines).'</table>';
02353                 }
02354 
02355                 return $content;
02356         }
02357 
02365         function extDelete($extKey,$extInfo)    {
02366                 $absPath = $this->getExtPath($extKey,$extInfo['type']);
02367                 if (t3lib_extMgm::isLoaded($extKey))    {
02368                         return 'This extension is currently installed (loaded and active) and so cannot be deleted!';
02369                 } elseif (!$this->deleteAsType($extInfo['type'])) {
02370                         return 'You cannot delete (and install/update) extensions in the '.$this->typeLabels[$extInfo['type']].' scope.';
02371                 } elseif (t3lib_div::inList('G,L',$extInfo['type'])) {
02372                         if ($this->CMD['doDelete'] && !strcmp($absPath,$this->CMD['absPath'])) {
02373                                 $res = $this->removeExtDirectory($absPath);
02374                                 if ($res) {
02375                                         return 'ERROR: Could not remove extension directory "'.$absPath.'". Had the following errors:<br /><br />'.
02376                                         nl2br($res);
02377                                 } else {
02378                                         return 'Removed extension in path "'.$absPath.'"!';
02379                                 }
02380                         } else {
02381                                 $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)."';}";
02382                                 $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>';
02383                                 $content.= '<br /><br />(Maybe you should make a backup first, see above.)';
02384                                 return $content;
02385                         }
02386                 } else return 'Extension is not a global or local extension and cannot be removed.';
02387         }
02388 
02396         function extUpdateEMCONF($extKey,$extInfo)      {
02397                 $absPath = $this->getExtPath($extKey,$extInfo['type']);
02398                 if ($this->CMD['doUpdateEMCONF']) {
02399                         return $this->updateLocalEM_CONF($extKey,$extInfo);
02400                 } else {
02401                         $onClick = "if (confirm('Are you sure you want to update EM_CONF?')) {window.location.href='index.php?CMD[showExt]=".$extKey."&CMD[doUpdateEMCONF]=1';}";
02402                         $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>';
02403                         $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 />
02404                                                 Updating this file will first of all reset this registration.';
02405                         return $content;
02406                 }
02407         }
02408 
02416         function extBackup($extKey,$extInfo)    {
02417                 $uArr = $this->makeUploadArray($extKey,$extInfo);
02418                 if (is_array($uArr))    {
02419                         $backUpData = $this->terConnection->makeUploadDataFromArray($uArr);
02420                         $filename = 'T3X_'.$extKey.'-'.str_replace('.','_',$extInfo['EM_CONF']['version']).'-z-'.date('YmdHi').'.t3x';
02421                         if (intval($this->CMD['doBackup'])==1)  {
02422                                 header('Content-Type: application/octet-stream');
02423                                 header('Content-Disposition: attachment; filename='.$filename);
02424                                 echo $backUpData;
02425                                 exit;
02426                         } elseif ($this->CMD['dumpTables'])     {
02427                                 $filename='T3X_'.$extKey;
02428                                 $cTables = count(explode(',',$this->CMD['dumpTables']));
02429                                 if ($cTables>1) {
02430                                         $filename.='-'.$cTables.'tables';
02431                                 } else {
02432                                         $filename.='-'.$this->CMD['dumpTables'];
02433                                 }
02434                                 $filename.='+adt.sql';
02435 
02436                                 header('Content-Type: application/octet-stream');
02437                                 header('Content-Disposition: attachment; filename='.$filename);
02438                                 echo $this->dumpStaticTables($this->CMD['dumpTables']);
02439                                 exit;
02440                         } else {
02441                                 $techInfo = $this->makeDetailedExtensionAnalysis($extKey,$extInfo);
02442                                 $lines=array();
02443                                 $lines[]='<tr class="bgColor5"><td colspan="2"><strong>Make selection:</strong></td></tr>';
02444                                 $lines[]='<tr class="bgColor4"><td><strong>Extension files:</strong></td><td>'.
02445                                 '<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>';
02446 
02447                                 if (is_array($techInfo['tables']))      {       $lines[]='<tr class="bgColor4"><td><strong>Data tables:</strong></td><td>'.$this->extBackup_dumpDataTablesLine($techInfo['tables'],$extKey).'</td></tr>';       }
02448                                 if (is_array($techInfo['static']))      {       $lines[]='<tr class="bgColor4"><td><strong>Static tables:</strong></td><td>'.$this->extBackup_dumpDataTablesLine($techInfo['static'],$extKey).'</td></tr>';     }
02449 
02450                                 $content = '<table border="0" cellpadding="2" cellspacing="2">'.implode('',$lines).'</table>';
02451                                 return $content;
02452                         }
02453                 } else die('Error...');
02454         }
02455 
02463         function extBackup_dumpDataTablesLine($tablesArray,$extKey)     {
02464                 $tables = array();
02465                 $tablesNA = array();
02466 
02467                 foreach($tablesArray as $tN)    {
02468                         $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('count(*)', $tN, '');
02469                         if (!$GLOBALS['TYPO3_DB']->sql_error()) {
02470                                 $row = $GLOBALS['TYPO3_DB']->sql_fetch_row($res);
02471                                 $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>';
02472                         } else {
02473                                 $tablesNA[$tN]='<tr><td>&nbsp;</td><td>'.$tN.'</td><td>&nbsp;</td><td>Did not exist.</td></tr>';
02474                         }
02475                 }
02476                 $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...
02477                 if (count($tables))     {
02478                         $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;
02479                 } else $label = 'Nothing to dump...<br /><br />'.$label;
02480                 return $label;
02481         }
02482 
02491         function extInformationArray($extKey,$extInfo,$remote=0)        {
02492                 $lines=array();
02493                 $lines[]='<tr class="bgColor5"><td colspan="2"><strong>General information:</strong></td>'.$this->helpCol('').'</tr>';
02494                 $lines[]='<tr class="bgColor4"><td>Title:</td><td>'.$extInfo['EM_CONF']['_icon'].$extInfo['EM_CONF']['title'].'</td>'.$this->helpCol('title').'</tr>';
02495                 $lines[]='<tr class="bgColor4"><td>Description:</td><td>'.nl2br(htmlspecialchars($extInfo['EM_CONF']['description'])).'</td>'.$this->helpCol('description').'</tr>';
02496                 $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']:'').
02497                 '</td>'.$this->helpCol('description').'</tr>';
02498 
02499                 $lines[]='<tr class="bgColor4"><td>Version:</td><td>'.$extInfo['EM_CONF']['version'].'</td>'.$this->helpCol('version').'</tr>';
02500                 $lines[]='<tr class="bgColor4"><td>Category:</td><td>'.$this->categories[$extInfo['EM_CONF']['category']].'</td>'.$this->helpCol('category').'</tr>';
02501                 $lines[]='<tr class="bgColor4"><td>State:</td><td>'.$this->states[$extInfo['EM_CONF']['state']].'</td>'.$this->helpCol('state').'</tr>';
02502                 $lines[]='<tr class="bgColor4"><td>Shy?</td><td>'.($extInfo['EM_CONF']['shy']?'Yes':'').'</td>'.$this->helpCol('shy').'</tr>';
02503                 $lines[]='<tr class="bgColor4"><td>Internal?</td><td>'.($extInfo['EM_CONF']['internal']?'Yes':'').'</td>'.$this->helpCol('internal').'</tr>';
02504 
02505                 $lines[]='<tr class="bgColor4"><td>Depends on:</td><td>'.$this->depToString($extInfo['EM_CONF']['constraints']).'</td>'.$this->helpCol('dependencies').'</tr>';
02506                 $lines[]='<tr class="bgColor4"><td>Conflicts with:</td><td>'.$this->depToString($extInfo['EM_CONF']['constraints'],'conflicts').'</td>'.$this->helpCol('dependencies').'</tr>';
02507                 $lines[]='<tr class="bgColor4"><td>Suggests:</td><td>'.$this->depToString($extInfo['EM_CONF']['constraints'],'suggests').'</td>'.$this->helpCol('dependencies').'</tr>';
02508                 if (!$remote)   {
02509                         $lines[]='<tr class="bgColor4"><td>Priority:</td><td>'.$extInfo['EM_CONF']['priority'].'</td>'.$this->helpCol('priority').'</tr>';
02510                         $lines[]='<tr class="bgColor4"><td>Clear cache?</td><td>'.($extInfo['EM_CONF']['clearCacheOnLoad']?'Yes':'').'</td>'.$this->helpCol('clearCacheOnLoad').'</tr>';
02511                         $lines[]='<tr class="bgColor4"><td>Includes modules:</td><td>'.$extInfo['EM_CONF']['module'].'</td>'.$this->helpCol('module').'</tr>';
02512                         $lines[]='<tr class="bgColor4"><td>Lock Type?</td><td>'.($extInfo['EM_CONF']['lockType']?$extInfo['EM_CONF']['lockType']:'').'</td>'.$this->helpCol('lockType').'</tr>';
02513                         $lines[]='<tr class="bgColor4"><td>Modifies tables:</td><td>'.$extInfo['EM_CONF']['modify_tables'].'</td>'.$this->helpCol('modify_tables').'</tr>';
02514 
02515                         // Installation status:
02516                         $techInfo = $this->makeDetailedExtensionAnalysis($extKey,$extInfo,1);
02517                         $lines[]='<tr><td>&nbsp;</td><td></td>'.$this->helpCol('').'</tr>';
02518                         $lines[]='<tr class="bgColor5"><td colspan="2"><strong>Installation status:</strong></td>'.$this->helpCol('').'</tr>';
02519                         $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>';
02520                         $lines[]='<tr class="bgColor4"><td>Double installs?</td><td>'.$this->extInformationArray_dbInst($extInfo['doubleInstall'],$extInfo['type']).'</td>'.$this->helpCol('doubleInstall').'</tr>';
02521                         if (is_array($extInfo['files']))        {
02522                                 sort($extInfo['files']);
02523                                 $lines[]='<tr class="bgColor4"><td>Root files:</td><td>'.implode('<br />',$extInfo['files']).'</td>'.$this->helpCol('rootfiles').'</tr>';
02524                         }
02525 
02526                         if ($techInfo['tables']||$techInfo['static']||$techInfo['fields'])      {
02527                                 if (!$remote && t3lib_extMgm::isLoaded($extKey))        {
02528                                         $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!':'').
02529                                         ($techInfo['static_error']?'<strong>Static table error!</strong><br />The static tables are missing or empty!':''));
02530                                 } else {
02531                                         $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!';
02532                                 }
02533                         }
02534 
02535                         $lines[]='<tr class="bgColor4"><td>Database requirements:</td><td>'.$this->extInformationArray_dbReq($techInfo,1).'</td>'.$this->helpCol('dbReq').'</tr>';
02536                         $lines[]='<tr class="bgColor4"><td>Database status:</td><td>'.$tableStatus.'</td>'.$this->helpCol('dbStatus').'</tr>';
02537                         $lines[]='<tr class="bgColor4"><td>Flags:</td><td>'.(is_array($techInfo['flags'])?implode('<br />',$techInfo['flags']):'').'</td>'.$this->helpCol('flags').'</tr>';
02538                         $lines[]='<tr class="bgColor4"><td>Config template?</td><td>'.($techInfo['conf']?'Yes':'').'</td>'.$this->helpCol('conf').'</tr>';
02539                         $lines[]='<tr class="bgColor4"><td>TypoScript files:</td><td>'.(is_array($techInfo['TSfiles'])?implode('<br />',$techInfo['TSfiles']):'').'</td>'.$this->helpCol('TSfiles').'</tr>';
02540                         $lines[]='<tr class="bgColor4"><td>Language files:</td><td>'.(is_array($techInfo['locallang'])?implode('<br />',$techInfo['locallang']):'').'</td>'.$this->helpCol('locallang').'</tr>';
02541                         $lines[]='<tr class="bgColor4"><td>Upload folder:</td><td>'.($techInfo['uploadfolder']?$techInfo['uploadfolder']:'').'</td>'.$this->helpCol('uploadfolder').'</tr>';
02542                         $lines[]='<tr class="bgColor4"><td>Create directories:</td><td>'.(is_array($techInfo['createDirs'])?implode('<br />',$techInfo['createDirs']):'').'</td>'.$this->helpCol('createDirs').'</tr>';
02543                         $lines[]='<tr class="bgColor4"><td>Module names:</td><td>'.(is_array($techInfo['moduleNames'])?implode('<br />',$techInfo['moduleNames']):'').'</td>'.$this->helpCol('moduleNames').'</tr>';
02544                         $lines[]='<tr class="bgColor4"><td>Class names:</td><td>'.(is_array($techInfo['classes'])?implode('<br />',$techInfo['classes']):'').'</td>'.$this->helpCol('classNames').'</tr>';
02545                         $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>';
02546                         $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>';
02547 
02548                         $currentMd5Array = $this->serverExtensionMD5Array($extKey,$extInfo);
02549                         $affectedFiles='';
02550 
02551                         $msgLines=array();
02552                         if (strcmp($extInfo['EM_CONF']['_md5_values_when_last_written'],serialize($currentMd5Array)))   {
02553                                 $msgLines[] = $GLOBALS['TBE_TEMPLATE']->rfw('<br /><strong>A difference between the originally installed version and the current was detected!</strong>');
02554                                 $affectedFiles = $this->findMD5ArrayDiff($currentMd5Array,unserialize($extInfo['EM_CONF']['_md5_values_when_last_written']));
02555                                 if (count($affectedFiles))      $msgLines[] = '<br /><strong>Modified files:</strong><br />'.$GLOBALS['TBE_TEMPLATE']->rfw(implode('<br />',$affectedFiles));
02556                         }
02557                         $lines[]='<tr class="bgColor4"><td>Files changed?</td><td>'.implode('<br />',$msgLines).'</td>'.$this->helpCol('filesChanged').'</tr>';
02558                 }
02559 
02560                 return '<table border="0" cellpadding="1" cellspacing="2">
02561                                         '.implode('
02562                                         ',$lines).'
02563                                 </table>';
02564         }
02565 
02573         function extInformationArray_dbReq($techInfo,$tableHeader=0)    {
02574                 return nl2br(trim((is_array($techInfo['tables'])?($tableHeader?"\n\n<strong>Tables:</strong>\n":'').implode(chr(10),$techInfo['tables']):'').
02575                 (is_array($techInfo['static'])?"\n\n<strong>Static tables:</strong>\n".implode(chr(10),$techInfo['static']):'').
02576                 (is_array($techInfo['fields'])?"\n\n<strong>Additional fields:</strong>\n".implode('<hr />',$techInfo['fields']):'')));
02577         }
02578 
02586         function extInformationArray_dbInst($dbInst,$current)   {
02587                 if (strlen($dbInst)>1)  {
02588                         $others = array();
02589                         for($a=0;$a<strlen($dbInst);$a++)       {
02590                                 if (substr($dbInst,$a,1)!=$current)     {
02591                                         $others[]='"'.$this->typeLabels[substr($dbInst,$a,1)].'"';
02592                                 }
02593                         }
02594                         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.');
02595                 } else return '';
02596         }
02597 
02605         function getRepositoryUploadForm($extKey,$extInfo)      {
02606                 $content.='
02607                         <input type="hidden" name="CMD[showExt]" value="'.$extKey.'" />
02608                         <input type="hidden" name="em[action]" value="doUpload" />
02609                         <table border="0" cellpadding="2" cellspacing="1">
02610                                 <tr class="bgColor4">
02611                                         <td>Repository Username:</td>
02612                                         <td><input'.$this->doc->formWidth(20).' type="text" name="em[user][fe_u]" value="'.$this->fe_user['username'].'" /></td>
02613                                 </tr>
02614                                 <tr class="bgColor4">
02615                                         <td>Repository Password:</td>
02616                                         <td><input'.$this->doc->formWidth(20).' type="password" name="em[user][fe_p]" value="'.$this->fe_user['password'].'" /></td>
02617                                 </tr>
02618                                 <tr class="bgColor4">
02619                                         <td>Changelog for upload:</td>
02620                                         <td><textarea'.$this->doc->formWidth(30,1).' rows="5" name="em[upload][comment]"></textarea></td>
02621                                 </tr>
02622                                 <tr class="bgColor4">
02623                                         <td>Upload command:</td>
02624                                         <td nowrap="nowrap">
02625                                                 <input type="radio" name="em[upload][mode]" id="new_dev" value="new_dev" checked="checked" /> <label for="new_dev">New development version (latest x.x.<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw('x+1').'</strong>)</label><br />
02626                                                 <input type="radio" name="em[upload][mode]" id="latest" value="latest" /> <label for="latest">Override <em>this</em> development version ('.$extInfo['EM_CONF']['version'].')</label><br />
02627                                                 <input type="radio" name="em[upload][mode]" id="new_sub" value="new_sub" /> <label for="new_sub">New sub version (latest x.<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw('x+1').'</strong>.0)</label><br />
02628                                                 <input type="radio" name="em[upload][mode]" id="new_main" value="new_main" /> <label for="new_main">New main version (latest <strong>'.$GLOBALS['TBE_TEMPLATE']->rfw('x+1').'</strong>.0.0)</label><br />
02629                                                 <input type="radio" name="em[upload][mode]" id="custom" value="custom" /> <label for="custom">This version: <input type="text" name="em[upload][version]" /></label><br />
02630                                         </td>
02631                                 </tr>
02632                                 <tr class="bgColor4">
02633                                         <td>&nbsp;</td>
02634                                         <td><input type="submit" name="submit" value="Upload extension" />
02635                                         </td>
02636                                 </tr>
02637                         </table>
02638                         ';
02639 
02640                 return $content;
02641         }
02642 
02643 
02644 
02645 
02646 
02647 
02648 
02649 
02650 
02651 
02652         /***********************************
02653         *
02654         * Extension list rendering
02655         *
02656         **********************************/
02657 
02666         function extensionListRowHeader($trAttrib,$cells,$import=0)     {
02667                 $cells[] = '<td></td>';
02668                 $cells[] = '<td>Title:</td>';
02669 
02670                 if (!$this->MOD_SETTINGS['display_details'])    {
02671                         $cells[] = '<td>Description:</td>';
02672                         $cells[] = '<td>Author:</td>';
02673                 } elseif ($this->MOD_SETTINGS['display_details']==2)    {
02674                         $cells[] = '<td>Priority:</td>';
02675                         $cells[] = '<td>Mod.Tables:</td>';
02676                         $cells[] = '<td>Modules:</td>';
02677                         $cells[] = '<td>Cl.Cache?</td>';
02678                         $cells[] = '<td>Internal?</td>';
02679                         $cells[] = '<td>Shy?</td>';
02680                 } elseif ($this->MOD_SETTINGS['display_details']==3)    {
02681                         $cells[] = '<td>Tables/Fields:</td>';
02682                         $cells[] = '<td>TS-files:</td>';
02683                         $cells[] = '<td>Affects:</td>';
02684                         $cells[] = '<td>Modules:</td>';
02685                         $cells[] = '<td>Config?</td>';
02686                         $cells[] = '<td>Code warnings:</td>';
02687                 } elseif ($this->MOD_SETTINGS['display_details']==4)    {
02688                         $cells[] = '<td>locallang:</td>';
02689                         $cells[] = '<td>Classes:</td>';
02690                         $cells[] = '<td>Code warnings:</td>';
02691                         $cells[] = '<td>Nameing annoyances:</td>';
02692                 } elseif ($this->MOD_SETTINGS['display_details']==5)    {
02693                         $cells[] = '<td>Changed files:</td>';
02694                 } else {
02695                         $cells[] = '<td>Extension key:</td>';
02696                         $cells[] = '<td>Version:</td>';
02697                         if (!$import) {
02698                                 $cells[] = '<td>DL:</td>';
02699                                 $cells[] = '<td>Doc:</td>';
02700                                 $cells[] = '<td>Type:</td>';
02701                         } else {
02702                                 $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>';
02703                                 $cells[] = '<td class="bgColor6"'.$this->labelInfo('Current type of installation of the extension on this server.').'>Cur. Type:</td>';
02704                                 $cells[] = '<td'.$this->labelInfo('Number of downloads, all versions/this version').'>DL:</td>';
02705                         }
02706                         $cells[] = '<td>State:</td>';
02707                 }
02708                 return '
02709                         <tr'.$trAttrib.'>
02710                                 '.implode('
02711                                 ',$cells).'
02712                         </tr>';
02713         }
02714 
02727         function extensionListRow($extKey,$extInfo,$cells,$bgColorClass='',$inst_list=array(),$import=0,$altLinkUrl='') {
02728 
02729                         // Icon:
02730                 $imgInfo = @getImageSize($this->getExtPath($extKey,$extInfo['type']).'/ext_icon.gif');
02731                 if (is_array($imgInfo)) {
02732                         $cells[] = '<td><img src="'.$GLOBALS['BACK_PATH'].$this->typeRelPaths[$extInfo['type']].$extKey.'/ext_icon.gif'.'" '.$imgInfo[3].' alt="" /></td>';
02733                 } elseif ($extInfo['_ICON']) {
02734                         $cells[] = '<td>'.$extInfo['_ICON'].'</td>';
02735                 } else {
02736                         $cells[] = '<td><img src="clear.gif" width="1" height="1" alt="" /></td>';
02737                 }
02738 
02739                         // Extension title:
02740                 $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>';
02741 
02742                         // Based on which display mode you will see more or less details:
02743                 if (!$this->MOD_SETTINGS['display_details'])    {
02744                         $cells[] = '<td>'.htmlspecialchars(t3lib_div::fixed_lgd($extInfo['EM_CONF']['description'],400)).'<br /><img src="clear.gif" width="300" height="1" alt="" /></td>';
02745                         $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>';
02746                 } elseif ($this->MOD_SETTINGS['display_details']==2)    {
02747                         $cells[] = '<td nowrap="nowrap">'.$extInfo['EM_CONF']['priority'].'</td>';
02748                         $cells[] = '<td nowrap="nowrap">'.implode('<br />',t3lib_div::trimExplode(',',$extInfo['EM_CONF']['modify_tables'],1)).'</td>';
02749                         $cells[] = '<td nowrap="nowrap">'.$extInfo['EM_CONF']['module'].'</td>';
02750                         $cells[] = '<td nowrap="nowrap">'.($extInfo['EM_CONF']['clearCacheOnLoad'] ? 'Yes' : '').'</td>';
02751                         $cells[] = '<td nowrap="nowrap">'.($extInfo['EM_CONF']['internal'] ? 'Yes' : '').'</td>';
02752                         $cells[] = '<td nowrap="nowrap">'.($extInfo['EM_CONF']['shy'] ? 'Yes' : '').'</td>';
02753                 } elseif ($this->MOD_SETTINGS['display_details']==3)    {
02754                         $techInfo = $this->makeDetailedExtensionAnalysis($extKey,$extInfo);
02755 
02756                         $cells[] = '<td>'.$this->extInformationArray_dbReq($techInfo).
02757                         '</td>';
02758                         $cells[] = '<td nowrap="nowrap">'.(is_array($techInfo['TSfiles']) ? implode('<br />',$techInfo['TSfiles']) : '').'</td>';
02759                         $cells[] = '<td nowrap="nowrap">'.(is_array($techInfo['flags']) ? implode('<br />',$techInfo['flags']) : '').'</td>';
02760                         $cells[] = '<td nowrap="nowrap">'.(is_array($techInfo['moduleNames']) ? implode('<br />',$techInfo['moduleNames']) : '').'</td>';
02761                         $cells[] = '<td nowrap="nowrap">'.($techInfo['conf'] ? 'Yes' : '').'</td>';
02762                         $cells[] = '<td>'.
02763                         $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!':'').
02764                         (t3lib_extMgm::isLoaded($extKey)&&$techInfo['static_error']?'<strong>Static table error!</strong><br />The static tables are missing or empty!':'')).
02765                         '</td>';
02766                 } elseif ($this->MOD_SETTINGS['display_details']==4)    {
02767                         $techInfo=$this->makeDetailedExtensionAnalysis($extKey,$extInfo,1);
02768 
02769                         $cells[] = '<td>'.(is_array($techInfo['locallang']) ? implode('<br />',$techInfo['locallang']) : '').'</td>';
02770                         $cells[] = '<td>'.(is_array($techInfo['classes']) ? implode('<br />',$techInfo['classes']) : '').'</td>';
02771                         $cells[] = '<td>'.(is_array($techInfo['errors']) ? $GLOBALS['TBE_TEMPLATE']->rfw(implode('<hr />',$techInfo['errors'])) : '').'</td>';
02772                         $cells[] = '<td>'.(is_array($techInfo['NSerrors']) ? (!t3lib_div::inList($this->nameSpaceExceptions,$extKey) ? t3lib_div::view_array($techInfo['NSerrors']) : $GLOBALS['TBE_TEMPLATE']->dfw('[exception]')) :'').'</td>';
02773                 } elseif ($this->MOD_SETTINGS['display_details']==5)    {
02774                         $currentMd5Array = $this->serverExtensionMD5Array($extKey,$extInfo);
02775                         $affectedFiles = '';
02776                         $msgLines = array();
02777                         $msgLines[] = 'Files: '.count($currentMd5Array);
02778                         if (strcmp($extInfo['EM_CONF']['_md5_values_when_last_written'],serialize($currentMd5Array)))   {
02779                                 $msgLines[] = $GLOBALS['TBE_TEMPLATE']->rfw('<br /><strong>A difference between the originally installed version and the current was detected!</strong>');
02780                                 $affectedFiles = $this->findMD5ArrayDiff($currentMd5Array,unserialize($extInfo['EM_CONF']['_md5_values_when_last_written']));
02781                                 if (count($affectedFiles))      $msgLines[] = '<br /><strong>Modified files:</strong><br />'.$GLOBALS['TBE_TEMPLATE']->rfw(implode('<br />',$affectedFiles));
02782                         }
02783                         $cells[] = '<td>'.implode('<br />',$msgLines).'</td>';
02784                 } else {
02785                                 // Default view:
02786                         $verDiff = $inst_list[$extKey] && $this->versionDifference($extInfo['EM_CONF']['version'],$inst_list[$extKey]['EM_CONF']['version'],$this->versionDiffFactor);
02787 
02788                         $cells[] = '<td nowrap="nowrap"><em>'.$extKey.'</em></td>';
02789                         $cells[] = '<td nowrap="nowrap">'.($verDiff ? '<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw(htmlspecialchars($extInfo['EM_CONF']['version'])).'</strong>' : $extInfo['EM_CONF']['version']).'</td>';
02790                         if (!$import) {         // Listing extenson on LOCAL server:
02791                                         // Extension Download:
02792                                 $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>';
02793 
02794                                         // Manual download
02795                                 $fileP = PATH_site.$this->typePaths[$extInfo['type']].$extKey.'/doc/manual.sxw';
02796                                 $cells[] = '<td nowrap="nowrap">'.
02797                                 ($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>':'').
02798                                 '</td>';
02799                                 $cells[] = '<td nowrap="nowrap">'.$this->typeLabels[$extInfo['type']].(strlen($extInfo['doubleInstall'])>1?'<strong> '.$GLOBALS['TBE_TEMPLATE']->rfw($extInfo['doubleInstall']).'</strong>':'').'</td>';
02800                         } else {        // Listing extensions from REMOTE repository:
02801                                 $inst_curVer = $inst_list[$extKey]['EM_CONF']['version'];
02802                                 if (isset($inst_list[$extKey])) {
02803                                         if ($verDiff)   $inst_curVer = '<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw($inst_curVer).'</strong>';
02804                                 }
02805                                 $cells[] = '<td nowrap="nowrap">'.$inst_curVer.'</td>';
02806                                 $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>';
02807                                 $cells[] = '<td nowrap="nowrap">'.($extInfo['downloadcounter_all']?$extInfo['downloadcounter_all']:'&nbsp;&nbsp;').'/'.($extInfo['downloadcounter']?$extInfo['downloadcounter']:'&nbsp;').'</td>';
02808                         }
02809                         $cells[] = '<td nowrap="nowrap" class="extstate" style="background-color:'.$this->stateColors[$extInfo['EM_CONF']['state']].';">'.$this->states[$extInfo['EM_CONF']['state']].'</td>';
02810                 }
02811 
02812                 if($this->xmlhandler->getReviewState($extKey,$extInfo['EM_CONF']['version'])<1) {
02813                         $bgclass = ' class="unsupported-ext"';
02814                 } else {
02815                         $bgclass = ' class="'.($bgColorClass?$bgColorClass:'bgColor4').'"';
02816                 }
02817 
02818                 return '
02819                         <tr'.$bgclass.'>
02820                                 '.implode('
02821                                 ',$cells).'
02822                         </tr>';
02823         }
02824 
02825 
02826 
02827 
02828 
02829 
02830         /************************************
02831         *
02832         * Output helper functions
02833         *
02834         ************************************/
02835 
02843         function wrapEmail($str,$email) {
02844                 if ($email)     {
02845                         $str = '<a href="mailto:'.htmlspecialchars($email).'">'.htmlspecialchars($str).'</a>';
02846                 }
02847                 return $str;
02848         }
02849 
02856         function helpCol($key)  {
02857                 global $BE_USER;
02858                 if ($BE_USER->uc['edit_showFieldHelp']) {
02859                         $hT = trim(t3lib_BEfunc::helpText($this->descrTable,'emconf_'.$key,$this->doc->backPath));
02860                         return '<td>'.($hT?$hT:t3lib_BEfunc::helpTextIcon($this->descrTable,'emconf_'.$key,$this->doc->backPath)).'</td>';
02861                 } else {
02862                         return '';
02863                 }
02864         }
02865 
02872         function labelInfo($str)        {
02873                 return ' title="'.htmlspecialchars($str).'" style="cursor:help;"';
02874         }
02875 
02884         function extensionTitleIconHeader($extKey,$extInfo,$align='top')        {
02885                 $imgInfo = @getImageSize($this->getExtPath($extKey,$extInfo['type']).'/ext_icon.gif');
02886                 $out = '';
02887                 if (is_array($imgInfo)) {
02888                         $out.= '<img src="'.$GLOBALS['BACK_PATH'].$this->typeRelPaths[$extInfo['type']].$extKey.'/ext_icon.gif" '.$imgInfo[3].' align="'.$align.'" alt="" />';
02889                 }
02890                 $out.= $extInfo['EM_CONF']['title'] ? htmlspecialchars(t3lib_div::fixed_lgd($extInfo['EM_CONF']['title'],40)) : '<em>'.$extKey.'</em>';
02891                 return $out;
02892         }
02893 
02899         function removeButton() {
02900                 return '<img src="uninstall.gif" width="16" height="16" title="Remove extension" align="top" alt="" />';
02901         }
02902 
02908         function installButton()        {
02909                 return '<img src="install.gif" width="16" height="16" title="Install extension..." align="top" alt="" />';
02910         }
02911 
02917         function noImportMsg()  {
02918                 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>';
02919         }
02920 
02930         function depToString($dep,$type='depends') {
02931                 if(is_array($dep)) {
02932                         unset($dep[$type]['php']);
02933                         unset($dep[$type]['typo3']);
02934                         $s = (count($dep[$type])) ? implode(',', array_keys($dep[$type])) : '';
02935                         return $s;
02936                 }
02937                 return '';
02938         }
02939 
02949         function stringToDep($dep) {
02950                 $constraint = array();
02951                 if(is_string($dep) && strlen($dep)) {
02952                         $dep = explode(',',$dep);
02953                         foreach($dep as $v) {
02954                                 $constraint[$v] = '';
02955                         }
02956                 }
02957                 return $constraint;
02958         }
02959 
02960 
02961 
02962 
02963 
02964 
02965 
02966 
02967         /********************************
02968         *
02969         * Read information about all available extensions
02970         *
02971         *******************************/
02972 
02979         function getInstalledExtensions()       {
02980                 $list = array();
02981                 $cat = $this->defaultCategories;
02982 
02983                 $path = PATH_typo3.'sysext/';
02984                 $this->getInstExtList($path,$list,$cat,'S');
02985 
02986                 $path = PATH_typo3.'ext/';
02987                 $this->getInstExtList($path,$list,$cat,'G');
02988 
02989                 $path = PATH_typo3conf.'ext/';
02990                 $this->getInstExtList($path,$list,$cat,'L');
02991 
02992                 return array($list,$cat);
02993         }
02994 
03006         function getInstExtList($path,&$list,&$cat,$type)       {
03007 
03008                 if (@is_dir($path))     {
03009                         $extList = t3lib_div::get_dirs($path);
03010                         if (is_array($extList)) {
03011                                 foreach($extList as $extKey)    {
03012                                         if (@is_file($path.$extKey.'/ext_emconf.php'))  {
03013                                                 $emConf = $this->includeEMCONF($path.$extKey.'/ext_emconf.php', $extKey);
03014                                                 if (is_array($emConf))  {
03015                                                         if (is_array($list[$extKey]))   {
03016                                                                 $list[$extKey]=array('doubleInstall'=>$list[$extKey]['doubleInstall']);
03017                                                         }
03018                                                         $list[$extKey]['doubleInstall'].= $type;
03019                                                         $list[$extKey]['type'] = $type;
03020                                                         $list[$extKey]['EM_CONF'] = $emConf;
03021                                                         $list[$extKey]['files'] = t3lib_div::getFilesInDir($path.$extKey, '', 0, '', $this->excludeForPackaging);
03022 
03023                                                         $this->setCat($cat,$list[$extKey], $extKey);
03024                                                 }
03025                                         }
03026                                 }
03027                         }
03028                 }
03029         }
03030 
03037         function fixEMCONF($emConf) {
03038                 if(!isset($emConf['constraints']) || !isset($emConf['constraints']['depends']) || !isset($emConf['constraints']['conflicts']) || !isset($emConf['constraints']['suggests'])) {
03039                         if(!isset($emConf['constraints']) || !isset($emConf['constraints']['depends'])) {
03040                                 $emConf['constraints']['depends'] = $this->stringToDep($emConf['dependencies']);
03041                                 if(strlen($emConf['PHP_version'])) {
03042                                         $versionRange = $this->splitVersionRange($emConf['PHP_version']);
03043                                         if (version_compare($versionRange[0],'3.0.0','<')) $versionRange[0] = '3.0.0';
03044                                         if (version_compare($versionRange[1],'3.0.0','<')) $versionRange[1] = '0.0.0';
03045                                         $emConf['constraints']['depends']['php'] = implode('-',$versionRange);
03046                                 }
03047                                 if(strlen($emConf['TYPO3_version'])) {
03048                                         $versionRange = $this->splitVersionRange($emConf['TYPO3_version']);
03049                                         if (version_compare($versionRange[0],'3.5.0','<')) $versionRange[0] = '3.5.0';
03050                                         if (version_compare($versionRange[1],'3.5.0','<')) $versionRange[1] = '0.0.0';
03051                                         $emConf['constraints']['depends']['typo3'] = implode('-',$versionRange);
03052                                 }
03053                         }
03054                         if(!isset($emConf['constraints']) || !isset($emConf['constraints']['conflicts'])) {
03055                                 $emConf['constraints']['conflicts'] = $this->stringToDep($emConf['conflicts']);
03056                         }
03057                         if(!isset($emConf['constraints']) || !isset($emConf['constraints']['suggests'])) {
03058                                 $emConf['constraints']['suggests'] = array();
03059                         }
03060                 } elseif (isset($emConf['constraints']) && isset($emConf['dependencies'])) {
03061                         $emConf['suggests'] = isset($emConf['suggests']) ? $emConf['suggests'] : array();
03062                         $emConf['dependencies'] = $this->depToString($emConf['constraints']);
03063                         $emConf['conflicts'] = $this->depToString($emConf['constraints'], 'conflicts');
03064                 }
03065 
03066                         // sanity check for version numbers, intentionally only checks php and typo3
03067                 if(isset($emConf['constraints']['depends']) && isset($emConf['constraints']['depends']['php'])) {
03068                         $versionRange = $this->splitVersionRange($emConf['constraints']['depends']['php']);
03069                         if (version_compare($versionRange[0],'3.0.0','<')) $versionRange[0] = '3.0.0';
03070                         if (version_compare($versionRange[1],'3.0.0','<')) $versionRange[1] = '0.0.0';
03071                         $emConf['constraints']['depends']['php'] = implode('-',$versionRange);
03072                 }
03073                 if(isset($emConf['constraints']['depends']) && isset($emConf['constraints']['depends']['typo3'])) {
03074                         $versionRange = $this->splitVersionRange($emConf['constraints']['depends']['typo3']);
03075                         if (version_compare($versionRange[0],'3.5.0','<')) $versionRange[0] = '3.5.0';
03076                         if (version_compare($versionRange[1],'3.5.0','<')) $versionRange[1] = '0.0.0';
03077                         $emConf['constraints']['depends']['typo3'] = implode('-',$versionRange);
03078                 }
03079 
03080                 unset($emConf['private']);
03081                 unset($emConf['download_password']);
03082                 unset($emConf['TYPO3_version']);
03083                 unset($emConf['PHP_version']);
03084 
03085                 return $emConf;
03086         }
03087 
03097         function splitVersionRange($ver)        {
03098                 $versionRange = array();
03099                 if (strstr($ver, '-'))  {
03100                         $versionRange = explode('-', $ver, 2);
03101                 } else {
03102                         $versionRange[0] = $ver;
03103                         $versionRange[1] = '';
03104                 }
03105 
03106                 if (!$versionRange[0])  { $versionRange[0] = '0.0.0'; }
03107                 if (!$versionRange[1])  { $versionRange[1] = '0.0.0'; }
03108 
03109                 return $versionRange;
03110         }
03111 
03118         function prepareImportExtList($unsetProc = false)       {
03119                 $list = array();
03120                 $cat = $this->defaultCategories;
03121                 $filepath = $this->getMirrorURL();
03122 
03123                 reset($this->xmlhandler->extensionsXML);
03124                 while (list($extKey, $data) = each($this->xmlhandler->extensionsXML)) {
03125                         $GLOBALS['LANG']->csConvObj->convArray($data,'utf-8',$GLOBALS['LANG']->charSet); // is there a better place for conversion?
03126                         $list[$extKey]['type'] = '_';
03127                         $version = array_keys($data['versions']);
03128                         $list[$extKey]['_ICON'] = '<img alt="" src="'.$filepath.$extKey{0}.'/'.$extKey{1}.'/'.$extKey.'_'.end($version).'.gif" />';
03129                         $list[$extKey]['downloadcounter'] = $data['downloadcounter'];
03130 
03131                         foreach(array_keys($data['versions']) as $version) {
03132                                 $list[$extKey]['versions'][$version]['downloadcounter'] = $data['versions'][$version]['downloadcounter'];
03133 
03134                                 $list[$extKey]['versions'][$version]['EM_CONF'] = array(
03135                                 'version' => $version,
03136                                 'title' => $data['versions'][$version]['title'],
03137                                 'description' => $data['versions'][$version]['description'],
03138                                 'category' => $data['versions'][$version]['category'],
03139                                 'constraints' => $data['versions'][$version]['dependencies'],
03140                                 'state' => $data['versions'][$version]['state'],
03141                                 'reviewstate' => $data['versions'][$version]['reviewstate'],
03142                                 'lastuploaddate' => $data['versions'][$version]['lastuploaddate'],
03143                                 'author' => $data['versions'][$version]['authorname'],
03144                                 'author_email' => $data['versions'][$version]['authoremail'],
03145                                 'author_company' => $data['versions'][$version]['authorcompany'],
03146                                 );
03147                         }
03148                         $this->setCat($cat, $list[$extKey]['versions'][$version], $extKey);
03149                         if ($unsetProc) {
03150                                 unset($this->xmlhandler->extensionsXML[$extKey]);
03151                         }
03152                 }
03153 
03154                 return array($list,$cat);
03155         }
03156 
03165         function setCat(&$cat,$listArrayPart,$extKey)   {
03166 
03167                 // Getting extension title:
03168                 $extTitle = $listArrayPart['EM_CONF']['title'];
03169 
03170                 // Category index:
03171                 $index = $listArrayPart['EM_CONF']['category'];
03172                 $cat['cat'][$index][$extKey] = $extTitle;
03173 
03174                 // Author index:
03175                 $index = $listArrayPart['EM_CONF']['author'].($listArrayPart['EM_CONF']['author_company']?', '.$listArrayPart['EM_CONF']['author_company']:'');
03176                 $cat['author_company'][$index][$extKey] = $extTitle;
03177 
03178                 // State index:
03179                 $index = $listArrayPart['EM_CONF']['state'];
03180                 $cat['state'][$index][$extKey] = $extTitle;
03181 
03182                 // Type index:
03183                 $index = $listArrayPart['type'];
03184                 $cat['type'][$index][$extKey] = $extTitle;
03185 
03186                 // Return categories:
03187                 return $cat;
03188         }
03189 
03190 
03191 
03192 
03193 
03194 
03195 
03196 
03197 
03198 
03199         /*******************************
03200         *
03201         * Extension analyzing (detailed information)
03202         *
03203         ******************************/
03204 
03215         function makeDetailedExtensionAnalysis($extKey,$extInfo,$validity=0)    {
03216 
03217                 // Get absolute path of the extension
03218                 $absPath = $this->getExtPath($extKey,$extInfo['type']);
03219 
03220                 $infoArray = array();
03221 
03222                 $table_class_prefix = substr($extKey,0,5)=='user_' ? 'user_' : 'tx_'.str_replace('_','',$extKey).'_';
03223                 $module_prefix = substr($extKey,0,5)=='user_' ? 'u' : 'tx'.str_replace('_','',$extKey);
03224 
03225                 // Database status:
03226                 $dbInfo = $this->checkDBupdates($extKey,$extInfo,1);
03227 
03228                 // Database structure required:
03229                 if (is_array($dbInfo['structure']['tables_fields']))    {
03230                         $modify_tables = t3lib_div::trimExplode(',',$extInfo['EM_CONF']['modify_tables'],1);
03231                         $infoArray['dump_tf'] = array();
03232 
03233                         foreach($dbInfo['structure']['tables_fields'] as $tN => $d)     {
03234                                 if (in_array($tN,$modify_tables))       {
03235                                         $infoArray['fields'][] = $tN.': <i>'.
03236                                         (is_array($d['fields']) ? implode(', ',array_keys($d['fields'])) : '').
03237                                         (is_array($d['keys']) ? ' + '.count($d['keys']).' keys' : '').
03238                                         '</i>';
03239                                         if (is_array($d['fields']))     {
03240                                                 reset($d['fields']);
03241                                                 while(list($fN) = each($d['fields']))   {
03242                                                         $infoArray['dump_tf'][] = $tN.'.'.$fN;
03243                                                         if (!t3lib_div::isFirstPartOfStr($fN,$table_class_prefix))      {
03244                                                                 $infoArray['NSerrors']['fields'][$fN] = $fN;
03245                                                         } else {
03246                                                                 $infoArray['NSok']['fields'][$fN] = $fN;
03247                                                         }
03248                                                 }
03249                                         }
03250                                         if (is_array($d['keys']))       {
03251                                                 reset($d['keys']);
03252                                                 while(list($fN)=each($d['keys']))       {
03253                                                         $infoArray['dump_tf'][] = $tN.'.KEY:'.$fN;
03254                                                 }
03255                                         }
03256                                 } else {
03257                                         $infoArray['dump_tf'][] = $tN;
03258                                         $infoArray['tables'][] = $tN;
03259                                         if (!t3lib_div::isFirstPartOfStr($tN,$table_class_prefix))      {
03260                                                 $infoArray['NSerrors']['tables'][$tN] = $tN;
03261                                         } else $infoArray['NSok']['tables'][$tN] = $tN;
03262                                 }
03263                         }
03264                         if (count($dbInfo['structure']['diff']['diff']) || count($dbInfo['structure']['diff']['extra']))        {
03265                                 $msg = array();
03266                                 if (count($dbInfo['structure']['diff']['diff']))        $msg[] = 'missing';
03267                                 if (count($dbInfo['structure']['diff']['extra']))       $msg[] = 'of wrong type';
03268                                 $infoArray['tables_error'] = 1;
03269                                 if (t3lib_extMgm::isLoaded($extKey))    $infoArray['errors'][] = 'Some tables or fields are '.implode(' and ',$msg).'!';
03270                         }
03271                 }
03272 
03273                 // Static tables?
03274                 if (is_array($dbInfo['static']))        {
03275                         $infoArray['static'] = array_keys($dbInfo['static']);
03276 
03277                         foreach($dbInfo['static'] as $tN => $d) {
03278                                 if (!$d['exists'])      {
03279                                         $infoArray['static_error'] = 1;
03280                                         if (t3lib_extMgm::isLoaded($extKey))    $infoArray['errors'][] = 'Static table(s) missing!';
03281                                         if (!t3lib_div::isFirstPartOfStr($tN,$table_class_prefix))      {
03282                                                 $infoArray['NSerrors']['tables'][$tN] = $tN;
03283                                         } else $infoArray['NSok']['tables'][$tN] = $tN;
03284                                 }
03285                         }
03286                 }
03287 
03288                 // Backend Module-check:
03289                 $knownModuleList = t3lib_div::trimExplode(',',$extInfo['EM_CONF']['module'],1);
03290                 foreach($knownModuleList as $mod)       {
03291                         if (@is_dir($absPath.$mod))     {
03292                                 if (@is_file($absPath.$mod.'/conf.php'))        {
03293                                         $confFileInfo = $this->modConfFileAnalysis($absPath.$mod.'/conf.php');
03294                                         if (is_array($confFileInfo['TYPO3_MOD_PATH']))  {
03295                                                 $shouldBePath = $this->typeRelPaths[$extInfo['type']].$extKey.'/'.$mod.'/';
03296                                                 if (strcmp($confFileInfo['TYPO3_MOD_PATH'][1][1],$shouldBePath))        {
03297                                                         $infoArray['errors'][] = 'Configured TYPO3_MOD_PATH "'.$confFileInfo['TYPO3_MOD_PATH'][1][1].'" different from "'.$shouldBePath.'"';
03298                                                 }
03299                                         } else $infoArray['errors'][] = 'No definition of TYPO3_MOD_PATH constant found inside!';
03300                                         if (is_array($confFileInfo['MCONF_name']))      {
03301                                                 $mName = $confFileInfo['MCONF_name'][1][1];
03302                                                 $mNameParts = explode('_',$mName);
03303                                                 $infoArray['moduleNames'][] = $mName;
03304                                                 if (!t3lib_div::isFirstPartOfStr($mNameParts[0],$module_prefix) &&
03305                                                 (!$mNameParts[1] || !t3lib_div::isFirstPartOfStr($mNameParts[1],$module_prefix)))       {
03306                                                         $infoArray['NSerrors']['modname'][] = $mName;
03307                                                 } else $infoArray['NSok']['modname'][] = $mName;
03308                                         } else $infoArray['errors'][] = 'No definition of MCONF[name] variable found inside!';
03309                                 } else  $infoArray['errors'][] = 'Backend module conf file "'.$mod.'/conf.php" should exist but does not!';
03310                         } else $infoArray['errors'][] = 'Backend module folder "'.$mod.'/" should exist but does not!';
03311                 }
03312                 $dirs = t3lib_div::get_dirs($absPath);
03313                 if (is_array($dirs))    {
03314                         reset($dirs);
03315                         while(list(,$mod) = each($dirs))        {
03316                                 if (!in_array($mod,$knownModuleList) && @is_file($absPath.$mod.'/conf.php'))    {
03317                                         $confFileInfo = $this->modConfFileAnalysis($absPath.$mod.'/conf.php');
03318                                         if (is_array($confFileInfo))    {
03319                                                 $infoArray['errors'][] = 'It seems like there is a backend module in "'.$mod.'/conf.php" which is not configured in ext_emconf.php';
03320                                         }
03321                                 }
03322                         }
03323                 }
03324 
03325                 // ext_tables.php:
03326                 if (@is_file($absPath.'ext_tables.php'))        {
03327                         $content = t3lib_div::getUrl($absPath.'ext_tables.php');
03328                         if (stristr($content,'t3lib_extMgm::addModule'))        $infoArray['flags'][] = 'Module';
03329                         if (stristr($content,'t3lib_extMgm::insertModuleFunction'))     $infoArray['flags'][] = 'Module+';
03330                         if (stristr($content,'t3lib_div::loadTCA'))     $infoArray['flags'][] = 'loadTCA';
03331                         if (stristr($content,'$TCA['))  $infoArray['flags'][] = 'TCA';
03332                         if (stristr($content,'t3lib_extMgm::addPlugin'))        $infoArray['flags'][] = 'Plugin';
03333                 }
03334 
03335                 // ext_localconf.php:
03336                 if (@is_file($absPath.'ext_localconf.php'))     {
03337                         $content = t3lib_div::getUrl($absPath.'ext_localconf.php');
03338                         if (stristr($content,'t3lib_extMgm::addPItoST43'))      $infoArray['flags'][]='Plugin/ST43';
03339                         if (stristr($content,'t3lib_extMgm::addPageTSConfig'))  $infoArray['flags'][]='Page-TSconfig';
03340                         if (stristr($content,'t3lib_extMgm::addUserTSConfig'))  $infoArray['flags'][]='User-TSconfig';
03341                         if (stristr($content,'t3lib_extMgm::addTypoScriptSetup'))       $infoArray['flags'][]='TS/Setup';
03342                         if (stristr($content,'t3lib_extMgm::addTypoScriptConstants'))   $infoArray['flags'][]='TS/Constants';
03343                 }
03344 
03345                 if (@is_file($absPath.'ext_typoscript_constants.txt'))  {
03346                         $infoArray['TSfiles'][] = 'Constants';
03347                 }
03348                 if (@is_file($absPath.'ext_typoscript_setup.txt'))      {
03349                         $infoArray['TSfiles'][] = 'Setup';
03350                 }
03351                 if (@is_file($absPath.'ext_conf_template.txt')) {
03352                         $infoArray['conf'] = 1;
03353                 }
03354 
03355                 // Classes:
03356                 if ($validity)  {
03357                         $filesInside = $this->getClassIndexLocallangFiles($absPath,$table_class_prefix,$extKey);
03358                         if (is_array($filesInside['errors']))   $infoArray['errors'] = array_merge((array)$infoArray['errors'],$filesInside['errors']);
03359                         if (is_array($filesInside['NSerrors'])) $infoArray['NSerrors'] = array_merge((array)$infoArray['NSerrors'],$filesInside['NSerrors']);
03360                         if (is_array($filesInside['NSok']))     $infoArray['NSok'] = array_merge((array)$infoArray['NSok'],$filesInside['NSok']);
03361                         $infoArray['locallang'] = $filesInside['locallang'];
03362                         $infoArray['classes'] = $filesInside['classes'];
03363                 }
03364 
03365                 // Upload folders
03366                 if ($extInfo['EM_CONF']['uploadfolder'])        {
03367                         $infoArray['uploadfolder'] = $this->ulFolder($extKey);
03368                         if (!@is_dir(PATH_site.$infoArray['uploadfolder']))     {
03369                                 $infoArray['errors'][] = 'Error: Upload folder "'.$infoArray['uploadfolder'].'" did not exist!';
03370                                 $infoArray['uploadfolder'] = '';
03371                         }
03372                 }
03373 
03374                 // Create directories:
03375                 if ($extInfo['EM_CONF']['createDirs'])  {
03376                         $infoArray['createDirs'] = array_unique(t3lib_div::trimExplode(',',$extInfo['EM_CONF']['createDirs'],1));
03377                         foreach($infoArray['createDirs'] as $crDir)     {
03378                                 if (!@is_dir(PATH_site.$crDir)) {
03379                                         $infoArray['errors'][]='Error: Upload folder "'.$crDir.'" did not exist!';
03380                                 }
03381                         }
03382                 }
03383 
03384                 // Return result array:
03385                 return $infoArray;
03386         }
03387 
03397         function getClassIndexLocallangFiles($absPath,$table_class_prefix,$extKey)      {
03398                 $filesInside = t3lib_div::removePrefixPathFromList(t3lib_div::getAllFilesAndFoldersInPath(array(),$absPath,'php,inc',0,99,$this->excludeForPackaging),$absPath);
03399                 $out = array();
03400 
03401                 foreach($filesInside as $fileName)      {
03402                         if (substr($fileName,0,4)!='ext_' && substr($fileName,0,6)!='tests/')   {       // ignore supposed-to-be unit tests as well
03403                                 $baseName = basename($fileName);
03404                                 if (substr($baseName,0,9)=='locallang' && substr($baseName,-4)=='.php') {
03405                                         $out['locallang'][] = $fileName;
03406                                 } elseif ($baseName!='conf.php')        {
03407                                         if (filesize($absPath.$fileName)<500*1024)      {
03408                                                 $fContent = t3lib_div::getUrl($absPath.$fileName);
03409                                                 unset($reg);
03410                                                 if (preg_match('/\n[[:space:]]*class[[:space:]]*([[:alnum:]_]+)([[:alnum:][:space:]_]*)/',$fContent,$reg))      {
03411 
03412                                                         // Find classes:
03413                                                         $lines = explode(chr(10),$fContent);
03414                                                         foreach($lines as $l)   {
03415                                                                 $line = trim($l);
03416                                                                 unset($reg);
03417                                                                 if (preg_match('/^class[[:space:]]*([[:alnum:]_]+)([[:alnum:][:space:]_]*)/',$line,$reg))       {
03418                                                                         $out['classes'][] = $reg[1];
03419                                                                         $out['files'][$fileName]['classes'][] = $reg[1];
03420                                                                         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]))      {
03421                                                                                 $out['NSerrors']['classname'][] = $reg[1];
03422                                                                         } else $out['NSok']['classname'][] = $reg[1];
03423                                                                 }
03424                                                         }
03425                                                         // If class file prefixed 'class.'....
03426                                                         if (substr($baseName,0,6)=='class.')    {
03427                                                                 $fI = pathinfo($baseName);
03428                                                                 $testName=substr($baseName,6,-(1+strlen($fI['extension'])));
03429                                                                 if ($testName!=='ext_update' && substr($testName,0,3)!='ux_' && !t3lib_div::isFirstPartOfStr($testName,$table_class_prefix) && strcmp(substr($table_class_prefix,0,-1),$testName))      {
03430                                                                         $out['NSerrors']['classfilename'][] = $baseName;
03431                                                                 } else {
03432                                                                         $out['NSok']['classfilename'][] = $baseName;
03433                                                                         if (is_array($out['files'][$fileName]['classes']) && $this->first_in_array($testName,$out['files'][$fileName]['classes'],1))    {
03434                                                                                 $out['msg'][] = 'Class filename "'.$fileName.'" did contain the class "'.$testName.'" just as it should.';
03435                                                                         } else $out['errors'][] = 'Class filename "'.$fileName.'" did NOT contain the class "'.$testName.'"!';
03436                                                                 }
03437                                                         }
03438                                                         //
03439                                                         $XclassParts = split('if \(defined\([\'"]TYPO3_MODE[\'"]\) && \$TYPO3_CONF_VARS\[TYPO3_MODE\]\[[\'"]XCLASS[\'"]\]',$fContent,2);
03440                                                         if (count($XclassParts)==2)     {
03441                                                                 unset($reg);
03442                                                                 preg_match('/^\[[\'"]([[:alnum:]_\/\.]*)[\'"]\]/',$XclassParts[1],$reg);
03443                                                                 if ($reg[1]) {
03444                                                                         $cmpF = 'ext/'.$extKey.'/'.$fileName;
03445                                                                         if (!strcmp($reg[1],$cmpF))     {
03446                                                                                 if (preg_match('/_once[[:space:]]*\(\$TYPO3_.ONF_VARS\[TYPO3_MODE\]\[[\'"]XCLASS[\'"]\]\[[\'"]'.preg_quote($cmpF,'/').'[\'"]\]\);/', $XclassParts[1]))  {
03447                                                                                         $out['msg'][] = 'XCLASS OK in '.$fileName;
03448                                                                                 } else $out['errors'][] = 'Couldn\'t find the include_once statement for XCLASS!';
03449                                                                         } else $out['errors'][] = 'The XCLASS filename-key "'.$reg[1].'" was different from "'.$cmpF.'" which it should have been!';
03450                                                                 } else $out['errors'][] = 'No XCLASS filename-key found in file "'.$fileName.'". Maybe a regex coding error here...';
03451                                                         } elseif (!$this->first_in_array('ux_',$out['files'][$fileName]['classes'])) $out['errors'][] = 'No XCLASS inclusion code found in file "'.$fileName.'"';
03452                                                 }
03453                                         }
03454                                 }
03455                         }
03456                 }
03457                 return $out;
03458         }
03459 
03467         function modConfFileAnalysis($confFilePath)     {
03468                 $lines = explode(chr(10),t3lib_div::getUrl($confFilePath));
03469                 $confFileInfo = array();
03470                 $confFileInfo['lines'] = $lines;
03471 
03472                 foreach($lines as $k => $l)     {
03473                         $line = trim($l);
03474 
03475                         unset($reg);
03476                         if (preg_match('/^define[[:space:]]*\([[:space:]]*["\']TYPO3_MOD_PATH["\'][[:space:]]*,[[:space:]]*["\']([[:alnum:]_\/\.]+)["\'][[:space:]]*\)[[:space:]]*;/',$line,$reg))      {
03477                                 $confFileInfo['TYPO3_MOD_PATH'] = array($k,$reg);
03478                         }
03479 
03480                         unset($reg);
03481                         if (preg_match('/^\$MCONF\[["\']?name["\']?\][[:space:]]*=[[:space:]]*["\']([[:alnum:]_]+)["\'];/',$line,$reg)) {
03482                                 $confFileInfo['MCONF_name'] = array($k,$reg);
03483                         }
03484                 }
03485                 return $confFileInfo;
03486         }
03487 
03495         function serverExtensionMD5Array($extKey,$conf) {
03496 
03497                 // Creates upload-array - including filelist.
03498                 $mUA = $this->makeUploadArray($extKey,$conf);
03499 
03500                 $md5Array = array();
03501                 if (is_array($mUA['FILES']))    {
03502 
03503                         // Traverse files.
03504                         foreach($mUA['FILES'] as $fN => $d)     {
03505                                 if ($fN!='ext_emconf.php')      {
03506                                         $md5Array[$fN] = substr($d['content_md5'],0,4);
03507                                 }
03508                         }
03509                 } else debug($mUA);
03510                 return $md5Array;
03511         }
03512 
03520         function findMD5ArrayDiff($current,$past)       {
03521                 if (!is_array($current))        $current = array();
03522                 if (!is_array($past))           $past = array();
03523                 $filesInCommon = array_intersect($current,$past);
03524                 $diff1 =  array_keys(array_diff($past,$filesInCommon));
03525                 $diff2 =  array_keys(array_diff($current,$filesInCommon));
03526                 $affectedFiles = array_unique(array_merge($diff1,$diff2));
03527                 return $affectedFiles;
03528         }
03529 
03530 
03531 
03532 
03533 
03534 
03535 
03536 
03537 
03538 
03539         /***********************************
03540         *
03541         * File system operations
03542         *
03543         **********************************/
03544 
03552         function createDirsInPath($dirs,$extDirPath)    {
03553                 if (is_array($dirs))    {
03554                         foreach($dirs as $dir)  {
03555                                 $error = t3lib_div::mkdir_deep($extDirPath,$dir);
03556                                 if ($error)     return $error;
03557                         }
03558                 }
03559 
03560                 return false;
03561         }
03562 
03570         function removeExtDirectory($removePath,$removeContentOnly=0)   {
03571                 $errors = array();
03572                 if (@is_dir($removePath) && substr($removePath,-1)=='/' && (
03573                 t3lib_div::isFirstPartOfStr($removePath,PATH_site.$this->typePaths['G']) ||
03574                 t3lib_div::isFirstPartOfStr($removePath,PATH_site.$this->typePaths['L']) ||
03575                 (t3lib_div::isFirstPartOfStr($removePath,PATH_site.$this->typePaths['S']) && $this->systemInstall) ||
03576                 t3lib_div::isFirstPartOfStr($removePath,PATH_site.'fileadmin/_temp_/'))         // Playing-around directory...
03577                 ) {
03578 
03579                         // All files in extension directory:
03580                         $fileArr = t3lib_div::getAllFilesAndFoldersInPath(array(),$removePath,'',1);
03581                         if (is_array($fileArr)) {
03582 
03583                                 // Remove files in dirs:
03584                                 foreach($fileArr as $removeFile)        {
03585                                         if (!@is_dir($removeFile))      {
03586                                                 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!
03587                                                         @unlink($removeFile);
03588                                                         clearstatcache();
03589                                                         if (@is_file($removeFile))      {
03590                                                                 $errors[] = 'Error: "'.$removeFile.'" could not be deleted!';
03591                                                         }
03592                                                 } else $errors[] = 'Error: "'.$removeFile.'" was either not a file, or it was equal to the removed directory or simply outside the removed directory "'.$removePath.'"!';
03593                                         }
03594                                 }
03595 
03596                                 // Remove directories:
03597                                 $remDirs = $this->extractDirsFromFileList(t3lib_div::removePrefixPathFromList($fileArr,$removePath));
03598                                 $remDirs = array_reverse($remDirs);     // Must delete outer directories first...
03599                                 foreach($remDirs as $removeRelDir)      {
03600                                         $removeDir = $removePath.$removeRelDir;
03601                                         if (@is_dir($removeDir))        {
03602                                                 rmdir($removeDir);
03603                                                 clearstatcache();
03604                                                 if (@is_dir($removeDir))        {
03605                                                         $errors[] = 'Error: "'.$removeDir.'" could not be removed (are there files left?)';
03606                                                 }
03607                                         } else $errors[] = 'Error: "'.$removeDir.'" was not a directory!';
03608                                 }
03609 
03610                                 // If extension dir should also be removed:
03611                                 if (!$removeContentOnly)        {
03612                                         rmdir($removePath);
03613                                         clearstatcache();
03614                                         if (@is_dir($removePath))       {
03615                                                 $errors[] = 'Error: Extension directory "'.$removePath.'" could not be removed (are there files or folders left?)';
03616                                         }
03617                                 }
03618                         } else $errors[] = 'Error: '.$fileArr;
03619                 } else $errors[] = 'Error: Unallowed path to remove: '.$removePath;
03620 
03621                 // Return errors if any:
03622                 return implode(chr(10),$errors);
03623         }
03624 
03633         function clearAndMakeExtensionDir($importedData,$type,$dontDelete=0)    {
03634                 if (!$importedData['extKey'])   return 'FATAL ERROR: Extension key was not set for some VERY strange reason. Nothing done...';
03635 
03636                 // Setting install path (L, G, S or fileadmin/_temp_/)
03637                 $path = '';
03638                 switch((string)$type)   {
03639                         case 'G':
03640                         case 'L':
03641                                 $path = PATH_site.$this->typePaths[$type];
03642                                 $suffix = '';
03643 
03644                                 // Creates the typo3conf/ext/ directory if it does NOT already exist:
03645                                 if ((string)$type=='L' && !@is_dir($path))      {
03646                                         t3lib_div::mkdir($path);
03647                                 }
03648                                 break;
03649                         default:
03650                                 if ($this->systemInstall && (string)$type=='S') {
03651                                         $path = PATH_site.$this->typePaths[$type];
03652                                         $suffix = '';
03653                                 } else {
03654                                         $path = PATH_site.'fileadmin/_temp_/';
03655                                         $suffix = '_'.date('dmy-His');
03656                                 }
03657                                 break;
03658                 }
03659 
03660                 // If the install path is OK...
03661                 if ($path && @is_dir($path))    {
03662 
03663                         // Set extension directory:
03664                         $extDirPath = $path.$importedData['extKey'].$suffix.'/';
03665 
03666                         // Install dir was found, remove it then:
03667                         if (@is_dir($extDirPath))       {
03668                                 if($dontDelete) return array($extDirPath);
03669                                 $res = $this->removeExtDirectory($extDirPath);
03670                                 if ($res) {
03671                                         return 'ERROR: Could not remove extension directory "'.$extDirPath.'". Reasons:<br /><br />'.nl2br($res);
03672                                 }
03673                         }
03674 
03675                         // We go create...
03676                         t3lib_div::mkdir($extDirPath);
03677                         if (!is_dir($extDirPath))       return 'ERROR: Could not create extension directory "'.$extDirPath.'"';
03678                         return array($extDirPath);
03679                 } else return 'ERROR: The extension install path "'.$path.'" was not a directory.';
03680         }
03681 
03687         function removeCacheFiles()     {
03688                 return t3lib_extMgm::removeCacheFiles();
03689         }
03690 
03697         function extractDirsFromFileList($files)        {
03698                 $dirs = array();
03699 
03700                 if (is_array($files))   {
03701                         // Traverse files / directories array:
03702                         foreach($files as $file)        {
03703                                 if (substr($file,-1)=='/')      {
03704                                         $dirs[$file] = $file;
03705                                 } else {
03706                                         $pI = pathinfo($file);
03707                                         if (strcmp($pI['dirname'],'') && strcmp($pI['dirname'],'.'))    {
03708                                                 $dirs[$pI['dirname'].'/'] = $pI['dirname'].'/';
03709                                         }
03710                                 }
03711                         }
03712                 }
03713                 return $dirs;
03714         }
03715 
03723         function getExtPath($extKey,$type)      {
03724                 $typeP = $this->typePaths[$type];
03725                 if ($typeP)     {
03726                         $path = PATH_site.$typeP.$extKey.'/';
03727                         return @is_dir($path) ? $path : '';
03728                 } else {
03729                         return '';
03730                 }
03731         }
03732 
03733 
03734 
03735 
03736 
03737 
03738 
03739 
03740 
03741 
03742         /*******************************
03743         *
03744         * Writing to "conf.php" and "localconf.php" files
03745         *
03746         ******************************/
03747 
03757         function writeTYPO3_MOD_PATH($confFilePath,$type,$mP)   {
03758                 $lines = explode(chr(10),t3lib_div::getUrl($confFilePath));
03759                 $confFileInfo = array();
03760                 $confFileInfo['lines'] = $lines;
03761 
03762                 $flag_M = 0;
03763                 $flag_B = 0;
03764 
03765                 foreach($lines as $k => $l)     {
03766                         $line = trim($l);
03767 
03768                         unset($reg);
03769                         if (preg_match('/^define[[:space:]]*\([[:space:]]*["\']TYPO3_MOD_PATH["\'][[:space:]]*,[[:space:]]*["\']([[:alnum:]_\/\.]+)["\'][[:space:]]*\)[[:space:]]*;/',$line,$reg))      {
03770                                 $lines[$k] = str_replace($reg[0], 'define(\'TYPO3_MOD_PATH\', \''.$this->typeRelPaths[$type].$mP.'\');', $lines[$k]);
03771                                 $flag_M = $k+1;
03772                         }
03773 
03774                         unset($reg);
03775                         if (preg_match('/^\$BACK_PATH[[:space:]]*=[[:space:]]*["\']([[:alnum:]_\/\.]+)["\'][[:space:]]*;/',$line,$reg)) {
03776                                 $lines[$k] = str_replace($reg[0], '$BACK_PATH=\''.$this->typeBackPaths[$type].'\';', $lines[$k]);
03777                                 $flag_B = $k+1;
03778                         }
03779                 }
03780 
03781                 if ($flag_B && $flag_M) {
03782                         t3lib_div::writeFile($confFilePath,implode(chr(10),$lines));
03783                         return 'TYPO3_MOD_PATH and $BACK_PATH was updated in "'.substr($confFilePath,strlen(PATH_site)).'"';
03784                 } else return 'Error: Either TYPO3_MOD_PATH or $BACK_PATH was not found in the "'.$confFilePath.'" file. You must manually configure that!';
03785         }
03786 
03794         function writeNewExtensionList($newExtList)     {
03795                 global $TYPO3_CONF_VARS;
03796 
03797                 // Instance of install tool
03798                 $instObj = new t3lib_install;
03799                 $instObj->allowUpdateLocalConf =1;
03800                 $instObj->updateIdentity = 'TYPO3 Extension Manager';
03801 
03802                 // Get lines from localconf file
03803                 $lines = $instObj->writeToLocalconf_control();
03804                 $instObj->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'EXT\'][\'extList\']', $newExtList);
03805                 $instObj->writeToLocalconf_control($lines);
03806 
03807                 $TYPO3_CONF_VARS['EXT']['extList'] = $newExtList;
03808                 $this->removeCacheFiles();
03809         }
03810 
03819         function writeTsStyleConfig($extKey,$arr)       {
03820 
03821                 // Instance of install tool
03822                 $instObj = new t3lib_install;
03823                 $instObj->allowUpdateLocalConf =1;
03824                 $instObj->updateIdentity = 'TYPO3 Extension Manager';
03825 
03826                 // Get lines from localconf file
03827                 $lines = $instObj->writeToLocalconf_control();
03828                 $instObj->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'EXT\'][\'extConf\'][\''.$extKey.'\']', serialize($arr));  // This will be saved only if there are no linebreaks in it !
03829                 $instObj->writeToLocalconf_control($lines);
03830 
03831                 $this->removeCacheFiles();
03832         }
03833 
03841         function updateLocalEM_CONF($extKey,$extInfo)   {
03842                 $extInfo['EM_CONF']['_md5_values_when_last_written'] = serialize($this->serverExtensionMD5Array($extKey,$extInfo));
03843                 $emConfFileContent = $this->construct_ext_emconf_file($extKey,$extInfo['EM_CONF']);
03844 
03845                 $absPath = $this->getExtPath($extKey,$extInfo['type']);
03846                 $emConfFileName = $absPath.'ext_emconf.php';
03847                 if($emConfFileContent)  {
03848 
03849                         if(@is_file($emConfFileName))   {
03850                                 if(t3lib_div::writeFile($emConfFileName,$emConfFileContent) === true) {
03851                                         return '"'.substr($emConfFileName,strlen($absPath)).'" was updated with a cleaned up EM_CONF array.';
03852                                 } else {
03853                                         return '<strong>Error: "'.$emConfFileName.'" was not writable!</strong>';
03854                                 }
03855                         } else return('<strong>Error: No file "'.$emConfFileName.'" found. DON\'T PANIC!</strong>');
03856                 } else {
03857                         return 'No content to write to "'.substr($emConfFileName,strlen($absPath)).'"!';
03858                 }
03859         }
03860 
03861 
03862 
03863 
03864 
03865 
03866 
03867 
03868 
03869 
03870         /*******************************************
03871         *
03872         * Compiling upload information, emconf-file etc.
03873         *
03874         *******************************************/
03875 
03883         function construct_ext_emconf_file($extKey,$EM_CONF)    {
03884 
03885                         // clean version number:
03886                 $vDat = $this->renderVersion($EM_CONF['version']);
03887                 $EM_CONF['version']=$vDat['version'];
03888 
03889                 $code = '<?php
03890 
03891 ########################################################################
03892 # Extension Manager/Repository config file for ext: "'.$extKey.'"
03893 #
03894 # Auto generated '.date('d-m-Y H:i').'
03895 #
03896 # Manual updates:
03897 # Only the data in the array - anything else is removed by next write.
03898 # "version" and "dependencies" must not be touched!
03899 ########################################################################
03900 
03901 $EM_CONF[$_EXTKEY] = '.$this->arrayToCode($EM_CONF, 0).';
03902 
03903 ?>';
03904                 return str_replace(chr(13), '', $code);
03905         }
03906 
03915         function arrayToCode($array, $level=0) {
03916                 $lines = 'array('.chr(10);
03917                 $level++;
03918                 foreach($array as $k => $v)     {
03919                         if(strlen($k) && is_array($v)) {
03920                                 $lines .= str_repeat(chr(9),$level)."'".$k."' => ".$this->arrayToCode($v, $level);
03921                         } elseif(strlen($k)) {
03922                                 $lines .= str_repeat(chr(9),$level)."'".$k."' => ".(t3lib_div::testInt($v) ? intval($v) : "'".t3lib_div::slashJS(trim($v),1)."'").','.chr(10);
03923                         }
03924                 }
03925 
03926                 $lines .= str_repeat(chr(9),$level-1).')'.($level-1==0 ? '':','.chr(10));
03927                 return $lines;
03928         }
03929 
03937         function makeUploadArray($extKey,$conf) {
03938                 $extPath = $this->getExtPath($extKey,$conf['type']);
03939 
03940                 if ($extPath)   {
03941 
03942                         // Get files for extension:
03943                         $fileArr = array();
03944                         $fileArr = t3lib_div::getAllFilesAndFoldersInPath($fileArr,$extPath,'',0,99,$this->excludeForPackaging);
03945 
03946                         // Calculate the total size of those files:
03947                         $totalSize = 0;
03948                         foreach($fileArr as $file)      {
03949                                 $totalSize+=filesize($file);
03950                         }
03951 
03952                         // If the total size is less than the upper limit, proceed:
03953                         if ($totalSize < $this->maxUploadSize)  {
03954 
03955                                 // Initialize output array:
03956                                 $uploadArray = array();
03957                                 $uploadArray['extKey'] = $extKey;
03958                                 $uploadArray['EM_CONF'] = $conf['EM_CONF'];
03959                                 $uploadArray['misc']['codelines'] = 0;
03960                                 $uploadArray['misc']['codebytes'] = 0;
03961 
03962                                 $uploadArray['techInfo'] = $this->makeDetailedExtensionAnalysis($extKey,$conf,1);
03963 
03964                                 // Read all files:
03965                                 foreach($fileArr as $file)      {
03966                                         $relFileName = substr($file,strlen($extPath));
03967                                         $fI = pathinfo($relFileName);
03968                                         if ($relFileName!='ext_emconf.php')     {               // This file should be dynamically written...
03969                                                 $uploadArray['FILES'][$relFileName] = array(
03970                                                 'name' => $relFileName,
03971                                                 'size' => filesize($file),
03972                                                 'mtime' => filemtime($file),
03973                                                 'is_executable' => (TYPO3_OS=='WIN' ? 0 : is_executable($file)),
03974                                                 'content' => t3lib_div::getUrl($file)
03975                                                 );
03976                                                 if (t3lib_div::inList('php,inc',strtolower($fI['extension'])))  {
03977                                                         $uploadArray['FILES'][$relFileName]['codelines']=count(explode(chr(10),$uploadArray['FILES'][$relFileName]['content']));
03978                                                         $uploadArray['misc']['codelines']+=$uploadArray['FILES'][$relFileName]['codelines'];
03979                                                         $uploadArray['misc']['codebytes']+=$uploadArray['FILES'][$relFileName]['size'];
03980 
03981                                                         // locallang*.php files:
03982                                                         if (substr($fI['basename'],0,9)=='locallang' && strstr($uploadArray['FILES'][$relFileName]['content'],'$LOCAL_LANG'))   {
03983                                                                 $uploadArray['FILES'][$relFileName]['LOCAL_LANG']=$this->getSerializedLocalLang($file,$uploadArray['FILES'][$relFileName]['content']);
03984                                                         }
03985                                                 }
03986                                                 $uploadArray['FILES'][$relFileName]['content_md5'] = md5($uploadArray['FILES'][$relFileName]['content']);
03987                                         }
03988                                 }
03989 
03990                                 // Return upload-array:
03991                                 return $uploadArray;
03992                         } else return 'Error: Total size of uncompressed upload ('.$totalSize.') exceeds '.t3lib_div::formatSize($this->maxUploadSize);
03993                 } else {
03994                         return 'Error: Extension path for extension "'.$extKey.'" not found';
03995                 }
03996         }
03997 
04006         function getSerializedLocalLang($file,$content) {
04007                 $returnParts = explode('$LOCAL_LANG',$content,2);
04008 
04009                 include($file);
04010                 if (is_array($LOCAL_LANG))      {
04011                         $returnParts[1] = serialize($LOCAL_LANG);
04012                         return $returnParts;
04013                 } else {
04014                         return array();
04015                 }
04016         }
04017 
04018 
04019 
04020 
04021 
04022 
04023 
04024 
04025 
04026 
04027         /********************************
04028         *
04029         * Managing dependencies, conflicts, priorities, load order of extension keys
04030         *
04031         *******************************/
04032 
04042         function addExtToList($extKey,$instExtInfo)     {
04043                 global $TYPO3_LOADED_EXT;
04044 
04045                         // ext_emconf.php information:
04046                 $conf = $instExtInfo[$extKey]['EM_CONF'];
04047 
04048                         // Get list of installed extensions and add this one.
04049                 $listArr = array_keys($TYPO3_LOADED_EXT);
04050                 if ($conf['priority']=='top')   {
04051                         array_unshift($listArr,$extKey);
04052                 } else {
04053                         $listArr[]=$extKey;
04054                 }
04055 
04056                         // Manage other circumstances:
04057                 $listArr = $this->managesPriorities($listArr,$instExtInfo);
04058                 $listArr = $this->removeRequiredExtFromListArr($listArr);
04059 
04060                         // Implode unique list of extensions to load and return:
04061                 $list = implode(',',array_unique($listArr));
04062                 return $list;
04063         }
04064 
04073         function checkDependencies($extKey, $conf, $instExtInfo) {
04074                 $content = '';
04075                 $depError = false;
04076                 $msg = array();
04077                 $depsolver = t3lib_div::_POST('depsolver');
04078 
04079                 foreach($conf['constraints']['depends'] as $depK => $depV)      {
04080                         if($depsolver['ignore'][$depK]) {
04081                                 $msg[] = '<br />Dependency on '.$depK.' ignored as requested.
04082                                 <input type="hidden" value="1" name="depsolver[ignore]['.$depK.']" />';
04083                                 continue;
04084                         }
04085                         if($depK == 'php') {
04086                                 if(!$depV) continue;
04087                                 $versionRange = $this->splitVersionRange($depV);
04088                                 $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!
04089                                 if ($versionRange[0]!='0.0.0' && version_compare($phpv,$versionRange[0],'<'))   {
04090                                         $msg[] = '<br />The running PHP version ('.$phpv.') is lower than required ('.$versionRange[0].')';
04091                                         $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore]['.$depK.']" id="checkIgnore_'.$depK.'" /> <label for="checkIgnore_'.$depK.'">Ignore this version requirement</label>';
04092                                         $depError = true;
04093                                         continue;
04094                                 } elseif ($versionRange[1]!='0.0.0' && version_compare($phpv,$versionRange[1],'>'))     {
04095                                         $msg[] = '<br />The running PHP version ('.$phpv.') is higher than allowed ('.$versionRange[1].')';
04096                                         $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore]['.$depK.']" id="checkIgnore_'.$depK.'" /> <label for="checkIgnore_'.$depK.'">Ignore this version requirement</label>';
04097                                         $depError = true;
04098                                         continue;
04099                                 }
04100 
04101                         } elseif ($depK == 'typo3')     {
04102                                 if (!$depV) continue;
04103 
04104                                 $versionRange = $this->splitVersionRange($depV);
04105                                 if ($versionRange[0]!='0.0.0' && version_compare(TYPO3_version,$versionRange[0],'<'))   {
04106                                         $msg[] = '<br />The running TYPO3 version ('.TYPO3_version.') is lower than required ('.$versionRange[0].')';
04107                                         $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore]['.$depK.']" id="checkIgnore_'.$depK.'" /> <label for="checkIgnore_'.$depK.'">Ignore this version requirement</label>';
04108                                         $depError = true;
04109                                         continue;
04110                                 } elseif ($versionRange[1]!='0.0.0' && version_compare(TYPO3_version,$versionRange[1],'>'))     {
04111                                         $msg[] = '<br />The running TYPO3 version ('.TYPO3_version.') is higher than allowed ('.$versionRange[1].')';
04112                                         $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore]['.$depK.']" id="checkIgnore_'.$depK.'" /> <label for="checkIgnore_'.$depK.'">Ignore this version requirement</label>';
04113                                         $depError = true;
04114                                         continue;
04115                                 }
04116                         } elseif (strlen($depK) && !t3lib_extMgm::isLoaded($depK))      {       // strlen check for braindead empty dependencies coming from extensions...
04117                                 if(!isset($instExtInfo[$depK])) {
04118                                         $msg[] = '<br />Extension "'.$depK.'" was not available in the system. Please 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]['.$depK.']" id="checkIgnore_'.$depK.'" /> <label for="checkIgnore_'.$depK.'">Ignore this extension requirement</label>';
04121                                 } else {
04122                                         $msg[] = '<br />Extension "'.$depK.'" ('.$instExtInfo[$depK]['EM_CONF']['title'].') was not installed. Please install it first.';
04123                                         $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>';
04124                                         $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore]['.$depK.']" id="checkIgnore_'.$depK.'" /> <label for="checkIgnore_'.$depK.'">Ignore this extension requirement</label>';
04125                                 }
04126                                 $depError = true;
04127                         } else {
04128                                 $versionRange = $this->splitVersionRange($depV);
04129                                 if ($versionRange[0]!='0.0.0' && version_compare($instExtInfo[$depK]['EM_CONF']['version'],$versionRange[0],'<'))       {
04130                                         $msg[] = '<br />The running version of extension "'.$depK.'" ('.$instExtInfo[$depK]['EM_CONF']['version'].') is lower than required ('.$versionRange[0].')';
04131                                         $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore]['.$depK.']" id="checkIgnore_'.$depK.'" /> <label for="checkIgnore_'.$depK.'">Ignore this version requirement</label>';
04132                                         $depError = true;
04133                                         continue;
04134                                 } elseif ($versionRange[1]!='0.0.0' && version_compare($instExtInfo[$depK]['EM_CONF']['version'],$versionRange[1],'>')) {
04135                                         $msg[] = '<br />The running version of extension "'.$depK.'" ('.$instExtInfo[$depK]['EM_CONF']['version'].') is higher than allowed ('.$versionRange[1].')';
04136                                         $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore]['.$depK.']" id="checkIgnore_'.$depK.'" /> <label for="checkIgnore_'.$depK.'">Ignore this version requirement</label>';
04137                                         $depError = true;
04138                                         continue;
04139                                 }
04140                         }
04141                 }
04142                 if($depError) {
04143                         $content.= $this->doc->section('Dependency Error',implode('<br />',$msg),0,1,2);
04144                 }
04145 
04146                         // Check conflicts with other extensions:
04147                 $conflictError = false;
04148                 $msg = array();
04149                 foreach((array)$conf['constraints']['conflicts'] as $conflictK => $conflictV)   {
04150                         if($depsolver['ignore'][$conflictK]) {
04151                                 $msg[] = '<br />Conflict with '.$conflictK.' ignored as requested.
04152                                 <input type="hidden" value="1" name="depsolver[ignore]['.$conflictK.']" />';
04153                                 continue;
04154                         }
04155                         if (t3lib_extMgm::isLoaded($conflictK)) {
04156                                 $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.'".';
04157                                 $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>';
04158                                 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore]['.$conflictK.']" id="checkIgnore_'.$conflictK.'" /> <label for="checkIgnore_'.$conflictK.'">Ignore this conflict error</label>';
04159                                 $conflictError = true;
04160                         }
04161                 }
04162                 if($conflictError) {
04163                         $content.= $this->doc->section('Conflict Error',implode('<br />',$msg),0,1,2);
04164                 }
04165 
04166                         // Check suggests on other extensions:
04167                 if(is_array($conf['constraints']['suggests'])) {
04168                         $suggestion = false;
04169                         $msg = array();
04170                         foreach($conf['constraints']['suggests'] as $suggestK => $suggestV)     {
04171                                 if($depsolver['ignore'][$suggestK]) {
04172                                         $msg[] = '<br />Suggestion of '.$suggestK.' acknowledged.
04173                                 <input type="hidden" value="1" name="depsolver[ignore]['.$suggestK.']" />';
04174                                         continue;
04175                                 }
04176                                 if (!t3lib_extMgm::isLoaded($suggestK)) {
04177                                         if (!isset($instExtInfo[$suggestK]))    {
04178                                                 $msg[] = 'Extension "'.$suggestK.'" was not available in the system. You may want to import it from the TYPO3 Extension Repository.';
04179                                                 $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>';
04180                                                 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore]['.$suggestK.']" id="checkIgnore_'.$suggestK.'" /> <label for="checkIgnore_'.$suggestK.'">Ignore this suggestion</label>';
04181                                         } else {
04182                                                 $msg[] = 'Extension "'.$suggestK.'" ('.$instExtInfo[$suggestK]['EM_CONF']['title'].') was not installed. You may want to install it.';
04183                                                 $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>';
04184                                                 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore]['.$suggestK.']" id="checkIgnore_'.$suggestK.'" /> <label for="checkIgnore_'.$suggestK.'">Ignore this suggestion</label>';
04185                                         }
04186                                         $suggestion = true;
04187                                 }
04188                         }
04189                         if($suggestion) {
04190                                 $content .= $this->doc->section('Extensions suggested by extension "'.$extKey.'"',implode('<br />',$msg),0,1,1);
04191                         }
04192                 }
04193 
04194                 if($depError || $conflictError || $suggestion) {
04195                         foreach($this->CMD as $k => $v) {
04196                                 $content .= '<input type="hidden" name="CMD['.$k.']" value="'.$v.'" />';
04197                         }
04198                         $content .= '<br /><br /><input type="submit" value="Try again" />';
04199 
04200                         return array('returnCode' => false, 'html' => $content);
04201                 }
04202 
04203                 return array('returnCode' => true);
04204         }
04205 
04215         function removeExtFromList($extKey,$instExtInfo)        {
04216                 global $TYPO3_LOADED_EXT;
04217 
04218                         // Initialize:
04219                 $depList = array();
04220                 $listArr = array_keys($TYPO3_LOADED_EXT);
04221 
04222                         // 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!
04223                 foreach($listArr as $k => $ext) {
04224                         if ($instExtInfo[$ext]['EM_CONF']['dependencies'])      {
04225                                 $dep = t3lib_div::trimExplode(',',$instExtInfo[$ext]['EM_CONF']['dependencies'],1);
04226                                 if (in_array($extKey,$dep))     {
04227                                         $depList[] = $ext;
04228                                 }
04229                         }
04230                         if (!strcmp($ext,$extKey))      unset($listArr[$k]);
04231                 }
04232 
04233                         // Returns either error or the new list
04234                 if (count($depList))    {
04235                         $msg = 'The extension(s) "'.implode(', ',$depList).'" depends on the extension you are trying to remove. The operation was not completed.';
04236                         $this->content.=$this->doc->section('Dependency Error',$msg,0,1,2);
04237                         return -1;
04238                 } else {
04239                         $listArr = $this->removeRequiredExtFromListArr($listArr);
04240                         $list = implode(',',array_unique($listArr));
04241                         return $list;
04242                 }
04243         }
04244 
04252         function removeRequiredExtFromListArr($listArr) {
04253                 foreach($listArr as $k => $ext) {
04254                         if (in_array($ext,$this->requiredExt) || !strcmp($ext,'_CACHEFILE'))    unset($listArr[$k]);
04255                 }
04256                 return $listArr;
04257         }
04258 
04267         function managesPriorities($listArr,$instExtInfo)       {
04268 
04269                         // Initialize:
04270                 $levels = array(
04271                         'top' => array(),
04272                         'middle' => array(),
04273                         'bottom' => array(),
04274                 );
04275 
04276                         // Traverse list of extensions:
04277                 foreach($listArr as $ext)       {
04278                         $prio = trim($instExtInfo[$ext]['EM_CONF']['priority']);
04279                         switch((string)$prio)   {
04280                                 case 'top':
04281                                 case 'bottom':
04282                                         $levels[$prio][] = $ext;
04283                                         break;
04284                                 default:
04285                                         $levels['middle'][] = $ext;
04286                                         break;
04287                         }
04288                 }
04289                 return array_merge(
04290                         $levels['top'],
04291                         $levels['middle'],
04292                         $levels['bottom']
04293                 );
04294         }
04295 
04296 
04297 
04298 
04299 
04300 
04301 
04302 
04303 
04304 
04305         /*******************************
04306         *
04307         * System Update functions (based on extension requirements)
04308         *
04309         ******************************/
04310 
04319         function checkClearCache($extInfo)      {
04320                 if ($extInfo['EM_CONF']['clearCacheOnLoad'])    {
04321                         if (t3lib_div::_POST('_clear_all_cache'))       {               // Action: Clearing the cache
04322                                 $tce = t3lib_div::makeInstance('t3lib_TCEmain');
04323                                 $tce->stripslashes_values = 0;
04324                                 $tce->start(Array(),Array());
04325                                 $tce->clear_cacheCmd('all');
04326                         } else {        // Show checkbox for clearing cache:
04327                                 $content.= '
04328                                         <br />
04329                                         <h3>Clear cache</h3>
04330                                         <p>This extension requests the cache to be cleared when it is installed/removed.<br />
04331                                                 <label for="check_clear_all_cache">Clear all cache:</label> <input type="checkbox" name="_clear_all_cache" id="check_clear_all_cache" checked="checked" value="1" /><br />
04332                                                 </p>
04333                                 ';
04334                         }
04335                 }
04336                 return $content;
04337         }
04338 
04346         function checkUploadFolder($extKey,$extInfo)    {
04347 
04348                         // Checking for upload folder:
04349                 $uploadFolder = PATH_site.$this->ulFolder($extKey);
04350                 if ($extInfo['EM_CONF']['uploadfolder'] && !@is_dir($uploadFolder))     {
04351                         if (t3lib_div::_POST('_uploadfolder'))  {       // CREATE dir:
04352                                 t3lib_div::mkdir($uploadFolder);
04353                                 $indexContent = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
04354 <HTML>
04355 <HEAD>
04356         <TITLE></TITLE>
04357 <META http-equiv=Refresh Content="0; Url=../../">
04358 </HEAD>
04359 </HTML>';
04360                                 t3lib_div::writeFile($uploadFolder.'index.html',$indexContent);
04361                         } else {        // Show checkbox / HTML for creation:
04362                                 $content.='
04363                                         <br /><h3>Create upload folder</h3>
04364                                         <p>The extension requires the upload folder "'.$this->ulFolder($extKey).'" to exist.<br />
04365                                 <label for="check_uploadfolder">Create directory "'.$this->ulFolder($extKey).'":</label> <input type="checkbox" name="_uploadfolder" id="check_uploadfolder" checked="checked" value="1" /><br />
04366                                 </p>
04367                                 ';
04368                         }
04369                 }
04370 
04371                         // Additional directories that should be created:
04372                 if ($extInfo['EM_CONF']['createDirs'])  {
04373                         $createDirs = array_unique(t3lib_div::trimExplode(',',$extInfo['EM_CONF']['createDirs'],1));
04374 
04375                         foreach($createDirs as $crDir)  {
04376                                 if (!@is_dir(PATH_site.$crDir)) {
04377                                         if (t3lib_div::_POST('_createDir_'.md5($crDir)))        {       // CREATE dir:
04378 
04379                                                         // Initialize:
04380                                                 $crDirStart = '';
04381                                                 $dirs_in_path = explode('/',preg_replace('/\/$/','',$crDir));
04382 
04383                                                         // Traverse each part of the dir path and create it one-by-one:
04384                                                 foreach($dirs_in_path as $dirP) {
04385                                                         if (strcmp($dirP,''))   {
04386                                                                 $crDirStart.= $dirP.'/';
04387                                                                 if (!@is_dir(PATH_site.$crDirStart))    {
04388                                                                         t3lib_div::mkdir(PATH_site.$crDirStart);
04389                                                                         $finalDir = PATH_site.$crDirStart;
04390                                                                 }
04391                                                         } else {
04392                                                                 die('ERROR: The path "'.PATH_site.$crDir.'" could not be created.');
04393                                                         }
04394                                                 }
04395                                                 if ($finalDir)  {
04396                                                         $indexContent = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
04397 <HTML>
04398 <HEAD>
04399         <TITLE></TITLE>
04400 <META http-equiv=Refresh Content="0; Url=/">
04401 </HEAD>
04402 </HTML>';
04403                                                         t3lib_div::writeFile($finalDir.'index.html',$indexContent);
04404                                                 }
04405                                         } else {        // Show checkbox / HTML for creation:
04406                                                 $md5CrDir = md5($crDir);
04407                                                 $content.='
04408                                                         <br />
04409                                                         <h3>Create folder</h3>
04410                                                         <p>The extension requires the folder "'.$crDir.'" to exist.<br />
04411                                                 <label for="check_createDir_'.$md5CrDir.'">Create directory "'.$crDir.'":</label> <input type="checkbox" name="_createDir_'.$md5CrDir.'" id="check_createDir_'.$md5CrDir.'" checked="checked" value="1" /><br />
04412                                                 </p>
04413                                                 ';
04414                                         }
04415                                 }
04416                         }
04417                 }
04418 
04419                 return $content;
04420         }
04421 
04432         function checkDBupdates($extKey,$extInfo,$infoOnly=0)   {
04433 
04434                         // Initializing Install Tool object:
04435                 $instObj = new t3lib_install;
04436                 $instObj->INSTALL = t3lib_div::_GP('TYPO3_INSTALL');
04437                 $dbStatus = array();
04438 
04439                         // Updating tables and fields?
04440                 if (is_array($extInfo['files']) && in_array('ext_tables.sql',$extInfo['files']))        {
04441                         $fileContent = t3lib_div::getUrl($this->getExtPath($extKey,$extInfo['type']).'ext_tables.sql');
04442 
04443                         $FDfile = $instObj->getFieldDefinitions_sqlContent($fileContent);
04444                         if (count($FDfile))     {
04445                                 $FDdb = $instObj->getFieldDefinitions_database(TYPO3_db);
04446                                 $diff = $instObj->getDatabaseExtra($FDfile, $FDdb);
04447                                 $update_statements = $instObj->getUpdateSuggestions($diff);
04448 
04449                                 $dbStatus['structure']['tables_fields'] = $FDfile;
04450                                 $dbStatus['structure']['diff'] = $diff;
04451 
04452                                         // Updating database...
04453                                 if (!$infoOnly && is_array($instObj->INSTALL['database_update']))       {
04454                                         $instObj->performUpdateQueries($update_statements['add'],$instObj->INSTALL['database_update']);
04455                                         $instObj->performUpdateQueries($update_statements['change'],$instObj->INSTALL['database_update']);
04456                                         $instObj->performUpdateQueries($update_statements['create_table'],$instObj->INSTALL['database_update']);
04457                                 } else {
04458                                         $content.=$instObj->generateUpdateDatabaseForm_checkboxes($update_statements['add'],'Add fields');
04459                                         $content.=$instObj->generateUpdateDatabaseForm_checkboxes($update_statements['change'],'Changing fields',1,0,$update_statements['change_currentValue']);
04460                                         $content.=$instObj->generateUpdateDatabaseForm_checkboxes($update_statements['create_table'],'Add tables');
04461                                 }
04462                         }
04463                 }
04464 
04465                         // Importing static tables?
04466                 if (is_array($extInfo['files']) && in_array('ext_tables_static+adt.sql',$extInfo['files']))     {
04467                         $fileContent = t3lib_div::getUrl($this->getExtPath($extKey,$extInfo['type']).'ext_tables_static+adt.sql');
04468 
04469                         $statements = $instObj->getStatementArray($fileContent,1);
04470                         list($statements_table, $insertCount) = $instObj->getCreateTables($statements,1);
04471 
04472                                 // Execute import of static table content:
04473                         if (!$infoOnly && is_array($instObj->INSTALL['database_import']))       {
04474 
04475                                         // Traverse the tables
04476                                 foreach($instObj->INSTALL['database_import'] as $table => $md5str)      {
04477                                         if ($md5str == md5($statements_table[$table]))  {
04478                                                 $GLOBALS['TYPO3_DB']->admin_query('DROP TABLE IF EXISTS '.$table);
04479                                                 $GLOBALS['TYPO3_DB']->admin_query($statements_table[$table]);
04480 
04481                                                 if ($insertCount[$table])       {
04482                                                         $statements_insert = $instObj->getTableInsertStatements($statements, $table);
04483 
04484                                                         foreach($statements_insert as $v)       {
04485                                                                 $GLOBALS['TYPO3_DB']->admin_query($v);
04486                                                         }
04487                                                 }
04488                                         }
04489                                 }
04490                         } else {
04491                                 $whichTables = $instObj->getListOfTables();
04492                                 if (count($statements_table))   {
04493                                         $out = '';
04494                                         foreach($statements_table as $table => $definition)     {
04495                                                 $exist = isset($whichTables[$table]);
04496 
04497                                                 $dbStatus['static'][$table]['exists'] = $exist;
04498                                                 $dbStatus['static'][$table]['count'] = $insertCount[$table];
04499 
04500                                                 $out.= '<tr>
04501                                                         <td><input type="checkbox" name="TYPO3_INSTALL[database_import]['.$table.']" checked="checked" value="'.md5($definition).'" /></td>
04502                                                         <td><strong>'.$table.'</strong></td>
04503                                                         <td><img src="clear.gif" width="10" height="1" alt="" /></td>
04504                                                         <td nowrap="nowrap">'.($insertCount[$table]?'Rows: '.$insertCount[$table]:'').'</td>
04505                                                         <td><img src="clear.gif" width="10" height="1" alt="" /></td>
04506                                                         <td nowrap="nowrap">'.($exist?'<img src="'.$GLOBALS['BACK_PATH'].'gfx/icon_warning.gif" width="18" height="16" align="top" alt="" />Table exists!':'').'</td>
04507                                                         </tr>';
04508                                         }
04509                                         $content.= '
04510                                                 <br />
04511                                                 <h3>Import static data</h3>
04512                                                 <table border="0" cellpadding="0" cellspacing="0">'.$out.'</table>';
04513                                 }
04514                         }
04515                 }
04516 
04517                         // Return array of information if $infoOnly, otherwise content.
04518                 return $infoOnly ? $dbStatus : $content;
04519         }
04520 
04529         function forceDBupdates($extKey, $extInfo)      {
04530                 $instObj = new t3lib_install;
04531 
04532                         // Updating tables and fields?
04533                 if (is_array($extInfo['files']) && in_array('ext_tables.sql',$extInfo['files']))        {
04534                         $fileContent = t3lib_div::getUrl($this->getExtPath($extKey,$extInfo['type']).'ext_tables.sql');
04535 
04536                         $FDfile = $instObj->getFieldDefinitions_sqlContent($fileContent);
04537                         if (count($FDfile))     {
04538                                 $FDdb = $instObj->getFieldDefinitions_database(TYPO3_db);
04539                                 $diff = $instObj->getDatabaseExtra($FDfile, $FDdb);
04540                                 $update_statements = $instObj->getUpdateSuggestions($diff);
04541 
04542                                 foreach((array)$update_statements['add'] as $string)    {
04543                                         $GLOBALS['TYPO3_DB']->admin_query($string);
04544                                 }
04545                                 foreach((array)$update_statements['change'] as $string) {
04546                                         $GLOBALS['TYPO3_DB']->admin_query($string);
04547                                 }
04548                                 foreach((array)$update_statements['create_table'] as $string)   {
04549                                         $GLOBALS['TYPO3_DB']->admin_query($string);
04550                                 }
04551                         }
04552                 }
04553 
04554                         // Importing static tables?
04555                 if (is_array($extInfo['files']) && in_array('ext_tables_static+adt.sql',$extInfo['files']))     {
04556                         $fileContent = t3lib_div::getUrl($this->getExtPath($extKey,$extInfo['type']).'ext_tables_static+adt.sql');
04557 
04558                         $statements = $instObj->getStatementArray($fileContent,1);
04559                         list($statements_table, $insertCount) = $instObj->getCreateTables($statements,1);
04560 
04561                                 // Traverse the tables
04562                         foreach($statements_table as $table => $query)  {
04563                                 $GLOBALS['TYPO3_DB']->admin_query('DROP TABLE IF EXISTS '.$table);
04564                                 $GLOBALS['TYPO3_DB']->admin_query($query);
04565 
04566                                 if ($insertCount[$table])       {
04567                                         $statements_insert = $instObj->getTableInsertStatements($statements, $table);
04568 
04569                                         foreach($statements_insert as $v)       {
04570                                                 $GLOBALS['TYPO3_DB']->admin_query($v);
04571                                         }
04572                                 }
04573                         }
04574                 }
04575         }
04576 
04587         function tsStyleConfigForm($extKey,$extInfo,$output=0,$script='',$addFields='') {
04588                 global $TYPO3_CONF_VARS;
04589 
04590                         // Initialize:
04591                 $absPath = $this->getExtPath($extKey,$extInfo['type']);
04592                 $relPath = $this->typeRelPaths[$extInfo['type']].$extKey.'/';
04593 
04594                         // Look for template file for form:
04595                 if (@is_file($absPath.'ext_conf_template.txt')) {
04596 
04597                                 // Load tsStyleConfig class and parse configuration template:
04598                         $tsStyleConfig = t3lib_div::makeInstance('t3lib_tsStyleConfig');
04599                         $tsStyleConfig->doNotSortCategoriesBeforeMakingForm = TRUE;
04600                         $theConstants = $tsStyleConfig->ext_initTSstyleConfig(
04601                         t3lib_div::getUrl($absPath.'ext_conf_template.txt'),
04602                         $relPath,
04603                         $absPath,
04604                         $GLOBALS['BACK_PATH']
04605                         );
04606 
04607                                 // Load the list of resources.
04608                         $tsStyleConfig->ext_loadResources($absPath.'res/');
04609 
04610                                 // Load current value:
04611                         $arr = unserialize($TYPO3_CONF_VARS['EXT']['extConf'][$extKey]);
04612                         $arr = is_array($arr) ? $arr : array();
04613 
04614                                 // Call processing function for constants config and data before write and form rendering:
04615                         if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/mod/tools/em/index.php']['tsStyleConfigForm']))      {
04616                                 $_params = array('fields' => &$theConstants, 'data' => &$arr, 'extKey' => $extKey);
04617                                 foreach($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/mod/tools/em/index.php']['tsStyleConfigForm'] as $_funcRef)       {
04618                                         t3lib_div::callUserFunction($_funcRef,$_params,$this);
04619                                 }
04620                                 unset($_params);
04621                         }
04622 
04623                                 // If saving operation is done:
04624                         if (t3lib_div::_POST('submit')) {
04625                                 $tsStyleConfig->ext_procesInput(t3lib_div::_POST(),array(),$theConstants,array());
04626                                 $arr = $tsStyleConfig->ext_mergeIncomingWithExisting($arr);
04627                                 $this->writeTsStyleConfig($extKey,$arr);
04628                         }
04629 
04630                                 // Setting value array
04631                         $tsStyleConfig->ext_setValueArray($theConstants,$arr);
04632 
04633                                 // Getting session data:
04634                         $MOD_MENU = array();
04635                         $MOD_MENU['constant_editor_cat'] = $tsStyleConfig->ext_getCategoriesForModMenu();
04636                         $MOD_SETTINGS = t3lib_BEfunc::getModuleData($MOD_MENU, t3lib_div::_GP('SET'), 'xMod_test');
04637 
04638                                 // Resetting the menu (stop)
04639                         if (count($MOD_MENU)>1) {
04640                                 $menu = 'Category: '.t3lib_BEfunc::getFuncMenu(0,'SET[constant_editor_cat]',$MOD_SETTINGS['constant_editor_cat'],$MOD_MENU['constant_editor_cat'],'','&CMD[showExt]='.$extKey);
04641                                 $this->content.=$this->doc->section('','<span class="nobr">'.$menu.'</span>');
04642                                 $this->content.=$this->doc->spacer(10);
04643                         }
04644 
04645                                 // Category and constant editor config:
04646                         $form = '
04647                                 <table border="0" cellpadding="0" cellspacing="0" width="600">
04648                                         <tr>
04649                                                 <td>'.$tsStyleConfig->ext_getForm($MOD_SETTINGS['constant_editor_cat'],$theConstants,$script,$addFields).'</td>
04650                                         </tr>
04651                                 </table>';
04652                         if ($output)    {
04653                                 return $form;
04654                         } else {
04655                                 $this->content.=$this->doc->section('','</form>'.$form.'<form>');
04656                         }
04657                 }
04658         }
04659 
04660 
04661 
04662 
04663 
04664 
04665 
04666 
04667 
04668 
04669         /*******************************
04670         *
04671         * Dumping database (MySQL compliant)
04672         *
04673         ******************************/
04674 
04682         function dumpTableAndFieldStructure($arr)       {
04683                 $tables = array();
04684 
04685                 if (count($arr))        {
04686 
04687                         // Get file header comment:
04688                         $tables[] = $this->dumpHeader();
04689 
04690                         // Traverse tables, write each table/field definition:
04691                         foreach($arr as $table => $fieldKeyInfo)        {
04692                                 $tables[] = $this->dumpTableHeader($table,$fieldKeyInfo);
04693                         }
04694                 }
04695 
04696                 // Return result:
04697                 return implode(chr(10).chr(10).chr(10),$tables);
04698         }
04699 
04707         function dumpStaticTables($tableList)   {
04708                 $instObj = new t3lib_install;
04709                 $dbFields = $instObj->getFieldDefinitions_database(TYPO3_db);
04710 
04711                 $out = '';
04712                 $parts = t3lib_div::trimExplode(',',$tableList,1);
04713 
04714                 // Traverse the table list and dump each:
04715                 foreach($parts as $table)       {
04716                         if (is_array($dbFields[$table]['fields']))      {
04717                                 $dHeader = $this->dumpHeader();
04718                                 $header = $this->dumpTableHeader($table,$dbFields[$table],1);
04719                                 $insertStatements = $this->dumpTableContent($table,$dbFields[$table]['fields']);
04720 
04721                                 $out.= $dHeader.chr(10).chr(10).chr(10).
04722                                 $header.chr(10).chr(10).chr(10).
04723                                 $insertStatements.chr(10).chr(10).chr(10);
04724                         } else {
04725                                 die('Fatal error: Table for dump not found in database...');
04726                         }
04727                 }
04728                 return $out;
04729         }
04730 
04736         function dumpHeader()   {
04737                 return trim('
04738 # TYPO3 Extension Manager dump 1.1
04739 #
04740 # Host: '.TYPO3_db_host.'    Database: '.TYPO3_db.'
04741 #--------------------------------------------------------
04742 ');
04743         }
04744 
04753         function dumpTableHeader($table,$fieldKeyInfo,$dropTableIfExists=0)     {
04754                 $lines = array();
04755                 $dump = '';
04756 
04757                 // Create field definitions
04758                 if (is_array($fieldKeyInfo['fields']))  {
04759                         foreach($fieldKeyInfo['fields'] as $fieldN => $data)    {
04760                                 $lines[]='  '.$fieldN.' '.$data;
04761                         }
04762                 }
04763 
04764                 // Create index key definitions
04765                 if (is_array($fieldKeyInfo['keys']))    {
04766                         foreach($fieldKeyInfo['keys'] as $fieldN => $data)      {
04767                                 $lines[]='  '.$data;
04768                         }
04769                 }
04770 
04771                 // Compile final output:
04772                 if (count($lines))      {
04773                         $dump = trim('
04774 #
04775 # Table structure for table "'.$table.'"
04776 #
04777 '.($dropTableIfExists ? 'DROP TABLE IF EXISTS '.$table.';
04778 ' : '').'CREATE TABLE '.$table.' (
04779 '.implode(','.chr(10),$lines).'
04780 );'
04781 );
04782                 }
04783 
04784                 return $dump;
04785         }
04786 
04795         function dumpTableContent($table,$fieldStructure)       {
04796 
04797                 // Substitution of certain characters (borrowed from phpMySQL):
04798                 $search = array('\\', '\'', "\x00", "\x0a", "\x0d", "\x1a");
04799                 $replace = array('\\\\', '\\\'', '\0', '\n', '\r', '\Z');
04800 
04801                 $lines = array();
04802 
04803                 // Select all rows from the table:
04804                 $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, '');
04805 
04806                 // Traverse the selected rows and dump each row as a line in the file:
04807                 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
04808                         $values = array();
04809                         reset($fieldStructure);
04810                         while(list($field) = each($fieldStructure))     {
04811                                 $values[] = isset($row[$field]) ? "'".str_replace($search, $replace, $row[$field])."'" : 'NULL';
04812                         }
04813                         $lines[] = 'INSERT INTO '.$table.' VALUES ('.implode(', ',$values).');';
04814                 }
04815 
04816                 // Free DB result:
04817                 $GLOBALS['TYPO3_DB']->sql_free_result($result);
04818 
04819                 // Implode lines and return:
04820                 return implode(chr(10),$lines);
04821         }
04822 
04830         function getTableAndFieldStructure($parts)      {
04831                 // Instance of install tool
04832                 $instObj = new t3lib_install;
04833                 $dbFields = $instObj->getFieldDefinitions_database(TYPO3_db);
04834 
04835 
04836                 $outTables = array();
04837                 foreach($parts as $table)       {
04838                         $tP = explode('.',$table);
04839                         if ($tP[0] && isset($dbFields[$tP[0]])) {
04840                                 if ($tP[1])     {
04841                                         $kfP = explode('KEY:',$tP[1],2);
04842                                         if (count($kfP)==2 && !$kfP[0]) {       // key:
04843                                                 if (isset($dbFields[$tP[0]]['keys'][$kfP[1]]))  $outTables[$tP[0]]['keys'][$kfP[1]] = $dbFields[$tP[0]]['keys'][$kfP[1]];
04844                                         } else {
04845                                                 if (isset($dbFields[$tP[0]]['fields'][$tP[1]])) $outTables[$tP[0]]['fields'][$tP[1]] = $dbFields[$tP[0]]['fields'][$tP[1]];
04846                                         }
04847                                 } else {
04848                                         $outTables[$tP[0]] = $dbFields[$tP[0]];
04849                                 }
04850                         }
04851                 }
04852 
04853                 return $outTables;
04854         }
04855 
04856 
04857 
04858 
04859 
04860 
04861 
04862 
04863 
04864 
04865         /*******************************
04866         *
04867         * TER Communication functions
04868         *
04869         ******************************/
04870 
04871 
04872 
04880         function uploadExtensionToTER($em)      {
04881                 $msg = '';
04882                 $response = $this->terConnection->uploadToTER($em);
04883 
04884                 if(!is_array($response)) return $response;
04885 
04886                 if($response['resultCode']==TX_TER_RESULT_EXTENSIONSUCCESSFULLYUPLOADED) {
04887                         $em['extInfo']['EM_CONF']['version'] = $response['version'];
04888                         $response['resultMessages'][] = 'The extension is now version: '.$response['version'];
04889                         $response['resultMessages'][] = $this->updateLocalEM_CONF($em['extKey'],$em['extInfo']);
04890                 }
04891 
04892                 $msg = '<ul><li>'.implode('</li><li>',$response['resultMessages']).'</li></ul>';
04893                 return $msg;
04894         }
04895 
04896 
04897 
04898 
04899 
04900 
04901 
04902 
04903 
04904 
04905         /************************************
04906         *
04907         * Various helper functions
04908         *
04909         ************************************/
04910 
04918         function listOrderTitle($listOrder,$key)        {
04919                 switch($listOrder)      {
04920                         case 'cat':
04921                                 return isset($this->categories[$key])?$this->categories[$key]:'<em>['.$key.']</em>';
04922                                 break;
04923                         case 'author_company':
04924                                 return $key;
04925                                 break;
04926                         case 'state':
04927                                 return $this->states[$key];
04928                                 break;
04929                         case 'type':
04930                                 return $this->typeDescr[$key];
04931                                 break;
04932                 }
04933         }
04934 
04943         function makeVersion($v,$mode)  {
04944                 $vDat = $this->renderVersion($v);
04945                 return $vDat['version_'.$mode];
04946         }
04947 
04955         function renderVersion($v,$raise='')    {
04956                 $parts = t3lib_div::intExplode('.',$v.'..');
04957                 $parts[0] = t3lib_div::intInRange($parts[0],0,999);
04958                 $parts[1] = t3lib_div::intInRange($parts[1],0,999);
04959                 $parts[2] = t3lib_div::intInRange($parts[2],0,999);
04960 
04961                 switch((string)$raise)  {
04962                         case 'main':
04963                                 $parts[0]++;
04964                                 $parts[1]=0;
04965                                 $parts[2]=0;
04966                                 break;
04967                         case 'sub':
04968                                 $parts[1]++;
04969                                 $parts[2]=0;
04970                                 break;
04971                         case 'dev':
04972                                 $parts[2]++;
04973                                 break;
04974                 }
04975 
04976                 $res = array();
04977                 $res['version'] = $parts[0].'.'.$parts[1].'.'.$parts[2];
04978                 $res['version_int'] = intval($parts[0]*1000000+$parts[1]*1000+$parts[2]);
04979                 $res['version_main'] = $parts[0];
04980                 $res['version_sub'] = $parts[1];
04981                 $res['version_dev'] = $parts[2];
04982 
04983                 return $res;
04984         }
04985 
04992         function ulFolder($extKey)      {
04993                 return 'uploads/tx_'.str_replace('_','',$extKey).'/';
04994         }
04995 
05001         function importAtAll()  {
05002                 return ($GLOBALS['TYPO3_CONF_VARS']['EXT']['allowGlobalInstall'] || $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowLocalInstall']);
05003         }
05004 
05012         function importAsType($type,$lockType='')       {
05013                 switch($type)   {
05014                         case 'G':
05015                                 return $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowGlobalInstall'] && (!$lockType || !strcmp($lockType,$type));
05016                                 break;
05017                         case 'L':
05018                                 return $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowLocalInstall'] && (!$lockType || !strcmp($lockType,$type));
05019                                 break;
05020                         case 'S':
05021                                 return $this->systemInstall;
05022                                 break;
05023                         default:
05024                                 return false;
05025                 }
05026         }
05027 
05034         function deleteAsType($type)    {
05035                 switch($type)   {
05036                         case 'G':
05037                                 return $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowGlobalInstall'];
05038                                 break;
05039                         case 'L':
05040                                 return $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowLocalInstall'];
05041                                 break;
05042                         default:
05043                                 return false;
05044                 }
05045         }
05046 
05055         function versionDifference($v1,$v2,$div=1)      {
05056                 return floor($this->makeVersion($v1,'int')/$div) > floor($this->makeVersion($v2,'int')/$div);
05057         }
05058 
05067         function first_in_array($str,$array,$caseInsensitive=FALSE)     {
05068                 if ($caseInsensitive)   $str = strtolower($str);
05069                 if (is_array($array))   {
05070                         foreach($array as $cl)  {
05071                                 if ($caseInsensitive)   $cl = strtolower($cl);
05072                                 if (t3lib_div::isFirstPartOfStr($cl,$str))      return true;
05073                         }
05074                 }
05075                 return false;
05076         }
05077 
05085         function includeEMCONF($path,$_EXTKEY)  {
05086                 @include($path);
05087                 if(is_array($EM_CONF[$_EXTKEY])) {
05088                         return $this->fixEMCONF($EM_CONF[$_EXTKEY]);
05089                 }
05090                 return false;
05091         }
05092 
05100         function searchExtension($extKey,$row) {
05101                 if ($this->lookUpStr)   {
05102                         return (
05103                         stristr($extKey,$this->lookUpStr) ||
05104                         stristr($row['EM_CONF']['title'],$this->lookUpStr) ||
05105                         stristr($row['EM_CONF']['description'],$this->lookUpStr) ||
05106                         stristr($row['EM_CONF']['author'],$this->lookUpStr) ||
05107                         stristr($row['EM_CONF']['author_company'],$this->lookUpStr)
05108                         );
05109                 } else return true;
05110         }
05111 }
05112 
05113 // Include extension?
05114 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/mod/tools/em/index.php'])    {
05115         include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/mod/tools/em/index.php']);
05116 }
05117 
05118 ?>


Généré par TYPO3 Ameos avec  doxygen 1.4.6