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->useUnsupported = $this->MOD_SETTINGS['display_unsupported'];
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_unsupported' => '',
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 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 unsupported extensions:</td>
00929 <td>'.t3lib_BEfunc::getFuncCheck(0,'SET[display_unsupported]',$this->MOD_SETTINGS['display_unsupported']).'</td>
00930 </tr>
00931 </table>
00932 <strong>Notice:</strong> Make sure you know what consequences enabling this checkbox might have. Check the information on typo3.org about security reviewing!
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 '.$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 if (is_array($directInput)) {
01627 $fetchData = array($directInput,'');
01628 $loc = ($loc==='G'||$loc==='S') ? $loc : 'L';
01629 } elseif ($uploadFlag) {
01630 if ($_FILES['upload_ext_file']['tmp_name']) {
01631
01632
01633 $uploadedTempFile = t3lib_div::upload_to_tempfile($_FILES['upload_ext_file']['tmp_name']);
01634 $fileContent = t3lib_div::getUrl($uploadedTempFile);
01635 t3lib_div::unlink_tempfile($uploadedTempFile);
01636
01637
01638 $fetchData = $this->terConnection->decodeExchangeData($fileContent);
01639
01640 if (is_array($fetchData)) {
01641 $extKey = $fetchData[0]['extKey'];
01642 if ($extKey) {
01643 if (!$this->CMD['uploadOverwrite']) {
01644 $loc = ($loc==='G'||$loc==='S') ? $loc : 'L';
01645 $comingExtPath = PATH_site.$this->typePaths[$loc].$extKey.'/';
01646 if (@is_dir($comingExtPath)) {
01647 return 'Extension was already present in "'.$comingExtPath.'" - and the overwrite flag was not set! So nothing done...';
01648 }
01649 }
01650 } else return 'No extension key in file. Strange...';
01651 } else return 'Wrong file format. No data recognized, '.$fetchData;
01652 } else return 'No file uploaded! Probably the file was too large for PHPs internal limit for uploadable files.';
01653 } else {
01654 $this->xmlhandler->loadExtensionsXML();
01655
01656
01657 if(!strlen($version)) {
01658 $versions = array_keys($this->xmlhandler->extensionsXML[$extKey]['versions']);
01659 $version = end($versions);
01660 }
01661 $fetchData = $this->terConnection->fetchExtension($extKey, $version, $this->xmlhandler->extensionsXML[$extKey]['versions'][$version]['t3xfilemd5'], $this->getMirrorURL());
01662 }
01663
01664
01665 if ($this->importAsType($loc)) {
01666 if (is_array($fetchData)) {
01667 if ($fetchData[0]['extKey'] && is_array($fetchData[0]['FILES'])) {
01668 $extKey = $fetchData[0]['extKey'];
01669 if(!isset($fetchData[0]['EM_CONF']['constraints'])) $fetchData[0]['EM_CONF']['constraints'] = $this->xmlhandler->extensionsXML[$extKey]['versions'][$version]['dependencies'];
01670 $EM_CONF = $this->fixEMCONF($fetchData[0]['EM_CONF']);
01671 if (!$EM_CONF['lockType'] || !strcmp($EM_CONF['lockType'],$loc)) {
01672
01673 list($instExtInfo,)=$this->getInstalledExtensions();
01674 $depStatus = $this->checkDependencies($extKey, $EM_CONF, $instExtInfo);
01675 if(t3lib_extMgm::isLoaded($extKey) && !$depStatus['returnCode']) {
01676 $this->content .= $depStatus['html'];
01677 } else {
01678 $res = $this->clearAndMakeExtensionDir($fetchData[0],$loc,$dontDelete);
01679 if (is_array($res)) {
01680 $extDirPath = trim($res[0]);
01681 if ($extDirPath && @is_dir($extDirPath) && substr($extDirPath,-1)=='/') {
01682
01683 $emConfFile = $this->construct_ext_emconf_file($extKey,$EM_CONF);
01684 $dirs = $this->extractDirsFromFileList(array_keys($fetchData[0]['FILES']));
01685
01686 $res = $this->createDirsInPath($dirs,$extDirPath);
01687 if (!$res) {
01688 $writeFiles = $fetchData[0]['FILES'];
01689 $writeFiles['ext_emconf.php']['content'] = $emConfFile;
01690 $writeFiles['ext_emconf.php']['content_md5'] = md5($emConfFile);
01691
01692
01693 foreach($writeFiles as $theFile => $fileData) {
01694 t3lib_div::writeFile($extDirPath.$theFile,$fileData['content']);
01695 if (!@is_file($extDirPath.$theFile)) {
01696 $content.='Error: File "'.$extDirPath.$theFile.'" could not be created!!!<br />';
01697 } elseif (md5(t3lib_div::getUrl($extDirPath.$theFile)) != $fileData['content_md5']) {
01698 $content.='Error: File "'.$extDirPath.$theFile.'" MD5 was different from the original files MD5 - so the file is corrupted!<br />';
01699 }
01700 }
01701
01702
01703 if (!$content) {
01704 $content='SUCCESS: '.$extDirPath.'<br />';
01705
01706
01707 $modules = t3lib_div::trimExplode(',',$EM_CONF['module'],1);
01708 if (count($modules)) {
01709 foreach($modules as $mD) {
01710 $confFileName = $extDirPath.$mD.'/conf.php';
01711 if (@is_file($confFileName)) {
01712 $content.= $this->writeTYPO3_MOD_PATH($confFileName,$loc,$extKey.'/'.$mD.'/').'<br />';
01713 } else $content.='Error: Couldn\'t find "'.$confFileName.'"<br />';
01714 }
01715 }
01716
01717
01718
01719
01720 $sEMD5A = $this->serverExtensionMD5Array($extKey,array('type' => $loc, 'EM_CONF' => array(), 'files' => array()));
01721 $EM_CONF['_md5_values_when_last_written'] = serialize($sEMD5A);
01722 $emConfFile = $this->construct_ext_emconf_file($extKey,$EM_CONF);
01723 t3lib_div::writeFile($extDirPath.'ext_emconf.php',$emConfFile);
01724
01725 $content.='ext_emconf.php: '.$extDirPath.'ext_emconf.php<br />';
01726 $content.='Type: '.$loc.'<br />';
01727
01728
01729 if (t3lib_extMgm::isLoaded($extKey)) {
01730 if ($this->removeCacheFiles()) {
01731 $content.='Cache-files are removed and will be re-written upon next hit<br />';
01732 }
01733
01734 list($new_list)=$this->getInstalledExtensions();
01735 $content.=$this->updatesForm($extKey,$new_list[$extKey],1,'index.php?CMD[showExt]='.$extKey.'&SET[singleDetails]=info');
01736 }
01737
01738
01739 if(!$this->CMD['standAlone']) {
01740 $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;
01741 $content.='<h3>Install / Uninstall Extension:</h3>';
01742 $content.= $new_list[$extKey] ?
01743 '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[remove]=1&CMD[clrCmd]=1&SET[singleDetails]=info').'">'.$this->removeButton().' Uninstall extension</a>' :
01744 '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[load]=1&CMD[clrCmd]=1&SET[singleDetails]=info').'">'.$this->installButton().' Install extension</a>';
01745 } else {
01746 $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>';
01747 }
01748
01749 }
01750 } else $content = $res;
01751 } else $content = 'Error: The extension path "'.$extDirPath.'" was different than expected...';
01752 } else $content = $res;
01753 }
01754 } else $content = 'Error: The extension can only be installed in the path '.$this->typePaths[$EM_CONF['lockType']].' (lockType='.$EM_CONF['lockType'].')';
01755 } else $content = 'Error: No extension key!!! Why? - nobody knows... (Or no files in the file-array...)';
01756 } else $content = 'Error: The datatransfer did not succeed. '.$fetchData;
01757 } else $content = 'Error: Installation is not allowed in this path ('.$this->typePaths[$loc].')';
01758
01759 $this->content.=$this->doc->section('Extension import results',$content,0,1);
01760
01761 return false;
01762 }
01763
01770 function showExtDetails($extKey) {
01771 global $TYPO3_LOADED_EXT;
01772
01773 list($list,)=$this->getInstalledExtensions();
01774 $absPath = $this->getExtPath($extKey,$list[$extKey]['type']);
01775
01776
01777 if (@is_file($absPath.'class.ext_update.php')) {
01778 require_once($absPath.'class.ext_update.php');
01779 $updateObj = new ext_update;
01780 if (!$updateObj->access()) {
01781 unset($this->MOD_MENU['singleDetails']['updateModule']);
01782 }
01783 } else {
01784 unset($this->MOD_MENU['singleDetails']['updateModule']);
01785 }
01786
01787 if($this->CMD['doDelete']) {
01788 $this->MOD_MENU['singleDetails'] = array();
01789 }
01790
01791
01792 if(!$this->CMD['standAlone'] && !t3lib_div::_GP('standAlone')) {
01793 $content = '
01794 <table border="0" cellpadding="0" cellspacing="0" width="100%">
01795 <tr>
01796 <td nowrap="nowrap">Extension: <strong>'.$this->extensionTitleIconHeader($extKey,$list[$extKey]).'</strong> ('.$extKey.')</td>
01797 <td align="right" nowrap="nowrap">'.
01798 t3lib_BEfunc::getFuncMenu(0,'SET[singleDetails]',$this->MOD_SETTINGS['singleDetails'],$this->MOD_MENU['singleDetails'],'','&CMD[showExt]='.$extKey).' '.
01799 '<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>
01800 </tr>
01801 </table>';
01802 $this->content.=$this->doc->section('',$content);
01803 }
01804
01805
01806 if ($list[$extKey]) {
01807
01808
01809 if (($this->CMD['remove'] || $this->CMD['load']) && !in_array($extKey,$this->requiredExt)) {
01810
01811
01812 if (t3lib_extMgm::isLocalconfWritable()) {
01813
01814 $depStatus = $this->checkDependencies($extKey, $list[$extKey]['EM_CONF'], $list);
01815 if(!$this->CMD['remove'] && !$depStatus['returnCode']) {
01816 $this->content .= $depStatus['html'];
01817 $newExtList = -1;
01818 } elseif ($this->CMD['remove']) {
01819 $newExtList = $this->removeExtFromList($extKey,$list);
01820 } else {
01821 $newExtList = $this->addExtToList($extKey,$list);
01822 }
01823
01824
01825 if ($newExtList!=-1) {
01826 $updates = '';
01827 if ($this->CMD['load']) {
01828 if($_SERVER['REQUEST_METHOD'] == 'POST') {
01829 $script = t3lib_div::linkThisScript(array('CMD[showExt]' => $extKey, 'CMD[load]' => 1, 'CMD[clrCmd]' => $this->CMD['clrCmd'], 'SET[singleDetails]' => 'info'));
01830 } else {
01831 $script = '';
01832 }
01833 $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'].'" />');
01834 if ($updates) {
01835 $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;
01836 if($this->CMD['standAlone']) $updates .= '<input type="hidden" name="standAlone" value="1" />';
01837 $depsolver = t3lib_div::_POST('depsolver');
01838 if(is_array($depsolver['ignore'])) {
01839 foreach($depsolver['ignore'] as $depK => $depV) {
01840 $updates .= '<input type="hidden" name="depsolver[ignore]['.$depK.']" value="1" />';
01841 }
01842 }
01843
01844 $this->content.=$this->doc->section('Installing '.$this->extensionTitleIconHeader($extKey,$list[$extKey]).strtoupper(': Database needs to be updated'),$updates,1,1,1,1);
01845 }
01846 } elseif ($this->CMD['remove']) {
01847 $updates.= $this->checkClearCache($list[$extKey]);
01848 if ($updates) {
01849 $updates = '
01850 </form><form action="'.t3lib_div::linkThisScript().'" method="post">'.$updates.'
01851 <br /><input type="submit" name="write" value="Remove extension" />
01852 <input type="hidden" name="_do_install" value="1" />
01853 <input type="hidden" name="_clrCmd" value="'.$this->CMD['clrCmd'].'" />
01854 <input type="hidden" name="standAlone" value="'.$this->CMD['standAlone'].'" />
01855 ';
01856 $this->content.=$this->doc->section('Removing '.$this->extensionTitleIconHeader($extKey,$list[$extKey]).strtoupper(': Database needs to be updated'),$updates,1,1,1,1);
01857 }
01858 }
01859 if (!$updates || t3lib_div::_GP('_do_install')) {
01860 $this->writeNewExtensionList($newExtList);
01861 $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')));
01862 if ($this->CMD['clrCmd'] || t3lib_div::_GP('_clrCmd')) {
01863 $vA = array('CMD'=>'');
01864 } else {
01865 $vA = array('CMD'=>Array('showExt'=>$extKey));
01866 }
01867 if($this->CMD['standAlone'] || t3lib_div::_GP('standAlone')) {
01868 $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>';
01869 } else {
01870 header('Location: '.t3lib_div::linkThisScript($vA));
01871 }
01872 }
01873 }
01874 } else {
01875 $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);
01876 }
01877
01878 } elseif ($this->CMD['downloadFile'] && !in_array($extKey,$this->requiredExt)) {
01879
01880
01881 $dlFile = $this->CMD['downloadFile'];
01882 if (t3lib_div::isFirstPartOfStr($dlFile,PATH_site) && t3lib_div::isFirstPartOfStr($dlFile,$absPath) && @is_file($dlFile)) {
01883 $mimeType = 'application/octet-stream';
01884 Header('Content-Type: '.$mimeType);
01885 Header('Content-Disposition: attachment; filename='.basename($dlFile));
01886 echo t3lib_div::getUrl($dlFile);
01887 exit;
01888 } else die('Error while trying to download extension file...');
01889
01890 } elseif ($this->CMD['editFile'] && !in_array($extKey,$this->requiredExt)) {
01891
01892
01893 $editFile = $this->CMD['editFile'];
01894 if (t3lib_div::isFirstPartOfStr($editFile,PATH_site) && t3lib_div::isFirstPartOfStr($editFile,$absPath)) {
01895
01896 $fI = t3lib_div::split_fileref($editFile);
01897 if (@is_file($editFile) && t3lib_div::inList($this->editTextExtensions,($fI['fileext']?$fI['fileext']:$fI['filebody']))) {
01898 if (filesize($editFile)<($this->kbMax*1024)) {
01899 $outCode = '';
01900 $info = '';
01901 $submittedContent = t3lib_div::_POST('edit');
01902 $saveFlag = 0;
01903
01904 if(isset($submittedContent['file']) && !$GLOBALS['TYPO3_CONF_VARS']['EXT']['noEdit']) {
01905 $oldFileContent = t3lib_div::getUrl($editFile);
01906 if($oldFileContent != $submittedContent['file']) {
01907 $oldMD5 = md5(str_replace(chr(13),'',$oldFileContent));
01908 $info.= 'MD5: <b>'.$oldMD5.'</b> (Previous File)<br />';
01909 t3lib_div::writeFile($editFile,$submittedContent['file']);
01910 $saveFlag = 1;
01911 } else {
01912 $info .= 'No changes to the file detected!<br />';
01913 }
01914 }
01915
01916 $fileContent = t3lib_div::getUrl($editFile);
01917
01918 $outCode.= 'File: <b>'.substr($editFile,strlen($absPath)).'</b> ('.t3lib_div::formatSize(filesize($editFile)).')<br />';
01919 $fileMD5 = md5(str_replace(chr(13),'',$fileContent));
01920 $info.= 'MD5: <b>'.$fileMD5.'</b> (Current File)<br />';
01921 if($saveFlag) {
01922 $saveMD5 = md5(str_replace(chr(13),'',$submittedContent['file']));
01923 $info.= 'MD5: <b>'.$saveMD5.'</b> (Submitted)<br />';
01924 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 />';
01925 else $info.= $GLOBALS['TBE_TEMPLATE']->rfw('<br /><strong>File saved.</strong>').'<br />';
01926 }
01927
01928 $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>';
01929 $outCode.= '<input type="hidden" name="edit[filename]" value="'.$editFile.'" />';
01930 $outCode.= '<input type="hidden" name="CMD[editFile]" value="'.htmlspecialchars($editFile).'" />';
01931 $outCode.= '<input type="hidden" name="CMD[showExt]" value="'.$extKey.'" />';
01932 $outCode.= $info;
01933
01934 if (!$GLOBALS['TYPO3_CONF_VARS']['EXT']['noEdit']) {
01935 $outCode.='<br /><input type="submit" name="save_file" value="Save file" />';
01936 } else $outCode.=$GLOBALS['TBE_TEMPLATE']->rfw('<br />[SAVING IS DISABLED - can be enabled by the $TYPO3_CONF_VARS[\'EXT\'][\'noEdit\']-flag] ');
01937
01938 $onClick = 'window.location.href=\'index.php?CMD[showExt]='.$extKey.'\';return false;';
01939 $outCode.='<input type="submit" name="cancel" value="Cancel" onclick="'.htmlspecialchars($onClick).'" />';
01940
01941 $theOutput.=$this->doc->spacer(15);
01942 $theOutput.=$this->doc->section('Edit file:','',0,1);
01943 $theOutput.=$this->doc->sectionEnd().$outCode;
01944 $this->content.=$theOutput;
01945 } else {
01946 $theOutput.=$this->doc->spacer(15);
01947 $theOutput.=$this->doc->section('Filesize exceeded '.$this->kbMax.' Kbytes','Files larger than '.$this->kbMax.' KBytes are not allowed to be edited.');
01948 }
01949 }
01950 } else die('Fatal Edit error: File "'.$editFile.'" was not inside the correct path of the TYPO3 Extension!');
01951 } else {
01952
01953
01954 switch((string)$this->MOD_SETTINGS['singleDetails']) {
01955 case 'info':
01956
01957 if (!in_array($extKey,$this->requiredExt)) {
01958 if ($TYPO3_LOADED_EXT[$extKey]) {
01959 $content = '<strong>The extension is installed (loaded and running)!</strong><br />'.
01960 '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[remove]=1').'">Click here to remove the extension: '.$this->removeButton().'</a>';
01961 } else {
01962 $content = 'The extension is <strong>not</strong> installed yet.<br />'.
01963 '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[load]=1').'">Click here to install the extension: '.$this->installButton().'</a>';
01964 }
01965 } else {
01966 $content = 'This extension is entered in the TYPO3_CONF_VARS[SYS][requiredExt] list and is therefore always loaded.';
01967 }
01968 $this->content.=$this->doc->spacer(10);
01969 $this->content.=$this->doc->section('Active status:',$content,0,1);
01970
01971 if (t3lib_extMgm::isLoaded($extKey)) {
01972 $updates=$this->updatesForm($extKey,$list[$extKey]);
01973 if ($updates) {
01974 $this->content.=$this->doc->spacer(10);
01975 $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);
01976 }
01977 }
01978
01979
01980 if (@is_file($absPath.'ext_conf_template.txt')) {
01981 $this->content.=$this->doc->spacer(10);
01982 $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);
01983 $this->tsStyleConfigForm($extKey,$list[$extKey]);
01984 }
01985
01986
01987 $content = t3lib_BEfunc::cshItem('_MOD_tools_em', 'info', $GLOBALS['BACK_PATH'],'|<br/>');
01988 $content.= $this->extInformationArray($extKey,$list[$extKey]);
01989
01990 $this->content.=$this->doc->spacer(10);
01991 $this->content.=$this->doc->section('Details:',$content,0,1);
01992 break;
01993 case 'upload':
01994 $em = t3lib_div::_POST('em');
01995 if($em['action'] == 'doUpload') {
01996 $em['extKey'] = $extKey;
01997 $em['extInfo'] = $list[$extKey];
01998 $content = $this->uploadExtensionToTER($em);
01999 $content .= $this->doc->spacer(10);
02000
02001 list($list,)=$this->getInstalledExtensions();
02002 } else {
02003
02004 $content = t3lib_BEfunc::cshItem('_MOD_tools_em', 'upload', $GLOBALS['BACK_PATH'],'|<br/>');
02005
02006
02007 if (substr($extKey,0,5)!='user_') {
02008 $content.= $this->getRepositoryUploadForm($extKey,$list[$extKey]);
02009 $eC=0;
02010 } else {
02011 $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.';
02012 $eC=2;
02013 }
02014 if (!$this->fe_user['username']) {
02015 $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 />';
02016 }
02017 }
02018 $this->content.=$this->doc->section('Upload extension to repository',$content,0,1,$eC);
02019 break;
02020 case 'backup':
02021 if($this->CMD['doDelete']) {
02022 $content = $this->extDelete($extKey,$list[$extKey]);
02023 $this->content.=$this->doc->section('Delete',$content,0,1);
02024 } else {
02025 $content = t3lib_BEfunc::cshItem('_MOD_tools_em', 'backup_delete', $GLOBALS['BACK_PATH'],'|<br/>');
02026 $content.= $this->extBackup($extKey,$list[$extKey]);
02027 $this->content.=$this->doc->section('Backup',$content,0,1);
02028
02029 $content = $this->extDelete($extKey,$list[$extKey]);
02030 $this->content.=$this->doc->section('Delete',$content,0,1);
02031
02032 $content = $this->extUpdateEMCONF($extKey,$list[$extKey]);
02033 $this->content.=$this->doc->section('Update EM_CONF',$content,0,1);
02034 }
02035 break;
02036 case 'dump':
02037 $this->extDumpTables($extKey,$list[$extKey]);
02038 break;
02039 case 'edit':
02040 $content = t3lib_BEfunc::cshItem('_MOD_tools_em', 'editfiles', $GLOBALS['BACK_PATH'],'|<br/>');
02041 $content.= $this->getFileListOfExtension($extKey,$list[$extKey]);
02042
02043 $this->content.=$this->doc->section('Extension files',$content,0,1);
02044 break;
02045 case 'updateModule':
02046 $this->content.=$this->doc->section('Update:',is_object($updateObj) ? $updateObj->main() : 'No update object',0,1);
02047 break;
02048 default:
02049 $this->extObjContent();
02050 break;
02051 }
02052 }
02053 }
02054 }
02055
02063 function requestInstallExtensions($extList) {
02064
02065
02066 $returnUrl = t3lib_div::_GP('returnUrl');
02067 $installOrImportExtension = t3lib_div::_POST('installOrImportExtension');
02068
02069
02070 $extArray = explode(',',$extList);
02071 $outputRow = array();
02072 $outputRow[] = '
02073 <tr class="bgColor5 tableheader">
02074 <td>Install/Import:</td>
02075 <td>Extension Key:</td>
02076 </tr>
02077 ';
02078
02079 foreach($extArray as $extKey) {
02080
02081
02082 if ($installOrImportExtension[$extKey]) {
02083 $this->installExtension($extKey);
02084 }
02085
02086
02087 if (!t3lib_extMgm::isLoaded($extKey)) {
02088 $outputRow[] = '
02089 <tr class="bgColor4">
02090 <td><input type="checkbox" name="'.htmlspecialchars('installOrImportExtension['.$extKey.']').'" value="1" checked="checked" /></td>
02091 <td>'.htmlspecialchars($extKey).'</td>
02092 </tr>
02093 ';
02094 }
02095 }
02096
02097 if (count($outputRow)>1 || !$returnUrl) {
02098 $content = '
02099 </form> <!-- ending page form ... -->
02100 <form action="'.htmlspecialchars(t3lib_div::getIndpEnv('REQUEST_URI')).'" method="post">
02101 <table border="0" cellpadding="1" cellspacing="1">'.implode('',$outputRow).'</table>
02102 <input type="submit" name="_" value="Import and Install selected" />
02103 </form>
02104 <form> <!-- continuing page form... -->';
02105
02106 if ($returnUrl) {
02107 $content.= '
02108 <br/>
02109 <br/>
02110 <a href="'.htmlspecialchars($returnUrl).'">Return</a>
02111 ';
02112 }
02113
02114 $this->content.= $this->doc->section('Import/Install Extensions:',$content,0,1);
02115 } else {
02116 header('Location: '.t3lib_div::locationHeaderUrl($returnUrl));
02117 }
02118 }
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02144 function updatesForm($extKey,$extInfo,$notSilent=0,$script='',$addFields='') {
02145 $script = $script ? $script : t3lib_div::linkThisScript();
02146 $updates.= $this->checkDBupdates($extKey,$extInfo);
02147 $uCache = $this->checkClearCache($extInfo);
02148 if ($notSilent) $updates.= $uCache;
02149 $updates.= $this->checkUploadFolder($extKey,$extInfo);
02150
02151 $absPath = $this->getExtPath($extKey,$extInfo['type']);
02152 if ($notSilent && @is_file($absPath.'ext_conf_template.txt')) {
02153 $cForm = $this->tsStyleConfigForm($extKey,$extInfo,1,$script,$updates.$addFields.'<br />');
02154 }
02155
02156 if ($updates || $cForm) {
02157 if ($cForm) {
02158 $updates = '</form>'.$cForm.'<form>';
02159 } else {
02160 $updates = '</form><form action="'.htmlspecialchars($script).'" method="post">'.$updates.$addFields.'
02161 <br /><input type="submit" name="write" value="Make updates" />
02162 ';
02163 }
02164 }
02165 return $updates;
02166 }
02167
02175 function extDumpTables($extKey,$extInfo) {
02176
02177
02178 $techInfo = $this->makeDetailedExtensionAnalysis($extKey,$extInfo);
02179 $absPath = $this->getExtPath($extKey,$extInfo['type']);
02180
02181
02182 if (is_array($techInfo['static'])) {
02183 if ($this->CMD['writeSTATICdump']) {
02184 $writeFile = $absPath.'ext_tables_static+adt.sql';
02185 if (@is_file($writeFile)) {
02186 $dump_static = $this->dumpStaticTables(implode(',',$techInfo['static']));
02187 t3lib_div::writeFile($writeFile,$dump_static);
02188 $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);
02189 }
02190 } else {
02191 $msg = 'Dumping table content for static tables:<br />';
02192 $msg.= '<br />'.implode('<br />',$techInfo['static']).'<br />';
02193
02194
02195 $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);
02196 $this->content.=$this->doc->spacer(20);
02197 }
02198 }
02199
02200
02201 if (is_array($techInfo['dump_tf'])) {
02202 $dump_tf_array = $this->getTableAndFieldStructure($techInfo['dump_tf']);
02203 $dump_tf = $this->dumpTableAndFieldStructure($dump_tf_array);
02204 if ($this->CMD['writeTFdump']) {
02205 $writeFile = $absPath.'ext_tables.sql';
02206 if (@is_file($writeFile)) {
02207 t3lib_div::writeFile($writeFile,$dump_tf);
02208 $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);
02209 }
02210 } else {
02211 $msg = 'Dumping current database structure for:<br />';
02212 if (is_array($techInfo['tables'])) {
02213 $msg.= '<br /><strong>Tables:</strong><br />'.implode('<br />',$techInfo['tables']).'<br />';
02214 }
02215 if (is_array($techInfo['fields'])) {
02216 $msg.= '<br /><strong>Solo-fields:</strong><br />'.implode('<br />',$techInfo['fields']).'<br />';
02217 }
02218
02219
02220 $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 />
02221 <pre>'.htmlspecialchars($dump_tf).'</pre>',0,1);
02222
02223
02224 $details = ' This dump is based on two factors:<br />
02225 <ul>
02226 <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>
02227 <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>
02228 </ul>
02229 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 />';
02230 $this->content.=$this->doc->section('',$details);
02231 }
02232 }
02233 }
02234
02242 function getFileListOfExtension($extKey,$conf) {
02243 $content = '';
02244 $extPath = $this->getExtPath($extKey,$conf['type']);
02245
02246 if ($extPath) {
02247
02248 $fileArr = array();
02249 $fileArr = t3lib_div::getAllFilesAndFoldersInPath($fileArr,$extPath);
02250
02251
02252 $lines = array();
02253 $totalSize = 0;
02254
02255
02256 $lines[] = '
02257 <tr class="bgColor5">
02258 <td>File:</td>
02259 <td>Size:</td>
02260 <td>Edit:</td>
02261 </tr>';
02262
02263 foreach($fileArr as $file) {
02264 $fI = t3lib_div::split_fileref($file);
02265 $lines[] = '
02266 <tr class="bgColor4">
02267 <td><a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[downloadFile]='.rawurlencode($file)).'" title="Download...">'.substr($file,strlen($extPath)).'</a></td>
02268 <td>'.t3lib_div::formatSize(filesize($file)).'</td>
02269 <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>
02270 </tr>';
02271 $totalSize+=filesize($file);
02272 }
02273
02274 $lines[] = '
02275 <tr class="bgColor6">
02276 <td><strong>Total:</strong></td>
02277 <td><strong>'.t3lib_div::formatSize($totalSize).'</strong></td>
02278 <td> </td>
02279 </tr>';
02280
02281 $content = '
02282 Path: '.$extPath.'<br /><br />
02283 <table border="0" cellpadding="1" cellspacing="2">'.implode('',$lines).'</table>';
02284 }
02285
02286 return $content;
02287 }
02288
02296 function extDelete($extKey,$extInfo) {
02297 $absPath = $this->getExtPath($extKey,$extInfo['type']);
02298 if (t3lib_extMgm::isLoaded($extKey)) {
02299 return 'This extension is currently installed (loaded and active) and so cannot be deleted!';
02300 } elseif (!$this->deleteAsType($extInfo['type'])) {
02301 return 'You cannot delete (and install/update) extensions in the '.$this->typeLabels[$extInfo['type']].' scope.';
02302 } elseif (t3lib_div::inList('G,L',$extInfo['type'])) {
02303 if ($this->CMD['doDelete'] && !strcmp($absPath,$this->CMD['absPath'])) {
02304 $res = $this->removeExtDirectory($absPath);
02305 if ($res) {
02306 return 'ERROR: Could not remove extension directory "'.$absPath.'". Had the following errors:<br /><br />'.
02307 nl2br($res);
02308 } else {
02309 return 'Removed extension in path "'.$absPath.'"!';
02310 }
02311 } else {
02312 $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)."';}";
02313 $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>';
02314 $content.= '<br /><br />(Maybe you should make a backup first, see above.)';
02315 return $content;
02316 }
02317 } else return 'Extension is not a global or local extension and cannot be removed.';
02318 }
02319
02327 function extUpdateEMCONF($extKey,$extInfo) {
02328 $absPath = $this->getExtPath($extKey,$extInfo['type']);
02329 if ($this->CMD['doUpdateEMCONF']) {
02330 return $this->updateLocalEM_CONF($extKey,$extInfo);
02331 } else {
02332 $onClick = "if (confirm('Are you sure you want to update EM_CONF?')) {window.location.href='index.php?CMD[showExt]=".$extKey."&CMD[doUpdateEMCONF]=1';}";
02333 $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>';
02334 $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 />
02335 Updating this file will first of all reset this registration.';
02336 return $content;
02337 }
02338 }
02339
02347 function extBackup($extKey,$extInfo) {
02348 $uArr = $this->makeUploadArray($extKey,$extInfo);
02349 if (is_array($uArr)) {
02350 $backUpData = $this->terConnection->makeUploadDataFromArray($uArr);
02351 $filename = 'T3X_'.$extKey.'-'.str_replace('.','_',$extInfo['EM_CONF']['version']).'-z-'.date('YmdHi').'.t3x';
02352 if (intval($this->CMD['doBackup'])==1) {
02353 header('Content-Type: application/octet-stream');
02354 header('Content-Disposition: attachment; filename='.$filename);
02355 echo $backUpData;
02356 exit;
02357 } elseif ($this->CMD['dumpTables']) {
02358 $filename='T3X_'.$extKey;
02359 $cTables = count(explode(',',$this->CMD['dumpTables']));
02360 if ($cTables>1) {
02361 $filename.='-'.$cTables.'tables';
02362 } else {
02363 $filename.='-'.$this->CMD['dumpTables'];
02364 }
02365 $filename.='+adt.sql';
02366
02367 header('Content-Type: application/octet-stream');
02368 header('Content-Disposition: attachment; filename='.$filename);
02369 echo $this->dumpStaticTables($this->CMD['dumpTables']);
02370 exit;
02371 } else {
02372 $techInfo = $this->makeDetailedExtensionAnalysis($extKey,$extInfo);
02373 $lines=array();
02374 $lines[]='<tr class="bgColor5"><td colspan="2"><strong>Make selection:</strong></td></tr>';
02375 $lines[]='<tr class="bgColor4"><td><strong>Extension files:</strong></td><td>'.
02376 '<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>';
02377
02378 if (is_array($techInfo['tables'])) { $lines[]='<tr class="bgColor4"><td><strong>Data tables:</strong></td><td>'.$this->extBackup_dumpDataTablesLine($techInfo['tables'],$extKey).'</td></tr>'; }
02379 if (is_array($techInfo['static'])) { $lines[]='<tr class="bgColor4"><td><strong>Static tables:</strong></td><td>'.$this->extBackup_dumpDataTablesLine($techInfo['static'],$extKey).'</td></tr>'; }
02380
02381 $content = '<table border="0" cellpadding="2" cellspacing="2">'.implode('',$lines).'</table>';
02382 return $content;
02383 }
02384 } else die('Error...');
02385 }
02386
02394 function extBackup_dumpDataTablesLine($tablesArray,$extKey) {
02395 $tables = array();
02396 $tablesNA = array();
02397
02398 foreach($tablesArray as $tN) {
02399 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('count(*)', $tN, '');
02400 if (!$GLOBALS['TYPO3_DB']->sql_error()) {
02401 $row = $GLOBALS['TYPO3_DB']->sql_fetch_row($res);
02402 $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>';
02403 } else {
02404 $tablesNA[$tN]='<tr><td> </td><td>'.$tN.'</td><td> </td><td>Did not exist.</td></tr>';
02405 }
02406 }
02407 $label = '<table border="0" cellpadding="0" cellspacing="0">'.implode('',array_merge($tables,$tablesNA)).'</table>';
02408 if (count($tables)) {
02409 $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;
02410 } else $label = 'Nothing to dump...<br /><br />'.$label;
02411 return $label;
02412 }
02413
02422 function extInformationArray($extKey,$extInfo,$remote=0) {
02423 $lines=array();
02424 $lines[]='<tr class="bgColor5"><td colspan="2"><strong>General information:</strong></td>'.$this->helpCol('').'</tr>';
02425 $lines[]='<tr class="bgColor4"><td>Title:</td><td>'.$extInfo['EM_CONF']['_icon'].$extInfo['EM_CONF']['title'].'</td>'.$this->helpCol('title').'</tr>';
02426 $lines[]='<tr class="bgColor4"><td>Description:</td><td>'.nl2br(htmlspecialchars($extInfo['EM_CONF']['description'])).'</td>'.$this->helpCol('description').'</tr>';
02427 $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']:'').
02428 '</td>'.$this->helpCol('description').'</tr>';
02429
02430 $lines[]='<tr class="bgColor4"><td>Version:</td><td>'.$extInfo['EM_CONF']['version'].'</td>'.$this->helpCol('version').'</tr>';
02431 $lines[]='<tr class="bgColor4"><td>Category:</td><td>'.$this->categories[$extInfo['EM_CONF']['category']].'</td>'.$this->helpCol('category').'</tr>';
02432 $lines[]='<tr class="bgColor4"><td>State:</td><td>'.$this->states[$extInfo['EM_CONF']['state']].'</td>'.$this->helpCol('state').'</tr>';
02433 $lines[]='<tr class="bgColor4"><td>Shy?</td><td>'.($extInfo['EM_CONF']['shy']?'Yes':'').'</td>'.$this->helpCol('shy').'</tr>';
02434 $lines[]='<tr class="bgColor4"><td>Internal?</td><td>'.($extInfo['EM_CONF']['internal']?'Yes':'').'</td>'.$this->helpCol('internal').'</tr>';
02435
02436 $lines[]='<tr class="bgColor4"><td>Depends on:</td><td>'.$this->depToString($extInfo['EM_CONF']['constraints']).'</td>'.$this->helpCol('dependencies').'</tr>';
02437 $lines[]='<tr class="bgColor4"><td>Conflicts with:</td><td>'.$this->depToString($extInfo['EM_CONF']['constraints'],'conflicts').'</td>'.$this->helpCol('dependencies').'</tr>';
02438 $lines[]='<tr class="bgColor4"><td>Suggests:</td><td>'.$this->depToString($extInfo['EM_CONF']['constraints'],'suggests').'</td>'.$this->helpCol('dependencies').'</tr>';
02439 if (!$remote) {
02440 $lines[]='<tr class="bgColor4"><td>Priority:</td><td>'.$extInfo['EM_CONF']['priority'].'</td>'.$this->helpCol('priority').'</tr>';
02441 $lines[]='<tr class="bgColor4"><td>Clear cache?</td><td>'.($extInfo['EM_CONF']['clearCacheOnLoad']?'Yes':'').'</td>'.$this->helpCol('clearCacheOnLoad').'</tr>';
02442 $lines[]='<tr class="bgColor4"><td>Includes modules:</td><td>'.$extInfo['EM_CONF']['module'].'</td>'.$this->helpCol('module').'</tr>';
02443 $lines[]='<tr class="bgColor4"><td>Lock Type?</td><td>'.($extInfo['EM_CONF']['lockType']?$extInfo['EM_CONF']['lockType']:'').'</td>'.$this->helpCol('lockType').'</tr>';
02444 $lines[]='<tr class="bgColor4"><td>Modifies tables:</td><td>'.$extInfo['EM_CONF']['modify_tables'].'</td>'.$this->helpCol('modify_tables').'</tr>';
02445
02446
02447 $techInfo = $this->makeDetailedExtensionAnalysis($extKey,$extInfo,1);
02448 $lines[]='<tr><td> </td><td></td>'.$this->helpCol('').'</tr>';
02449 $lines[]='<tr class="bgColor5"><td colspan="2"><strong>Installation status:</strong></td>'.$this->helpCol('').'</tr>';
02450 $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>';
02451 $lines[]='<tr class="bgColor4"><td>Double installs?</td><td>'.$this->extInformationArray_dbInst($extInfo['doubleInstall'],$extInfo['type']).'</td>'.$this->helpCol('doubleInstall').'</tr>';
02452 if (is_array($extInfo['files'])) {
02453 sort($extInfo['files']);
02454 $lines[]='<tr class="bgColor4"><td>Root files:</td><td>'.implode('<br />',$extInfo['files']).'</td>'.$this->helpCol('rootfiles').'</tr>';
02455 }
02456
02457 if ($techInfo['tables']||$techInfo['static']||$techInfo['fields']) {
02458 if (!$remote && t3lib_extMgm::isLoaded($extKey)) {
02459 $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!':'').
02460 ($techInfo['static_error']?'<strong>Static table error!</strong><br />The static tables are missing or empty!':''));
02461 } else {
02462 $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!';
02463 }
02464 }
02465
02466 $lines[]='<tr class="bgColor4"><td>Database requirements:</td><td>'.$this->extInformationArray_dbReq($techInfo,1).'</td>'.$this->helpCol('dbReq').'</tr>';
02467 $lines[]='<tr class="bgColor4"><td>Database status:</td><td>'.$tableStatus.'</td>'.$this->helpCol('dbStatus').'</tr>';
02468 $lines[]='<tr class="bgColor4"><td>Flags:</td><td>'.(is_array($techInfo['flags'])?implode('<br />',$techInfo['flags']):'').'</td>'.$this->helpCol('flags').'</tr>';
02469 $lines[]='<tr class="bgColor4"><td>Config template?</td><td>'.($techInfo['conf']?'Yes':'').'</td>'.$this->helpCol('conf').'</tr>';
02470 $lines[]='<tr class="bgColor4"><td>TypoScript files:</td><td>'.(is_array($techInfo['TSfiles'])?implode('<br />',$techInfo['TSfiles']):'').'</td>'.$this->helpCol('TSfiles').'</tr>';
02471 $lines[]='<tr class="bgColor4"><td>Language files:</td><td>'.(is_array($techInfo['locallang'])?implode('<br />',$techInfo['locallang']):'').'</td>'.$this->helpCol('locallang').'</tr>';
02472 $lines[]='<tr class="bgColor4"><td>Upload folder:</td><td>'.($techInfo['uploadfolder']?$techInfo['uploadfolder']:'').'</td>'.$this->helpCol('uploadfolder').'</tr>';
02473 $lines[]='<tr class="bgColor4"><td>Create directories:</td><td>'.(is_array($techInfo['createDirs'])?implode('<br />',$techInfo['createDirs']):'').'</td>'.$this->helpCol('createDirs').'</tr>';
02474 $lines[]='<tr class="bgColor4"><td>Module names:</td><td>'.(is_array($techInfo['moduleNames'])?implode('<br />',$techInfo['moduleNames']):'').'</td>'.$this->helpCol('moduleNames').'</tr>';
02475 $lines[]='<tr class="bgColor4"><td>Class names:</td><td>'.(is_array($techInfo['classes'])?implode('<br />',$techInfo['classes']):'').'</td>'.$this->helpCol('classNames').'</tr>';
02476 $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>';
02477 $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>';
02478
02479 $currentMd5Array = $this->serverExtensionMD5Array($extKey,$extInfo);
02480 $affectedFiles='';
02481
02482 $msgLines=array();
02483 if (strcmp($extInfo['EM_CONF']['_md5_values_when_last_written'],serialize($currentMd5Array))) {
02484 $msgLines[] = $GLOBALS['TBE_TEMPLATE']->rfw('<br /><strong>A difference between the originally installed version and the current was detected!</strong>');
02485 $affectedFiles = $this->findMD5ArrayDiff($currentMd5Array,unserialize($extInfo['EM_CONF']['_md5_values_when_last_written']));
02486 if (count($affectedFiles)) $msgLines[] = '<br /><strong>Modified files:</strong><br />'.$GLOBALS['TBE_TEMPLATE']->rfw(implode('<br />',$affectedFiles));
02487 }
02488 $lines[]='<tr class="bgColor4"><td>Files changed?</td><td>'.implode('<br />',$msgLines).'</td>'.$this->helpCol('filesChanged').'</tr>';
02489 }
02490
02491 return '<table border="0" cellpadding="1" cellspacing="2">
02492 '.implode('
02493 ',$lines).'
02494 </table>';
02495 }
02496
02504 function extInformationArray_dbReq($techInfo,$tableHeader=0) {
02505 return nl2br(trim((is_array($techInfo['tables'])?($tableHeader?"\n\n<strong>Tables:</strong>\n":'').implode(chr(10),$techInfo['tables']):'').
02506 (is_array($techInfo['static'])?"\n\n<strong>Static tables:</strong>\n".implode(chr(10),$techInfo['static']):'').
02507 (is_array($techInfo['fields'])?"\n\n<strong>Additional fields:</strong>\n".implode('<hr />',$techInfo['fields']):'')));
02508 }
02509
02517 function extInformationArray_dbInst($dbInst,$current) {
02518 if (strlen($dbInst)>1) {
02519 $others = array();
02520 for($a=0;$a<strlen($dbInst);$a++) {
02521 if (substr($dbInst,$a,1)!=$current) {
02522 $others[]='"'.$this->typeLabels[substr($dbInst,$a,1)].'"';
02523 }
02524 }
02525 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.');
02526 } else return '';
02527 }
02528
02536 function getRepositoryUploadForm($extKey,$extInfo) {
02537 $content.='
02538 <input type="hidden" name="CMD[showExt]" value="'.$extKey.'" />
02539 <input type="hidden" name="em[action]" value="doUpload" />
02540 <table border="0" cellpadding="2" cellspacing="1">
02541 <tr class="bgColor4">
02542 <td>Repository Username:</td>
02543 <td><input'.$this->doc->formWidth(20).' type="text" name="em[user][fe_u]" value="'.$this->fe_user['username'].'" /></td>
02544 </tr>
02545 <tr class="bgColor4">
02546 <td>Repository Password:</td>
02547 <td><input'.$this->doc->formWidth(20).' type="password" name="em[user][fe_p]" value="'.$this->fe_user['password'].'" /></td>
02548 </tr>
02549 <tr class="bgColor4">
02550 <td>Changelog for upload:</td>
02551 <td><textarea'.$this->doc->formWidth(30,1).' rows="5" name="em[upload][comment]"></textarea></td>
02552 </tr>
02553 <tr class="bgColor4">
02554 <td>Upload command:</td>
02555 <td nowrap="nowrap">
02556 <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 />
02557 <input type="radio" name="em[upload][mode]" value="latest" /> Override <em>this</em> development version ('.$extInfo['EM_CONF']['version'].')<br />
02558 <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 />
02559 <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 />
02560 <input type="radio" name="em[upload][mode]" value="custom" /> This version: <input type="text" name="em[upload][version]" /><br />
02561 </td>
02562 </tr>
02563 <tr class="bgColor4">
02564 <td> </td>
02565 <td><input type="submit" name="submit" value="Upload extension" />
02566 </td>
02567 </tr>
02568 </table>
02569 ';
02570
02571 return $content;
02572 }
02573
02574
02575
02576
02577
02578
02579
02580
02581
02582
02583
02584
02585
02586
02587
02588
02597 function extensionListRowHeader($trAttrib,$cells,$import=0) {
02598 $cells[] = '<td></td>';
02599 $cells[] = '<td>Title:</td>';
02600
02601 if (!$this->MOD_SETTINGS['display_details']) {
02602 $cells[] = '<td>Description:</td>';
02603 $cells[] = '<td>Author:</td>';
02604 } elseif ($this->MOD_SETTINGS['display_details']==2) {
02605 $cells[] = '<td>Priority:</td>';
02606 $cells[] = '<td>Mod.Tables:</td>';
02607 $cells[] = '<td>Modules:</td>';
02608 $cells[] = '<td>Cl.Cache?</td>';
02609 $cells[] = '<td>Internal?</td>';
02610 $cells[] = '<td>Shy?</td>';
02611 } elseif ($this->MOD_SETTINGS['display_details']==3) {
02612 $cells[] = '<td>Tables/Fields:</td>';
02613 $cells[] = '<td>TS-files:</td>';
02614 $cells[] = '<td>Affects:</td>';
02615 $cells[] = '<td>Modules:</td>';
02616 $cells[] = '<td>Config?</td>';
02617 $cells[] = '<td>Code warnings:</td>';
02618 } elseif ($this->MOD_SETTINGS['display_details']==4) {
02619 $cells[] = '<td>locallang:</td>';
02620 $cells[] = '<td>Classes:</td>';
02621 $cells[] = '<td>Code warnings:</td>';
02622 $cells[] = '<td>Nameing annoyances:</td>';
02623 } elseif ($this->MOD_SETTINGS['display_details']==5) {
02624 $cells[] = '<td>Changed files:</td>';
02625 } else {
02626 $cells[] = '<td>Extension key:</td>';
02627 $cells[] = '<td>Version:</td>';
02628 if (!$import) {
02629 $cells[] = '<td>DL:</td>';
02630 $cells[] = '<td>Doc:</td>';
02631 $cells[] = '<td>Type:</td>';
02632 } else {
02633 $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>';
02634 $cells[] = '<td class="bgColor6"'.$this->labelInfo('Current type of installation of the extension on this server.').'>Cur. Type:</td>';
02635 $cells[] = '<td'.$this->labelInfo('Number of downloads, all versions/this version').'>DL:</td>';
02636 }
02637 $cells[] = '<td>State:</td>';
02638 }
02639 return '
02640 <tr'.$trAttrib.'>
02641 '.implode('
02642 ',$cells).'
02643 </tr>';
02644 }
02645
02658 function extensionListRow($extKey,$extInfo,$cells,$bgColorClass='',$inst_list=array(),$import=0,$altLinkUrl='') {
02659
02660
02661 $imgInfo = @getImageSize($this->getExtPath($extKey,$extInfo['type']).'/ext_icon.gif');
02662 if (is_array($imgInfo)) {
02663 $cells[] = '<td><img src="'.$GLOBALS['BACK_PATH'].$this->typeRelPaths[$extInfo['type']].$extKey.'/ext_icon.gif'.'" '.$imgInfo[3].' alt="" /></td>';
02664 } elseif ($extInfo['_ICON']) {
02665 $cells[] = '<td>'.$extInfo['_ICON'].'</td>';
02666 } else {
02667 $cells[] = '<td><img src="clear.gif" width="1" height="1" alt="" /></td>';
02668 }
02669
02670
02671 $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>';
02672
02673
02674 if (!$this->MOD_SETTINGS['display_details']) {
02675 $cells[] = '<td>'.htmlspecialchars(t3lib_div::fixed_lgd($extInfo['EM_CONF']['description'],400)).'<br /><img src="clear.gif" width="300" height="1" alt="" /></td>';
02676 $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>';
02677 } elseif ($this->MOD_SETTINGS['display_details']==2) {
02678 $cells[] = '<td nowrap="nowrap">'.$extInfo['EM_CONF']['priority'].'</td>';
02679 $cells[] = '<td nowrap="nowrap">'.implode('<br />',t3lib_div::trimExplode(',',$extInfo['EM_CONF']['modify_tables'],1)).'</td>';
02680 $cells[] = '<td nowrap="nowrap">'.$extInfo['EM_CONF']['module'].'</td>';
02681 $cells[] = '<td nowrap="nowrap">'.($extInfo['EM_CONF']['clearCacheOnLoad'] ? 'Yes' : '').'</td>';
02682 $cells[] = '<td nowrap="nowrap">'.($extInfo['EM_CONF']['internal'] ? 'Yes' : '').'</td>';
02683 $cells[] = '<td nowrap="nowrap">'.($extInfo['EM_CONF']['shy'] ? 'Yes' : '').'</td>';
02684 } elseif ($this->MOD_SETTINGS['display_details']==3) {
02685 $techInfo = $this->makeDetailedExtensionAnalysis($extKey,$extInfo);
02686
02687 $cells[] = '<td>'.$this->extInformationArray_dbReq($techInfo).
02688 '</td>';
02689 $cells[] = '<td nowrap="nowrap">'.(is_array($techInfo['TSfiles']) ? implode('<br />',$techInfo['TSfiles']) : '').'</td>';
02690 $cells[] = '<td nowrap="nowrap">'.(is_array($techInfo['flags']) ? implode('<br />',$techInfo['flags']) : '').'</td>';
02691 $cells[] = '<td nowrap="nowrap">'.(is_array($techInfo['moduleNames']) ? implode('<br />',$techInfo['moduleNames']) : '').'</td>';
02692 $cells[] = '<td nowrap="nowrap">'.($techInfo['conf'] ? 'Yes' : '').'</td>';
02693 $cells[] = '<td>'.
02694 $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!':'').
02695 (t3lib_extMgm::isLoaded($extKey)&&$techInfo['static_error']?'<strong>Static table error!</strong><br />The static tables are missing or empty!':'')).
02696 '</td>';
02697 } elseif ($this->MOD_SETTINGS['display_details']==4) {
02698 $techInfo=$this->makeDetailedExtensionAnalysis($extKey,$extInfo,1);
02699
02700 $cells[] = '<td>'.(is_array($techInfo['locallang']) ? implode('<br />',$techInfo['locallang']) : '').'</td>';
02701 $cells[] = '<td>'.(is_array($techInfo['classes']) ? implode('<br />',$techInfo['classes']) : '').'</td>';
02702 $cells[] = '<td>'.(is_array($techInfo['errors']) ? $GLOBALS['TBE_TEMPLATE']->rfw(implode('<hr />',$techInfo['errors'])) : '').'</td>';
02703 $cells[] = '<td>'.(is_array($techInfo['NSerrors']) ? (!t3lib_div::inList($this->nameSpaceExceptions,$extKey) ? t3lib_div::view_array($techInfo['NSerrors']) : $GLOBALS['TBE_TEMPLATE']->dfw('[exception]')) :'').'</td>';
02704 } elseif ($this->MOD_SETTINGS['display_details']==5) {
02705 $currentMd5Array = $this->serverExtensionMD5Array($extKey,$extInfo);
02706 $affectedFiles = '';
02707 $msgLines = array();
02708 $msgLines[] = 'Files: '.count($currentMd5Array);
02709 if (strcmp($extInfo['EM_CONF']['_md5_values_when_last_written'],serialize($currentMd5Array))) {
02710 $msgLines[] = $GLOBALS['TBE_TEMPLATE']->rfw('<br /><strong>A difference between the originally installed version and the current was detected!</strong>');
02711 $affectedFiles = $this->findMD5ArrayDiff($currentMd5Array,unserialize($extInfo['EM_CONF']['_md5_values_when_last_written']));
02712 if (count($affectedFiles)) $msgLines[] = '<br /><strong>Modified files:</strong><br />'.$GLOBALS['TBE_TEMPLATE']->rfw(implode('<br />',$affectedFiles));
02713 }
02714 $cells[] = '<td>'.implode('<br />',$msgLines).'</td>';
02715 } else {
02716
02717 $verDiff = $inst_list[$extKey] && $this->versionDifference($extInfo['EM_CONF']['version'],$inst_list[$extKey]['EM_CONF']['version'],$this->versionDiffFactor);
02718
02719 $cells[] = '<td nowrap="nowrap"><em>'.$extKey.'</em></td>';
02720 $cells[] = '<td nowrap="nowrap">'.($verDiff ? '<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw(htmlspecialchars($extInfo['EM_CONF']['version'])).'</strong>' : $extInfo['EM_CONF']['version']).'</td>';
02721 if (!$import) {
02722
02723 $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>';
02724
02725
02726 $fileP = PATH_site.$this->typePaths[$extInfo['type']].$extKey.'/doc/manual.sxw';
02727 $cells[] = '<td nowrap="nowrap">'.
02728 ($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>':'').
02729 '</td>';
02730 $cells[] = '<td nowrap="nowrap">'.$this->typeLabels[$extInfo['type']].(strlen($extInfo['doubleInstall'])>1?'<strong> '.$GLOBALS['TBE_TEMPLATE']->rfw($extInfo['doubleInstall']).'</strong>':'').'</td>';
02731 } else {
02732 $inst_curVer = $inst_list[$extKey]['EM_CONF']['version'];
02733 if (isset($inst_list[$extKey])) {
02734 if ($verDiff) $inst_curVer = '<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw($inst_curVer).'</strong>';
02735 }
02736 $cells[] = '<td nowrap="nowrap">'.$inst_curVer.'</td>';
02737 $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>';
02738 $cells[] = '<td nowrap="nowrap">'.($extInfo['downloadcounter_all']?$extInfo['downloadcounter_all']:' ').'/'.($extInfo['downloadcounter']?$extInfo['downloadcounter']:' ').'</td>';
02739 }
02740 $cells[] = '<td nowrap="nowrap" class="extstate" style="background-color:'.$this->stateColors[$extInfo['EM_CONF']['state']].';">'.$this->states[$extInfo['EM_CONF']['state']].'</td>';
02741 }
02742
02743 if($this->xmlhandler->getReviewState($extKey,$extInfo['EM_CONF']['version'])<1) {
02744 $bgclass = ' class="unsupported-ext"';
02745 } else {
02746 $bgclass = ' class="'.($bgColorClass?$bgColorClass:'bgColor4').'"';
02747 }
02748
02749 return '
02750 <tr'.$bgclass.'>
02751 '.implode('
02752 ',$cells).'
02753 </tr>';
02754 }
02755
02756
02757
02758
02759
02760
02761
02762
02763
02764
02765
02766
02774 function wrapEmail($str,$email) {
02775 if ($email) {
02776 $str = '<a href="mailto:'.htmlspecialchars($email).'">'.htmlspecialchars($str).'</a>';
02777 }
02778 return $str;
02779 }
02780
02787 function helpCol($key) {
02788 global $BE_USER;
02789 if ($BE_USER->uc['edit_showFieldHelp']) {
02790 $hT = trim(t3lib_BEfunc::helpText($this->descrTable,'emconf_'.$key,$this->doc->backPath));
02791 return '<td>'.($hT?$hT:t3lib_BEfunc::helpTextIcon($this->descrTable,'emconf_'.$key,$this->doc->backPath)).'</td>';
02792 } else {
02793 return '';
02794 }
02795 }
02796
02803 function labelInfo($str) {
02804 return ' title="'.htmlspecialchars($str).'" style="cursor:help;"';
02805 }
02806
02815 function extensionTitleIconHeader($extKey,$extInfo,$align='top') {
02816 $imgInfo = @getImageSize($this->getExtPath($extKey,$extInfo['type']).'/ext_icon.gif');
02817 $out = '';
02818 if (is_array($imgInfo)) {
02819 $out.= '<img src="'.$GLOBALS['BACK_PATH'].$this->typeRelPaths[$extInfo['type']].$extKey.'/ext_icon.gif" '.$imgInfo[3].' align="'.$align.'" alt="" />';
02820 }
02821 $out.= $extInfo['EM_CONF']['title'] ? htmlspecialchars(t3lib_div::fixed_lgd($extInfo['EM_CONF']['title'],40)) : '<em>'.$extKey.'</em>';
02822 return $out;
02823 }
02824
02830 function removeButton() {
02831 return '<img src="uninstall.gif" width="16" height="16" title="Remove extension" align="top" alt="" />';
02832 }
02833
02839 function installButton() {
02840 return '<img src="install.gif" width="16" height="16" title="Install extension..." align="top" alt="" />';
02841 }
02842
02848 function noImportMsg() {
02849 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>';
02850 }
02851
02861 function depToString($dep,$type='depends') {
02862 if(is_array($dep)) {
02863 unset($dep[$type]['php']);
02864 unset($dep[$type]['typo3']);
02865 $s = (count($dep[$type])) ? implode(',', array_keys($dep[$type])) : '';
02866 return $s;
02867 }
02868 return '';
02869 }
02870
02880 function stringToDep($dep) {
02881 $constraint = array();
02882 if(is_string($dep) && strlen($dep)) {
02883 $dep = explode(',',$dep);
02884 foreach($dep as $v) {
02885 $constraint[$v] = '';
02886 }
02887 }
02888 return $constraint;
02889 }
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02910 function getInstalledExtensions() {
02911 $list = array();
02912 $cat = $this->defaultCategories;
02913
02914 $path = PATH_site.TYPO3_mainDir.'sysext/';
02915 $this->getInstExtList($path,$list,$cat,'S');
02916
02917 $path = PATH_site.TYPO3_mainDir.'ext/';
02918 $this->getInstExtList($path,$list,$cat,'G');
02919
02920 $path = PATH_site.'typo3conf/ext/';
02921 $this->getInstExtList($path,$list,$cat,'L');
02922
02923 return array($list,$cat);
02924 }
02925
02937 function getInstExtList($path,&$list,&$cat,$type) {
02938
02939 if (@is_dir($path)) {
02940 $extList = t3lib_div::get_dirs($path);
02941 if (is_array($extList)) {
02942 foreach($extList as $extKey) {
02943 if (@is_file($path.$extKey.'/ext_emconf.php')) {
02944 $emConf = $this->includeEMCONF($path.$extKey.'/ext_emconf.php', $extKey);
02945 if (is_array($emConf)) {
02946 if (is_array($list[$extKey])) {
02947 $list[$extKey]=array('doubleInstall'=>$list[$extKey]['doubleInstall']);
02948 }
02949 $list[$extKey]['doubleInstall'].= $type;
02950 $list[$extKey]['type'] = $type;
02951 $list[$extKey]['EM_CONF'] = $emConf;
02952 $list[$extKey]['files'] = t3lib_div::getFilesInDir($path.$extKey);
02953
02954 $this->setCat($cat,$list[$extKey], $extKey);
02955 }
02956 }
02957 }
02958 }
02959 }
02960 }
02961
02968 function fixEMCONF($emConf) {
02969 if(!isset($emConf['constraints']) || !isset($emConf['constraints']['depends']) || !isset($emConf['constraints']['conflicts']) || !isset($emConf['constraints']['suggests'])) {
02970 if(!isset($emConf['constraints']) || !isset($emConf['constraints']['depends'])) {
02971 $emConf['constraints']['depends'] = $this->stringToDep($emConf['dependencies']);
02972 if(strlen($emConf['PHP_version'])) {
02973 $versionRange = $this->splitVersionRange($emConf['PHP_version']);
02974 if(version_compare($versionRange[0],'3.0.0','<')) $versionRange[0] = '3.0.0';
02975 if(version_compare($versionRange[1],'3.0.0','<')) $versionRange[1] = '';
02976 $emConf['constraints']['depends']['php'] = implode('-',$versionRange);
02977 }
02978 if(strlen($emConf['TYPO3_version'])) {
02979 $versionRange = $this->splitVersionRange($emConf['TYPO3_version']);
02980 if(version_compare($versionRange[0],'3.5.0','<')) $versionRange[0] = '3.5.0';
02981 if(version_compare($versionRange[1],'3.5.0','<')) $versionRange[1] = '';
02982 $emConf['constraints']['depends']['typo3'] = implode('-',$versionRange);
02983 }
02984 }
02985 if(!isset($emConf['constraints']) || !isset($emConf['constraints']['conflicts'])) {
02986 $emConf['constraints']['conflicts'] = $this->stringToDep($emConf['conflicts']);
02987 }
02988 if(!isset($emConf['constraints']) || !isset($emConf['constraints']['suggests'])) {
02989 $emConf['constraints']['suggests'] = array();
02990 }
02991 } elseif (isset($emConf['constraints']) && isset($emConf['dependencies'])) {
02992 $emConf['suggests'] = isset($emConf['suggests']) ? $emConf['suggests'] : array();
02993 $emConf['dependencies'] = $this->depToString($emConf['constraints']);
02994 $emConf['conflicts'] = $this->depToString($emConf['constraints'], 'conflicts');
02995 }
02996 unset($emConf['private']);
02997 unset($emConf['download_password']);
02998 unset($emConf['TYPO3_version']);
02999 unset($emConf['PHP_version']);
03000
03001 return $emConf;
03002 }
03003
03013 function splitVersionRange($ver) {
03014 $versionRange = array();
03015 if(strstr($ver, '-')) $versionRange = explode('-', $ver, 2);
03016 else {
03017 $versionRange[0] = $ver;
03018 $versionRange[1] = '';
03019 }
03020
03021 return $versionRange;
03022 }
03023
03029 function prepareImportExtList() {
03030 $list = array();
03031 $cat = $this->defaultCategories;
03032 $filepath = $this->getMirrorURL();
03033
03034 reset($this->xmlhandler->extensionsXML);
03035 while (list($extKey, $data) = each($this->xmlhandler->extensionsXML)) {
03036 $GLOBALS['LANG']->csConvObj->convArray($data,'utf-8',$GLOBALS['LANG']->charSet);
03037 $list[$extKey]['type'] = '_';
03038 $version = array_keys($data['versions']);
03039 $list[$extKey]['_ICON'] = '<img alt="" src="'.$filepath.$extKey{0}.'/'.$extKey{1}.'/'.$extKey.'_'.end($version).'.gif" />';
03040 $list[$extKey]['downloadcounter'] = $data['downloadcounter'];
03041
03042 foreach(array_keys($data['versions']) as $version) {
03043 $list[$extKey]['versions'][$version]['downloadcounter'] = $data['versions'][$version]['downloadcounter'];
03044
03045 $list[$extKey]['versions'][$version]['EM_CONF'] = array(
03046 'version' => $version,
03047 'title' => $data['versions'][$version]['title'],
03048 'description' => $data['versions'][$version]['description'],
03049 'category' => $data['versions'][$version]['category'],
03050 'constraints' => $data['versions'][$version]['dependencies'],
03051 'state' => $data['versions'][$version]['state'],
03052 'reviewstate' => $data['versions'][$version]['reviewstate'],
03053 'lastuploaddate' => $data['versions'][$version]['lastuploaddate'],
03054 'author' => $data['versions'][$version]['authorname'],
03055 'author_email' => $data['versions'][$version]['authoremail'],
03056 'author_company' => $data['versions'][$version]['authorcompany'],
03057 );
03058 }
03059 $this->setCat($cat, $list[$extKey]['versions'][$version], $extKey);
03060 }
03061
03062 return array($list,$cat);
03063 }
03064
03073 function setCat(&$cat,$listArrayPart,$extKey) {
03074
03075
03076 $extTitle = $listArrayPart['EM_CONF']['title'];
03077
03078
03079 $index = $listArrayPart['EM_CONF']['category'];
03080 $cat['cat'][$index][$extKey] = $extTitle;
03081
03082
03083 $index = $listArrayPart['EM_CONF']['author'].($listArrayPart['EM_CONF']['author_company']?', '.$listArrayPart['EM_CONF']['author_company']:'');
03084 $cat['author_company'][$index][$extKey] = $extTitle;
03085
03086
03087 $index = $listArrayPart['EM_CONF']['state'];
03088 $cat['state'][$index][$extKey] = $extTitle;
03089
03090
03091 $index = $listArrayPart['type'];
03092 $cat['type'][$index][$extKey] = $extTitle;
03093
03094
03095 return $cat;
03096 }
03097
03098
03099
03100
03101
03102
03103
03104
03105
03106
03107
03108
03109
03110
03111
03112
03123 function makeDetailedExtensionAnalysis($extKey,$extInfo,$validity=0) {
03124
03125
03126 $absPath = $this->getExtPath($extKey,$extInfo['type']);
03127
03128 $infoArray = array();
03129
03130 $table_class_prefix = substr($extKey,0,5)=='user_' ? 'user_' : 'tx_'.str_replace('_','',$extKey).'_';
03131 $module_prefix = substr($extKey,0,5)=='user_' ? 'u' : 'tx'.str_replace('_','',$extKey);
03132
03133
03134 $dbInfo = $this->checkDBupdates($extKey,$extInfo,1);
03135
03136
03137 if (is_array($dbInfo['structure']['tables_fields'])) {
03138 $modify_tables = t3lib_div::trimExplode(',',$extInfo['EM_CONF']['modify_tables'],1);
03139 $infoArray['dump_tf'] = array();
03140
03141 foreach($dbInfo['structure']['tables_fields'] as $tN => $d) {
03142 if (in_array($tN,$modify_tables)) {
03143 $infoArray['fields'][] = $tN.': <i>'.
03144 (is_array($d['fields']) ? implode(', ',array_keys($d['fields'])) : '').
03145 (is_array($d['keys']) ? ' + '.count($d['keys']).' keys' : '').
03146 '</i>';
03147 if (is_array($d['fields'])) {
03148 reset($d['fields']);
03149 while(list($fN) = each($d['fields'])) {
03150 $infoArray['dump_tf'][] = $tN.'.'.$fN;
03151 if (!t3lib_div::isFirstPartOfStr($fN,$table_class_prefix)) {
03152 $infoArray['NSerrors']['fields'][$fN] = $fN;
03153 } else {
03154 $infoArray['NSok']['fields'][$fN] = $fN;
03155 }
03156 }
03157 }
03158 if (is_array($d['keys'])) {
03159 reset($d['keys']);
03160 while(list($fN)=each($d['keys'])) {
03161 $infoArray['dump_tf'][] = $tN.'.KEY:'.$fN;
03162 }
03163 }
03164 } else {
03165 $infoArray['dump_tf'][] = $tN;
03166 $infoArray['tables'][] = $tN;
03167 if (!t3lib_div::isFirstPartOfStr($tN,$table_class_prefix)) {
03168 $infoArray['NSerrors']['tables'][$tN] = $tN;
03169 } else $infoArray['NSok']['tables'][$tN] = $tN;
03170 }
03171 }
03172 if (count($dbInfo['structure']['diff']['diff']) || count($dbInfo['structure']['diff']['extra'])) {
03173 $msg = array();
03174 if (count($dbInfo['structure']['diff']['diff'])) $msg[] = 'missing';
03175 if (count($dbInfo['structure']['diff']['extra'])) $msg[] = 'of wrong type';
03176 $infoArray['tables_error'] = 1;
03177 if (t3lib_extMgm::isLoaded($extKey)) $infoArray['errors'][] = 'Some tables or fields are '.implode(' and ',$msg).'!';
03178 }
03179 }
03180
03181
03182 if (is_array($dbInfo['static'])) {
03183 $infoArray['static'] = array_keys($dbInfo['static']);
03184
03185 foreach($dbInfo['static'] as $tN => $d) {
03186 if (!$d['exists']) {
03187 $infoArray['static_error'] = 1;
03188 if (t3lib_extMgm::isLoaded($extKey)) $infoArray['errors'][] = 'Static table(s) missing!';
03189 if (!t3lib_div::isFirstPartOfStr($tN,$table_class_prefix)) {
03190 $infoArray['NSerrors']['tables'][$tN] = $tN;
03191 } else $infoArray['NSok']['tables'][$tN] = $tN;
03192 }
03193 }
03194 }
03195
03196
03197 $knownModuleList = t3lib_div::trimExplode(',',$extInfo['EM_CONF']['module'],1);
03198 foreach($knownModuleList as $mod) {
03199 if (@is_dir($absPath.$mod)) {
03200 if (@is_file($absPath.$mod.'/conf.php')) {
03201 $confFileInfo = $this->modConfFileAnalysis($absPath.$mod.'/conf.php');
03202 if (is_array($confFileInfo['TYPO3_MOD_PATH'])) {
03203 $shouldBePath = $this->typeRelPaths[$extInfo['type']].$extKey.'/'.$mod.'/';
03204 if (strcmp($confFileInfo['TYPO3_MOD_PATH'][1][1],$shouldBePath)) {
03205 $infoArray['errors'][] = 'Configured TYPO3_MOD_PATH "'.$confFileInfo['TYPO3_MOD_PATH'][1][1].'" different from "'.$shouldBePath.'"';
03206 }
03207 } else $infoArray['errors'][] = 'No definition of TYPO3_MOD_PATH constant found inside!';
03208 if (is_array($confFileInfo['MCONF_name'])) {
03209 $mName = $confFileInfo['MCONF_name'][1][1];
03210 $mNameParts = explode('_',$mName);
03211 $infoArray['moduleNames'][] = $mName;
03212 if (!t3lib_div::isFirstPartOfStr($mNameParts[0],$module_prefix) &&
03213 (!$mNameParts[1] || !t3lib_div::isFirstPartOfStr($mNameParts[1],$module_prefix))) {
03214 $infoArray['NSerrors']['modname'][] = $mName;
03215 } else $infoArray['NSok']['modname'][] = $mName;
03216 } else $infoArray['errors'][] = 'No definition of MCONF[name] variable found inside!';
03217 } else $infoArray['errors'][] = 'Backend module conf file "'.$mod.'/conf.php" should exist but does not!';
03218 } else $infoArray['errors'][] = 'Backend module folder "'.$mod.'/" should exist but does not!';
03219 }
03220 $dirs = t3lib_div::get_dirs($absPath);
03221 if (is_array($dirs)) {
03222 reset($dirs);
03223 while(list(,$mod) = each($dirs)) {
03224 if (!in_array($mod,$knownModuleList) && @is_file($absPath.$mod.'/conf.php')) {
03225 $confFileInfo = $this->modConfFileAnalysis($absPath.$mod.'/conf.php');
03226 if (is_array($confFileInfo)) {
03227 $infoArray['errors'][] = 'It seems like there is a backend module in "'.$mod.'/conf.php" which is not configured in ext_emconf.php';
03228 }
03229 }
03230 }
03231 }
03232
03233
03234 if (@is_file($absPath.'ext_tables.php')) {
03235 $content = t3lib_div::getUrl($absPath.'ext_tables.php');
03236 if (stristr($content,'t3lib_extMgm::addModule')) $infoArray['flags'][] = 'Module';
03237 if (stristr($content,'t3lib_extMgm::insertModuleFunction')) $infoArray['flags'][] = 'Module+';
03238 if (stristr($content,'t3lib_div::loadTCA')) $infoArray['flags'][] = 'loadTCA';
03239 if (stristr($content,'$TCA[')) $infoArray['flags'][] = 'TCA';
03240 if (stristr($content,'t3lib_extMgm::addPlugin')) $infoArray['flags'][] = 'Plugin';
03241 }
03242
03243
03244 if (@is_file($absPath.'ext_localconf.php')) {
03245 $content = t3lib_div::getUrl($absPath.'ext_localconf.php');
03246 if (stristr($content,'t3lib_extMgm::addPItoST43')) $infoArray['flags'][]='Plugin/ST43';
03247 if (stristr($content,'t3lib_extMgm::addPageTSConfig')) $infoArray['flags'][]='Page-TSconfig';
03248 if (stristr($content,'t3lib_extMgm::addUserTSConfig')) $infoArray['flags'][]='User-TSconfig';
03249 if (stristr($content,'t3lib_extMgm::addTypoScriptSetup')) $infoArray['flags'][]='TS/Setup';
03250 if (stristr($content,'t3lib_extMgm::addTypoScriptConstants')) $infoArray['flags'][]='TS/Constants';
03251 }
03252
03253 if (@is_file($absPath.'ext_typoscript_constants.txt')) {
03254 $infoArray['TSfiles'][] = 'Constants';
03255 }
03256 if (@is_file($absPath.'ext_typoscript_setup.txt')) {
03257 $infoArray['TSfiles'][] = 'Setup';
03258 }
03259 if (@is_file($absPath.'ext_conf_template.txt')) {
03260 $infoArray['conf'] = 1;
03261 }
03262
03263
03264 if ($validity) {
03265 $filesInside = $this->getClassIndexLocallangFiles($absPath,$table_class_prefix,$extKey);
03266 if (is_array($filesInside['errors'])) $infoArray['errors'] = array_merge((array)$infoArray['errors'],$filesInside['errors']);
03267 if (is_array($filesInside['NSerrors'])) $infoArray['NSerrors'] = array_merge((array)$infoArray['NSerrors'],$filesInside['NSerrors']);
03268 if (is_array($filesInside['NSok'])) $infoArray['NSok'] = array_merge((array)$infoArray['NSok'],$filesInside['NSok']);
03269 $infoArray['locallang'] = $filesInside['locallang'];
03270 $infoArray['classes'] = $filesInside['classes'];
03271 }
03272
03273
03274 if ($extInfo['EM_CONF']['uploadfolder']) {
03275 $infoArray['uploadfolder'] = $this->ulFolder($extKey);
03276 if (!@is_dir(PATH_site.$infoArray['uploadfolder'])) {
03277 $infoArray['errors'][] = 'Error: Upload folder "'.$infoArray['uploadfolder'].'" did not exist!';
03278 $infoArray['uploadfolder'] = '';
03279 }
03280 }
03281
03282
03283 if ($extInfo['EM_CONF']['createDirs']) {
03284 $infoArray['createDirs'] = array_unique(t3lib_div::trimExplode(',',$extInfo['EM_CONF']['createDirs'],1));
03285 foreach($infoArray['createDirs'] as $crDir) {
03286 if (!@is_dir(PATH_site.$crDir)) {
03287 $infoArray['errors'][]='Error: Upload folder "'.$crDir.'" did not exist!';
03288 }
03289 }
03290 }
03291
03292
03293 return $infoArray;
03294 }
03295
03305 function getClassIndexLocallangFiles($absPath,$table_class_prefix,$extKey) {
03306 $filesInside = t3lib_div::removePrefixPathFromList(t3lib_div::getAllFilesAndFoldersInPath(array(),$absPath,'php,inc'),$absPath);
03307 $out = array();
03308
03309 foreach($filesInside as $fileName) {
03310 if (substr($fileName,0,4)!='ext_' && substr($fileName,0,6)!='tests/') {
03311 $baseName = basename($fileName);
03312 if (substr($baseName,0,9)=='locallang' && substr($baseName,-4)=='.php') {
03313 $out['locallang'][] = $fileName;
03314 } elseif ($baseName!='conf.php') {
03315 if (filesize($absPath.$fileName)<500*1024) {
03316 $fContent = t3lib_div::getUrl($absPath.$fileName);
03317 unset($reg);
03318 if (preg_match('/\n[[:space:]]*class[[:space:]]*([[:alnum:]_]+)([[:alnum:][:space:]_]*)/',$fContent,$reg)) {
03319
03320
03321 $lines = explode(chr(10),$fContent);
03322 foreach($lines as $l) {
03323 $line = trim($l);
03324 unset($reg);
03325 if (preg_match('/^class[[:space:]]*([[:alnum:]_]+)([[:alnum:][:space:]_]*)/',$line,$reg)) {
03326 $out['classes'][] = $reg[1];
03327 $out['files'][$fileName]['classes'][] = $reg[1];
03328 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])) {
03329 $out['NSerrors']['classname'][] = $reg[1];
03330 } else $out['NSok']['classname'][] = $reg[1];
03331 }
03332 }
03333
03334 if (substr($baseName,0,6)=='class.') {
03335 $fI = pathinfo($baseName);
03336 $testName=substr($baseName,6,-(1+strlen($fI['extension'])));
03337 if ($testName!=='ext_update' && substr($testName,0,3)!='ux_' && !t3lib_div::isFirstPartOfStr($testName,$table_class_prefix) && strcmp(substr($table_class_prefix,0,-1),$testName)) {
03338 $out['NSerrors']['classfilename'][] = $baseName;
03339 } else {
03340 $out['NSok']['classfilename'][] = $baseName;
03341 if (is_array($out['files'][$fileName]['classes']) && $this->first_in_array($testName,$out['files'][$fileName]['classes'],1)) {
03342 $out['msg'][] = 'Class filename "'.$fileName.'" did contain the class "'.$testName.'" just as it should.';
03343 } else $out['errors'][] = 'Class filename "'.$fileName.'" did NOT contain the class "'.$testName.'"!';
03344 }
03345 }
03346
03347 $XclassParts = split('if \(defined\([\'"]TYPO3_MODE[\'"]\) && \$TYPO3_CONF_VARS\[TYPO3_MODE\]\[[\'"]XCLASS[\'"]\]',$fContent,2);
03348 if (count($XclassParts)==2) {
03349 unset($reg);
03350 preg_match('/^\[[\'"]([[:alnum:]_\/\.]*)[\'"]\]/',$XclassParts[1],$reg);
03351 if ($reg[1]) {
03352 $cmpF = 'ext/'.$extKey.'/'.$fileName;
03353 if (!strcmp($reg[1],$cmpF)) {
03354 if (preg_match('/_once[[:space:]]*\(\$TYPO3_.ONF_VARS\[TYPO3_MODE\]\[[\'"]XCLASS[\'"]\]\[[\'"]'.preg_quote($cmpF,'/').'[\'"]\]\);/', $XclassParts[1])) {
03355 $out['msg'][] = 'XCLASS OK in '.$fileName;
03356 } else $out['errors'][] = 'Couldn\'t find the include_once statement for XCLASS!';
03357 } else $out['errors'][] = 'The XCLASS filename-key "'.$reg[1].'" was different from "'.$cmpF.'" which it should have been!';
03358 } else $out['errors'][] = 'No XCLASS filename-key found in file "'.$fileName.'". Maybe a regex coding error here...';
03359 } elseif (!$this->first_in_array('ux_',$out['files'][$fileName]['classes'])) $out['errors'][] = 'No XCLASS inclusion code found in file "'.$fileName.'"';
03360 }
03361 }
03362 }
03363 }
03364 }
03365 return $out;
03366 }
03367
03375 function modConfFileAnalysis($confFilePath) {
03376 $lines = explode(chr(10),t3lib_div::getUrl($confFilePath));
03377 $confFileInfo = array();
03378 $confFileInfo['lines'] = $lines;
03379
03380 foreach($lines as $k => $l) {
03381 $line = trim($l);
03382
03383 unset($reg);
03384 if (preg_match('/^define[[:space:]]*\([[:space:]]*["\']TYPO3_MOD_PATH["\'][[:space:]]*,[[:space:]]*["\']([[:alnum:]_\/\.]+)["\'][[:space:]]*\)[[:space:]]*;/',$line,$reg)) {
03385 $confFileInfo['TYPO3_MOD_PATH'] = array($k,$reg);
03386 }
03387
03388 unset($reg);
03389 if (preg_match('/^\$MCONF\[["\']?name["\']?\][[:space:]]*=[[:space:]]*["\']([[:alnum:]_]+)["\'];/',$line,$reg)) {
03390 $confFileInfo['MCONF_name'] = array($k,$reg);
03391 }
03392 }
03393 return $confFileInfo;
03394 }
03395
03403 function serverExtensionMD5Array($extKey,$conf) {
03404
03405
03406 $mUA = $this->makeUploadArray($extKey,$conf);
03407
03408 $md5Array = array();
03409 if (is_array($mUA['FILES'])) {
03410
03411
03412 foreach($mUA['FILES'] as $fN => $d) {
03413 if ($fN!='ext_emconf.php') {
03414 $md5Array[$fN] = substr($d['content_md5'],0,4);
03415 }
03416 }
03417 } else debug($mUA);
03418 return $md5Array;
03419 }
03420
03428 function findMD5ArrayDiff($current,$past) {
03429 if (!is_array($current)) $current = array();
03430 if (!is_array($past)) $past = array();
03431 $filesInCommon = array_intersect($current,$past);
03432 $diff1 = array_keys(array_diff($past,$filesInCommon));
03433 $diff2 = array_keys(array_diff($current,$filesInCommon));
03434 $affectedFiles = array_unique(array_merge($diff1,$diff2));
03435 return $affectedFiles;
03436 }
03437
03438
03439
03440
03441
03442
03443
03444
03445
03446
03447
03448
03449
03450
03451
03452
03460 function createDirsInPath($dirs,$extDirPath) {
03461 if (is_array($dirs)) {
03462 foreach($dirs as $dir) {
03463 $error = t3lib_div::mkdir_deep($extDirPath,$dir);
03464 if ($error) return $error;
03465 }
03466 }
03467
03468 return false;
03469 }
03470
03478 function removeExtDirectory($removePath,$removeContentOnly=0) {
03479 $errors = array();
03480 if (@is_dir($removePath) && substr($removePath,-1)=='/' && (
03481 t3lib_div::isFirstPartOfStr($removePath,PATH_site.$this->typePaths['G']) ||
03482 t3lib_div::isFirstPartOfStr($removePath,PATH_site.$this->typePaths['L']) ||
03483 (t3lib_div::isFirstPartOfStr($removePath,PATH_site.$this->typePaths['S']) && $this->systemInstall) ||
03484 t3lib_div::isFirstPartOfStr($removePath,PATH_site.'fileadmin/_temp_/'))
03485 ) {
03486
03487
03488 $fileArr = t3lib_div::getAllFilesAndFoldersInPath(array(),$removePath,'',1);
03489 if (is_array($fileArr)) {
03490
03491
03492 foreach($fileArr as $removeFile) {
03493 if (!@is_dir($removeFile)) {
03494 if (@is_file($removeFile) && t3lib_div::isFirstPartOfStr($removeFile,$removePath) && strcmp($removeFile,$removePath)) {
03495 @unlink($removeFile);
03496 clearstatcache();
03497 if (@is_file($removeFile)) {
03498 $errors[] = 'Error: "'.$removeFile.'" could not be deleted!';
03499 }
03500 } else $errors[] = 'Error: "'.$removeFile.'" was either not a file, or it was equal to the removed directory or simply outside the removed directory "'.$removePath.'"!';
03501 }
03502 }
03503
03504
03505 $remDirs = $this->extractDirsFromFileList(t3lib_div::removePrefixPathFromList($fileArr,$removePath));
03506 $remDirs = array_reverse($remDirs);
03507 foreach($remDirs as $removeRelDir) {
03508 $removeDir = $removePath.$removeRelDir;
03509 if (@is_dir($removeDir)) {
03510 rmdir($removeDir);
03511 clearstatcache();
03512 if (@is_dir($removeDir)) {
03513 $errors[] = 'Error: "'.$removeDir.'" could not be removed (are there files left?)';
03514 }
03515 } else $errors[] = 'Error: "'.$removeDir.'" was not a directory!';
03516 }
03517
03518
03519 if (!$removeContentOnly) {
03520 rmdir($removePath);
03521 clearstatcache();
03522 if (@is_dir($removePath)) {
03523 $errors[] = 'Error: Extension directory "'.$removePath.'" could not be removed (are there files or folders left?)';
03524 }
03525 }
03526 } else $errors[] = 'Error: '.$fileArr;
03527 } else $errors[] = 'Error: Unallowed path to remove: '.$removePath;
03528
03529
03530 return implode(chr(10),$errors);
03531 }
03532
03541 function clearAndMakeExtensionDir($importedData,$type,$dontDelete=0) {
03542 if (!$importedData['extKey']) return 'FATAL ERROR: Extension key was not set for some VERY strange reason. Nothing done...';
03543
03544
03545 $path = '';
03546 switch((string)$type) {
03547 case 'G':
03548 case 'L':
03549 $path = PATH_site.$this->typePaths[$type];
03550 $suffix = '';
03551
03552
03553 if ((string)$type=='L' && !@is_dir($path)) {
03554 t3lib_div::mkdir($path);
03555 }
03556 break;
03557 default:
03558 if ($this->systemInstall && (string)$type=='S') {
03559 $path = PATH_site.$this->typePaths[$type];
03560 $suffix = '';
03561 } else {
03562 $path = PATH_site.'fileadmin/_temp_/';
03563 $suffix = '_'.date('dmy-His');
03564 }
03565 break;
03566 }
03567
03568
03569 if ($path && @is_dir($path)) {
03570
03571
03572 $extDirPath = $path.$importedData['extKey'].$suffix.'/';
03573
03574
03575 if (@is_dir($extDirPath)) {
03576 if($dontDelete) return array($extDirPath);
03577 $res = $this->removeExtDirectory($extDirPath);
03578 if ($res) {
03579 return 'ERROR: Could not remove extension directory "'.$extDirPath.'". Reasons:<br /><br />'.nl2br($res);
03580 }
03581 }
03582
03583
03584 t3lib_div::mkdir($extDirPath);
03585 if (!is_dir($extDirPath)) return 'ERROR: Could not create extension directory "'.$extDirPath.'"';
03586 return array($extDirPath);
03587 } else return 'ERROR: The extension install path "'.$path.'" was not a directory.';
03588 }
03589
03595 function removeCacheFiles() {
03596 return t3lib_extMgm::removeCacheFiles();
03597 }
03598
03605 function extractDirsFromFileList($files) {
03606 $dirs = array();
03607
03608 if (is_array($files)) {
03609
03610 foreach($files as $file) {
03611 if (substr($file,-1)=='/') {
03612 $dirs[$file] = $file;
03613 } else {
03614 $pI = pathinfo($file);
03615 if (strcmp($pI['dirname'],'') && strcmp($pI['dirname'],'.')) {
03616 $dirs[$pI['dirname'].'/'] = $pI['dirname'].'/';
03617 }
03618 }
03619 }
03620 }
03621 return $dirs;
03622 }
03623
03631 function getExtPath($extKey,$type) {
03632 $typeP = $this->typePaths[$type];
03633 if ($typeP) {
03634 $path = PATH_site.$typeP.$extKey.'/';
03635 return @is_dir($path) ? $path : '';
03636 } else {
03637 return '';
03638 }
03639 }
03640
03641
03642
03643
03644
03645
03646
03647
03648
03649
03650
03651
03652
03653
03654
03655
03665 function writeTYPO3_MOD_PATH($confFilePath,$type,$mP) {
03666 $lines = explode(chr(10),t3lib_div::getUrl($confFilePath));
03667 $confFileInfo = array();
03668 $confFileInfo['lines'] = $lines;
03669
03670 $flag_M = 0;
03671 $flag_B = 0;
03672
03673 foreach($lines as $k => $l) {
03674 $line = trim($l);
03675
03676 unset($reg);
03677 if (preg_match('/^define[[:space:]]*\([[:space:]]*["\']TYPO3_MOD_PATH["\'][[:space:]]*,[[:space:]]*["\']([[:alnum:]_\/\.]+)["\'][[:space:]]*\)[[:space:]]*;/',$line,$reg)) {
03678 $lines[$k] = str_replace($reg[0], 'define(\'TYPO3_MOD_PATH\', \''.$this->typeRelPaths[$type].$mP.'\');', $lines[$k]);
03679 $flag_M = $k+1;
03680 }
03681
03682 unset($reg);
03683 if (preg_match('/^\$BACK_PATH[[:space:]]*=[[:space:]]*["\']([[:alnum:]_\/\.]+)["\'][[:space:]]*;/',$line,$reg)) {
03684 $lines[$k] = str_replace($reg[0], '$BACK_PATH=\''.$this->typeBackPaths[$type].'\';', $lines[$k]);
03685 $flag_B = $k+1;
03686 }
03687 }
03688
03689 if ($flag_B && $flag_M) {
03690 t3lib_div::writeFile($confFilePath,implode(chr(10),$lines));
03691 return 'TYPO3_MOD_PATH and $BACK_PATH was updated in "'.substr($confFilePath,strlen(PATH_site)).'"';
03692 } else return 'Error: Either TYPO3_MOD_PATH or $BACK_PATH was not found in the "'.$confFilePath.'" file. You must manually configure that!';
03693 }
03694
03702 function writeNewExtensionList($newExtList) {
03703 global $TYPO3_CONF_VARS;
03704
03705
03706 $instObj = new t3lib_install;
03707 $instObj->allowUpdateLocalConf =1;
03708 $instObj->updateIdentity = 'TYPO3 Extension Manager';
03709
03710
03711 $lines = $instObj->writeToLocalconf_control();
03712 $instObj->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'EXT\'][\'extList\']', $newExtList);
03713 $instObj->writeToLocalconf_control($lines);
03714
03715 $TYPO3_CONF_VARS['EXT']['extList'] = $newExtList;
03716 $this->removeCacheFiles();
03717 }
03718
03727 function writeTsStyleConfig($extKey,$arr) {
03728
03729
03730 $instObj = new t3lib_install;
03731 $instObj->allowUpdateLocalConf =1;
03732 $instObj->updateIdentity = 'TYPO3 Extension Manager';
03733
03734
03735 $lines = $instObj->writeToLocalconf_control();
03736 $instObj->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'EXT\'][\'extConf\'][\''.$extKey.'\']', serialize($arr));
03737 $instObj->writeToLocalconf_control($lines);
03738
03739 $this->removeCacheFiles();
03740 }
03741
03749 function updateLocalEM_CONF($extKey,$extInfo) {
03750 $extInfo['EM_CONF']['_md5_values_when_last_written'] = serialize($this->serverExtensionMD5Array($extKey,$extInfo));
03751 $emConfFileContent = $this->construct_ext_emconf_file($extKey,$extInfo['EM_CONF']);
03752
03753 if($emConfFileContent) {
03754 $absPath = $this->getExtPath($extKey,$extInfo['type']);
03755 $emConfFileName = $absPath.'ext_emconf.php';
03756
03757 if(@is_file($emConfFileName)) {
03758 if(t3lib_div::writeFile($emConfFileName,$emConfFileContent) === true) {
03759 return '"'.substr($emConfFileName,strlen($absPath)).'" was updated with a cleaned up EM_CONF array.';
03760 } else {
03761 return '<strong>Error: "'.$emConfFileName.'" was not writable!</strong>';
03762 }
03763 } else return('<strong>Error: No file "'.$emConfFileName.'" found. DON\'T PANIC!</strong>');
03764 } else {
03765 return 'No content to write to "'.substr($emConfFileName,strlen($absPath)).'"!';
03766 }
03767 }
03768
03769
03770
03771
03772
03773
03774
03775
03776
03777
03778 /*******************************************
03779 *
03780 * Compiling upload information, emconf-file etc.
03781 *
03782 *******************************************/
03783
03791 function construct_ext_emconf_file($extKey,$EM_CONF) {
03792
03793 // clean version number:
03794 $vDat = $this->renderVersion($EM_CONF['version']);
03795 $EM_CONF['version']=$vDat['version'];
03796
03797 return '<?php
03798
03799 ########################################################################
03800 # Extension Manager/Repository config file for ext: "'.$extKey.'"
03801 #
03802 # Auto generated '.date('d-m-Y H:i').'
03803 #
03804 # Manual updates:
03805 # Only the data in the array - anything else is removed by next write.
03806 # "version" and "dependencies" must not be touched!
03807 ########################################################################
03808
03809 $EM_CONF[$_EXTKEY] = '.$this->arrayToCode($EM_CONF, 0).';
03810
03811 ?>';
03812 }
03813
03822 function arrayToCode($array, $level=0) {
03823 $lines = 'array('.chr(10);
03824 $level++;
03825 foreach($array as $k => $v) {
03826 if(strlen($k) && is_array($v)) {
03827 $lines .= str_repeat(chr(9),$level)."'".$k."' => ".$this->arrayToCode($v, $level);
03828 } elseif(strlen($k)) {
03829 $lines .= str_repeat(chr(9),$level)."'".$k."' => ".(t3lib_div::testInt($v) ? intval($v) : "'".t3lib_div::slashJS(trim($v),1)."'").','.chr(10);
03830 }
03831 }
03832
03833 $lines .= str_repeat(chr(9),$level-1).')'.($level-1==0 ? '':','.chr(10));
03834 return $lines;
03835 }
03836
03844 function makeUploadArray($extKey,$conf) {
03845 $extPath = $this->getExtPath($extKey,$conf['type']);
03846
03847 if ($extPath) {
03848
03849 // Get files for extension:
03850 $fileArr = array();
03851 $fileArr = t3lib_div::getAllFilesAndFoldersInPath($fileArr,$extPath);
03852
03853 // Calculate the total size of those files:
03854 $totalSize = 0;
03855 foreach($fileArr as $file) {
03856 $totalSize+=filesize($file);
03857 }
03858
03859 // If the total size is less than the upper limit, proceed:
03860 if ($totalSize < $this->maxUploadSize) {
03861
03862 // Initialize output array:
03863 $uploadArray = array();
03864 $uploadArray['extKey'] = $extKey;
03865 $uploadArray['EM_CONF'] = $conf['EM_CONF'];
03866 $uploadArray['misc']['codelines'] = 0;
03867 $uploadArray['misc']['codebytes'] = 0;
03868
03869 $uploadArray['techInfo'] = $this->makeDetailedExtensionAnalysis($extKey,$conf,1);
03870
03871 // Read all files:
03872 foreach($fileArr as $file) {
03873 $relFileName = substr($file,strlen($extPath));
03874 $fI = pathinfo($relFileName);
03875 if ($relFileName!='ext_emconf.php') { // This file should be dynamically written...
03876 $uploadArray['FILES'][$relFileName] = array(
03877 'name' => $relFileName,
03878 'size' => filesize($file),
03879 'mtime' => filemtime($file),
03880 'is_executable' => (TYPO3_OS=='WIN' ? 0 : is_executable($file)),
03881 'content' => t3lib_div::getUrl($file)
03882 );
03883 if (t3lib_div::inList('php,inc',strtolower($fI['extension']))) {
03884 $uploadArray['FILES'][$relFileName]['codelines']=count(explode(chr(10),$uploadArray['FILES'][$relFileName]['content']));
03885 $uploadArray['misc']['codelines']+=$uploadArray['FILES'][$relFileName]['codelines'];
03886 $uploadArray['misc']['codebytes']+=$uploadArray['FILES'][$relFileName]['size'];
03887
03888 // locallang*.php files:
03889 if (substr($fI['basename'],0,9)=='locallang' && strstr($uploadArray['FILES'][$relFileName]['content'],'$LOCAL_LANG')) {
03890 $uploadArray['FILES'][$relFileName]['LOCAL_LANG']=$this->getSerializedLocalLang($file,$uploadArray['FILES'][$relFileName]['content']);
03891 }
03892 }
03893 $uploadArray['FILES'][$relFileName]['content_md5'] = md5($uploadArray['FILES'][$relFileName]['content']);
03894 }
03895 }
03896
03897 // Return upload-array:
03898 return $uploadArray;
03899 } else return 'Error: Total size of uncompressed upload ('.$totalSize.') exceeds '.t3lib_div::formatSize($this->maxUploadSize);
03900 } else {
03901 return 'Error: Extension path for extension "'.$extKey.'" not found';
03902 }
03903 }
03904
03913 function getSerializedLocalLang($file,$content) {
03914 $returnParts = explode('$LOCAL_LANG',$content,2);
03915
03916 include($file);
03917 if (is_array($LOCAL_LANG)) {
03918 $returnParts[1] = serialize($LOCAL_LANG);
03919 return $returnParts;
03920 } else {
03921 return array();
03922 }
03923 }
03924
03925
03926
03927
03928
03929
03930
03931
03932
03933
03934 /********************************
03935 *
03936 * Managing dependencies, conflicts, priorities, load order of extension keys
03937 *
03938 *******************************/
03939
03949 function addExtToList($extKey,$instExtInfo) {
03950 global $TYPO3_LOADED_EXT;
03951
03952 // ext_emconf.php information:
03953 $conf = $instExtInfo[$extKey]['EM_CONF'];
03954
03955 // Get list of installed extensions and add this one.
03956 $listArr = array_keys($TYPO3_LOADED_EXT);
03957 if ($conf['priority']=='top') {
03958 array_unshift($listArr,$extKey);
03959 } else {
03960 $listArr[]=$extKey;
03961 }
03962
03963 // Manage other circumstances:
03964 $listArr = $this->managesPriorities($listArr,$instExtInfo);
03965 $listArr = $this->removeRequiredExtFromListArr($listArr);
03966
03967 // Implode unique list of extensions to load and return:
03968 $list = implode(',',array_unique($listArr));
03969 return $list;
03970 }
03971
03980 function checkDependencies($extKey, $conf, $instExtInfo) {
03981 $content = '';
03982 $depError = false;
03983 $msg = array();
03984 $depsolver = t3lib_div::_POST('depsolver');
03985
03986 foreach($conf['constraints']['depends'] as $depK => $depV) {
03987 if($depsolver['ignore'][$depK]) {
03988 $msg[] = '<br />Dependency on '.$depK.' ignored as requested.
03989 <input type="hidden" value="1" name="depsolver[ignore]['.$depK.']" />';
03990 continue;
03991 }
03992 if($depK == 'php') {
03993 if(!$depV) continue;
03994 $versionRange = $this->splitVersionRange($depV);
03995 $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!
03996 if($versionRange[0] && version_compare($phpv,$versionRange[0],'<')) {
03997 $msg[] = '<br />The running PHP version ('.$phpv.') is lower than required ('.$versionRange[0].')';
03998 $msg[] = ' <input type="checkbox" value="1" name="depsolver[ignore]['.$depK.']" /> Ignore this version requirement';
03999 $depError = true;
04000 continue;
04001 } elseif($versionRange[1] && version_compare($phpv,$versionRange[1],'>')) {
04002 $msg[] = '<br />The running PHP version ('.$phpv.') is higher than allowed ('.$versionRange[1].')';
04003 $msg[] = ' <input type="checkbox" value="1" name="depsolver[ignore]['.$depK.']" /> Ignore this version requirement';
04004 $depError = true;
04005 continue;
04006 }
04007 } elseif($depK == 'typo3') {
04008 if(!$depV) continue;
04009 $versionRange = $this->splitVersionRange($depV);
04010 if($versionRange[0] && version_compare(TYPO3_version,$versionRange[0],'<')) {
04011 $msg[] = '<br />The running TYPO3 version ('.TYPO3_version.') is lower than required ('.$versionRange[0].')';
04012 $msg[] = ' <input type="checkbox" value="1" name="depsolver[ignore]['.$depK.']" /> Ignore this version requirement';
04013 $depError = true;
04014 continue;
04015 } elseif($versionRange[1] && version_compare(TYPO3_version,$versionRange[1],'>')) {
04016 $msg[] = '<br />The running TYPO3 version ('.TYPO3_version.') is higher than allowed ('.$versionRange[1].')';
04017 $msg[] = ' <input type="checkbox" value="1" name="depsolver[ignore]['.$depK.']" /> Ignore this version requirement';
04018 $depError = true;
04019 continue;
04020 }
04021 } elseif (strlen($depK) && !t3lib_extMgm::isLoaded($depK)) { // strlen check for braindead empty dependencies coming from extensions...
04022 if(!isset($instExtInfo[$depK])) {
04023 $msg[] = '<br />Extension "'.$depK.'" was not available in the system. Please import it from the TYPO3 Extension Repository.';
04024 $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>';
04025 $msg[] = ' <input type="checkbox" value="1" name="depsolver[ignore]['.$depK.']" /> Ignore this extension requirement';
04026 } else {
04027 $msg[] = '<br />Extension "'.$depK.'" ('.$instExtInfo[$depK]['EM_CONF']['title'].') was not installed. Please install it first.';
04028 $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>';
04029 $msg[] = ' <input type="checkbox" value="1" name="depsolver[ignore]['.$depK.']" /> Ignore this extension requirement';
04030 }
04031 $depError = true;
04032 } else {
04033 $versionRange = $this->splitVersionRange($depV);
04034 if($versionRange[0] && version_compare($instExtInfo[$depK]['EM_CONF']['version'],$versionRange[0],'<')) {
04035 $msg[] = '<br />The running version of extension "'.$depK.'" ('.$instExtInfo[$depK]['EM_CONF']['version'].') is lower than required ('.$versionRange[0].')';
04036 $msg[] = ' <input type="checkbox" value="1" name="depsolver[ignore]['.$depK.']" /> Ignore this version requirement';
04037 $depError = true;
04038 continue;
04039 } elseif($versionRange[1] && version_compare($instExtInfo[$depK]['EM_CONF']['version'],$versionRange[1],'>')) {
04040 $msg[] = '<br />The running version of extension "'.$depK.'" ('.$instExtInfo[$depK]['EM_CONF']['version'].') is higher than allowed ('.$versionRange[1].')';
04041 $msg[] = ' <input type="checkbox" value="1" name="depsolver[ignore]['.$depK.']" /> Ignore this version requirement';
04042 $depError = true;
04043 continue;
04044 }
04045 }
04046 }
04047 if($depError) {
04048 $content .= $this->doc->section('Dependency Error',implode('<br />',$msg),0,1,2);
04049 }
04050
04051 // Check conflicts with other extensions:
04052 $conflictError = false;
04053 $msg = array();
04054 foreach((array)$conf['constraints']['conflicts'] as $conflictK => $conflictV) {
04055 if($depsolver['ignore'][$conflictK]) {
04056 $msg[] = '<br />Conflict with '.$conflictK.' ignored as requested.
04057 <input type="hidden" value="1" name="depsolver[ignore]['.$conflictK.']" />';
04058 continue;
04059 }
04060 if (t3lib_extMgm::isLoaded($conflictK)) {
04061 $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.'".';
04062 $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>';
04063 $msg[] = ' <input type="checkbox" value="1" name="depsolver[ignore]['.$conflictK.']" /> Ignore this conflict error';
04064 $conflictError = true;
04065 }
04066 }
04067 if($conflictError) {
04068 $content .= $this->doc->section('Conflict Error',implode('<br />',$msg),0,1,2);
04069 }
04070
04071 // Check suggests on other extensions:
04072 if(is_array($conf['constraints']['suggests'])) {
04073 $suggestion = false;
04074 $msg = array();
04075 foreach($conf['constraints']['suggests'] as $suggestK => $suggestV) {
04076 if($depsolver['ignore'][$suggestK]) {
04077 $msg[] = '<br />Suggestion of '.$suggestK.' acknowledged.
04078 <input type="hidden" value="1" name="depsolver[ignore]['.$suggestK.']" />';
04079 continue;
04080 }
04081 if (!t3lib_extMgm::isLoaded($suggestK)) {
04082 if (!isset($instExtInfo[$suggestK])) {
04083 $msg[] = 'Extension "'.$suggestK.'" was not available in the system. You may want to import it from the TYPO3 Extension Repository.';
04084 $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>';
04085 $msg[] = ' <input type="checkbox" value="1" name="depsolver[ignore]['.$suggestK.']" /> Ignore this suggestion';
04086 } else {
04087 $msg[] = 'Extension "'.$suggestK.'" ('.$instExtInfo[$suggestK]['EM_CONF']['title'].') was not installed. You may want to install it.';
04088 $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>';
04089 $msg[] = ' <input type="checkbox" value="1" name="depsolver[ignore]['.$suggestK.']" /> Ignore this suggestion';
04090 }
04091 $suggestion = true;
04092 }
04093 }
04094 if($suggestion) {
04095 $content .= $this->doc->section('Extensions suggested by extension "'.$extKey.'"',implode('<br />',$msg),0,1,1);
04096 }
04097 }
04098
04099 if($depError || $conflictError || $suggestion) {
04100 foreach($this->CMD as $k => $v) {
04101 $content .= '<input type="hidden" name="CMD['.$k.']" value="'.$v.'" />';
04102 }
04103 $content .= '<br /><br /><input type="submit" value="Try again" />';
04104
04105 return array('returnCode' => false, 'html' => $content);
04106 }
04107
04108 return array('returnCode' => true);
04109 }
04110
04120 function removeExtFromList($extKey,$instExtInfo) {
04121 global $TYPO3_LOADED_EXT;
04122
04123
04124 $depList = array();
04125 $listArr = array_keys($TYPO3_LOADED_EXT);
04126
04127
04128 foreach($listArr as $k => $ext) {
04129 if ($instExtInfo[$ext]['EM_CONF']['dependencies']) {
04130 $dep = t3lib_div::trimExplode(',',$instExtInfo[$ext]['EM_CONF']['dependencies'],1);
04131 if (in_array($extKey,$dep)) {
04132 $depList[] = $ext;
04133 }
04134 }
04135 if (!strcmp($ext,$extKey)) unset($listArr[$k]);
04136 }
04137
04138
04139 if (count($depList)) {
04140 $msg = 'The extension(s) "'.implode(', ',$depList).'" depends on the extension you are trying to remove. The operation was not completed.';
04141 $this->content.=$this->doc->section('Dependency Error',$msg,0,1,2);
04142 return -1;
04143 } else {
04144 $listArr = $this->removeRequiredExtFromListArr($listArr);
04145 $list = implode(',',array_unique($listArr));
04146 return $list;
04147 }
04148 }
04149
04157 function removeRequiredExtFromListArr($listArr) {
04158 foreach($listArr as $k => $ext) {
04159 if (in_array($ext,$this->requiredExt) || !strcmp($ext,'_CACHEFILE')) unset($listArr[$k]);
04160 }
04161 return $listArr;
04162 }
04163
04172 function managesPriorities($listArr,$instExtInfo) {
04173
04174
04175 $levels = array(
04176 'top' => array(),
04177 'middle' => array(),
04178 'bottom' => array(),
04179 );
04180
04181
04182 foreach($listArr as $ext) {
04183 $prio = trim($instExtInfo[$ext]['EM_CONF']['priority']);
04184 switch((string)$prio) {
04185 case 'top':
04186 case 'bottom':
04187 $levels[$prio][] = $ext;
04188 break;
04189 default:
04190 $levels['middle'][] = $ext;
04191 break;
04192 }
04193 }
04194 return array_merge(
04195 $levels['top'],
04196 $levels['middle'],
04197 $levels['bottom']
04198 );
04199 }
04200
04201
04202
04203
04204
04205
04206
04207
04208
04209
04210
04211
04212
04213
04214
04215
04224 function checkClearCache($extInfo) {
04225 if ($extInfo['EM_CONF']['clearCacheOnLoad']) {
04226 if (t3lib_div::_POST('_clear_all_cache')) {
04227 $tce = t3lib_div::makeInstance('t3lib_TCEmain');
04228 $tce->stripslashes_values = 0;
04229 $tce->start(Array(),Array());
04230 $tce->clear_cacheCmd('all');
04231 } else {
04232 $content.= '
04233 <br />
04234 <h3>Clear cache</h3>
04235 <p>This extension requests the cache to be cleared when it is installed/removed.<br />
04236 Clear all cache: <input type="checkbox" name="_clear_all_cache" checked="checked" value="1" /><br />
04237 </p>
04238 ';
04239 }
04240 }
04241 return $content;
04242 }
04243
04251 function checkUploadFolder($extKey,$extInfo) {
04252
04253
04254 $uploadFolder = PATH_site.$this->ulFolder($extKey);
04255 if ($extInfo['EM_CONF']['uploadfolder'] && !@is_dir($uploadFolder)) {
04256 if (t3lib_div::_POST('_uploadfolder')) {
04257 t3lib_div::mkdir($uploadFolder);
04258 $indexContent = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
04259 <HTML>
04260 <HEAD>
04261 <TITLE></TITLE>
04262 <META http-equiv=Refresh Content="0; Url=../../">
04263 </HEAD>
04264 </HTML>';
04265 t3lib_div::writeFile($uploadFolder.'index.html',$indexContent);
04266 } else {
04267 $content.='
04268 <br /><h3>Create upload folder</h3>
04269 <p>The extension requires the upload folder "'.$this->ulFolder($extKey).'" to exist.<br />
04270 Create directory "'.$this->ulFolder($extKey).'": <input type="checkbox" name="_uploadfolder" checked="checked" value="1" /><br />
04271 </p>
04272 ';
04273 }
04274 }
04275
04276
04277 if ($extInfo['EM_CONF']['createDirs']) {
04278 $createDirs = array_unique(t3lib_div::trimExplode(',',$extInfo['EM_CONF']['createDirs'],1));
04279
04280 foreach($createDirs as $crDir) {
04281 if (!@is_dir(PATH_site.$crDir)) {
04282 if (t3lib_div::_POST('_createDir_'.md5($crDir))) {
04283
04284
04285 $crDirStart = '';
04286 $dirs_in_path = explode('/',preg_replace('/\/$/','',$crDir));
04287
04288
04289 foreach($dirs_in_path as $dirP) {
04290 if (strcmp($dirP,'')) {
04291 $crDirStart.= $dirP.'/';
04292 if (!@is_dir(PATH_site.$crDirStart)) {
04293 t3lib_div::mkdir(PATH_site.$crDirStart);
04294 $finalDir = PATH_site.$crDirStart;
04295 }
04296 } else {
04297 die('ERROR: The path "'.PATH_site.$crDir.'" could not be created.');
04298 }
04299 }
04300 if ($finalDir) {
04301 $indexContent = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
04302 <HTML>
04303 <HEAD>
04304 <TITLE></TITLE>
04305 <META http-equiv=Refresh Content="0; Url=/">
04306 </HEAD>
04307 </HTML>';
04308 t3lib_div::writeFile($finalDir.'index.html',$indexContent);
04309 }
04310 } else {
04311 $content.='
04312 <br />
04313 <h3>Create folder</h3>
04314 <p>The extension requires the folder "'.$crDir.'" to exist.<br />
04315 Create directory "'.$crDir.'": <input type="checkbox" name="_createDir_'.md5($crDir).'" checked="checked" value="1" /><br />
04316 </p>
04317 ';
04318 }
04319 }
04320 }
04321 }
04322
04323 return $content;
04324 }
04325
04336 function checkDBupdates($extKey,$extInfo,$infoOnly=0) {
04337
04338
04339 $instObj = new t3lib_install;
04340 $instObj->INSTALL = t3lib_div::_GP('TYPO3_INSTALL');
04341 $dbStatus = array();
04342
04343
04344 if (is_array($extInfo['files']) && in_array('ext_tables.sql',$extInfo['files'])) {
04345 $fileContent = t3lib_div::getUrl($this->getExtPath($extKey,$extInfo['type']).'ext_tables.sql');
04346
04347 $FDfile = $instObj->getFieldDefinitions_sqlContent($fileContent);
04348 if (count($FDfile)) {
04349 $FDdb = $instObj->getFieldDefinitions_database(TYPO3_db);
04350 $diff = $instObj->getDatabaseExtra($FDfile, $FDdb);
04351 $update_statements = $instObj->getUpdateSuggestions($diff);
04352
04353 $dbStatus['structure']['tables_fields'] = $FDfile;
04354 $dbStatus['structure']['diff'] = $diff;
04355
04356
04357 if (!$infoOnly && is_array($instObj->INSTALL['database_update'])) {
04358 $instObj->performUpdateQueries($update_statements['add'],$instObj->INSTALL['database_update']);
04359 $instObj->performUpdateQueries($update_statements['change'],$instObj->INSTALL['database_update']);
04360 $instObj->performUpdateQueries($update_statements['create_table'],$instObj->INSTALL['database_update']);
04361 } else {
04362 $content.=$instObj->generateUpdateDatabaseForm_checkboxes($update_statements['add'],'Add fields');
04363 $content.=$instObj->generateUpdateDatabaseForm_checkboxes($update_statements['change'],'Changing fields',1,0,$update_statements['change_currentValue']);
04364 $content.=$instObj->generateUpdateDatabaseForm_checkboxes($update_statements['create_table'],'Add tables');
04365 }
04366 }
04367 }
04368
04369
04370 if (is_array($extInfo['files']) && in_array('ext_tables_static+adt.sql',$extInfo['files'])) {
04371 $fileContent = t3lib_div::getUrl($this->getExtPath($extKey,$extInfo['type']).'ext_tables_static+adt.sql');
04372
04373 $statements = $instObj->getStatementArray($fileContent,1);
04374 list($statements_table, $insertCount) = $instObj->getCreateTables($statements,1);
04375
04376
04377 if (!$infoOnly && is_array($instObj->INSTALL['database_import'])) {
04378
04379
04380 foreach($instObj->INSTALL['database_import'] as $table => $md5str) {
04381 if ($md5str == md5($statements_table[$table])) {
04382 $GLOBALS['TYPO3_DB']->admin_query('DROP TABLE IF EXISTS '.$table);
04383 $GLOBALS['TYPO3_DB']->admin_query($statements_table[$table]);
04384
04385 if ($insertCount[$table]) {
04386 $statements_insert = $instObj->getTableInsertStatements($statements, $table);
04387
04388 foreach($statements_insert as $v) {
04389 $GLOBALS['TYPO3_DB']->admin_query($v);
04390 }
04391 }
04392 }
04393 }
04394 } else {
04395 $whichTables = $instObj->getListOfTables();
04396 if (count($statements_table)) {
04397 $out = '';
04398 foreach($statements_table as $table => $definition) {
04399 $exist = isset($whichTables[$table]);
04400
04401 $dbStatus['static'][$table]['exists'] = $exist;
04402 $dbStatus['static'][$table]['count'] = $insertCount[$table];
04403
04404 $out.= '<tr>
04405 <td><input type="checkbox" name="TYPO3_INSTALL[database_import]['.$table.']" checked="checked" value="'.md5($definition).'" /></td>
04406 <td><strong>'.$table.'</strong></td>
04407 <td><img src="clear.gif" width="10" height="1" alt="" /></td>
04408 <td nowrap="nowrap">'.($insertCount[$table]?'Rows: '.$insertCount[$table]:'').'</td>
04409 <td><img src="clear.gif" width="10" height="1" alt="" /></td>
04410 <td nowrap="nowrap">'.($exist?'<img src="'.$GLOBALS['BACK_PATH'].'gfx/icon_warning.gif" width="18" height="16" align="top" alt="" />Table exists!':'').'</td>
04411 </tr>';
04412 }
04413 $content.= '
04414 <br />
04415 <h3>Import static data</h3>
04416 <table border="0" cellpadding="0" cellspacing="0">'.$out.'</table>';
04417 }
04418 }
04419 }
04420
04421
04422 return $infoOnly ? $dbStatus : $content;
04423 }
04424
04433 function forceDBupdates($extKey, $extInfo) {
04434 $instObj = new t3lib_install;
04435
04436
04437 if (is_array($extInfo['files']) && in_array('ext_tables.sql',$extInfo['files'])) {
04438 $fileContent = t3lib_div::getUrl($this->getExtPath($extKey,$extInfo['type']).'ext_tables.sql');
04439
04440 $FDfile = $instObj->getFieldDefinitions_sqlContent($fileContent);
04441 if (count($FDfile)) {
04442 $FDdb = $instObj->getFieldDefinitions_database(TYPO3_db);
04443 $diff = $instObj->getDatabaseExtra($FDfile, $FDdb);
04444 $update_statements = $instObj->getUpdateSuggestions($diff);
04445
04446 foreach((array)$update_statements['add'] as $string) {
04447 $GLOBALS['TYPO3_DB']->admin_query($string);
04448 }
04449 foreach((array)$update_statements['change'] as $string) {
04450 $GLOBALS['TYPO3_DB']->admin_query($string);
04451 }
04452 foreach((array)$update_statements['create_table'] as $string) {
04453 $GLOBALS['TYPO3_DB']->admin_query($string);
04454 }
04455 }
04456 }
04457
04458
04459 if (is_array($extInfo['files']) && in_array('ext_tables_static+adt.sql',$extInfo['files'])) {
04460 $fileContent = t3lib_div::getUrl($this->getExtPath($extKey,$extInfo['type']).'ext_tables_static+adt.sql');
04461
04462 $statements = $instObj->getStatementArray($fileContent,1);
04463 list($statements_table, $insertCount) = $instObj->getCreateTables($statements,1);
04464
04465
04466 foreach($statements_table as $table => $query) {
04467 $GLOBALS['TYPO3_DB']->admin_query('DROP TABLE IF EXISTS '.$table);
04468 $GLOBALS['TYPO3_DB']->admin_query($query);
04469
04470 if ($insertCount[$table]) {
04471 $statements_insert = $instObj->getTableInsertStatements($statements, $table);
04472
04473 foreach($statements_insert as $v) {
04474 $GLOBALS['TYPO3_DB']->admin_query($v);
04475 }
04476 }
04477 }
04478 }
04479 }
04480
04491 function tsStyleConfigForm($extKey,$extInfo,$output=0,$script='',$addFields='') {
04492 global $TYPO3_CONF_VARS;
04493
04494
04495 $absPath = $this->getExtPath($extKey,$extInfo['type']);
04496 $relPath = $this->typeRelPaths[$extInfo['type']].$extKey.'/';
04497
04498
04499 if (@is_file($absPath.'ext_conf_template.txt')) {
04500
04501
04502 $tsStyleConfig = t3lib_div::makeInstance('t3lib_tsStyleConfig');
04503 $tsStyleConfig->doNotSortCategoriesBeforeMakingForm = TRUE;
04504 $theConstants = $tsStyleConfig->ext_initTSstyleConfig(
04505 t3lib_div::getUrl($absPath.'ext_conf_template.txt'),
04506 $relPath,
04507 $absPath,
04508 $GLOBALS['BACK_PATH']
04509 );
04510
04511
04512 $tsStyleConfig->ext_loadResources($absPath.'res/');
04513
04514
04515 $arr = unserialize($TYPO3_CONF_VARS['EXT']['extConf'][$extKey]);
04516 $arr = is_array($arr) ? $arr : array();
04517
04518
04519 if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/mod/tools/em/index.php']['tsStyleConfigForm'])) {
04520 $_params = array('fields' => &$theConstants, 'data' => &$arr, 'extKey' => $extKey);
04521 foreach($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/mod/tools/em/index.php']['tsStyleConfigForm'] as $_funcRef) {
04522 t3lib_div::callUserFunction($_funcRef,$_params,$this);
04523 }
04524 unset($_params);
04525 }
04526
04527
04528 if (t3lib_div::_POST('submit')) {
04529 $tsStyleConfig->ext_procesInput(t3lib_div::_POST(),array(),$theConstants,array());
04530 $arr = $tsStyleConfig->ext_mergeIncomingWithExisting($arr);
04531 $this->writeTsStyleConfig($extKey,$arr);
04532 }
04533
04534
04535 $tsStyleConfig->ext_setValueArray($theConstants,$arr);
04536
04537
04538 $MOD_MENU = array();
04539 $MOD_MENU['constant_editor_cat'] = $tsStyleConfig->ext_getCategoriesForModMenu();
04540 $MOD_SETTINGS = t3lib_BEfunc::getModuleData($MOD_MENU, t3lib_div::_GP('SET'), 'xMod_test');
04541
04542
04543 if (count($MOD_MENU)>1) {
04544 $menu = 'Category: '.t3lib_BEfunc::getFuncMenu(0,'SET[constant_editor_cat]',$MOD_SETTINGS['constant_editor_cat'],$MOD_MENU['constant_editor_cat'],'','&CMD[showExt]='.$extKey);
04545 $this->content.=$this->doc->section('','<span class="nobr">'.$menu.'</span>');
04546 $this->content.=$this->doc->spacer(10);
04547 }
04548
04549
04550 $form = '
04551 <table border="0" cellpadding="0" cellspacing="0" width="600">
04552 <tr>
04553 <td>'.$tsStyleConfig->ext_getForm($MOD_SETTINGS['constant_editor_cat'],$theConstants,$script,$addFields).'</td>
04554 </tr>
04555 </table>';
04556 if ($output) {
04557 return $form;
04558 } else {
04559 $this->content.=$this->doc->section('','</form>'.$form.'<form>');
04560 }
04561 }
04562 }
04563
04564
04565
04566
04567
04568
04569
04570
04571
04572
04573
04574
04575
04576
04577
04578
04586 function dumpTableAndFieldStructure($arr) {
04587 $tables = array();
04588
04589 if (count($arr)) {
04590
04591
04592 $tables[] = $this->dumpHeader();
04593
04594
04595 foreach($arr as $table => $fieldKeyInfo) {
04596 $tables[] = $this->dumpTableHeader($table,$fieldKeyInfo);
04597 }
04598 }
04599
04600
04601 return implode(chr(10).chr(10).chr(10),$tables);
04602 }
04603
04611 function dumpStaticTables($tableList) {
04612 $instObj = new t3lib_install;
04613 $dbFields = $instObj->getFieldDefinitions_database(TYPO3_db);
04614
04615 $out = '';
04616 $parts = t3lib_div::trimExplode(',',$tableList,1);
04617
04618
04619 foreach($parts as $table) {
04620 if (is_array($dbFields[$table]['fields'])) {
04621 $dHeader = $this->dumpHeader();
04622 $header = $this->dumpTableHeader($table,$dbFields[$table],1);
04623 $insertStatements = $this->dumpTableContent($table,$dbFields[$table]['fields']);
04624
04625 $out.= $dHeader.chr(10).chr(10).chr(10).
04626 $header.chr(10).chr(10).chr(10).
04627 $insertStatements.chr(10).chr(10).chr(10);
04628 } else {
04629 die('Fatal error: Table for dump not found in database...');
04630 }
04631 }
04632 return $out;
04633 }
04634
04640 function dumpHeader() {
04641 return trim('
04642 # TYPO3 Extension Manager dump 1.1
04643 #
04644 # Host: '.TYPO3_db_host.' Database: '.TYPO3_db.'
04645 #--------------------------------------------------------
04646 ');
04647 }
04648
04657 function dumpTableHeader($table,$fieldKeyInfo,$dropTableIfExists=0) {
04658 $lines = array();
04659 $dump = '';
04660
04661
04662 if (is_array($fieldKeyInfo['fields'])) {
04663 foreach($fieldKeyInfo['fields'] as $fieldN => $data) {
04664 $lines[]=' '.$fieldN.' '.$data;
04665 }
04666 }
04667
04668
04669 if (is_array($fieldKeyInfo['keys'])) {
04670 foreach($fieldKeyInfo['keys'] as $fieldN => $data) {
04671 $lines[]=' '.$data;
04672 }
04673 }
04674
04675
04676 if (count($lines)) {
04677 $dump = trim('
04678 #
04679 # Table structure for table "'.$table.'"
04680 #
04681 '.($dropTableIfExists ? 'DROP TABLE IF EXISTS '.$table.';
04682 ' : '').'CREATE TABLE '.$table.' (
04683 '.implode(','.chr(10),$lines).'
04684 );'
04685 );
04686 }
04687
04688 return $dump;
04689 }
04690
04699 function dumpTableContent($table,$fieldStructure) {
04700
04701
04702 $search = array('\\', '\'', "\x00", "\x0a", "\x0d", "\x1a");
04703 $replace = array('\\\\', '\\\'', '\0', '\n', '\r', '\Z');
04704
04705 $lines = array();
04706
04707
04708 $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, '');
04709
04710
04711 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
04712 $values = array();
04713 reset($fieldStructure);
04714 while(list($field) = each($fieldStructure)) {
04715 $values[] = isset($row[$field]) ? "'".str_replace($search, $replace, $row[$field])."'" : 'NULL';
04716 }
04717 $lines[] = 'INSERT INTO '.$table.' VALUES ('.implode(', ',$values).');';
04718 }
04719
04720
04721 $GLOBALS['TYPO3_DB']->sql_free_result($result);
04722
04723
04724 return implode(chr(10),$lines);
04725 }
04726
04734 function getTableAndFieldStructure($parts) {
04735
04736 $instObj = new t3lib_install;
04737 $dbFields = $instObj->getFieldDefinitions_database(TYPO3_db);
04738
04739
04740 $outTables = array();
04741 foreach($parts as $table) {
04742 $tP = explode('.',$table);
04743 if ($tP[0] && isset($dbFields[$tP[0]])) {
04744 if ($tP[1]) {
04745 $kfP = explode('KEY:',$tP[1],2);
04746 if (count($kfP)==2 && !$kfP[0]) {
04747 if (isset($dbFields[$tP[0]]['keys'][$kfP[1]])) $outTables[$tP[0]]['keys'][$kfP[1]] = $dbFields[$tP[0]]['keys'][$kfP[1]];
04748 } else {
04749 if (isset($dbFields[$tP[0]]['fields'][$tP[1]])) $outTables[$tP[0]]['fields'][$tP[1]] = $dbFields[$tP[0]]['fields'][$tP[1]];
04750 }
04751 } else {
04752 $outTables[$tP[0]] = $dbFields[$tP[0]];
04753 }
04754 }
04755 }
04756
04757 return $outTables;
04758 }
04759
04760
04761
04762
04763
04764
04765
04766
04767
04768
04769
04770
04771
04772
04773
04774
04775
04776
04784 function uploadExtensionToTER($em) {
04785 $msg = '';
04786 $response = $this->terConnection->uploadToTER($em);
04787
04788 if(!is_array($response)) return $response;
04789
04790 if($response['resultCode']==TX_TER_RESULT_EXTENSIONSUCCESSFULLYUPLOADED) {
04791 $em['extInfo']['EM_CONF']['version'] = $response['version'];
04792 $response['resultMessages'][] = 'The extension is now version: '.$response['version'];
04793 $response['resultMessages'][] = $this->updateLocalEM_CONF($em['extKey'],$em['extInfo']);
04794 }
04795
04796 $msg = '<ul><li>'.implode('</li><li>',$response['resultMessages']).'</li></ul>';
04797 return $msg;
04798 }
04799
04800
04801
04802
04803
04804
04805
04806
04807
04808
04809
04810
04811
04812
04813
04814
04822 function listOrderTitle($listOrder,$key) {
04823 switch($listOrder) {
04824 case 'cat':
04825 return isset($this->categories[$key])?$this->categories[$key]:'<em>['.$key.']</em>';
04826 break;
04827 case 'author_company':
04828 return $key;
04829 break;
04830 case 'state':
04831 return $this->states[$key];
04832 break;
04833 case 'type':
04834 return $this->typeDescr[$key];
04835 break;
04836 }
04837 }
04838
04847 function makeVersion($v,$mode) {
04848 $vDat = $this->renderVersion($v);
04849 return $vDat['version_'.$mode];
04850 }
04851
04859 function renderVersion($v,$raise='') {
04860 $parts = t3lib_div::intExplode('.',$v.'..');
04861 $parts[0] = t3lib_div::intInRange($parts[0],0,999);
04862 $parts[1] = t3lib_div::intInRange($parts[1],0,999);
04863 $parts[2] = t3lib_div::intInRange($parts[2],0,999);
04864
04865 switch((string)$raise) {
04866 case 'main':
04867 $parts[0]++;
04868 $parts[1]=0;
04869 $parts[2]=0;
04870 break;
04871 case 'sub':
04872 $parts[1]++;
04873 $parts[2]=0;
04874 break;
04875 case 'dev':
04876 $parts[2]++;
04877 break;
04878 }
04879
04880 $res = array();
04881 $res['version'] = $parts[0].'.'.$parts[1].'.'.$parts[2];
04882 $res['version_int'] = intval(str_pad($parts[0],3,'0',STR_PAD_LEFT).str_pad($parts[1],3,'0',STR_PAD_LEFT).str_pad($parts[2],3,'0',STR_PAD_LEFT));
04883 $res['version_main'] = $parts[0];
04884 $res['version_sub'] = $parts[1];
04885 $res['version_dev'] = $parts[2];
04886
04887 return $res;
04888 }
04889
04896 function ulFolder($extKey) {
04897 return 'uploads/tx_'.str_replace('_','',$extKey).'/';
04898 }
04899
04905 function importAtAll() {
04906 return ($GLOBALS['TYPO3_CONF_VARS']['EXT']['allowGlobalInstall'] || $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowLocalInstall']);
04907 }
04908
04916 function importAsType($type,$lockType='') {
04917 switch($type) {
04918 case 'G':
04919 return $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowGlobalInstall'] && (!$lockType || !strcmp($lockType,$type));
04920 break;
04921 case 'L':
04922 return $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowLocalInstall'] && (!$lockType || !strcmp($lockType,$type));
04923 break;
04924 case 'S':
04925 return $this->systemInstall;
04926 break;
04927 default:
04928 return false;
04929 }
04930 }
04931
04938 function deleteAsType($type) {
04939 switch($type) {
04940 case 'G':
04941 return $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowGlobalInstall'];
04942 break;
04943 case 'L':
04944 return $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowLocalInstall'];
04945 break;
04946 default:
04947 return false;
04948 }
04949 }
04950
04959 function versionDifference($v1,$v2,$div=1) {
04960 return floor($this->makeVersion($v1,'int')/$div) > floor($this->makeVersion($v2,'int')/$div);
04961 }
04962
04971 function first_in_array($str,$array,$caseInsensitive=FALSE) {
04972 if ($caseInsensitive) $str = strtolower($str);
04973 if (is_array($array)) {
04974 foreach($array as $cl) {
04975 if ($caseInsensitive) $cl = strtolower($cl);
04976 if (t3lib_div::isFirstPartOfStr($cl,$str)) return true;
04977 }
04978 }
04979 return false;
04980 }
04981
04989 function includeEMCONF($path,$_EXTKEY) {
04990 @include($path);
04991 if(is_array($EM_CONF[$_EXTKEY])) {
04992 return $this->fixEMCONF($EM_CONF[$_EXTKEY]);
04993 }
04994 return false;
04995 }
04996
05004 function searchExtension($extKey,$row) {
05005 if ($this->lookUpStr) {
05006 return (
05007 stristr($extKey,$this->lookUpStr) ||
05008 stristr($row['EM_CONF']['title'],$this->lookUpStr) ||
05009 stristr($row['EM_CONF']['description'],$this->lookUpStr) ||
05010 stristr($row['EM_CONF']['author'],$this->lookUpStr) ||
05011 stristr($row['EM_CONF']['author_company'],$this->lookUpStr)
05012 );
05013 } else return true;
05014 }
05015 }
05016
05017
05018 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/mod/tools/em/index.php']) {
05019 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/mod/tools/em/index.php']);
05020 }
05021
05022 ?>