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