Documentation TYPO3 par Ameos |
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 1999-2004 Kasper Skaarhoj (kasperYYYY@typo3.com) 00006 * All rights reserved 00007 * 00008 * This script is part of the TYPO3 project. The TYPO3 project is 00009 * free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * The GNU General Public License can be found at 00015 * http://www.gnu.org/copyleft/gpl.html. 00016 * A copy is found in the textfile GPL.txt and important notices to the license 00017 * from the author is found in LICENSE.txt distributed with these scripts. 00018 * 00019 * 00020 * This script is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * This copyright notice MUST APPEAR in all copies of the script! 00026 ***************************************************************/ 00166 unset($MCONF); 00167 require ('conf.php'); 00168 require ($BACK_PATH.'init.php'); 00169 require ($BACK_PATH.'template.php'); 00170 $BE_USER->modAccess($MCONF,1); 00171 00172 // Include classes needed: 00173 require_once(PATH_t3lib.'class.t3lib_tcemain.php'); 00174 require_once(PATH_t3lib.'class.t3lib_install.php'); 00175 require_once(PATH_t3lib.'class.t3lib_tsstyleconfig.php'); 00176 require_once(PATH_t3lib.'class.t3lib_scbase.php'); 00177 00178 00179 00180 00181 00182 00183 00191 class SC_mod_tools_em_index extends t3lib_SCbase { 00192 00193 // Internal, static: 00194 var $versionDiffFactor = 1000; // This means that version difference testing for import is detected for sub-versions only, not dev-versions. Default: 1000 00195 var $systemInstall = 0; // If "1" then installs in the sysext directory is allowed. Default: 0 00196 var $repositoryUrl = ''; // Default is "http://ter.typo3.com/?id=t3_extrep" configured in config_default.php 00197 var $requiredExt = ''; // List of required extension (from TYPO3_CONF_VARS) 00198 var $maxUploadSize = 6024000; // Max size of extension upload to repository 00199 var $kbMax = 100; // Max size in kilobytes for files to be edited. 00200 00205 var $defaultCategories = Array( 00206 'cat' => Array ( 00207 'be' => array(), 00208 'module' => array(), 00209 'fe' => array(), 00210 'plugin' => array(), 00211 'misc' => array(), 00212 'services' => array(), 00213 'templates' => array(), 00214 'example' => array(), 00215 'doc' => array() 00216 ) 00217 ); 00218 00223 var $categories = Array( 00224 'be' => 'Backend', 00225 'module' => 'Backend Modules', 00226 'fe' => 'Frontend', 00227 'plugin' => 'Frontend Plugins', 00228 'misc' => 'Miscellaneous', 00229 'services' => 'Services', 00230 'templates' => 'Templates', 00231 'example' => 'Examples', 00232 'doc' => 'Documentation' 00233 ); 00234 00239 var $states = Array ( 00240 'alpha' => 'Alpha', 00241 'beta' => 'Beta', 00242 'stable' => 'Stable', 00243 'experimental' => 'Experimental', 00244 'test' => 'Test', 00245 'obsolete' => 'Obsolete', 00246 ); 00247 00251 var $typeLabels = Array ( 00252 'S' => 'System', 00253 'G' => 'Global', 00254 'L' => 'Local', 00255 ); 00256 var $typeDescr = Array ( 00257 'S' => 'System extension (typo3/sysext/) - Always distributed with source code (Static).', 00258 'G' => 'Global extensions (typo3/ext/) - Available for shared source on server (Dynamic).', 00259 'L' => 'Local extensions (typo3conf/ext/) - Local for this TYPO3 installation only (Dynamic).', 00260 ); 00261 var $typePaths = Array(); // Also static, set in init() 00262 var $typeBackPaths = Array(); // Also static, set in init() 00263 00264 var $typeRelPaths = Array ( 00265 'S' => 'sysext/', 00266 'G' => 'ext/', 00267 'L' => '../typo3conf/ext/', 00268 ); 00269 00273 var $remoteAccess = Array ( 00274 'all' => '', 00275 'owner' => 'Owner', 00276 'selected' => 'Selected', 00277 'member' => 'Member', 00278 ); 00279 00280 var $detailCols = Array ( 00281 0 => 2, 00282 1 => 5, 00283 2 => 6, 00284 3 => 6, 00285 4 => 4, 00286 5 => 1 00287 ); 00288 00289 var $fe_user = array( 00290 'username' => '', 00291 'password' => '', 00292 'uploadPass' => '', 00293 ); 00294 00295 var $privacyNotice = 'When ever you interact with the online repository, server information is sent and stored in the repository for statistics. No personal information is sent, only identification of this TYPO3 install. If you want know exactly what is sent, look in typo3/tools/em/index.php, function repTransferParams()'; 00296 var $editTextExtensions = 'html,htm,txt,css,tmpl,inc,php,sql,conf,cnf,pl,pm,sh'; 00297 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,plugin_mgm,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'; 00298 00299 00300 00301 00302 00303 // Default variables for backend modules 00304 var $MCONF = array(); // Module configuration 00305 var $MOD_MENU = array(); // Module menu items 00306 var $MOD_SETTINGS = array(); // Module session settings 00307 var $doc; // Document Template Object 00308 var $content; // Accumulated content 00309 00310 var $inst_keys = array(); // Storage of installed extensions 00311 var $gzcompress = 0; // Is set true, if system support compression. 00312 00313 // GPvars: 00314 var $CMD = array(); // CMD array 00315 var $listRemote; // If set, connects to remote repository 00316 00317 00318 00319 00320 00321 00322 00323 00324 00325 00326 00327 00328 00329 00330 /********************************* 00331 * 00332 * Standard module initialization 00333 * 00334 *********************************/ 00335 00341 function init() { 00342 global $BE_USER,$LANG,$BACK_PATH,$TYPO3_CONF_VARS; 00343 00344 // Setting paths of install scopes: 00345 $this->typePaths = Array ( 00346 'S' => TYPO3_mainDir.'sysext/', 00347 'G' => TYPO3_mainDir.'ext/', 00348 'L' => 'typo3conf/ext/' 00349 ); 00350 $this->typeBackPaths = Array ( 00351 'S' => '../../../', 00352 'G' => '../../../', 00353 'L' => '../../../../'.TYPO3_mainDir 00354 ); 00355 00356 // Setting module configuration: 00357 $this->MCONF = $GLOBALS['MCONF']; 00358 00359 // Setting GPvars: 00360 $this->CMD = t3lib_div::_GP('CMD'); 00361 $this->listRemote = t3lib_div::_GP('ter_connect'); 00362 $this->listRemote_search = t3lib_div::_GP('ter_search'); 00363 00364 00365 // Configure menu 00366 $this->menuConfig(); 00367 00368 // Setting internal static: 00369 $this->gzcompress = function_exists('gzcompress'); 00370 if ($TYPO3_CONF_VARS['EXT']['em_devVerUpdate']) $this->versionDiffFactor = 1; 00371 if ($TYPO3_CONF_VARS['EXT']['em_systemInstall']) $this->systemInstall = 1; 00372 $this->repositoryUrl = $TYPO3_CONF_VARS['EXT']['em_TERurls'][0]; 00373 $this->requiredExt = t3lib_div::trimExplode(',',$TYPO3_CONF_VARS['EXT']['requiredExt'],1); 00374 00375 // Initialize Document Template object: 00376 $this->doc = t3lib_div::makeInstance('noDoc'); 00377 $this->doc->backPath = $BACK_PATH; 00378 $this->doc->docType = 'xhtml_trans'; 00379 00380 // JavaScript 00381 $this->doc->JScode = $this->doc->wrapScriptTags(' 00382 script_ended = 0; 00383 function jumpToUrl(URL) { // 00384 document.location = URL; 00385 } 00386 '); 00387 $this->doc->form = '<form action="" method="post" name="pageform">'; 00388 00389 // Descriptions: 00390 $this->descrTable = '_MOD_'.$this->MCONF['name']; 00391 if ($BE_USER->uc['edit_showFieldHelp']) { 00392 $LANG->loadSingleTableDescription($this->descrTable); 00393 } 00394 00395 // Setting username/password etc. for upload-user: 00396 $this->fe_user['username'] = $this->MOD_SETTINGS['fe_u']; 00397 $this->fe_user['password'] = $this->MOD_SETTINGS['fe_p']; 00398 $this->fe_user['uploadPass'] = $this->MOD_SETTINGS['fe_up']; 00399 parent::init(); 00400 $this->handleExternalFunctionValue('singleDetails'); 00401 } 00402 00414 function handleExternalFunctionValue($MM_key='function', $MS_value=NULL) { 00415 $MS_value = is_null($MS_value) ? $this->MOD_SETTINGS[$MM_key] : $MS_value; 00416 $externalItems = $this->getExternalItemConfig($this->MCONF['name'],$MM_key,$MS_value); 00417 if (is_array($externalItems)) $this->extClassConf = array_merge($externalItems,is_array($this->extClassConf)?$this->extClassConf:array()); 00418 if (is_array($this->extClassConf) && $this->extClassConf['path']) { 00419 $this->include_once[]=$this->extClassConf['path']; 00420 } 00421 } 00422 00428 function menuConfig() { 00429 global $BE_USER; 00430 00431 // MENU-ITEMS: 00432 $this->MOD_MENU = array( 00433 'function' => array( 00434 0 => 'Loaded extensions', 00435 1 => 'Available extensions to install', 00436 2 => 'Import extensions from online repository', 00437 3 => 'Settings', 00438 ), 00439 'listOrder' => array( 00440 'cat' => 'Category', 00441 'author_company' => 'Author', 00442 'state' => 'State', 00443 'private' => 'Private', 00444 'type' => 'Type', 00445 'dep' => 'Dependencies', 00446 ), 00447 'display_details' => array( 00448 1 => 'Details', 00449 0 => 'Description', 00450 2 => 'More details', 00451 00452 3 => 'Technical (takes time!)', 00453 4 => 'Validating (takes time!)', 00454 5 => 'Changed? (takes time!)', 00455 ), 00456 'display_shy' => '', 00457 'own_member_only' => '', 00458 'singleDetails' => array( 00459 'info' => 'Information', 00460 'edit' => 'Edit files', 00461 'backup' => 'Backup/Delete', 00462 'dump' => 'Dump DB', 00463 'upload' => 'Upload', 00464 'updateModule' => 'UPDATE!', 00465 ), 00466 'fe_u' => '', 00467 'fe_p' => '', 00468 'fe_up' => '', 00469 ); 00470 00471 $this->MOD_MENU['singleDetails'] = $this->mergeExternalItems($this->MCONF['name'],'singleDetails',$this->MOD_MENU['singleDetails']); 00472 00473 // page/be_user TSconfig settings and blinding of menu-items 00474 if (!$BE_USER->getTSConfigVal('mod.'.$this->MCONF['name'].'.allowTVlisting')) { 00475 unset($this->MOD_MENU['display_details'][3]); 00476 unset($this->MOD_MENU['display_details'][4]); 00477 unset($this->MOD_MENU['display_details'][5]); 00478 } 00479 00480 // CLEANSE SETTINGS 00481 $this->MOD_SETTINGS = t3lib_BEfunc::getModuleData($this->MOD_MENU, t3lib_div::_GP('SET'), $this->MCONF['name']); 00482 00483 if ($this->MOD_SETTINGS['function']==2) { 00484 // If listing from online repository, certain items are removed though: 00485 unset($this->MOD_MENU['listOrder']['type']); 00486 unset($this->MOD_MENU['listOrder']['private']); 00487 unset($this->MOD_MENU['display_details'][3]); 00488 unset($this->MOD_MENU['display_details'][4]); 00489 unset($this->MOD_MENU['display_details'][5]); 00490 $this->MOD_SETTINGS = t3lib_BEfunc::getModuleData($this->MOD_MENU, t3lib_div::_GP('SET'), $this->MCONF['name']); 00491 } 00492 parent::menuConfig(); 00493 } 00494 00500 function main() { 00501 global $BE_USER,$LANG; 00502 00503 // Starting page: 00504 $this->content.=$this->doc->startPage('Extension Manager'); 00505 $this->content.=$this->doc->header('Extension Manager'); 00506 $this->content.=$this->doc->spacer(5); 00507 00508 00509 // Commands given which is executed regardless of main menu setting: 00510 if ($this->CMD['showExt']) { // Show details for a single extension 00511 $this->showExtDetails($this->CMD['showExt']); 00512 } elseif ($this->CMD['importExt'] || $this->CMD['uploadExt']) { // Imports an extension from online rep. 00513 $err = $this->importExtFromRep($this->CMD['importExt'],$this->CMD['loc'],$this->CMD['uploadExt'],'',$this->CMD['transl'],$this->CMD['inc_manual']); 00514 if ($err) { 00515 $this->content.=$this->doc->section('',$GLOBALS['TBE_TEMPLATE']->rfw($err)); 00516 } 00517 } elseif ($this->CMD['importExtInfo']) { // Gets detailed information of an extension from online rep. 00518 $this->importExtInfo($this->CMD['importExtInfo']); 00519 } else { // No command - we show what the menu setting tells us: 00520 00521 $menu = $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.menu').' '. 00522 t3lib_BEfunc::getFuncMenu(0,'SET[function]',$this->MOD_SETTINGS['function'],$this->MOD_MENU['function']); 00523 00524 if (t3lib_div::inList('0,1,2',$this->MOD_SETTINGS['function'])) { 00525 $menu.=' Order by: '.t3lib_BEfunc::getFuncMenu(0,'SET[listOrder]',$this->MOD_SETTINGS['listOrder'],$this->MOD_MENU['listOrder']). 00526 ' Show: '.t3lib_BEfunc::getFuncMenu(0,'SET[display_details]',$this->MOD_SETTINGS['display_details'],$this->MOD_MENU['display_details']). 00527 '<br />Display shy extensions: '.t3lib_BEfunc::getFuncCheck(0,'SET[display_shy]',$this->MOD_SETTINGS['display_shy']); 00528 } 00529 00530 if ($this->MOD_SETTINGS['function']==2) { 00531 $menu.=' Get own/member/selected extensions only: '. 00532 t3lib_BEfunc::getFuncCheck(0,'SET[own_member_only]',$this->MOD_SETTINGS['own_member_only']); 00533 } 00534 00535 $this->content.=$this->doc->section('','<span class="nobr">'.$menu.'</span>'); 00536 $this->content.=$this->doc->spacer(10); 00537 00538 switch((string)$this->MOD_SETTINGS['function']) { 00539 case '0': 00540 // Lists loaded (installed) extensions 00541 $this->extensionList_loaded(); 00542 break; 00543 case '1': 00544 // Lists the installed (available) extensions 00545 $this->extensionList_installed(); 00546 break; 00547 case '2': 00548 // Lists the extensions available from online rep. 00549 $this->extensionList_import(); 00550 break; 00551 case '3': 00552 // Lists the extensions available from online rep. 00553 $this->alterSettings(); 00554 break; 00555 default: 00556 $this->extObjContent(); 00557 break; 00558 } 00559 } 00560 00561 // Shortcuts: 00562 if ($BE_USER->mayMakeShortcut()) { 00563 $this->content.=$this->doc->spacer(20).$this->doc->section('',$this->doc->makeShortcutIcon('CMD','function',$this->MCONF['name'])); 00564 } 00565 } 00566 00572 function printContent() { 00573 global $SOBE; 00574 00575 $this->content.= $this->doc->endPage(); 00576 echo $this->content; 00577 } 00578 00579 00580 00581 00582 00583 00584 00585 00586 00587 00588 /********************************* 00589 * 00590 * Function Menu Applications 00591 * 00592 *********************************/ 00593 00599 function extensionList_loaded() { 00600 global $TYPO3_LOADED_EXT; 00601 00602 list($list) = $this->getInstalledExtensions(); 00603 00604 // Loaded extensions 00605 $content = ''; 00606 $lines = array(); 00607 $lines[] = $this->extensionListRowHeader(' class="bgColor5"',array('<td><img src="clear.gif" width="1" height="1" alt="" /></td>')); 00608 00609 foreach($TYPO3_LOADED_EXT as $extKey => $eConf) { 00610 if (strcmp($extKey, '_CACHEFILE')) { 00611 if ($this->MOD_SETTINGS['display_shy'] || !$list[$extKey]['EM_CONF']['shy']) { 00612 if (in_array($extKey, $this->requiredExt)) { 00613 $loadUnloadLink = '<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw('Rq').'</strong>'; 00614 } else { 00615 $loadUnloadLink = '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[remove]=1').'">'.$this->removeButton().'</a>'; 00616 } 00617 00618 $lines[] = $this->extensionListRow($extKey,$list[$extKey],array('<td class="bgColor">'.$loadUnloadLink.'</td>')); 00619 } 00620 } 00621 } 00622 00623 $content.= t3lib_BEfunc::cshItem('_MOD_tools_em', 'loaded', $GLOBALS['BACK_PATH'],''); 00624 $content.= ' 00625 00626 <!-- Loaded Extensions List --> 00627 <table border="0" cellpadding="2" cellspacing="1">'.implode('',$lines).'</table>'; 00628 00629 $this->content.=$this->doc->section('Loaded Extensions',$content,0,1); 00630 } 00631 00637 function extensionList_installed() { 00638 global $TYPO3_LOADED_EXT; 00639 00640 list($list,$cat)=$this->getInstalledExtensions(); 00641 00642 // Available extensions 00643 if (is_array($cat[$this->MOD_SETTINGS['listOrder']])) { 00644 $content=''; 00645 $lines=array(); 00646 $lines[]=$this->extensionListRowHeader(' class="bgColor5"',array('<td><img src="clear.gif" width="18" height="1" alt="" /></td>')); 00647 00648 $allKeys=array(); 00649 foreach($cat[$this->MOD_SETTINGS['listOrder']] as $catName => $extEkeys) { 00650 $allKeys[]=''; 00651 $allKeys[]='TYPE: '.$catName; 00652 00653 $lines[]='<tr><td colspan="'.(3+$this->detailCols[$this->MOD_SETTINGS['display_details']]).'"><br /></td></tr>'; 00654 $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>'; 00655 00656 asort($extEkeys); 00657 reset($extEkeys); 00658 while(list($extKey)=each($extEkeys)) { 00659 $allKeys[]=$extKey; 00660 if ($this->MOD_SETTINGS['display_shy'] || !$list[$extKey]['EM_CONF']['shy']) { 00661 $loadUnloadLink = t3lib_extMgm::isLoaded($extKey)? 00662 '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[remove]=1&CMD[clrCmd]=1&SET[singleDetails]=info').'">'.$this->removeButton().'</a>': 00663 '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[load]=1&CMD[clrCmd]=1&SET[singleDetails]=info').'">'.$this->installButton().'</a>'; 00664 if (in_array($extKey,$this->requiredExt)) $loadUnloadLink='<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw('Rq').'</strong>'; 00665 00666 if ($list[$extKey]['EM_CONF']['private']) { 00667 $theRowClass = 'em-private'; 00668 } else { 00669 $theRowClass = t3lib_extMgm::isLoaded($extKey)? 'em-listbg1' : 'em-listbg2'; 00670 } 00671 $lines[]=$this->extensionListRow($extKey,$list[$extKey],array('<td class="bgColor">'.$loadUnloadLink.'</td>'),$theRowClass); 00672 } 00673 } 00674 } 00675 00676 $content.=' 00677 00678 00679 <!-- 00680 EXTENSION KEYS: 00681 00682 00683 '.trim(implode(chr(10),$allKeys)).' 00684 00685 --> 00686 00687 00688 00689 00690 '; 00691 00692 #debug($this->MOD_SETTINGS['listOrder']); 00693 $content.= t3lib_BEfunc::cshItem('_MOD_tools_em', 'avail', $GLOBALS['BACK_PATH'],'|<br/>'); 00694 $content.= 'If you want to use an extension in TYPO3, you should simply click the "plus" button '.$this->installButton().' . <br /> 00695 Installed extensions can also be removed again - just click the remove button '.$this->removeButton().' .<br /><br />'; 00696 $content.= '<table border="0" cellpadding="2" cellspacing="1">'.implode('',$lines).'</table>'; 00697 00698 $this->content.=$this->doc->section('Available Extensions - Order by: '.$this->MOD_MENU['listOrder'][$this->MOD_SETTINGS['listOrder']],$content,0,1); 00699 } 00700 } 00701 00707 function extensionList_import() { 00708 global $TYPO3_LOADED_EXT; 00709 00710 // Listing from online repository: 00711 if ($this->listRemote) { 00712 list($inst_list,$inst_cat) = $this->getInstalledExtensions(); 00713 $this->inst_keys = array_flip(array_keys($inst_list)); 00714 00715 $this->detailCols[1]+=6; 00716 00717 // Getting data from repository: 00718 $repositoryUrl=$this->repositoryUrl. 00719 $this->repTransferParams(). 00720 '&tx_extrep[cmd]=currentListing'. 00721 ($this->MOD_SETTINGS['own_member_only']?'&tx_extrep[listmode]=1':''). 00722 ($this->listRemote_search ? '&tx_extrep[search]='.rawurlencode($this->listRemote_search) : ''); 00723 00724 $fetchData = $this->fetchServerData($repositoryUrl); 00725 00726 if (is_array($fetchData)) { 00727 $listArr = $fetchData[0]; 00728 list($list,$cat) = $this->getImportExtList($listArr); 00729 00730 // Available extensions 00731 if (is_array($cat[$this->MOD_SETTINGS['listOrder']])) { 00732 $content=''; 00733 $lines=array(); 00734 $lines[]=$this->extensionListRowHeader(' class="bgColor5"',array('<td><img src="clear.gif" width="18" height="1" alt="" /></td>'),1); 00735 00736 foreach($cat[$this->MOD_SETTINGS['listOrder']] as $catName => $extEkeys) { 00737 if (count($extEkeys)) { 00738 $lines[]='<tr><td colspan="'.(3+$this->detailCols[$this->MOD_SETTINGS['display_details']]).'"><br /></td></tr>'; 00739 $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>'; 00740 00741 asort($extEkeys); 00742 reset($extEkeys); 00743 while(list($extKey)=each($extEkeys)) { 00744 if ($this->MOD_SETTINGS['display_shy'] || !$list[$extKey]['EM_CONF']['shy']) { 00745 $loadUnloadLink=''; 00746 if ($inst_list[$extKey]['type']!='S' && (!isset($inst_list[$extKey]) || $this->versionDifference($list[$extKey]['EM_CONF']['version'],$inst_list[$extKey]['EM_CONF']['version'],$this->versionDiffFactor))) { 00747 if (isset($inst_list[$extKey])) { 00748 // update 00749 $loc= ($inst_list[$extKey]['type']=='G'?'G':'L'); 00750 $aUrl = 'index.php?CMD[importExt]='.$list[$extKey]['extRepUid'].'&CMD[loc]='.$loc.($this->getDocManual($extKey,$loc)?'&CMD[inc_manual]=1':''); 00751 $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>'; 00752 } else { 00753 // import 00754 $aUrl = 'index.php?CMD[importExt]='.$list[$extKey]['extRepUid'].'&CMD[loc]=L'.($this->getDocManual($extKey)?'&CMD[inc_manual]=1':''); 00755 $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>'; 00756 } 00757 } else { 00758 $loadUnloadLink = ' '; 00759 } 00760 00761 if ($list[$extKey]['_MEMBERS_ONLY']) { 00762 $theRowClass = 'em-private'; 00763 } elseif (isset($inst_list[$extKey])) { 00764 $theRowClass = t3lib_extMgm::isLoaded($extKey) ? 'em-listbg1' : 'em-listbg2'; 00765 } else { 00766 $theRowClass = 'em-listbg3'; 00767 } 00768 $lines[]=$this->extensionListRow($extKey,$list[$extKey],array('<td class="bgColor">'.$loadUnloadLink.'</td>'),$theRowClass,$inst_list,1,'index.php?CMD[importExtInfo]='.$list[$extKey]['extRepUid']); 00769 } 00770 } 00771 } 00772 } 00773 00774 // CSH: 00775 $content.= t3lib_BEfunc::cshItem('_MOD_tools_em', 'import_ter', $GLOBALS['BACK_PATH'],'|<br/>'); 00776 00777 $content.= ' 00778 00779 <!-- TER Extensions list --> 00780 <table border="0" cellpadding="2" cellspacing="1">'.implode('',$lines).'</table>'; 00781 00782 $content.= '<br />Data fetched: ['.implode('][',$fetchData[1]).']'; 00783 $content.= '<br /><br /><strong>PRIVACY NOTICE:</strong><br /> '.$this->privacyNotice; 00784 00785 $this->content.=$this->doc->section('Extensions in TYPO3 Extension Repository (online) - Order by: '.$this->MOD_MENU['listOrder'][$this->MOD_SETTINGS['listOrder']],$content,0,1); 00786 00787 if (!$this->MOD_SETTINGS['own_member_only'] && !$this->listRemote_search) { 00788 // Plugins which are NOT uploaded to repository but present on this server. 00789 $content=''; 00790 $lines=array(); 00791 if (count($this->inst_keys)) { 00792 $lines[]=$this->extensionListRowHeader(' class="bgColor5"',array('<td><img src="clear.gif" width="18" height="1" alt="" /></td>')); 00793 00794 reset($this->inst_keys); 00795 while(list($extKey)=each($this->inst_keys)) { 00796 if ($this->MOD_SETTINGS['display_shy'] || !$inst_list[$extKey]['EM_CONF']['shy']) { 00797 $loadUnloadLink = t3lib_extMgm::isLoaded($extKey)? 00798 '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[remove]=1&CMD[clrCmd]=1&SET[singleDetails]=info').'">'.$this->removeButton().'</a>': 00799 '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[load]=1&CMD[clrCmd]=1&SET[singleDetails]=info').'">'.$this->installButton().'</a>'; 00800 if (in_array($extKey,$this->requiredExt)) $loadUnloadLink='<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw('Rq').'</strong>'; 00801 $lines[]=$this->extensionListRow($extKey,$inst_list[$extKey],array('<td class="bgColor">'.$loadUnloadLink.'</td>'),t3lib_extMgm::isLoaded($extKey)?'em-listbg1':'em-listbg2'); 00802 } 00803 } 00804 } 00805 00806 $content.= 'This is the list of extensions which are either user-defined (should be prepended user_ then) or which are private (and does not show up in the public list above).<br /><br />'; 00807 $content.= '<table border="0" cellpadding="2" cellspacing="1">'.implode('',$lines).'</table>'; 00808 $this->content.=$this->doc->spacer(20); 00809 $this->content.=$this->doc->section('Extensions found only on this server',$content,0,1); 00810 } 00811 } 00812 } 00813 } else { 00814 // CSH 00815 $content.= t3lib_BEfunc::cshItem('_MOD_tools_em', 'import', $GLOBALS['BACK_PATH'],'|<br/>'); 00816 $content.= 'Click here to connect to "'.$this->repositoryUrl.'" and retrieve the list of publicly available plugins from the TYPO3 Extension Repository.<br />'; 00817 00818 if ($this->fe_user['username']) { 00819 $content.= '<br /><img src="'.$GLOBALS['BACK_PATH'].'gfx/icon_note.gif" width="18" height="16" align="top" alt="" />Repository username "'.$this->fe_user['username'].'" will be sent as authentication.<br />'; 00820 } else { 00821 $content.= '<br /><img src="'.$GLOBALS['BACK_PATH'].'gfx/icon_warning2.gif" width="18" height="16" align="top" alt="" />You have not configured a repository username/password yet. Please <a href="index.php?SET[function]=3">go to "Settings"</a> and do that.<br />'; 00822 } 00823 00824 $onCLick = "document.location='index.php?ter_connect=1&ter_search='+escape(this.form['_lookUp'].value);return false;"; 00825 $content.= '<br /> 00826 Look up: <input type="text" name="_lookUp" value="" /> 00827 <input type="submit" value="Connect to online repository" onclick="'.htmlspecialchars($onCLick).'" />'; 00828 00829 $this->content.=$this->doc->section('Extensions in TYPO3 Extension Repository',$content,0,1); 00830 } 00831 00832 // Private lookup: 00833 /* 00834 $onClick = 'document.location=\'index.php?CMD[importExtInfo]=\'+document.pageform.uid_private_key.value+\'&CMD[download_password]=\'+document.pageform.download_password.value; return false;'; 00835 $content= 'Privat lookup key: <input type="text" name="uid_private_key" /> Password, if any: <input type="text" name="download_password" /><input type="submit" value="Lookup" onclick="'.htmlspecialchars($onClick).'" />'; 00836 $this->content.=$this->doc->spacer(20); 00837 $this->content.=$this->doc->section('Private extension lookup:',$content,0,1); 00838 */ 00839 00840 // Upload: 00841 if ($this->importAtAll()) { 00842 $content= '</form><form action="index.php" enctype="'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['form_enctype'].'" method="post"> 00843 Upload extension file (.t3x):<br /> 00844 <input type="file" size="60" name="upload_ext_file" /><br /> 00845 ... in location:<br /> 00846 <select name="CMD[loc]">'; 00847 if ($this->importAsType('L')) $content.='<option value="L">Local (../typo3conf/ext/)</option>'; 00848 if ($this->importAsType('G')) $content.='<option value="G">Global (typo3/ext/)</option>'; 00849 if ($this->importAsType('S')) $content.='<option value="S">System (typo3/sysext/)</option>'; 00850 $content.='</select><br /> 00851 <input type="checkbox" value="1" name="CMD[uploadOverwrite]" /> Overwrite any existing extension!<br /> 00852 <input type="submit" name="CMD[uploadExt]" value="Upload extension file" /><br /> 00853 '; 00854 if (!$this->gzcompress) { 00855 $content.='<br />'.$GLOBALS['TBE_TEMPLATE']->rfw("NOTE: No decompression available! Don't upload a compressed extension - it will not succeed."); 00856 } 00857 } else $content=$this->noImportMsg(); 00858 00859 $this->content.=$this->doc->spacer(20); 00860 $this->content.=$this->doc->section('Upload extension file directly (.t3x):',$content,0,1); 00861 } 00862 00868 function alterSettings() { 00869 $content.= t3lib_BEfunc::cshItem('_MOD_tools_em', 'settings', $GLOBALS['BACK_PATH'],'|<br/>'); 00870 $content.= ' 00871 <table border="0" cellpadding="2" cellspacing="2"> 00872 <tr class="bgColor4"> 00873 <td>Enter repository username:</td> 00874 <td><input type="text" name="SET[fe_u]" value="'.htmlspecialchars($this->MOD_SETTINGS['fe_u']).'" /></td> 00875 </tr> 00876 <tr class="bgColor4"> 00877 <td>Enter repository password:</td> 00878 <td><input type="password" name="SET[fe_p]" value="'.htmlspecialchars($this->MOD_SETTINGS['fe_p']).'" /></td> 00879 </tr> 00880 <tr class="bgColor4"> 00881 <td>Enter default upload password:</td> 00882 <td><input type="password" name="SET[fe_up]" value="'.htmlspecialchars($this->MOD_SETTINGS['fe_up']).'" /></td> 00883 </tr> 00884 </table> 00885 00886 <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!<br /> 00887 <br /> 00888 <input type="submit" value="Update" /> 00889 '; 00890 00891 $this->content.=$this->doc->section('Repository settings',$content,0,1); 00892 } 00893 00894 00895 00896 00897 00898 00899 00900 00901 00902 00903 /********************************* 00904 * 00905 * Command Applications (triggered by GET var) 00906 * 00907 *********************************/ 00908 00915 function importExtInfo($extRepUid) { 00916 00917 // "Go back" link 00918 $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>'; 00919 $this->content.= $this->doc->section('',$content); 00920 $content = ''; 00921 00922 // Create connection URL: 00923 $uidParts = t3lib_div::trimExplode('-',$extRepUid); 00924 if (count($uidParts)==2) { 00925 $extRepUid = $uidParts[0]; 00926 $addParams = '&tx_extrep[pKey]='.rawurlencode(trim($uidParts[1])) 00927 .'&tx_extrep[pPass]='.rawurlencode(trim($this->CMD['download_password'])); 00928 $addImportParams = '&CMD[download_password]='.rawurlencode(trim($this->CMD['download_password'])); 00929 } else $addParams = ''; 00930 00931 $repositoryUrl = $this->repositoryUrl. 00932 $this->repTransferParams(). 00933 $addParams. 00934 '&tx_extrep[cmd]=extensionInfo'. 00935 '&tx_extrep[uid]='.$extRepUid; 00936 00937 // Fetch remote data: 00938 list($fetchData) = $this->fetchServerData($repositoryUrl); 00939 if (is_array($fetchData['_other_versions'])) { 00940 $opt = array(); 00941 $opt[] = '<option value=""></option>'; 00942 $selectWasSet=0; 00943 00944 foreach($fetchData['_other_versions'] as $dat) { 00945 $setSel = ($dat['uid']==$extRepUid?' selected="selected"':''); 00946 if ($setSel) $selectWasSet=1; 00947 $opt[]='<option value="'.$dat['uid'].'"'.$setSel.'>'.$dat['version'].'</option>'; 00948 } 00949 if (!$selectWasSet && $fetchData['emconf_private']) { 00950 $opt[]='<option value="'.$fetchData['uid'].'-'.$fetchData['private_key'].'" selected="selected">'.$fetchData['version'].' (Private)</option>'; 00951 } 00952 00953 // "Select version" box: 00954 $onClick = 'document.location=\'index.php?CMD[importExtInfo]=\'+document.pageform.repUid.options[document.pageform.repUid.selectedIndex].value; return false;'; 00955 $select='<select name="repUid">'.implode('',$opt).'</select> <input type="submit" value="Load details" onclick="'.htmlspecialchars($onClick).'" /> or<br /><br />'; 00956 if ($this->importAtAll()) { 00957 $onClick = ' 00958 document.location=\'index.php?CMD[importExt]=\' 00959 +document.pageform.repUid.options[document.pageform.repUid.selectedIndex].value 00960 +\'&CMD[loc]=\'+document.pageform.loc.options[document.pageform.loc.selectedIndex].value 00961 +\'&CMD[transl]=\'+(document.pageform.transl.checked?1:0) 00962 +\'&CMD[inc_manual]=\'+(document.pageform.inc_manual.checked?1:0) 00963 +\''.$addImportParams.'\'; return false;'; 00964 $select.=' 00965 <input type="submit" value="Import/Update" onclick="'.htmlspecialchars($onClick).'"> to: 00966 <select name="loc">'. 00967 ($this->importAsType('G',$fetchData['emconf_lockType'])?'<option value="G">Global: '.$this->typePaths['G'].$fetchData['extension_key'].'/'.(@is_dir(PATH_site.$this->typePaths['G'].$fetchData['extension_key'])?' (OVERWRITE)':' (empty)').'</option>':''). 00968 ($this->importAsType('L',$fetchData['emconf_lockType'])?'<option value="L">Local: '.$this->typePaths['L'].$fetchData['extension_key'].'/'.(@is_dir(PATH_site.$this->typePaths['L'].$fetchData['extension_key'])?' (OVERWRITE)':' (empty)').'</option>':''). 00969 ($this->importAsType('S',$fetchData['emconf_lockType'])?'<option value="S">System: '.$this->typePaths['S'].$fetchData['extension_key'].'/'.(@is_dir(PATH_site.$this->typePaths['S'].$fetchData['extension_key'])?' (OVERWRITE)':' (empty)').'</option>':''). 00970 #'<option value="fileadmin">'.htmlspecialchars('TEST: fileadmin/_temp_/[extension key name + date]').'</option>'. 00971 '</select> 00972 <br /><input type="checkbox" name="transl" value="1" />Include most recent translations 00973 <br /><input type="checkbox" name="inc_manual" value="1"'.($this->getDocManual($fetchData['extension_key'],@is_dir(PATH_site.$this->typePaths['G'].$fetchData['extension_key'])?'G':'L')?' checked="checked"':'').' />Include "doc/manual.sxw", if any 00974 '; 00975 } else $select.= $this->noImportMsg(); 00976 $content.= $select; 00977 $this->content.= $this->doc->section('Select command',$content,0,1); 00978 } 00979 00980 // Details: 00981 $extKey = $fetchData['extension_key']; 00982 list($xList) = $this->getImportExtList(array($fetchData)); 00983 $eInfo = $xList[$extKey]; 00984 $eInfo['_TECH_INFO'] = unserialize($fetchData['techinfo']); 00985 $tempFiles = unserialize($fetchData['files']); 00986 00987 if (is_array($tempFiles)) { 00988 reset($tempFiles); 00989 while(list($fk)=each($tempFiles)) { 00990 if (!strstr($fk,'/')) $eInfo['files'][]=$fk; 00991 } 00992 } 00993 00994 $content='<strong>'.$fetchData['_ICON'].' '.$eInfo['EM_CONF']['title'].'</strong><br /><br />'; 00995 $content.=$this->extInformationArray($extKey,$eInfo,1); 00996 $this->content.=$this->doc->spacer(10); 00997 $this->content.=$this->doc->section('Remote Extension Details:',$content,0,1); 00998 00999 if (is_array($fetchData['_MESSAGES'])) { 01000 $content = implode('<hr />',$fetchData['_MESSAGES']); 01001 $this->content.=$this->doc->section('Messages from repository server:',$content,0,1,1); 01002 } 01003 } 01004 01016 function importExtFromRep($extRepUid,$loc,$uploadFlag=0,$directInput='',$recentTranslations=0,$incManual=0) { 01017 01018 if (is_array($directInput)) { 01019 $fetchData = array($directInput,''); 01020 $loc = !strcmp($loc,'G')?'G':'L'; 01021 } elseif ($uploadFlag) { 01022 if ($_FILES['upload_ext_file']['tmp_name']) { 01023 01024 // Read uploaded file: 01025 $uploadedTempFile = t3lib_div::upload_to_tempfile($_FILES['upload_ext_file']['tmp_name']); 01026 $fileContent = t3lib_div::getUrl($uploadedTempFile); 01027 t3lib_div::unlink_tempfile($uploadedTempFile); 01028 01029 // Decode file data: 01030 $fetchData = array($this->decodeExchangeData($fileContent),''); 01031 01032 if (is_array($fetchData)) { 01033 $extKey = $fetchData[0]['extKey']; 01034 if ($extKey) { 01035 if (!$this->CMD['uploadOverwrite']) { 01036 $loc = !strcmp($loc,'G')?'G':'L'; 01037 $comingExtPath = PATH_site.$this->typePaths[$loc].$extKey.'/'; 01038 if (@is_dir($comingExtPath)) { 01039 # debug('!'); 01040 return 'Extension was already present in "'.$comingExtPath.'" - and the overwrite flag was not set! So nothing done...'; 01041 } // ... else go on, install... 01042 } // ... else go on, install... 01043 } else return 'No extension key in file. Strange...'; 01044 } else return 'Wrong file format. No data recognized.'; 01045 } else return 'No file uploaded! Probably the file was too large for PHPs internal limit for uploadable files.'; 01046 } else { 01047 01048 // Create link: 01049 $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>'; 01050 $this->content.= $this->doc->section('',$content); 01051 $content = ''; 01052 01053 // Building request URL: 01054 $uidParts = t3lib_div::trimExplode('-',$extRepUid); 01055 if (count($uidParts)==2) { 01056 $extRepUid=$uidParts[0]; 01057 $addParams='&tx_extrep[pKey]='.rawurlencode(trim($uidParts[1])) 01058 .'&tx_extrep[pPass]='.rawurlencode(trim($this->CMD['download_password'])); 01059 } else $addParams=''; 01060 01061 // If most recent translation should be delivered, send this: 01062 if ($recentTranslations) { 01063 $addParams.='&tx_extrep[transl]=1'; 01064 } 01065 01066 // If manual should be included, send this: 01067 if ($incManual) { 01068 $addParams.='&tx_extrep[inc_manual]=1'; 01069 } 01070 01071 $repositoryUrl=$this->repositoryUrl. 01072 $this->repTransferParams(). 01073 $addParams. 01074 '&tx_extrep[cmd]=importExtension'. 01075 '&tx_extrep[uid]='.$extRepUid; 01076 01077 // Fetch extension from TER: 01078 $fetchData = $this->fetchServerData($repositoryUrl); 01079 } 01080 01081 // At this point the extension data should be present; so we want to write it to disc: 01082 if ($this->importAsType($loc)) { 01083 if (is_array($fetchData)) { // There was some data successfully transferred 01084 if ($fetchData[0]['extKey'] && is_array($fetchData[0]['FILES'])) { 01085 $extKey = $fetchData[0]['extKey']; 01086 $EM_CONF = $fetchData[0]['EM_CONF']; 01087 if (!$EM_CONF['lockType'] || !strcmp($EM_CONF['lockType'],$loc)) { 01088 $res = $this->clearAndMakeExtensionDir($fetchData[0],$loc); 01089 if (is_array($res)) { 01090 $extDirPath = trim($res[0]); 01091 if ($extDirPath && @is_dir($extDirPath) && substr($extDirPath,-1)=='/') { 01092 01093 $emConfFile = $this->construct_ext_emconf_file($extKey,$EM_CONF); 01094 $dirs = $this->extractDirsFromFileList(array_keys($fetchData[0]['FILES'])); 01095 01096 $res = $this->createDirsInPath($dirs,$extDirPath); 01097 if (!$res) { 01098 $writeFiles = $fetchData[0]['FILES']; 01099 $writeFiles['ext_emconf.php']['content'] = $emConfFile; 01100 $writeFiles['ext_emconf.php']['content_md5'] = md5($emConfFile); 01101 01102 // Write files: 01103 foreach($writeFiles as $theFile => $fileData) { 01104 t3lib_div::writeFile($extDirPath.$theFile,$fileData['content']); 01105 if (!@is_file($extDirPath.$theFile)) { 01106 $content.='Error: File "'.$extDirPath.$theFile.'" could not be created!!!<br />'; 01107 } elseif (md5(t3lib_div::getUrl($extDirPath.$theFile)) != $fileData['content_md5']) { 01108 $content.='Error: File "'.$extDirPath.$theFile.'" MD5 was different from the original files MD5 - so the file is corrupted!<br />'; 01109 } elseif (TYPO3_OS!='WIN') { 01110 #chmod ($extDirPath.$theFile, 0755); # SHOULD NOT do that here since writing the file should already have set adequate permissions! 01111 } 01112 } 01113 01114 // No content, no errors. Create success output here: 01115 if (!$content) { 01116 $content='SUCCESS: '.$extDirPath.'<br />'; 01117 01118 // Fix TYPO3_MOD_PATH for backend modules in extension: 01119 $modules = t3lib_div::trimExplode(',',$EM_CONF['module'],1); 01120 if (count($modules)) { 01121 foreach($modules as $mD) { 01122 $confFileName = $extDirPath.$mD.'/conf.php'; 01123 if (@is_file($confFileName)) { 01124 $content.= $this->writeTYPO3_MOD_PATH($confFileName,$loc,$extKey.'/'.$mD.'/').'<br />'; 01125 } else $content.='Error: Couldn\'t find "'.$confFileName.'"<br />'; 01126 } 01127 } 01128 // NOTICE: I used two hours trying to find out why a script, ext_emconf.php, written twice and in between included by PHP did not update correct the second time. Probably something with PHP-A cache and mtime-stamps. 01129 // But this order of the code works.... (using the empty Array with type, EMCONF and files hereunder). 01130 01131 // Writing to ext_emconf.php: 01132 $sEMD5A = $this->serverExtensionMD5Array($extKey,array( 01133 'type' => $loc, 01134 'EM_CONF' => array(), 01135 'files' => array() 01136 )); 01137 $EM_CONF['_md5_values_when_last_written'] = serialize($sEMD5A); 01138 $emConfFile = $this->construct_ext_emconf_file($extKey,$EM_CONF); 01139 t3lib_div::writeFile($extDirPath.'ext_emconf.php',$emConfFile); 01140 01141 $content.='ext_emconf.php: '.$extDirPath.'ext_emconf.php<br />'; 01142 $content.='Type: '.$loc.'<br />'; 01143 01144 // Remove cache files: 01145 if (t3lib_extMgm::isLoaded($extKey)) { 01146 if ($this->removeCacheFiles()) { 01147 $content.='Cache-files are removed and will be re-written upon next hit<br />'; 01148 } 01149 01150 list($new_list)=$this->getInstalledExtensions(); 01151 $content.=$this->updatesForm($extKey,$new_list[$extKey],1,'index.php?CMD[showExt]='.$extKey.'&SET[singleDetails]=info'); 01152 } 01153 01154 // Show any messages: 01155 if (is_array($fetchData[0]['_MESSAGES'])) { 01156 $content.='<hr /><strong>Messages from repository:</strong><br /><br />'.implode('<br />',$fetchData[0]['_MESSAGES']); 01157 } 01158 01159 // Install / Uninstall: 01160 $content.='<h3>Install / Uninstall Extension:</h3>'; 01161 $content.= 01162 $new_list[$extKey] ? 01163 '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[remove]=1&CMD[clrCmd]=1&SET[singleDetails]=info').'">'.$this->removeButton().' Uninstall extension</a>' : 01164 '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[load]=1&CMD[clrCmd]=1&SET[singleDetails]=info').'">'.$this->installButton().' Install extension</a>'; 01165 01166 } 01167 } else $content = $res; 01168 } else $content = 'Error: The extension path "'.$extDirPath.'" was different than expected...'; 01169 } else $content = $res; 01170 } else $content = 'Error: The extension can only be installed in the path '.$this->typePaths[$EM_CONF['lockType']].' (lockType='.$EM_CONF['lockType'].')'; 01171 } else $content = 'Error: No extension key!!! Why? - nobody knows... (Or no files in the file-array...)'; 01172 } else $content = 'Error: The datatransfer did not succeed...'; 01173 } else $content = 'Error: Installation is not allowed in this path ('.$this->typePaths[$loc].')'; 01174 01175 $this->content.=$this->doc->section('Extension copied to server',$content,0,1); 01176 } 01177 01184 function showExtDetails($extKey) { 01185 global $TYPO3_LOADED_EXT; 01186 01187 list($list,$cat)=$this->getInstalledExtensions(); 01188 $absPath = $this->getExtPath($extKey,$list[$extKey]['type']); 01189 01190 // Check updateModule: 01191 if (@is_file($absPath.'class.ext_update.php')) { 01192 require_once($absPath.'class.ext_update.php'); 01193 $updateObj = new ext_update; 01194 if (!$updateObj->access()) { 01195 unset($this->MOD_MENU['singleDetails']['updateModule']); 01196 } 01197 } else { 01198 unset($this->MOD_MENU['singleDetails']['updateModule']); 01199 } 01200 01201 // Function menu here: 01202 $content = ' 01203 <table border="0" cellpadding="0" cellspacing="0" width="100%"> 01204 <tr> 01205 <td nowrap="nowrap">Extension: <strong>'.$this->extensionTitleIconHeader($extKey,$list[$extKey]).'</strong> ('.$extKey.')</td> 01206 <td align="right" nowrap="nowrap">'. 01207 t3lib_BEfunc::getFuncMenu(0,'SET[singleDetails]',$this->MOD_SETTINGS['singleDetails'],$this->MOD_MENU['singleDetails'],'','&CMD[showExt]='.$extKey).' '. 01208 '<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> 01209 </tr> 01210 </table>'; 01211 $this->content.=$this->doc->section('',$content); 01212 01213 // Show extension details: 01214 if ($list[$extKey]) { 01215 01216 // Checking if a command for install/uninstall is executed: 01217 if (($this->CMD['remove'] || $this->CMD['load']) && !in_array($extKey,$this->requiredExt)) { 01218 01219 // Install / Uninstall extension here: 01220 if (t3lib_extMgm::isLocalconfWritable()) { 01221 if ($this->CMD['remove']) { 01222 $newExtList = $this->removeExtFromList($extKey,$list); 01223 } else { 01224 $newExtList = $this->addExtToList($extKey,$list); 01225 } 01226 01227 // Success-installation: 01228 if ($newExtList!=-1) { 01229 $updates = ''; 01230 if ($this->CMD['load']) { 01231 $updates = $this->updatesForm($extKey,$list[$extKey],1,'','<input type="hidden" name="_do_install" value="1" /><input type="hidden" name="_clrCmd" value="'.$this->CMD['clrCmd'].'" />'); 01232 if ($updates) { 01233 $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; 01234 $this->content.=$this->doc->section('Installing '.$this->extensionTitleIconHeader($extKey,$list[$extKey]).strtoupper(': Database needs to be updated'),$updates,1,1,1,1); 01235 } 01236 # $updates.=$this->checkDBupdates($extKey,$list[$extKey]); 01237 # $updates.= $this->checkClearCache($extKey,$list[$extKey]); 01238 # $updates.= $this->checkUploadFolder($extKey,$list[$extKey]); 01239 /* if ($updates) { 01240 $updates=' 01241 Before the extension can be installed the database needs to be updated with new tables or fields. Please select which operations to perform: 01242 </form><form action="'.t3lib_div::linkThisScript().'" method="post">'.$updates.' 01243 <br /><input type="submit" name="write" value="Update database and install extension" /> 01244 <input type="hidden" name="_do_install" value="1" /> 01245 '; 01246 $this->content.=$this->doc->section('Installing '.$this->extensionTitleIconHeader($extKey,$list[$extKey]).strtoupper(': Database needs to be updated'),$updates,1,1,1); 01247 } 01248 */ } elseif ($this->CMD['remove']) { 01249 $updates.= $this->checkClearCache($extKey,$list[$extKey]); 01250 if ($updates) { 01251 $updates = ' 01252 </form><form action="'.t3lib_div::linkThisScript().'" method="post">'.$updates.' 01253 <br /><input type="submit" name="write" value="Remove extension" /> 01254 <input type="hidden" name="_do_install" value="1" /> 01255 <input type="hidden" name="_clrCmd" value="'.$this->CMD['clrCmd'].'" /> 01256 '; 01257 $this->content.=$this->doc->section('Installing '.$this->extensionTitleIconHeader($extKey,$list[$extKey]).strtoupper(': Database needs to be updated'),$updates,1,1,1,1); 01258 } 01259 } 01260 if (!$updates || t3lib_div::_GP('_do_install')) { 01261 $this->writeNewExtensionList($newExtList); 01262 01263 01264 /* 01265 $content = $newExtList; 01266 $this->content.=$this->doc->section('Active status'," 01267 <strong>Extension list is written to localconf.php!</strong><br /> 01268 It may be necessary to reload TYPO3 depending on the change.<br /> 01269 01270 <em>(".$content.")</em>",0,1); 01271 */ 01272 if ($this->CMD['clrCmd'] || t3lib_div::_GP('_clrCmd')) { 01273 $vA = array('CMD'=>''); 01274 } else { 01275 $vA = array('CMD'=>Array('showExt'=>$extKey)); 01276 } 01277 header('Location: '.t3lib_div::linkThisScript($vA)); 01278 } 01279 } 01280 } else { 01281 $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); 01282 } 01283 01284 } elseif ($this->CMD['downloadFile'] && !in_array($extKey,$this->requiredExt)) { 01285 01286 // Link for downloading extension has been clicked - deliver content stream: 01287 $dlFile = $this->CMD['downloadFile']; 01288 if (t3lib_div::isFirstPartOfStr($dlFile,PATH_site) && t3lib_div::isFirstPartOfStr($dlFile,$absPath) && @is_file($dlFile)) { 01289 $mimeType = 'application/octet-stream'; 01290 Header('Content-Type: '.$mimeType); 01291 Header('Content-Disposition: attachment; filename='.basename($dlFile)); 01292 echo t3lib_div::getUrl($dlFile); 01293 exit; 01294 } else die('error....'); 01295 01296 } elseif ($this->CMD['editFile'] && !in_array($extKey,$this->requiredExt)) { 01297 01298 // Editing extension file: 01299 $editFile = $this->CMD['editFile']; 01300 if (t3lib_div::isFirstPartOfStr($editFile,PATH_site) && t3lib_div::isFirstPartOfStr($editFile,$absPath)) { // Paranoia... 01301 01302 $fI = t3lib_div::split_fileref($editFile); 01303 if (@is_file($editFile) && t3lib_div::inList($this->editTextExtensions,$fI['fileext'])) { 01304 if (filesize($editFile)<($this->kbMax*1024)) { 01305 $outCode = ''; 01306 $info = ''; 01307 $submittedContent = t3lib_div::_POST('edit'); 01308 $saveFlag = 0; 01309 01310 if(isset($submittedContent['file'])) { // Check referer here? 01311 $info.= $GLOBALS['TBE_TEMPLATE']->rfw('<br /><strong>File saved.</strong>').'<br />'; 01312 $oldFileContent = t3lib_div::getUrl($editFile); 01313 $info.= 'MD5: <b>'.md5(str_replace(chr(13),'',$oldFileContent)).'</b> (Previous File)<br />'; 01314 if (!$GLOBALS['TYPO3_CONF_VARS']['EXT']['noEdit']) { 01315 t3lib_div::writeFile($editFile,$submittedContent['file']); 01316 $saveFlag = 1; 01317 } else die('Saving disabled!!!'); 01318 } 01319 01320 $fileContent = t3lib_div::getUrl($editFile); 01321 $numberOfRows = 35; 01322 01323 $outCode.= 'File: <b>'.substr($editFile,strlen($absPath)).'</b> ('.t3lib_div::formatSize(filesize($editFile)).')<br />'; 01324 $info.= 'MD5: <b>'.md5(str_replace(chr(13),'',$fileContent)).'</b> (File)<br />'; 01325 if($saveFlag) $info.= 'MD5: <b>'.md5(str_replace(chr(13),'',$submittedContent['file'])).'</b> (Saved)<br />'; 01326 $outCode.= '<textarea name="edit[file]" rows="'.$numberOfRows.'" wrap="off"'.$this->doc->formWidthText(48,'width:98%;height:70%','off').'>'.t3lib_div::formatForTextarea($fileContent).'</textarea>'; 01327 $outCode.= '<input type="hidden" name="edit[filename]" value="'.$editFile.'" />'; 01328 $outCode.= '<input type="hidden" name="CMD[editFile]" value="'.htmlspecialchars($editFile).'" />'; 01329 $outCode.= '<input type="hidden" name="CMD[showExt]" value="'.$extKey.'" />'; 01330 $outCode.= $info; 01331 01332 if (!$GLOBALS['TYPO3_CONF_VARS']['EXT']['noEdit']) { 01333 $outCode.='<br /><input type="submit" name="save_file" value="Save file" />'; 01334 } else $outCode.=$GLOBALS['TBE_TEMPLATE']->rfw('<br />[SAVING IS DISABLED - can be enabled by the TYPO3_CONF_VARS[EXT][noEdit]-flag] '); 01335 01336 $onClick = 'document.location=\'index.php?CMD[showExt]='.$extKey.'\';return false;'; 01337 $outCode.='<input type="submit" name="cancel" value="Cancel" onclick="'.htmlspecialchars($onClick).'" />'; 01338 01339 $theOutput.=$this->doc->spacer(15); 01340 $theOutput.=$this->doc->section('Edit file:','',0,1); 01341 $theOutput.=$this->doc->sectionEnd().$outCode; 01342 $this->content.=$theOutput; 01343 } else { 01344 $theOutput.=$this->doc->spacer(15); 01345 $theOutput.=$this->doc->section('Filesize exceeded '.$this->kbMax.' Kbytes','Files larger than '.$this->kbMax.' KBytes are not allowed to be edited.'); 01346 } 01347 } 01348 } else die('Fatal Edit error: File "'.$editFile.'" was not inside the correct path of the TYPO3 Extension!'); 01349 } else { 01350 01351 // MAIN: 01352 switch((string)$this->MOD_SETTINGS['singleDetails']) { 01353 case 'info': 01354 // Loaded / Not loaded: 01355 if (!in_array($extKey,$this->requiredExt)) { 01356 if ($TYPO3_LOADED_EXT[$extKey]) { 01357 $content = '<strong>The extension is installed (loaded and running)!</strong><br />'. 01358 '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[remove]=1').'">Click here to remove the extension: '.$this->removeButton().'</a>'; 01359 } else { 01360 $content = 'The extension is <strong>not</strong> installed yet.<br />'. 01361 '<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[load]=1').'">Click here to install the extension: '.$this->installButton().'</a>'; 01362 } 01363 } else { 01364 $content = 'This extension is entered in the TYPO3_CONF_VARS[SYS][requiredExt] list and is therefore always loaded.'; 01365 } 01366 $this->content.=$this->doc->spacer(10); 01367 $this->content.=$this->doc->section('Active status:',$content,0,1); 01368 01369 if (t3lib_extMgm::isLoaded($extKey)) { 01370 $updates=$this->updatesForm($extKey,$list[$extKey]); 01371 if ($updates) { 01372 $this->content.=$this->doc->spacer(10); 01373 $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); 01374 } 01375 } 01376 01377 // Config: 01378 if (@is_file($absPath.'ext_conf_template.txt')) { 01379 $this->content.=$this->doc->spacer(10); 01380 $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); 01381 $this->tsStyleConfigForm($extKey,$list[$extKey]); 01382 } 01383 01384 // Show details: 01385 $content = t3lib_BEfunc::cshItem('_MOD_tools_em', 'info', $GLOBALS['BACK_PATH'],'|<br/>'); 01386 $content.= $this->extInformationArray($extKey,$list[$extKey]); 01387 01388 $this->content.=$this->doc->spacer(10); 01389 $this->content.=$this->doc->section('Details:',$content,0,1); 01390 break; 01391 case 'upload': 01392 $TER_CMD = t3lib_div::_GP('TER_CMD'); 01393 if (is_array($TER_CMD)) { 01394 $msg = $this->processRepositoryReturnData($TER_CMD); 01395 if ($msg) { 01396 $this->content.=$this->doc->section('Local update of EM_CONF',$msg,0,1,1); 01397 $this->content.=$this->doc->spacer(10); 01398 } 01399 // Must reload this, because EM_CONF information has been updated! 01400 list($list,$cat)=$this->getInstalledExtensions(); 01401 } else { 01402 // CSH: 01403 $content = t3lib_BEfunc::cshItem('_MOD_tools_em', 'upload', $GLOBALS['BACK_PATH'],'|<br/>'); 01404 01405 // Upload: 01406 if (substr($extKey,0,5)!='user_') { 01407 $content.= $this->getRepositoryUploadForm($extKey,$list[$extKey]); 01408 $eC=0; 01409 } else { 01410 $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.<br /> 01411 You are encouraged to register a unique extension key for all your TYPO3 extensions - even if the project is current not official.'; 01412 $eC=2; 01413 } 01414 $this->content.=$this->doc->section('Upload extension to repository',$content,0,1,$eC); 01415 } 01416 break; 01417 case 'download': 01418 break; 01419 case 'backup': 01420 $content = t3lib_BEfunc::cshItem('_MOD_tools_em', 'backup_delete', $GLOBALS['BACK_PATH'],'|<br/>'); 01421 $content.= $this->extBackup($extKey,$list[$extKey]); 01422 $this->content.=$this->doc->section('Backup',$content,0,1); 01423 01424 $content = $this->extDelete($extKey,$list[$extKey]); 01425 $this->content.=$this->doc->section('Delete',$content,0,1); 01426 01427 $content = $this->extUpdateEMCONF($extKey,$list[$extKey]); 01428 $this->content.=$this->doc->section('Update EM_CONF',$content,0,1); 01429 break; 01430 case 'dump': 01431 $this->extDumpTables($extKey,$list[$extKey]); 01432 break; 01433 case 'edit': 01434 // Files: 01435 $content = t3lib_BEfunc::cshItem('_MOD_tools_em', 'editfiles', $GLOBALS['BACK_PATH'],'|<br/>'); 01436 $content.= $this->getFileListOfExtension($extKey,$list[$extKey]); 01437 01438 $this->content.=$this->doc->section('Extension files',$content,0,1); 01439 break; 01440 case 'updateModule': 01441 $this->content.=$this->doc->section('Update:',$updateObj->main(),0,1); 01442 break; 01443 default: 01444 $this->extObjContent(); 01445 break; 01446 } 01447 } 01448 } 01449 } 01450 01451 01452 01453 01454 01455 01456 01457 01458 01459 01460 /*********************************** 01461 * 01462 * Application Sub-functions (HTML parts) 01463 * 01464 **********************************/ 01465 01477 function updatesForm($extKey,$extInfo,$notSilent=0,$script='',$addFields='') { 01478 $script = $script ? $script : t3lib_div::linkThisScript(); 01479 $updates.= $this->checkDBupdates($extKey,$extInfo); 01480 $uCache = $this->checkClearCache($extKey,$extInfo); 01481 if ($notSilent) $updates.= $uCache; 01482 $updates.= $this->checkUploadFolder($extKey,$extInfo); 01483 01484 $absPath = $this->getExtPath($extKey,$extInfo['type']); 01485 if ($notSilent && @is_file($absPath.'ext_conf_template.txt')) { 01486 $cForm = $this->tsStyleConfigForm($extKey,$extInfo,1,$script,$updates.$addFields.'<br />'); 01487 } 01488 01489 if ($updates || $cForm) { 01490 if ($cForm) { 01491 $updates = '</form>'.$cForm.'<form>'; 01492 } else { 01493 $updates = '</form><form action="'.htmlspecialchars($script).'" method="post">'.$updates.$addFields.' 01494 <br /><input type="submit" name="write" value="Make updates" /> 01495 '; 01496 } 01497 } 01498 return $updates; 01499 } 01500 01508 function extDumpTables($extKey,$extInfo) { 01509 01510 // Get dbInfo which holds the structure known from the tables.sql file 01511 $techInfo = $this->makeDetailedExtensionAnalysis($extKey,$extInfo); 01512 $absPath = $this->getExtPath($extKey,$extInfo['type']); 01513 01514 // Static tables: 01515 if (is_array($techInfo['static'])) { 01516 if ($this->CMD['writeSTATICdump']) { // Writing static dump: 01517 $writeFile = $absPath.'ext_tables_static+adt.sql'; 01518 if (@is_file($writeFile)) { 01519 $dump_static = $this->dumpStaticTables(implode(',',$techInfo['static'])); 01520 t3lib_div::writeFile($writeFile,$dump_static); 01521 $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); 01522 } 01523 } else { // Showing info about what tables to dump - and giving the link to execute it. 01524 $msg = 'Dumping table content for static tables:<br />'; 01525 $msg.= '<br />'.implode('<br />',$techInfo['static']).'<br />'; 01526 01527 // ... then feed that to this function which will make new CREATE statements of the same fields but based on the current database content. 01528 $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); 01529 $this->content.=$this->doc->spacer(20); 01530 } 01531 } 01532 01533 // Table and field definitions: 01534 if (is_array($techInfo['dump_tf'])) { 01535 $dump_tf_array = $this->getTableAndFieldStructure($techInfo['dump_tf']); 01536 $dump_tf = $this->dumpTableAndFieldStructure($dump_tf_array); 01537 if ($this->CMD['writeTFdump']) { 01538 $writeFile = $absPath.'ext_tables.sql'; 01539 if (@is_file($writeFile)) { 01540 t3lib_div::writeFile($writeFile,$dump_tf); 01541 $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); 01542 } 01543 } else { 01544 $msg = 'Dumping current database structure for:<br />'; 01545 if (is_array($techInfo['tables'])) { 01546 $msg.= '<br /><strong>Tables:</strong><br />'.implode('<br />',$techInfo['tables']).'<br />'; 01547 } 01548 if (is_array($techInfo['fields'])) { 01549 $msg.= '<br /><strong>Solo-fields:</strong><br />'.implode('<br />',$techInfo['fields']).'<br />'; 01550 } 01551 01552 // ... then feed that to this function which will make new CREATE statements of the same fields but based on the current database content. 01553 $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 /> 01554 <pre>'.htmlspecialchars($dump_tf).'</pre>',0,1); 01555 01556 01557 $details = ' This dump is based on two factors:<br /> 01558 <ul> 01559 <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> 01560 <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> 01561 </ul> 01562 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 />'; 01563 $this->content.=$this->doc->section('',$details); 01564 } 01565 } 01566 } 01567 01575 function getFileListOfExtension($extKey,$conf) { 01576 $extPath = $this->getExtPath($extKey,$conf['type']); 01577 01578 if ($extPath) { 01579 // Read files: 01580 $fileArr = array(); 01581 $fileArr = t3lib_div::getAllFilesAndFoldersInPath($fileArr,$extPath); 01582 01583 // Start table: 01584 $lines = array(); 01585 $totalSize = 0; 01586 01587 // Header: 01588 $lines[] = ' 01589 <tr class="bgColor5"> 01590 <td>File:</td> 01591 <td>Size:</td> 01592 <td>Edit:</td> 01593 </tr>'; 01594 01595 foreach($fileArr as $file) { 01596 $fI = t3lib_div::split_fileref($file); 01597 $lines[] = ' 01598 <tr class="bgColor4"> 01599 <td><a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[downloadFile]='.rawurlencode($file)).'" title="Download...">'.substr($file,strlen($extPath)).'</a></td> 01600 <td>'.t3lib_div::formatSize(filesize($file)).'</td> 01601 <td>'.(!in_array($extKey,$this->requiredExt)&&t3lib_div::inList($this->editTextExtensions,$fI['fileext'])?'<a href="'.htmlspecialchars('index.php?CMD[showExt]='.$extKey.'&CMD[editFile]='.rawurlencode($file)).'">Edit file</a>':'').'</td> 01602 </tr>'; 01603 $totalSize+=filesize($file); 01604 } 01605 01606 $lines[] = ' 01607 <tr class="bgColor6"> 01608 <td><strong>Total:</strong></td> 01609 <td><strong>'.t3lib_div::formatSize($totalSize).'</strong></td> 01610 <td> </td> 01611 </tr>'; 01612 01613 return ' 01614 Path: '.$extPath.'<br /><br /> 01615 <table border="0" cellpadding="1" cellspacing="2">'.implode('',$lines).'</table>'; 01616 } 01617 } 01618 01626 function extDelete($extKey,$extInfo) { 01627 $absPath = $this->getExtPath($extKey,$extInfo['type']); 01628 if (t3lib_extMgm::isLoaded($extKey)) { 01629 return 'This extension is currently installed (loaded and active) and so cannot be deleted!'; 01630 } elseif (!$this->deleteAsType($extInfo['type'])) { 01631 return 'You cannot delete (and install/update) extensions in the '.$this->typeLabels[$extInfo['type']].' scope.'; 01632 } elseif (t3lib_div::inList('G,L',$extInfo['type'])) { 01633 if ($this->CMD['doDelete'] && !strcmp($absPath,$this->CMD['absPath'])) { 01634 $res = $this->removeExtDirectory($absPath); 01635 if ($res) { 01636 return 'ERROR: Could not remove extension directory "'.$absPath.'". Had the following errors:<br /><br />'. 01637 nl2br($res); 01638 } else { 01639 return 'Removed extension in path "'.$absPath.'"!'; 01640 } 01641 } else { 01642 $onClick = "if (confirm('Are you sure you want to delete this extension from the server?')) {document.location='index.php?CMD[showExt]=".$extKey.'&CMD[doDelete]=1&CMD[absPath]='.rawurlencode($absPath)."';}"; 01643 $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>'; 01644 $content.= '<br /><br />(Maybe you should make a backup first, see above.)'; 01645 return $content; 01646 } 01647 } else return 'Extension is not a global or local extension and cannot be removed.'; 01648 } 01649 01657 function extUpdateEMCONF($extKey,$extInfo) { 01658 $absPath = $this->getExtPath($extKey,$extInfo['type']); 01659 if ($this->CMD['doUpdateEMCONF']) { 01660 return $this->updateLocalEM_CONF($extKey,$extInfo); 01661 } else { 01662 $onClick = "if (confirm('Are you sure you want to update EM_CONF?')) {document.location='index.php?CMD[showExt]=".$extKey."&CMD[doUpdateEMCONF]=1';}"; 01663 $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>'; 01664 $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 /> 01665 Updating this file will first of all reset this registration.'; 01666 return $content; 01667 } 01668 } 01669 01677 function extBackup($extKey,$extInfo) { 01678 $uArr = $this->makeUploadArray($extKey,$extInfo); 01679 if (is_array($uArr)) { 01680 $local_gzcompress = $this->gzcompress && !$this->CMD['dontCompress']; 01681 $backUpData = $this->makeUploadDataFromArray($uArr,intval($local_gzcompress)); 01682 $filename = 'T3X_'.$extKey.'-'.str_replace('.','_',$extInfo['EM_CONF']['version']).($local_gzcompress?'-z':'').'-'.date('YmdHi').'.t3x'; 01683 if (intval($this->CMD['doBackup'])==1) { 01684 01685 $mimeType = 'application/octet-stream'; 01686 Header('Content-Type: '.$mimeType); 01687 Header('Content-Disposition: attachment; filename='.$filename); 01688 01689 // New headers suggested by Xin: 01690 // For now they are commented out because a) I have seen no official support yet, b) when clicking the back-link in MSIE after download you see ugly binary stuff and c) I couldn't see a BIG difference, in particular not in Moz/Opera. 01691 /* header('Content-Type: application/force-download'); 01692 header('Content-Length: '.strlen($backUpData)); 01693 01694 header('Content-Disposition: attachment; filename='.$filename); 01695 header('Content-Description: File Transfer'); 01696 header('Content-Transfer-Encoding: binary'); 01697 */ 01698 01699 // ANYWAYS! The download is NOT always working - in some cases extensions will never get the same MD5 sum as the one shown at the download link - and they should in order to work! We do NOT know why yet. 01700 01701 echo $backUpData; 01702 exit; 01703 } elseif ($this->CMD['dumpTables']) { 01704 $filename='T3X_'.$extKey; 01705 $cTables = count(explode(',',$this->CMD['dumpTables'])); 01706 if ($cTables>1) { 01707 $filename.='-'.$cTables.'tables'; 01708 } else { 01709 $filename.='-'.$this->CMD['dumpTables']; 01710 } 01711 $filename.='+adt.sql'; 01712 01713 $mimeType = 'application/octet-stream'; 01714 Header('Content-Type: '.$mimeType); 01715 Header('Content-Disposition: attachment; filename='.$filename); 01716 echo $this->dumpStaticTables($this->CMD['dumpTables']); 01717 exit; 01718 } else { 01719 $techInfo = $this->makeDetailedExtensionAnalysis($extKey,$extInfo); 01720 // if ($techInfo['tables']||$techInfo['static']||$techInfo['fields']) { 01721 #debug($techInfo); 01722 $lines=array(); 01723 $lines[]='<tr class="bgColor5"><td colspan="2"><strong>Make selection:</strong></td></tr>'; 01724 $lines[]='<tr class="bgColor4"><td><strong>Extension files:</strong></td><td>'. 01725 '<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 />'. 01726 ($this->gzcompress ? '<br /><a href="'.htmlspecialchars('index.php?CMD[doBackup]=1&CMD[dontCompress]=1&CMD[showExt]='.$extKey).'">(Click here to download extension without compression.)</a>':''). 01727 '</td></tr>'; 01728 01729 if (is_array($techInfo['tables'])) { $lines[]='<tr class="bgColor4"><td><strong>Data tables:</strong></td><td>'.$this->extBackup_dumpDataTablesLine($techInfo['tables'],$extKey).'</td></tr>'; } 01730 if (is_array($techInfo['static'])) { $lines[]='<tr class="bgColor4"><td><strong>Static tables:</strong></td><td>'.$this->extBackup_dumpDataTablesLine($techInfo['static'],$extKey).'</td></tr>'; } 01731 01732 $content = '<table border="0" cellpadding="2" cellspacing="2">'.implode('',$lines).'</table>'; 01733 return $content; 01734 } 01735 } else die('Error...'); 01736 } 01737 01745 function extBackup_dumpDataTablesLine($tablesArray,$extKey) { 01746 $tables = array(); 01747 $tablesNA = array(); 01748 01749 foreach($tablesArray as $tN) { 01750 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('count(*)', $tN, ''); 01751 if (!$GLOBALS['TYPO3_DB']->sql_error()) { 01752 $row = $GLOBALS['TYPO3_DB']->sql_fetch_row($res); 01753 $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>'; 01754 } else { 01755 $tablesNA[$tN]='<tr><td> </td><td>'.$tN.'</td><td> </td><td>Did not exist.</td></tr>'; 01756 } 01757 } 01758 $label = '<table border="0" cellpadding="0" cellspacing="0">'.implode('',array_merge($tables,$tablesNA)).'</table>';// Candidate for t3lib_div::array_merge() if integer-keys will some day make trouble... 01759 if (count($tables)) { 01760 $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; 01761 } else $label = 'Nothing to dump...<br /><br />'.$label; 01762 return $label; 01763 } 01764 01773 function extInformationArray($extKey,$extInfo,$remote=0) { 01774 $lines=array(); 01775 $lines[]='<tr class="bgColor5"><td colspan="2"><strong>General information:</strong></td>'.$this->helpCol('').'</tr>'; 01776 $lines[]='<tr class="bgColor4"><td>Title:</td><td>'.$extInfo['EM_CONF']['_icon'].$extInfo['EM_CONF']['title'].'</td>'.$this->helpCol('title').'</tr>'; 01777 $lines[]='<tr class="bgColor4"><td>Description:</td><td>'.nl2br(htmlspecialchars($extInfo['EM_CONF']['description'])).'</td>'.$this->helpCol('description').'</tr>'; 01778 $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']). 01779 ($extInfo['EM_CONF']['author_company']?', '.$extInfo['EM_CONF']['author_company']:''). 01780 '</td>'.$this->helpCol('description').'</tr>'; 01781 01782 $lines[]='<tr class="bgColor4"><td>Version:</td><td>'.$extInfo['EM_CONF']['version'].'</td>'.$this->helpCol('version').'</tr>'; 01783 $lines[]='<tr class="bgColor4"><td>Category:</td><td>'.$this->categories[$extInfo['EM_CONF']['category']].'</td>'.$this->helpCol('category').'</tr>'; 01784 $lines[]='<tr class="bgColor4"><td>State:</td><td>'.$this->states[$extInfo['EM_CONF']['state']].'</td>'.$this->helpCol('state').'</tr>'; 01785 $lines[]='<tr class="bgColor4"><td>Shy?</td><td>'.($extInfo['EM_CONF']['shy']?'Yes':'').'</td>'.$this->helpCol('shy').'</tr>'; 01786 $lines[]='<tr class="bgColor4"><td>Internal?</td><td>'.($extInfo['EM_CONF']['internal']?'Yes':'').'</td>'.$this->helpCol('internal').'</tr>'; 01787 01788 $lines[]='<tr class="bgColor4"><td>Dependencies:</td><td>'.$extInfo['EM_CONF']['dependencies'].'</td>'.$this->helpCol('dependencies').'</tr>'; 01789 if (!$remote) { 01790 $lines[]='<tr class="bgColor4"><td>Conflicts:</td><td>'.$extInfo['EM_CONF']['conflicts'].'</td>'.$this->helpCol('conflicts').'</tr>'; 01791 $lines[]='<tr class="bgColor4"><td>Priority:</td><td>'.$extInfo['EM_CONF']['priority'].'</td>'.$this->helpCol('priority').'</tr>'; 01792 $lines[]='<tr class="bgColor4"><td>Clear cache?</td><td>'.($extInfo['EM_CONF']['clearCacheOnLoad']?'Yes':'').'</td>'.$this->helpCol('clearCacheOnLoad').'</tr>'; 01793 $lines[]='<tr class="bgColor4"><td>Includes modules:</td><td>'.$extInfo['EM_CONF']['module'].'</td>'.$this->helpCol('module').'</tr>'; 01794 } 01795 $lines[]='<tr class="bgColor4"><td>Lock Type?</td><td>'.($extInfo['EM_CONF']['lockType']?$extInfo['EM_CONF']['lockType']:'').'</td>'.$this->helpCol('lockType').'</tr>'; 01796 $lines[]='<tr class="bgColor4"><td>Modifies tables:</td><td>'.$extInfo['EM_CONF']['modify_tables'].'</td>'.$this->helpCol('modify_tables').'</tr>'; 01797 01798 $lines[]='<tr class="bgColor4"><td>Private?</td><td>'.($extInfo['EM_CONF']['private']?'Yes':'').'</td>'.$this->helpCol('private').'</tr>'; 01799 if (!$remote) $lines[]='<tr class="bgColor4"><td>Download password:</td><td>'.$extInfo['EM_CONF']['download_password'].'</td>'.$this->helpCol('download_password').'</tr>'; 01800 01801 // Installation status: 01802 $lines[]='<tr><td> </td><td></td>'.$this->helpCol('').'</tr>'; 01803 $lines[]='<tr class="bgColor5"><td colspan="2"><strong>Installation status:</strong></td>'.$this->helpCol('').'</tr>'; 01804 if (!$remote) { 01805 $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>'; 01806 $lines[]='<tr class="bgColor4"><td>Double installs?</td><td>'.$this->extInformationArray_dbInst($extInfo['doubleInstall'],$extInfo['type']).'</td>'.$this->helpCol('doubleInstall').'</tr>'; 01807 } 01808 if (is_array($extInfo['files'])) { 01809 sort($extInfo['files']); 01810 $lines[]='<tr class="bgColor4"><td>Root files:</td><td>'.implode('<br />',$extInfo['files']).'</td>'.$this->helpCol('rootfiles').'</tr>'; 01811 } 01812 01813 if (!$remote) { 01814 $techInfo = $this->makeDetailedExtensionAnalysis($extKey,$extInfo,1); 01815 } else $techInfo = $extInfo['_TECH_INFO']; 01816 #debug($techInfo); 01817 01818 if ($techInfo['tables']||$techInfo['static']||$techInfo['fields']) { 01819 if (!$remote && t3lib_extMgm::isLoaded($extKey)) { 01820 $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!':''). 01821 ($techInfo['static_error']?'<strong>Static table error!</strong><br />The static tables are missing or empty!':'')); 01822 } else { 01823 $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!'; 01824 } 01825 } 01826 01827 $lines[]='<tr class="bgColor4"><td>Database requirements:</td><td>'.$this->extInformationArray_dbReq($techInfo,1).'</td>'.$this->helpCol('dbReq').'</tr>'; 01828 if (!$remote) $lines[]='<tr class="bgColor4"><td>Database status:</td><td>'.$tableStatus.'</td>'.$this->helpCol('dbStatus').'</tr>'; 01829 $lines[]='<tr class="bgColor4"><td>Flags:</td><td>'.(is_array($techInfo['flags'])?implode('<br />',$techInfo['flags']):'').'</td>'.$this->helpCol('flags').'</tr>'; 01830 $lines[]='<tr class="bgColor4"><td>Config template?</td><td>'.($techInfo['conf']?'Yes':'').'</td>'.$this->helpCol('conf').'</tr>'; 01831 $lines[]='<tr class="bgColor4"><td>TypoScript files:</td><td>'.(is_array($techInfo['TSfiles'])?implode('<br />',$techInfo['TSfiles']):'').'</td>'.$this->helpCol('TSfiles').'</tr>'; 01832 $lines[]='<tr class="bgColor4"><td>Language files:</td><td>'.(is_array($techInfo['locallang'])?implode('<br />',$techInfo['locallang']):'').'</td>'.$this->helpCol('locallang').'</tr>'; 01833 $lines[]='<tr class="bgColor4"><td>Upload folder:</td><td>'.($techInfo['uploadfolder']?$techInfo['uploadfolder']:'').'</td>'.$this->helpCol('uploadfolder').'</tr>'; 01834 $lines[]='<tr class="bgColor4"><td>Create directories:</td><td>'.(is_array($techInfo['createDirs'])?implode('<br />',$techInfo['createDirs']):'').'</td>'.$this->helpCol('createDirs').'</tr>'; 01835 $lines[]='<tr class="bgColor4"><td>Module names:</td><td>'.(is_array($techInfo['moduleNames'])?implode('<br />',$techInfo['moduleNames']):'').'</td>'.$this->helpCol('moduleNames').'</tr>'; 01836 $lines[]='<tr class="bgColor4"><td>Class names:</td><td>'.(is_array($techInfo['classes'])?implode('<br />',$techInfo['classes']):'').'</td>'.$this->helpCol('classNames').'</tr>'; 01837 $lines[]='<tr class="bgColor4"><td>Errors:</td><td>'.(is_array($techInfo['errors'])?$GLOBALS['TBE_TEMPLATE']->rfw(implode('<hr />',$techInfo['errors'])):'').'</td>'.$this->helpCol('errors').'</tr>'; 01838 $lines[]='<tr class="bgColor4"><td>Naming errors:</td><td>'.(is_array($techInfo['NSerrors'])? 01839 (!t3lib_div::inList($this->nameSpaceExceptions,$extKey)?t3lib_div::view_array($techInfo['NSerrors']):$GLOBALS['TBE_TEMPLATE']->dfw('[exception]')) 01840 :'').'</td>'.$this->helpCol('NSerrors').'</tr>'; 01841 01842 01843 if (!$remote) { 01844 $currentMd5Array = $this->serverExtensionMD5Array($extKey,$extInfo); 01845 $affectedFiles=''; 01846 01847 $msgLines=array(); 01848 # $msgLines[] = 'Files: '.count($currentMd5Array); 01849 if (strcmp($extInfo['EM_CONF']['_md5_values_when_last_written'],serialize($currentMd5Array))) { 01850 $msgLines[] = $GLOBALS['TBE_TEMPLATE']->rfw('<br /><strong>A difference between the originally installed version and the current was detected!</strong>'); 01851 $affectedFiles = $this->findMD5ArrayDiff($currentMd5Array,unserialize($extInfo['EM_CONF']['_md5_values_when_last_written'])); 01852 if (count($affectedFiles)) $msgLines[] = '<br /><strong>Modified files:</strong><br />'.$GLOBALS['TBE_TEMPLATE']->rfw(implode('<br />',$affectedFiles)); 01853 } 01854 $lines[]='<tr class="bgColor4"><td>Files changed?</td><td>'.implode('<br />',$msgLines).'</td>'.$this->helpCol('filesChanged').'</tr>'; 01855 } 01856 01857 return '<table border="0" cellpadding="1" cellspacing="2"> 01858 '.implode(' 01859 ',$lines).' 01860 </table>'; 01861 } 01862 01870 function extInformationArray_dbReq($techInfo,$tableHeader=0) { 01871 return nl2br(trim((is_array($techInfo['tables'])?($tableHeader?"\n\n<strong>Tables:</strong>\n":'').implode(chr(10),$techInfo['tables']):''). 01872 (is_array($techInfo['static'])?"\n\n<strong>Static tables:</strong>\n".implode(chr(10),$techInfo['static']):''). 01873 (is_array($techInfo['fields'])?"\n\n<strong>Additional fields:</strong>\n".implode('<hr />',$techInfo['fields']):''))); 01874 } 01875 01883 function extInformationArray_dbInst($dbInst,$current) { 01884 if (strlen($dbInst)>1) { 01885 $others = array(); 01886 for($a=0;$a<strlen($dbInst);$a++) { 01887 if (substr($dbInst,$a,1)!=$current) { 01888 $others[]='"'.$this->typeLabels[substr($dbInst,$a,1)].'"'; 01889 } 01890 } 01891 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.'); 01892 } else return ''; 01893 } 01894 01902 function getRepositoryUploadForm($extKey,$extInfo) { 01903 $uArr = $this->makeUploadArray($extKey,$extInfo); 01904 if (is_array($uArr)) { 01905 $backUpData = $this->makeUploadDataFromArray($uArr); 01906 01907 #debug($this->decodeExchangeData($backUpData)); 01908 $content.='Extension "'.$this->extensionTitleIconHeader($extKey,$extInfo).'" is ready to be uploaded.<br /> 01909 The size of the upload is <strong>'.t3lib_div::formatSize(strlen($backUpData)).'</strong><br /> 01910 '; 01911 01912 $b64data = base64_encode($backUpData); 01913 $content='</form><form action="'.$this->repositoryUrl.'" method="post" enctype="application/x-www-form-urlencoded"> 01914 <input type="hidden" name="tx_extrep[upload][returnUrl]" value="'.htmlspecialchars($this->makeReturnUrl()).'" /> 01915 <input type="hidden" name="tx_extrep[upload][data]" value="'.$b64data.'" /> 01916 <input type="hidden" name="tx_extrep[upload][typo3ver]" value="'.$GLOBALS['TYPO_VERSION'].'" /> 01917 <input type="hidden" name="tx_extrep[upload][os]" value="'.TYPO3_OS.'" /> 01918 <input type="hidden" name="tx_extrep[upload][sapi]" value="'.php_sapi_name().'" /> 01919 <input type="hidden" name="tx_extrep[upload][phpver]" value="'.phpversion().'" /> 01920 <input type="hidden" name="tx_extrep[upload][gzcompressed]" value="'.$this->gzcompress.'" /> 01921 <input type="hidden" name="tx_extrep[upload][data_md5]" value="'.md5($b64data).'" /> 01922 <table border="0" cellpadding="2" cellspacing="1"> 01923 <tr class="bgColor4"> 01924 <td>Repository Username:</td> 01925 <td><input'.$this->doc->formWidth(20).' type="text" name="tx_extrep[user][fe_u]" value="'.$this->fe_user['username'].'" /></td> 01926 </tr> 01927 <tr class="bgColor4"> 01928 <td>Repository Password:</td> 01929 <td><input'.$this->doc->formWidth(20).' type="password" name="tx_extrep[user][fe_p]" value="'.$this->fe_user['password'].'" /></td> 01930 </tr> 01931 <tr class="bgColor4"> 01932 <td>Upload password for this extension:</td> 01933 <td><input'.$this->doc->formWidth(30).' type="password" name="tx_extrep[upload][upload_p]" value="'.$this->fe_user['uploadPass'].'" /></td> 01934 </tr> 01935 <tr class="bgColor4"> 01936 <td>Changelog for upload:</td> 01937 <td><textarea'.$this->doc->formWidth(30,1).' rows="5" name="tx_extrep[upload][comment]"></textarea></td> 01938 </tr> 01939 <tr class="bgColor4"> 01940 <td>Upload command:</td> 01941 <td nowrap="nowrap"> 01942 <input type="radio" name="tx_extrep[upload][mode]" value="new_dev" checked="checked" /> New development version (latest x.x.<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw('x+1').'</strong>)<br /> 01943 <input type="radio" name="tx_extrep[upload][mode]" value="latest" /> Override <em>this</em> development version ('.$extInfo['EM_CONF']['version'].')<br /> 01944 <input type="radio" name="tx_extrep[upload][mode]" value="new_sub" /> New sub version (latest x.<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw('x+1').'</strong>.0)<br /> 01945 <input type="radio" name="tx_extrep[upload][mode]" value="new_main" /> New main version (latest <strong>'.$GLOBALS['TBE_TEMPLATE']->rfw('x+1').'</strong>.0.0)<br /> 01946 </td> 01947 </tr> 01948 <!-- Removing "private keys" since they are probably not used much. Better option for people is to distribute "private" extensions as files by emails. 01949 <tr class="bgColor4"> 01950 <td>Private?</td> 01951 <td> 01952 <input type="checkbox" name="tx_extrep[upload][private]" value="1"'.($extInfo['EM_CONF']['private'] ? ' checked="checked"' : '').' />Yes, dont show <em>this upload</em> in the public list.<br /> 01953 ("Private" uploads requires you to manually enter a special key (which will be shown to you after the upload has been completed) to be able to import and view details for the upload. This is nice when you are working on something internally which you do not want others to look at.)<br /> 01954 <br /><strong>Additional import password:</strong><br /> 01955 <input'.$this->doc->formWidth(20).' type="text" name="tx_extrep[upload][download_password]" value="'.htmlspecialchars(trim($extInfo['EM_CONF']['download_password'])).'" /> (Textfield!) <br /> 01956 (Anybody who knows the "special key" assigned to the private upload will be able to import it. Specifying an import password allows you to give away the download key for private uploads and also require a password given in addition. The password can be changed later on.)<br /> 01957 </td> 01958 </tr> 01959 --> 01960 <tr class="bgColor4"> 01961 <td> </td> 01962 <td><input type="submit" name="submit" value="Upload extension" /><br /> 01963 '.t3lib_div::formatSize(strlen($b64data)).($this->gzcompress?", compressed":"").', base64<br /> 01964 <br /> 01965 01966 </td> 01967 </tr> 01968 </table> 01969 '; 01970 01971 return $content; 01972 } else { 01973 return $uArr; 01974 } 01975 } 01976 01977 01978 01979 01980 01981 01982 01983 01984 01985 01986 /*********************************** 01987 * 01988 * Extension list rendering 01989 * 01990 **********************************/ 01991 02000 function extensionListRowHeader($trAttrib,$cells,$import=0) { 02001 $cells[] = '<td></td>'; 02002 $cells[] = '<td>Title:</td>'; 02003 02004 if (!$this->MOD_SETTINGS['display_details']) { 02005 $cells[] = '<td>Description:</td>'; 02006 $cells[] = '<td>Author:</td>'; 02007 } elseif ($this->MOD_SETTINGS['display_details']==2) { 02008 $cells[] = '<td>Priority:</td>'; 02009 $cells[] = '<td>Mod.Tables:</td>'; 02010 $cells[] = '<td>Modules:</td>'; 02011 $cells[] = '<td>Cl.Cache?</td>'; 02012 $cells[] = '<td>Internal?</td>'; 02013 $cells[] = '<td>Shy?</td>'; 02014 } elseif ($this->MOD_SETTINGS['display_details']==3) { 02015 $cells[] = '<td>Tables/Fields:</td>'; 02016 $cells[] = '<td>TS-files:</td>'; 02017 $cells[] = '<td>Affects:</td>'; 02018 $cells[] = '<td>Modules:</td>'; 02019 $cells[] = '<td>Config?</td>'; 02020 $cells[] = '<td>Errors:</td>'; 02021 } elseif ($this->MOD_SETTINGS['display_details']==4) { 02022 $cells[] = '<td>locallang:</td>'; 02023 $cells[] = '<td>Classes:</td>'; 02024 $cells[] = '<td>Errors:</td>'; 02025 $cells[] = '<td>NameSpace Errors:</td>'; 02026 } elseif ($this->MOD_SETTINGS['display_details']==5) { 02027 $cells[] = '<td>Changed files:</td>'; 02028 } else { 02029 $cells[] = '<td>Extension key:</td>'; 02030 $cells[] = '<td>Version:</td>'; 02031 if (!$import) { 02032 $cells[] = '<td>Doc:</td>'; 02033 $cells[] = '<td>Type:</td>'; 02034 } else { 02035 $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>'; 02036 $cells[] = '<td class="bgColor6"'.$this->labelInfo('Current type of installation of the extension on this server.').'>Cur. Type:</td>'; 02037 $cells[] = '<td'.$this->labelInfo('If blank, everyone has access to this extension. "Owner" means that you see it ONLY because you are the owner. "Member" means you see it ONLY because you are among the project members.').'>Access:</td>'; 02038 $cells[] = '<td'.$this->labelInfo('TYPO3 version of last uploading server.').'>T3 ver:</td>'; 02039 $cells[] = '<td'.$this->labelInfo('PHP version of last uploading server.').'>PHP:</td>'; 02040 $cells[] = '<td'.$this->labelInfo('Size of extension, uncompressed / compressed').'>Size:</td>'; 02041 $cells[] = '<td'.$this->labelInfo('Number of downloads, all versions/this version').'>DL:</td>'; 02042 } 02043 $cells[] = '<td>State:</td>'; 02044 $cells[] = '<td>Dependencies:</td>'; 02045 } 02046 return ' 02047 <tr'.$trAttrib.'> 02048 '.implode(' 02049 ',$cells).' 02050 </tr>'; 02051 } 02052 02065 function extensionListRow($extKey,$extInfo,$cells,$bgColorClass='',$inst_list=array(),$import=0,$altLinkUrl='') { 02066 02067 // Initialize: 02068 $style = t3lib_extMgm::isLoaded($extKey) ? '' : ' style="color:#666666;"'; 02069 02070 // Icon: 02071 $imgInfo = @getImageSize($this->getExtPath($extKey,$extInfo['type']).'/ext_icon.gif'); 02072 if (is_array($imgInfo)) { 02073 $cells[] = '<td><img src="'.$GLOBALS['BACK_PATH'].$this->typeRelPaths[$extInfo['type']].$extKey.'/ext_icon.gif'.'" '.$imgInfo[3].' alt="" /></td>'; 02074 } elseif ($extInfo['_ICON']) { 02075 $cells[] = '<td>'.$extInfo['_ICON'].'</td>'; 02076 } else { 02077 $cells[] = '<td><img src="clear.gif" width="1" height="1" alt="" /></td>'; 02078 } 02079 02080 // Extension title: 02081 $cells[] = '<td nowrap="nowrap"><a href="'.htmlspecialchars($altLinkUrl?$altLinkUrl:'index.php?CMD[showExt]='.$extKey.'&SET[singleDetails]=info').'" title="'.$extKey.'"'.$style.'>'.t3lib_div::fixed_lgd($extInfo['EM_CONF']['title']?$extInfo['EM_CONF']['title']:'<em>'.$extKey.'</em>',40).'</a></td>'; 02082 02083 // Unset extension key in installed keys array (for tracking) 02084 if (isset($inst_list[$extKey])) { 02085 unset($this->inst_keys[$extKey]); 02086 } 02087 02088 // Based on which display mode you will see more or less details: 02089 if (!$this->MOD_SETTINGS['display_details']) { 02090 $cells[] = '<td>'.htmlspecialchars(t3lib_div::fixed_lgd($extInfo['EM_CONF']['description'],400)).'<br /><img src="clear.gif" width="300" height="1" alt="" /></td>'; 02091 $cells[] = '<td nowrap="nowrap">'.htmlspecialchars($extInfo['EM_CONF']['author'].($extInfo['EM_CONF']['author_company'] ? '<br />'.$extInfo['EM_CONF']['author_company'] : '')).'</td>'; 02092 } elseif ($this->MOD_SETTINGS['display_details']==2) { 02093 $cells[] = '<td nowrap="nowrap">'.$extInfo['EM_CONF']['priority'].'</td>'; 02094 $cells[] = '<td nowrap="nowrap">'.implode('<br />',t3lib_div::trimExplode(',',$extInfo['EM_CONF']['modify_tables'],1)).'</td>'; 02095 $cells[] = '<td nowrap="nowrap">'.$extInfo['EM_CONF']['module'].'</td>'; 02096 $cells[] = '<td nowrap="nowrap">'.($extInfo['EM_CONF']['clearCacheOnLoad'] ? 'Yes' : '').'</td>'; 02097 $cells[] = '<td nowrap="nowrap">'.($extInfo['EM_CONF']['internal'] ? 'Yes' : '').'</td>'; 02098 $cells[] = '<td nowrap="nowrap">'.($extInfo['EM_CONF']['shy'] ? 'Yes' : '').'</td>'; 02099 } elseif ($this->MOD_SETTINGS['display_details']==3) { 02100 $techInfo = $this->makeDetailedExtensionAnalysis($extKey,$extInfo); 02101 02102 $cells[] = '<td>'.$this->extInformationArray_dbReq($techInfo). 02103 '</td>'; 02104 $cells[] = '<td nowrap="nowrap">'.(is_array($techInfo['TSfiles']) ? implode('<br />',$techInfo['TSfiles']) : '').'</td>'; 02105 $cells[] = '<td nowrap="nowrap">'.(is_array($techInfo['flags']) ? implode('<br />',$techInfo['flags']) : '').'</td>'; 02106 $cells[] = '<td nowrap="nowrap">'.(is_array($techInfo['moduleNames']) ? implode('<br />',$techInfo['moduleNames']) : '').'</td>'; 02107 $cells[] = '<td nowrap="nowrap">'.($techInfo['conf'] ? 'Yes' : '').'</td>'; 02108 $cells[] = '<td>'. 02109 $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!':''). 02110 (t3lib_extMgm::isLoaded($extKey)&&$techInfo['static_error']?'<strong>Static table error!</strong><br />The static tables are missing or empty!':'')). 02111 '</td>'; 02112 } elseif ($this->MOD_SETTINGS['display_details']==4) { 02113 $techInfo=$this->makeDetailedExtensionAnalysis($extKey,$extInfo,1); 02114 02115 $cells[] = '<td>'.(is_array($techInfo['locallang']) ? implode('<br />',$techInfo['locallang']) : '').'</td>'; 02116 $cells[] = '<td>'.(is_array($techInfo['classes']) ? implode('<br />',$techInfo['classes']) : '').'</td>'; 02117 $cells[] = '<td>'.(is_array($techInfo['errors']) ? $GLOBALS['TBE_TEMPLATE']->rfw(implode('<hr />',$techInfo['errors'])) : '').'</td>'; 02118 $cells[] = '<td>'.(is_array($techInfo['NSerrors']) ? (!t3lib_div::inList($this->nameSpaceExceptions,$extKey) ? t3lib_div::view_array($techInfo['NSerrors']) : $GLOBALS['TBE_TEMPLATE']->dfw('[exception]')) :'').'</td>'; 02119 } elseif ($this->MOD_SETTINGS['display_details']==5) { 02120 $currentMd5Array = $this->serverExtensionMD5Array($extKey,$extInfo); 02121 $affectedFiles = ''; 02122 $msgLines = array(); 02123 $msgLines[] = 'Files: '.count($currentMd5Array); 02124 if (strcmp($extInfo['EM_CONF']['_md5_values_when_last_written'],serialize($currentMd5Array))) { 02125 $msgLines[] = $GLOBALS['TBE_TEMPLATE']->rfw('<br /><strong>A difference between the originally installed version and the current was detected!</strong>'); 02126 $affectedFiles = $this->findMD5ArrayDiff($currentMd5Array,unserialize($extInfo['EM_CONF']['_md5_values_when_last_written'])); 02127 if (count($affectedFiles)) $msgLines[] = '<br /><strong>Modified files:</strong><br />'.$GLOBALS['TBE_TEMPLATE']->rfw(implode('<br />',$affectedFiles)); 02128 } 02129 $cells[] = '<td>'.implode('<br />',$msgLines).'</td>'; 02130 } else { 02131 // Default view: 02132 $verDiff = $inst_list[$extKey] && $this->versionDifference($extInfo['EM_CONF']['version'],$inst_list[$extKey]['EM_CONF']['version'],$this->versionDiffFactor); 02133 02134 $cells[] = '<td nowrap="nowrap"><em>'.$extKey.'</em></td>'; 02135 $cells[] = '<td nowrap="nowrap">'.($verDiff ? '<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw(htmlspecialchars($extInfo['EM_CONF']['version'])).'</strong>' : $extInfo['EM_CONF']['version']).'</td>'; 02136 if (!$import) { // Listing extenson on LOCAL server: 02137 $fileP = PATH_site.$this->typePaths[$extInfo['type']].$extKey.'/doc/manual.sxw'; 02138 02139 $cells[] = '<td nowrap="nowrap">'. 02140 ($this->typePaths[$extInfo['type']] && @is_file($fileP)?'<img src="oodoc.gif" width="13" height="16" title="Local Open Office Manual" alt="" />':''). 02141 '</td>'; 02142 $cells[] = '<td nowrap="nowrap">'.$this->typeLabels[$extInfo['type']].(strlen($extInfo['doubleInstall'])>1?'<strong> '.$GLOBALS['TBE_TEMPLATE']->rfw($extInfo['doubleInstall']).'</strong>':'').'</td>'; 02143 } else { // Listing extensions from REMOTE repository: 02144 $inst_curVer = $inst_list[$extKey]['EM_CONF']['version']; 02145 if (isset($inst_list[$extKey])) { 02146 if ($verDiff) $inst_curVer = '<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw($inst_curVer).'</strong>'; 02147 } 02148 $cells[] = '<td nowrap="nowrap">'.$inst_curVer.'</td>'; 02149 $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>'; 02150 $cells[] = '<td nowrap="nowrap"><strong>'.$GLOBALS['TBE_TEMPLATE']->rfw($this->remoteAccess[$extInfo['_ACCESS']]).'</strong></td>'; 02151 $cells[] = '<td nowrap="nowrap">'.$extInfo['EM_CONF']['_typo3_ver'].'</td>'; 02152 $cells[] = '<td nowrap="nowrap">'.$extInfo['EM_CONF']['_php_ver'].'</td>'; 02153 $cells[] = '<td nowrap="nowrap">'.$extInfo['EM_CONF']['_size'].'</td>'; 02154 $cells[] = '<td nowrap="nowrap">'.($extInfo['_STAT_IMPORT']['extension_allversions']?$extInfo['_STAT_IMPORT']['extension_allversions']:' ').'/'.($extInfo['_STAT_IMPORT']['extension_thisversion']?$extInfo['_STAT_IMPORT']['extension_thisversion']:' ').'</td>'; 02155 } 02156 $cells[] = '<td nowrap="nowrap">'.$this->states[$extInfo['EM_CONF']['state']].'</td>'; 02157 $cells[] = '<td nowrap="nowrap">'.$extInfo['EM_CONF']['dependencies'].'</td>'; 02158 } 02159 02160 $bgColor = ' class="'.($bgColorClass?$bgColorClass:'bgColor4').'"'; 02161 return ' 02162 <tr'.$bgColor.$style.'> 02163 '.implode(' 02164 ',$cells).' 02165 </tr>'; 02166 } 02167 02168 02169 02170 02171 02172 02173 02174 02175 02176 02177 /************************************ 02178 * 02179 * Output helper functions 02180 * 02181 ************************************/ 02182 02190 function wrapEmail($str,$email) { 02191 if ($email) { 02192 $str = '<a href="mailto:'.htmlspecialchars($email).'">'.htmlspecialchars($str).'</a>'; 02193 } 02194 return $str; 02195 } 02196 02203 function helpCol($key) { 02204 global $BE_USER; 02205 if ($BE_USER->uc['edit_showFieldHelp']) { 02206 $hT = trim(t3lib_BEfunc::helpText($this->descrTable,'emconf_'.$key,$this->doc->backPath)); 02207 return '<td>'.($hT?$hT:t3lib_BEfunc::helpTextIcon($this->descrTable,'emconf_'.$key,$this->doc->backPath)).'</td>'; 02208 } 02209 } 02210 02217 function labelInfo($str) { 02218 return ' title="'.htmlspecialchars($str).'" style="cursor:help;"'; 02219 } 02220 02229 function extensionTitleIconHeader($extKey,$extInfo,$align='top') { 02230 $imgInfo = @getImageSize($this->getExtPath($extKey,$extInfo['type']).'/ext_icon.gif'); 02231 $out = ''; 02232 if (is_array($imgInfo)) { 02233 $out.= '<img src="'.$GLOBALS['BACK_PATH'].$this->typeRelPaths[$extInfo['type']].$extKey.'/ext_icon.gif" '.$imgInfo[3].' align="'.$align.'" alt="" />'; 02234 } 02235 $out.= $extInfo['EM_CONF']['title'] ? htmlspecialchars(t3lib_div::fixed_lgd($extInfo['EM_CONF']['title'],40)) : '<em>'.$extKey.'</em>'; 02236 return $out; 02237 } 02238 02244 function removeButton() { 02245 return '<img src="uninstall.gif" width="16" height="16" title="Remove extension" align="top" alt="" />'; 02246 } 02247 02253 function installButton() { 02254 return '<img src="install.gif" width="16" height="16" title="Install extension..." align="top" alt="" />'; 02255 } 02256 02262 function noImportMsg() { 02263 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>'; 02264 } 02265 02266 02267 02268 02269 02270 02271 02272 02273 02274 02275 /******************************** 02276 * 02277 * Read information about all available extensions 02278 * 02279 *******************************/ 02280 02287 function getInstalledExtensions() { 02288 $list = array(); 02289 $cat = $this->defaultCategories; 02290 02291 $path = PATH_site.TYPO3_mainDir.'sysext/'; 02292 $this->getInstExtList($path,$list,$cat,'S'); 02293 02294 $path = PATH_site.TYPO3_mainDir.'ext/'; 02295 $this->getInstExtList($path,$list,$cat,'G'); 02296 02297 $path = PATH_site.'typo3conf/ext/'; 02298 $this->getInstExtList($path,$list,$cat,'L'); 02299 02300 return array($list,$cat); 02301 } 02302 02314 function getInstExtList($path,&$list,&$cat,$type) { 02315 02316 if (@is_dir($path)) { 02317 $extList = t3lib_div::get_dirs($path); 02318 if (is_array($extList)) { 02319 foreach($extList as $extKey) { 02320 if (@is_file($path.$extKey.'/ext_emconf.php')) { 02321 $emConf = $this->includeEMCONF($path.$extKey.'/ext_emconf.php', $extKey); 02322 if (is_array($emConf)) { 02323 # unset($emConf['_md5_values_when_last_written']); // Trying to save space - hope this doesn't break anything. Shaves of maybe 100K! 02324 # unset($emConf['description']); // Trying to save space - hope this doesn't break anything 02325 if (is_array($list[$extKey])) { 02326 $list[$extKey]=array('doubleInstall'=>$list[$extKey]['doubleInstall']); 02327 } 02328 $list[$extKey]['doubleInstall'].= $type; 02329 $list[$extKey]['type'] = $type; 02330 $list[$extKey]['EM_CONF'] = $emConf; 02331 # $list[$extKey]['files'] = array_keys(array_flip(t3lib_div::getFilesInDir($path.$extKey))); // Shaves off a little by using num-indexes 02332 $list[$extKey]['files'] = t3lib_div::getFilesInDir($path.$extKey); 02333 02334 $this->setCat($cat,$list[$extKey], $extKey); 02335 } 02336 } 02337 } 02338 } 02339 } 02340 } 02341 02348 function getImportExtList($listArr) { 02349 $list = array(); 02350 $cat = $this->defaultCategories; 02351 02352 if (is_array($listArr)) { 02353 02354 foreach($listArr as $dat) { 02355 $extKey = $dat['extension_key']; 02356 $list[$extKey]['type'] = '_'; 02357 $list[$extKey]['extRepUid'] = $dat['uid']; 02358 $list[$extKey]['_STAT_IMPORT'] = $dat['_STAT_IMPORT']; 02359 $list[$extKey]['_ACCESS'] = $dat['_ACCESS']; 02360 $list[$extKey]['_ICON'] = $dat['_ICON']; 02361 $list[$extKey]['_MEMBERS_ONLY'] = $dat['_MEMBERS_ONLY']; 02362 $list[$extKey]['EM_CONF'] = array( 02363 'title' => $dat['emconf_title'], 02364 'description' => $dat['emconf_description'], 02365 'category' => $dat['emconf_category'], 02366 'shy' => $dat['emconf_shy'], 02367 'dependencies' => $dat['emconf_dependencies'], 02368 'state' => $dat['emconf_state'], 02369 'private' => $dat['emconf_private'], 02370 'uploadfolder' => $dat['emconf_uploadfolder'], 02371 'createDirs' => $dat['emconf_createDirs'], 02372 'modify_tables' => $dat['emconf_modify_tables'], 02373 'module' => $dat['emconf_module'], 02374 'lockType' => $dat['emconf_lockType'], 02375 'clearCacheOnLoad' => $dat['emconf_clearCacheOnLoad'], 02376 'priority' => $dat['emconf_priority'], 02377 'version' => $dat['version'], 02378 'internal' => $dat['emconf_internal'], 02379 'author' => $dat['emconf_author'], 02380 'author_company' => $dat['emconf_author_company'], 02381 02382 '_typo3_ver' => $dat['upload_typo3_version'], 02383 '_php_ver' => $dat['upload_php_version'], 02384 '_size' => t3lib_div::formatSize($dat['datasize']).'/'.t3lib_div::formatSize($dat['datasize_gz']), 02385 ); 02386 $this->setCat($cat, $list[$extKey], $extKey); 02387 } 02388 } 02389 return array($list,$cat); 02390 } 02391 02400 function setCat(&$cat,$listArrayPart,$extKey) { 02401 02402 // Getting extension title: 02403 $extTitle = $listArrayPart['EM_CONF']['title']; 02404 02405 // Category index: 02406 $index = $listArrayPart['EM_CONF']['category']; 02407 $cat['cat'][$index][$extKey] = $extTitle; 02408 02409 // Author index: 02410 $index = $listArrayPart['EM_CONF']['author'].($listArrayPart['EM_CONF']['author_company']?', '.$listArrayPart['EM_CONF']['author_company']:''); 02411 $cat['author_company'][$index][$extKey] = $extTitle; 02412 02413 // State index: 02414 $index = $listArrayPart['EM_CONF']['state']; 02415 $cat['state'][$index][$extKey] = $extTitle; 02416 02417 // Private index: 02418 $index = $listArrayPart['EM_CONF']['private'] ? 1 : 0; 02419 $cat['private'][$index][$extKey] = $extTitle; 02420 02421 // Type index: 02422 $index = $listArrayPart['type']; 02423 $cat['type'][$index][$extKey] = $extTitle; 02424 02425 // Dependencies: 02426 if ($list[$extKey]['EM_CONF']['dependencies']) { 02427 $depItems = t3lib_div::trimExplode(',', $list[$extKey]['EM_CONF']['dependencies'], 1); 02428 foreach($depItems as $depKey) { 02429 $cat['dep'][$depKey][$extKey] = $extTitle; 02430 } 02431 } 02432 02433 // Return categories: 02434 return $cat; 02435 } 02436 02437 02438 02439 02440 02441 02442 02443 02444 02445 02446 /******************************* 02447 * 02448 * Extension analyzing (detailed information) 02449 * 02450 ******************************/ 02451 02462 function makeDetailedExtensionAnalysis($extKey,$extInfo,$validity=0) { 02463 02464 // Get absolute path of the extension 02465 $absPath = $this->getExtPath($extKey,$extInfo['type']); 02466 02467 $infoArray = array(); 02468 02469 $table_class_prefix = substr($extKey,0,5)=='user_' ? 'user_' : 'tx_'.str_replace('_','',$extKey).'_'; 02470 $module_prefix = substr($extKey,0,5)=='user_' ? 'u' : 'tx'.str_replace('_','',$extKey); 02471 02472 // Database status: 02473 $dbInfo = $this->checkDBupdates($extKey,$extInfo,1); 02474 02475 // Database structure required: 02476 if (is_array($dbInfo['structure']['tables_fields'])) { 02477 $modify_tables = t3lib_div::trimExplode(',',$extInfo['EM_CONF']['modify_tables'],1); 02478 $infoArray['dump_tf'] = array(); 02479 02480 foreach($dbInfo['structure']['tables_fields'] as $tN => $d) { 02481 if (in_array($tN,$modify_tables)) { 02482 $infoArray['fields'][] = $tN.': <i>'. 02483 (is_array($d['fields']) ? implode(', ',array_keys($d['fields'])) : ''). 02484 (is_array($d['keys']) ? ' + '.count($d['keys']).' keys' : ''). 02485 '</i>'; 02486 if (is_array($d['fields'])) { 02487 reset($d['fields']); 02488 while(list($fN) = each($d['fields'])) { 02489 $infoArray['dump_tf'][] = $tN.'.'.$fN; 02490 if (!t3lib_div::isFirstPartOfStr($fN,$table_class_prefix)) { 02491 $infoArray['NSerrors']['fields'][$fN] = $fN; 02492 } else { 02493 $infoArray['NSok']['fields'][$fN] = $fN; 02494 } 02495 } 02496 } 02497 if (is_array($d['keys'])) { 02498 reset($d['keys']); 02499 while(list($fN)=each($d['keys'])) { 02500 $infoArray['dump_tf'][] = $tN.'.KEY:'.$fN; 02501 } 02502 } 02503 } else { 02504 $infoArray['dump_tf'][] = $tN; 02505 $infoArray['tables'][] = $tN; 02506 if (!t3lib_div::isFirstPartOfStr($tN,$table_class_prefix)) { 02507 $infoArray['NSerrors']['tables'][$tN] = $tN; 02508 } else $infoArray['NSok']['tables'][$tN] = $tN; 02509 } 02510 } 02511 if (count($dbInfo['structure']['diff']['diff']) || count($dbInfo['structure']['diff']['extra'])) { 02512 $msg = array(); 02513 if (count($dbInfo['structure']['diff']['diff'])) $msg[] = 'missing'; 02514 if (count($dbInfo['structure']['diff']['extra'])) $msg[] = 'of wrong type'; 02515 $infoArray['tables_error'] = 1; 02516 if (t3lib_extMgm::isLoaded($extKey)) $infoArray['errors'][] = 'Some tables or fields are '.implode(' and ',$msg).'!'; 02517 } 02518 } 02519 02520 // Static tables? 02521 if (is_array($dbInfo['static'])) { 02522 $infoArray['static'] = array_keys($dbInfo['static']); 02523 02524 foreach($dbInfo['static'] as $tN => $d) { 02525 if (!$d['exists']) { 02526 $infoArray['static_error'] = 1; 02527 if (t3lib_extMgm::isLoaded($extKey)) $infoArray['errors'][] = 'Static table(s) missing!'; 02528 if (!t3lib_div::isFirstPartOfStr($tN,$table_class_prefix)) { 02529 $infoArray['NSerrors']['tables'][$tN] = $tN; 02530 } else $infoArray['NSok']['tables'][$tN] = $tN; 02531 } 02532 } 02533 } 02534 02535 // Backend Module-check: 02536 $knownModuleList = t3lib_div::trimExplode(',',$extInfo['EM_CONF']['module'],1); 02537 foreach($knownModuleList as $mod) { 02538 if (@is_dir($absPath.$mod)) { 02539 if (@is_file($absPath.$mod.'/conf.php')) { 02540 $confFileInfo = $this->modConfFileAnalysis($absPath.$mod.'/conf.php'); 02541 if (is_array($confFileInfo['TYPO3_MOD_PATH'])) { 02542 $shouldBePath = $this->typeRelPaths[$extInfo['type']].$extKey.'/'.$mod.'/'; 02543 if (strcmp($confFileInfo['TYPO3_MOD_PATH'][1][1],$shouldBePath)) { 02544 $infoArray['errors'][] = 'Configured TYPO3_MOD_PATH "'.$confFileInfo['TYPO3_MOD_PATH'][1][1].'" different from "'.$shouldBePath.'"'; 02545 } 02546 } else $infoArray['errors'][] = 'No definition of TYPO3_MOD_PATH constant found inside!'; 02547 if (is_array($confFileInfo['MCONF_name'])) { 02548 $mName = $confFileInfo['MCONF_name'][1][1]; 02549 $mNameParts = explode('_',$mName); 02550 $infoArray['moduleNames'][] = $mName; 02551 if (!t3lib_div::isFirstPartOfStr($mNameParts[0],$module_prefix) && 02552 (!$mNameParts[1] || !t3lib_div::isFirstPartOfStr($mNameParts[1],$module_prefix))) { 02553 $infoArray['NSerrors']['modname'][] = $mName; 02554 } else $infoArray['NSok']['modname'][] = $mName; 02555 } else $infoArray['errors'][] = 'No definition of MCONF[name] variable found inside!'; 02556 } else $infoArray['errors'][] = 'Backend module conf file "'.$mod.'/conf.php" should exist but does not!'; 02557 } else $infoArray['errors'][] = 'Backend module folder "'.$mod.'/" should exist but does not!'; 02558 } 02559 $dirs = t3lib_div::get_dirs($absPath); 02560 if (is_array($dirs)) { 02561 reset($dirs); 02562 while(list(,$mod) = each($dirs)) { 02563 if (!in_array($mod,$knownModuleList) && @is_file($absPath.$mod.'/conf.php')) { 02564 $confFileInfo = $this->modConfFileAnalysis($absPath.$mod.'/conf.php'); 02565 if (is_array($confFileInfo)) { 02566 $infoArray['errors'][] = 'It seems like there is a backend module in "'.$mod.'/conf.php" which is not configured in ext_emconf.php'; 02567 } 02568 } 02569 } 02570 } 02571 02572 // ext_tables.php: 02573 if (@is_file($absPath.'ext_tables.php')) { 02574 $content = t3lib_div::getUrl($absPath.'ext_tables.php'); 02575 if (eregi('t3lib_extMgm::addModule',$content)) $infoArray['flags'][] = 'Module'; 02576 if (eregi('t3lib_extMgm::insertModuleFunction',$content)) $infoArray['flags'][] = 'Module+'; 02577 if (stristr($content,'t3lib_div::loadTCA')) $infoArray['flags'][] = 'loadTCA'; 02578 if (stristr($content,'$TCA[')) $infoArray['flags'][] = 'TCA'; 02579 if (eregi('t3lib_extMgm::addPlugin',$content)) $infoArray['flags'][] = 'Plugin'; 02580 } 02581 02582 // ext_localconf.php: 02583 if (@is_file($absPath.'ext_localconf.php')) { 02584 $content = t3lib_div::getUrl($absPath.'ext_localconf.php'); 02585 if (eregi('t3lib_extMgm::addPItoST43',$content)) $infoArray['flags'][]='Plugin/ST43'; 02586 if (eregi('t3lib_extMgm::addPageTSConfig',$content)) $infoArray['flags'][]='Page-TSconfig'; 02587 if (eregi('t3lib_extMgm::addUserTSConfig',$content)) $infoArray['flags'][]='User-TSconfig'; 02588 if (eregi('t3lib_extMgm::addTypoScriptSetup',$content)) $infoArray['flags'][]='TS/Setup'; 02589 if (eregi('t3lib_extMgm::addTypoScriptConstants',$content)) $infoArray['flags'][]='TS/Constants'; 02590 } 02591 02592 if (@is_file($absPath.'ext_typoscript_constants.txt')) { 02593 $infoArray['TSfiles'][] = 'Constants'; 02594 } 02595 if (@is_file($absPath.'ext_typoscript_setup.txt')) { 02596 $infoArray['TSfiles'][] = 'Setup'; 02597 } 02598 if (@is_file($absPath.'ext_conf_template.txt')) { 02599 $infoArray['conf'] = 1; 02600 } 02601 02602 // Classes: 02603 if ($validity) { 02604 $filesInside = $this->getClassIndexLocallangFiles($absPath,$table_class_prefix,$extKey); 02605 if (is_array($filesInside['errors'])) $infoArray['errors'] = array_merge((array)$infoArray['errors'],$filesInside['errors']); 02606 if (is_array($filesInside['NSerrors'])) $infoArray['NSerrors'] = array_merge((array)$infoArray['NSerrors'],$filesInside['NSerrors']); 02607 if (is_array($filesInside['NSok'])) $infoArray['NSok'] = array_merge((array)$infoArray['NSok'],$filesInside['NSok']); 02608 $infoArray['locallang'] = $filesInside['locallang']; 02609 $infoArray['classes'] = $filesInside['classes']; 02610 } 02611 02612 // Upload folders 02613 if ($extInfo['EM_CONF']['uploadfolder']) { 02614 $infoArray['uploadfolder'] = $this->ulFolder($extKey); 02615 if (!@is_dir(PATH_site.$infoArray['uploadfolder'])) { 02616 $infoArray['errors'][] = 'Error: Upload folder "'.$infoArray['uploadfolder'].'" did not exist!'; 02617 $infoArray['uploadfolder'] = ''; 02618 } 02619 } 02620 02621 // Create directories: 02622 if ($extInfo['EM_CONF']['createDirs']) { 02623 $infoArray['createDirs'] = array_unique(t3lib_div::trimExplode(',',$extInfo['EM_CONF']['createDirs'],1)); 02624 foreach($infoArray['createDirs'] as $crDir) { 02625 if (!@is_dir(PATH_site.$crDir)) { 02626 $infoArray['errors'][]='Error: Upload folder "'.$crDir.'" did not exist!'; 02627 } 02628 } 02629 } 02630 02631 // Return result array: 02632 return $infoArray; 02633 } 02634 02644 function getClassIndexLocallangFiles($absPath,$table_class_prefix,$extKey) { 02645 $filesInside = t3lib_div::removePrefixPathFromList(t3lib_div::getAllFilesAndFoldersInPath(array(),$absPath,'php,inc'),$absPath); 02646 $out = array(); 02647 02648 foreach($filesInside as $fileName) { 02649 if (substr($fileName,0,4)!='ext_') { 02650 $baseName = basename($fileName); 02651 if (substr($baseName,0,9)=='locallang' && substr($baseName,-4)=='.php') { 02652 $out['locallang'][] = $fileName; 02653 } elseif ($baseName!='conf.php') { 02654 if (filesize($absPath.$fileName)<500*1024) { 02655 $fContent = t3lib_div::getUrl($absPath.$fileName); 02656 unset($reg); 02657 if (ereg("\n[[:space:]]*class[[:space:]]*([[:alnum:]_]+)([[:alnum:][:space:]_]*){",$fContent,$reg)) { 02658 02659 // Find classes: 02660 $classesInFile=array(); 02661 $lines = explode(chr(10),$fContent); 02662 foreach($lines as $k => $l) { 02663 $line = trim($l); 02664 unset($reg); 02665 if (ereg('^class[[:space:]]*([[:alnum:]_]+)([[:alnum:][:space:]_]*){',$line,$reg)) { 02666 $out['classes'][] = $reg[1]; 02667 $out['files'][$fileName]['classes'][] = $reg[1]; 02668 if (substr($reg[1],0,3)!='ux_' && !t3lib_div::isFirstPartOfStr($reg[1],$table_class_prefix) && strcmp(substr($table_class_prefix,0,-1),$reg[1])) { 02669 $out['NSerrors']['classname'][] = $reg[1]; 02670 } else $out['NSok']['classname'][] = $reg[1]; 02671 } 02672 } 02673 // If class file prefixed 'class.'.... 02674 if (substr($baseName,0,6)=='class.') { 02675 $fI = pathinfo($baseName); 02676 $testName=substr($baseName,6,-(1+strlen($fI['extension']))); 02677 if (substr($testName,0,3)!='ux_' && !t3lib_div::isFirstPartOfStr($testName,$table_class_prefix) && strcmp(substr($table_class_prefix,0,-1),$testName)) { 02678 $out['NSerrors']['classfilename'][] = $baseName; 02679 } else { 02680 $out['NSok']['classfilename'][] = $baseName; 02681 if (is_array($out['files'][$fileName]['classes']) && $this->first_in_array($testName,$out['files'][$fileName]['classes'],1)) { 02682 $out['msg'][] = 'Class filename "'.$fileName.'" did contain the class "'.$testName.'" just as it should.'; 02683 } else $out['errors'][] = 'Class filename "'.$fileName.'" did NOT contain the class "'.$testName.'"!'; 02684 } 02685 } 02686 // 02687 $XclassParts = split('if \(defined\([\'"]TYPO3_MODE[\'"]\) && \$TYPO3_CONF_VARS\[TYPO3_MODE\]\[[\'"]XCLASS[\'"]\]',$fContent,2); 02688 if (count($XclassParts)==2) { 02689 unset($reg); 02690 ereg('^\[[\'"]([[:alnum:]_\/\.]*)[\'"]\]',$XclassParts[1],$reg); 02691 if ($reg[1]) { 02692 $cmpF = 'ext/'.$extKey.'/'.$fileName; 02693 if (!strcmp($reg[1],$cmpF)) { 02694 if (ereg('_once\(\$TYPO3_CONF_VARS\[TYPO3_MODE\]\[[\'"]XCLASS[\'"]\]\[[\'"]'.$cmpF.'[\'"]\]\);', $XclassParts[1])) { 02695 $out['msg'][] = 'XCLASS OK in '.$fileName; 02696 } else $out['errors'][] = 'Couldn\'t find the include_once statement for XCLASS!'; 02697 } else $out['errors'][] = 'The XCLASS filename-key "'.$reg[1].'" was different from "'.$cmpF.'" which it should have been!'; 02698 } else $out['errors'][] = 'No XCLASS filename-key found in file "'.$fileName.'". Maybe a regex coding error here...'; 02699 } elseif (!$this->first_in_array('ux_',$out['files'][$fileName]['classes'])) $out['errors'][] = 'No XCLASS inclusion code found in file "'.$fileName.'"'; 02700 } 02701 } 02702 } 02703 } 02704 } 02705 return $out; 02706 } 02707 02715 function modConfFileAnalysis($confFilePath) { 02716 $lines = explode(chr(10),t3lib_div::getUrl($confFilePath)); 02717 $confFileInfo = array(); 02718 $confFileInfo['lines'] = $lines; 02719 02720 foreach($lines as $k => $l) { 02721 $line = trim($l); 02722 02723 unset($reg); 02724 if (ereg('^define[[:space:]]*\([[:space:]]*["\']TYPO3_MOD_PATH["\'][[:space:]]*,[[:space:]]*["\']([[:alnum:]_\/\.]+)["\'][[:space:]]*\)[[:space:]]*;',$line,$reg)) { 02725 $confFileInfo['TYPO3_MOD_PATH'] = array($k,$reg); 02726 } 02727 02728 unset($reg); 02729 if (ereg('^\$MCONF\[["\']?name["\']?\][[:space:]]*=[[:space:]]*["\']([[:alnum:]_]+)["\'];',$line,$reg)) { 02730 $confFileInfo['MCONF_name'] = array($k,$reg); 02731 } 02732 } 02733 return $confFileInfo; 02734 } 02735 02743 function serverExtensionMD5Array($extKey,$conf) { 02744 02745 // Creates upload-array - including filelist. 02746 $mUA = $this->makeUploadArray($extKey,$conf); 02747 02748 $md5Array = array(); 02749 if (is_array($mUA['FILES'])) { 02750 02751 // Traverse files. 02752 foreach($mUA['FILES'] as $fN => $d) { 02753 if ($fN!='ext_emconf.php') { 02754 $md5Array[$fN] = substr($d['content_md5'],0,4); 02755 } 02756 } 02757 } else debug($mUA); 02758 return $md5Array; 02759 } 02760 02768 function findMD5ArrayDiff($current,$past) { 02769 if (!is_array($current)) $current = array(); 02770 if (!is_array($past)) $past = array(); 02771 $filesInCommon = array_intersect($current,$past); 02772 $diff1 = array_keys(array_diff($past,$filesInCommon)); 02773 $diff2 = array_keys(array_diff($current,$filesInCommon)); 02774 $affectedFiles = array_unique(array_merge($diff1,$diff2)); 02775 return $affectedFiles; 02776 } 02777 02778 02779 02780 02781 02782 02783 02784 02785 02786 02787 /*********************************** 02788 * 02789 * File system operations 02790 * 02791 **********************************/ 02792 02800 function createDirsInPath($dirs,$extDirPath) { 02801 if (is_array($dirs)) { 02802 foreach($dirs as $dir) { 02803 $allDirs = t3lib_div::trimExplode('/',$dir,1); 02804 $root = ''; 02805 foreach($allDirs as $dirParts) { 02806 $root.=$dirParts.'/'; 02807 if (!is_dir($extDirPath.$root)) { 02808 t3lib_div::mkdir($extDirPath.$root); 02809 if (!@is_dir($extDirPath.$root)) { 02810 return 'Error: The directory "'.$extDirPath.$root.'" could not be created...'; 02811 } 02812 } 02813 } 02814 } 02815 } 02816 } 02817 02825 function removeExtDirectory($removePath,$removeContentOnly=0) { 02826 $errors = array(); 02827 if (@is_dir($removePath) && substr($removePath,-1)=='/' && ( 02828 t3lib_div::isFirstPartOfStr($removePath,PATH_site.$this->typePaths['G']) || 02829 t3lib_div::isFirstPartOfStr($removePath,PATH_site.$this->typePaths['L']) || 02830 (t3lib_div::isFirstPartOfStr($removePath,PATH_site.$this->typePaths['S']) && $this->systemInstall) || 02831 t3lib_div::isFirstPartOfStr($removePath,PATH_site.'fileadmin/_temp_/')) // Playing-around directory... 02832 ) { 02833 02834 // All files in extension directory: 02835 $fileArr = t3lib_div::getAllFilesAndFoldersInPath(array(),$removePath,'',1); 02836 if (is_array($fileArr)) { 02837 02838 // Remove files in dirs: 02839 foreach($fileArr as $removeFile) { 02840 if (!@is_dir($removeFile)) { 02841 if (@is_file($removeFile) && t3lib_div::isFirstPartOfStr($removeFile,$removePath) && strcmp($removeFile,$removePath)) { // ... we are very paranoid, so we check what cannot go wrong: that the file is in fact within the prefix path! 02842 @unlink($removeFile); 02843 clearstatcache(); 02844 if (@is_file($removeFile)) { 02845 $errors[] = 'Error: "'.$removeFile.'" could not be deleted!'; 02846 } 02847 } else $errors[] = 'Error: "'.$removeFile.'" was either not a file, or it was equal to the removed directory or simply outside the removed directory "'.$removePath.'"!'; 02848 } 02849 } 02850 02851 // Remove directories: 02852 $remDirs = $this->extractDirsFromFileList(t3lib_div::removePrefixPathFromList($fileArr,$removePath)); 02853 $remDirs = array_reverse($remDirs); // Must delete outer directories first... 02854 foreach($remDirs as $removeRelDir) { 02855 $removeDir = $removePath.$removeRelDir; 02856 if (@is_dir($removeDir)) { 02857 rmdir($removeDir); 02858 clearstatcache(); 02859 if (@is_dir($removeDir)) { 02860 $errors[] = 'Error: "'.$removeDir.'" could not be removed (are there files left?)'; 02861 } 02862 } else $errors[] = 'Error: "'.$removeDir.'" was not a directory!'; 02863 } 02864 02865 // If extension dir should also be removed: 02866 if (!$removeContentOnly) { 02867 rmdir($removePath); 02868 clearstatcache(); 02869 if (@is_dir($removePath)) { 02870 $errors[] = 'Error: Extension directory "'.$removePath.'" could not be removed (are there files or folders left?)'; 02871 } 02872 } 02873 } else $errors[] = 'Error: '.$fileArr; 02874 } else $errors[] = 'Error: Unallowed path to remove: '.$removePath; 02875 02876 // Return errors if any: 02877 return implode(chr(10),$errors); 02878 } 02879 02887 function clearAndMakeExtensionDir($importedData,$type) { 02888 if (!$importedData['extKey']) return 'FATAL ERROR: Extension key was not set for some VERY strange reason. Nothing done...'; 02889 02890 // Setting install path (L, G, S or fileadmin/_temp_/) 02891 $path = ''; 02892 switch((string)$type) { 02893 case 'G': 02894 case 'L': 02895 $path = PATH_site.$this->typePaths[$type]; 02896 $suffix = ''; 02897 02898 // Creates the typo3conf/ext/ directory if it does NOT already exist: 02899 if ((string)$type=='L' && !@is_dir($path)) { 02900 t3lib_div::mkdir($path); 02901 } 02902 break; 02903 default: 02904 if ($this->systemInstall && (string)$type=='S') { 02905 $path = PATH_site.$this->typePaths[$type]; 02906 $suffix = ''; 02907 } else { 02908 $path = PATH_site.'fileadmin/_temp_/'; 02909 $suffix = '_'.date('dmy-His'); 02910 } 02911 break; 02912 } 02913 02914 // If the install path is OK... 02915 if ($path && @is_dir($path)) { 02916 02917 // Set extension directory: 02918 $extDirPath = $path.$importedData['extKey'].$suffix.'/'; 02919 02920 // Install dir was found, remove it then: 02921 if (@is_dir($extDirPath)) { 02922 $res = $this->removeExtDirectory($extDirPath); 02923 if ($res) { 02924 return 'ERROR: Could not remove extension directory "'.$extDirPath.'". Reasons:<br /><br />'.nl2br($res); 02925 } 02926 } 02927 02928 // We go create... 02929 t3lib_div::mkdir($extDirPath); 02930 if (!is_dir($extDirPath)) return 'ERROR: Could not create extension directory "'.$extDirPath.'"'; 02931 return array($extDirPath); 02932 } else return 'ERROR: The extension install path "'.$path.'" was not a directory.'; 02933 } 02934 02940 function removeCacheFiles() { 02941 $cacheFiles = t3lib_extMgm::currentCacheFiles(); 02942 $out = 0; 02943 if (is_array($cacheFiles)) { 02944 reset($cacheFiles); 02945 while(list(,$cfile) = each($cacheFiles)) { 02946 @unlink($cfile); 02947 clearstatcache(); 02948 $out++; 02949 } 02950 } 02951 return $out; 02952 } 02953 02960 function extractDirsFromFileList($files) { 02961 $dirs = array(); 02962 02963 if (is_array($files)) { 02964 // Traverse files / directories array: 02965 foreach($files as $file) { 02966 if (substr($file,-1)=='/') { 02967 $dirs[$file] = $file; 02968 } else { 02969 $pI = pathinfo($file); 02970 if (strcmp($pI['dirname'],'') && strcmp($pI['dirname'],'.')) { 02971 $dirs[$pI['dirname'].'/'] = $pI['dirname'].'/'; 02972 } 02973 } 02974 } 02975 } 02976 return $dirs; 02977 } 02978 02986 function getExtPath($extKey,$type) { 02987 $typeP = $this->typePaths[$type]; 02988 if ($typeP) { 02989 $path = PATH_site.$typeP.$extKey.'/'; 02990 return @is_dir($path) ? $path : ''; 02991 } 02992 } 02993 02994 02995 02996 02997 02998 02999 03000 03001 03002 03003 /******************************* 03004 * 03005 * Writing to "conf.php" and "localconf.php" files 03006 * 03007 ******************************/ 03008 03018 function writeTYPO3_MOD_PATH($confFilePath,$type,$mP) { 03019 $lines = explode(chr(10),t3lib_div::getUrl($confFilePath)); 03020 $confFileInfo = array(); 03021 $confFileInfo['lines'] = $lines; 03022 03023 $flag_M = 0; 03024 $flag_B = 0; 03025 03026 foreach($lines as $k => $l) { 03027 $line = trim($l); 03028 03029 unset($reg); 03030 if (ereg('^define[[:space:]]*\([[:space:]]*["\']TYPO3_MOD_PATH["\'][[:space:]]*,[[:space:]]*["\']([[:alnum:]_\/\.]+)["\'][[:space:]]*\)[[:space:]]*;',$line,$reg)) { 03031 $lines[$k] = str_replace($reg[0], 'define(\'TYPO3_MOD_PATH\', \''.$this->typeRelPaths[$type].$mP.'\');', $lines[$k]); 03032 $flag_M = $k+1; 03033 } 03034 03035 unset($reg); 03036 if (ereg('^\$BACK_PATH[[:space:]]*=[[:space:]]*["\']([[:alnum:]_\/\.]+)["\'][[:space:]]*;',$line,$reg)) { 03037 $lines[$k] = str_replace($reg[0], '$BACK_PATH=\''.$this->typeBackPaths[$type].'\';', $lines[$k]); 03038 $flag_B = $k+1; 03039 } 03040 } 03041 03042 if ($flag_B && $flag_M) { 03043 t3lib_div::writeFile($confFilePath,implode(chr(10),$lines)); 03044 return 'TYPO3_MOD_PATH and $BACK_PATH was updated in "'.substr($confFilePath,strlen(PATH_site)).'"'; 03045 } else return 'Error: Either TYPO3_MOD_PATH or $BACK_PATH was not found in the "'.$confFilePath.'" file. You must manually configure that!'; 03046 } 03047 03055 function writeNewExtensionList($newExtList) { 03056 03057 // Instance of install tool 03058 $instObj = new t3lib_install; 03059 $instObj->allowUpdateLocalConf =1; 03060 $instObj->updateIdentity = 'TYPO3 Extension Manager'; 03061 03062 // Get lines from localconf file 03063 $lines = $instObj->writeToLocalconf_control(); 03064 $instObj->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'EXT\'][\'extList\']', $newExtList); 03065 $instObj->writeToLocalconf_control($lines); 03066 03067 $this->removeCacheFiles(); 03068 } 03069 03078 function writeTsStyleConfig($extKey,$arr) { 03079 03080 // Instance of install tool 03081 $instObj = new t3lib_install; 03082 $instObj->allowUpdateLocalConf =1; 03083 $instObj->updateIdentity = 'TYPO3 Extension Manager'; 03084 03085 // Get lines from localconf file 03086 $lines = $instObj->writeToLocalconf_control(); 03087 $instObj->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'EXT\'][\'extConf\'][\''.$extKey.'\']', serialize($arr)); // This will be saved only if there are no linebreaks in it ! 03088 $instObj->writeToLocalconf_control($lines); 03089 03090 $this->removeCacheFiles(); 03091 } 03092 03100 function updateLocalEM_CONF($extKey,$extInfo) { 03101 $EM_CONF = $extInfo['EM_CONF']; 03102 $EM_CONF['_md5_values_when_last_written'] = serialize($this->serverExtensionMD5Array($extKey,$extInfo)); 03103 $emConfFileContent = $this->construct_ext_emconf_file($extKey,$EM_CONF); 03104 03105 if ($emConfFileContent) { 03106 $absPath = $this->getExtPath($extKey,$extInfo['type']); 03107 $emConfFileName = $absPath.'ext_emconf.php'; 03108 03109 if (@is_file($emConfFileName)) { 03110 t3lib_div::writeFile($emConfFileName,$emConfFileContent); 03111 return '"'.substr($emConfFileName,strlen($absPath)).'" was updated with a cleaned up EM_CONF array.'; 03112 } else die('Error: No file "'.$emConfFileName.'" found.'); 03113 } 03114 } 03115 03116 03117 03118 03119 03120 03121 03122 03123 03124 03125 /******************************************* 03126 * 03127 * Compiling upload information, emconf-file etc. 03128 * 03129 *******************************************/ 03130 03138 function construct_ext_emconf_file($extKey,$EM_CONF) { 03139 03140 $fMsg = array( 03141 'version' => ' // Don\'t modify this! Managed automatically during upload to repository.' 03142 ); 03143 03144 // clean version number: 03145 $vDat = $this->renderVersion($EM_CONF['version']); 03146 $EM_CONF['version']=$vDat['version']; 03147 03148 $lines=array(); 03149 $lines[]='<?php'; 03150 $lines[]=''; 03151 $lines[]='########################################################################'; 03152 $lines[]='# Extension Manager/Repository config file for ext: "'.$extKey.'"'; 03153 $lines[]='# '; 03154 $lines[]='# Auto generated '.date('d-m-Y H:i'); 03155 $lines[]='# '; 03156 $lines[]='# Manual updates:'; 03157 $lines[]='# Only the data in the array - anything else is removed by next write'; 03158 $lines[]='########################################################################'; 03159 $lines[]=''; 03160 $lines[]='$EM_CONF[$_EXTKEY] = Array ('; 03161 03162 foreach($EM_CONF as $k => $v) { 03163 $lines[] = chr(9)."'".$k."' => ".( 03164 t3lib_div::testInt($v)? 03165 intval($v): 03166 "'".t3lib_div::slashJS(trim($v),1)."'" 03167 ).','.$fMsg[$k]; 03168 } 03169 $lines[]=');'; 03170 $lines[]=''; 03171 $lines[]='?>'; 03172 03173 return implode(chr(10),$lines); 03174 } 03175 03183 function makeUploadArray($extKey,$conf) { 03184 $extPath = $this->getExtPath($extKey,$conf['type']); 03185 03186 if ($extPath) { 03187 03188 // Get files for extension: 03189 $fileArr = array(); 03190 $fileArr = t3lib_div::getAllFilesAndFoldersInPath($fileArr,$extPath); 03191 03192 // Calculate the total size of those files: 03193 $totalSize = 0; 03194 foreach($fileArr as $file) { 03195 $totalSize+=filesize($file); 03196 } 03197 03198 // If the total size is less than the upper limit, proceed: 03199 if ($totalSize < $this->maxUploadSize) { 03200 03201 // Initialize output array: 03202 $uploadArray = array(); 03203 $uploadArray['extKey'] = $extKey; 03204 $uploadArray['EM_CONF'] = $conf['EM_CONF']; 03205 $uploadArray['misc']['codelines'] = 0; 03206 $uploadArray['misc']['codebytes'] = 0; 03207 03208 $uploadArray['techInfo'] = $this->makeDetailedExtensionAnalysis($extKey,$conf,1); 03209 03210 // Read all files: 03211 foreach($fileArr as $file) { 03212 $relFileName = substr($file,strlen($extPath)); 03213 $fI = pathinfo($relFileName); 03214 if ($relFileName!='ext_emconf.php') { // This file should be dynamically written... 03215 $uploadArray['FILES'][$relFileName] = array( 03216 'name' => $relFileName, 03217 'size' => filesize($file), 03218 'mtime' => filemtime($file), 03219 'is_executable' => (TYPO3_OS=='WIN' ? 0 : is_executable($file)), 03220 'content' => t3lib_div::getUrl($file) 03221 ); 03222 if (t3lib_div::inList('php,inc',strtolower($fI['extension']))) { 03223 $uploadArray['FILES'][$relFileName]['codelines']=count(explode(chr(10),$uploadArray['FILES'][$relFileName]['content'])); 03224 $uploadArray['misc']['codelines']+=$uploadArray['FILES'][$relFileName]['codelines']; 03225 $uploadArray['misc']['codebytes']+=$uploadArray['FILES'][$relFileName]['size']; 03226 03227 // locallang*.php files: 03228 if (substr($fI['basename'],0,9)=='locallang' && strstr($uploadArray['FILES'][$relFileName]['content'],'$LOCAL_LANG')) { 03229 $uploadArray['FILES'][$relFileName]['LOCAL_LANG']=$this->getSerializedLocalLang($file,$uploadArray['FILES'][$relFileName]['content']); 03230 } 03231 } 03232 $uploadArray['FILES'][$relFileName]['content_md5'] = md5($uploadArray['FILES'][$relFileName]['content']); 03233 } 03234 } 03235 03236 // Return upload-array: 03237 return $uploadArray; 03238 } else return 'Error: Total size of uncompressed upload ('.$totalSize.') exceeds '.t3lib_div::formatSize($this->maxUploadSize); 03239 } 03240 } 03241 03250 function getSerializedLocalLang($file,$content) { 03251 $returnParts = explode('$LOCAL_LANG',$content,2); 03252 03253 include($file); 03254 if (is_array($LOCAL_LANG)) { 03255 $returnParts[1] = serialize($LOCAL_LANG); 03256 return $returnParts; 03257 } 03258 } 03259 03260 03261 03262 03263 03264 03265 03266 03267 03268 03269 /******************************** 03270 * 03271 * Managing dependencies, conflicts, priorities, load order of extension keys 03272 * 03273 *******************************/ 03274 03284 function addExtToList($extKey,$instExtInfo) { 03285 global $TYPO3_LOADED_EXT; 03286 03287 // ext_emconf.php information: 03288 $conf = $instExtInfo[$extKey]['EM_CONF']; 03289 03290 // Check dependencies on other extensions: 03291 if ($conf['dependencies']) { 03292 $dep = t3lib_div::trimExplode(',',$conf['dependencies'],1); 03293 03294 foreach($dep as $depK) { 03295 if (!t3lib_extMgm::isLoaded($depK)) { 03296 if (!isset($instExtInfo[$depK])) { 03297 $msg = 'Extension "'.$depK.'" was not available in the system. Please import it from the TYPO3 Extension Repository.'; 03298 } else { 03299 $msg = 'Extension "'.$depK.'" ('.$instExtInfo[$depK]['EM_CONF']['title'].') was not installed. Please install it first.'; 03300 } 03301 $this->content.= $this->doc->section('Dependency Error',$msg,0,1,2); 03302 return -1; 03303 } 03304 } 03305 } 03306 03307 // Check conflicts with other extensions: 03308 if ($conf['conflicts']) { 03309 $conflict = t3lib_div::trimExplode(',',$conf['conflicts'],1); 03310 03311 foreach($conflict as $conflictK) { 03312 if (t3lib_extMgm::isLoaded($conflictK)) { 03313 $msg = 'The extention "'.$extKey.'" and "'.$conflictK.'" ('.$instExtInfo[$conflictK]['EM_CONF']['title'].') will conflict with each other. Please remove "'.$conflictK.'" if you want to install "'.$extKey.'".'; 03314 $this->content.= $this->doc->section('Conflict Error',$msg,0,1,2); 03315 return -1; 03316 } 03317 } 03318 } 03319 03320 // Get list of installed extensions and add this one. 03321 $listArr = array_keys($TYPO3_LOADED_EXT); 03322 if ($conf['priority']=='top') { 03323 array_unshift($listArr,$extKey); 03324 } else { 03325 $listArr[]=$extKey; 03326 } 03327 03328 // Manage other circumstances: 03329 $listArr = $this->managesPriorities($listArr,$instExtInfo); 03330 $listArr = $this->removeRequiredExtFromListArr($listArr); 03331 03332 // Implode unique list of extensions to load and return: 03333 $list = implode(',',array_unique($listArr)); 03334 return $list; 03335 } 03336 03346 function removeExtFromList($extKey,$instExtInfo) { 03347 global $TYPO3_LOADED_EXT; 03348 03349 // Initialize: 03350 $depList = array(); 03351 $listArr = array_keys($TYPO3_LOADED_EXT); 03352 03353 // Traverse all installed extensions to check if any of them have this extension as dependency since if that is the case it will not work out! 03354 foreach($listArr as $k => $ext) { 03355 if ($instExtInfo[$ext]['EM_CONF']['dependencies']) { 03356 $dep = t3lib_div::trimExplode(',',$instExtInfo[$ext]['EM_CONF']['dependencies'],1); 03357 if (in_array($extKey,$dep)) { 03358 $depList[] = $ext; 03359 } 03360 } 03361 if (!strcmp($ext,$extKey)) unset($listArr[$k]); 03362 } 03363 03364 // Returns either error or the new list 03365 if (count($depList)) { 03366 $msg = 'The extension(s) "'.implode(', ',$depList).'" depends on the extension you are trying to remove. The operation was not completed.'; 03367 $this->content.=$this->doc->section('Dependency Error',$msg,0,1,2); 03368 return -1; 03369 } else { 03370 $listArr = $this->removeRequiredExtFromListArr($listArr); 03371 $list = implode(',',array_unique($listArr)); 03372 return $list; 03373 } 03374 } 03375 03383 function removeRequiredExtFromListArr($listArr) { 03384 foreach($listArr as $k => $ext) { 03385 if (in_array($ext,$this->requiredExt) || !strcmp($ext,'_CACHEFILE')) unset($listArr[$k]); 03386 } 03387 return $listArr; 03388 } 03389 03398 function managesPriorities($listArr,$instExtInfo) { 03399 03400 // Initialize: 03401 $levels = array( 03402 'top' => array(), 03403 'middle' => array(), 03404 'bottom' => array(), 03405 ); 03406 03407 // Traverse list of extensions: 03408 foreach($listArr as $k => $ext) { 03409 $prio = trim($instExtInfo[$ext]['EM_CONF']['priority']); 03410 switch((string)$prio) { 03411 case 'top': 03412 case 'bottom': 03413 $levels[$prio][] = $ext; 03414 break; 03415 default: 03416 $levels['middle'][] = $ext; 03417 break; 03418 } 03419 } 03420 return array_merge( 03421 $levels['top'], 03422 $levels['middle'], 03423 $levels['bottom'] 03424 ); 03425 } 03426 03427 03428 03429 03430 03431 03432 03433 03434 03435 03436 /******************************* 03437 * 03438 * System Update functions (based on extension requirements) 03439 * 03440 ******************************/ 03441 03450 function checkClearCache($extKey,$extInfo) { 03451 if ($extInfo['EM_CONF']['clearCacheOnLoad']) { 03452 if (t3lib_div::_POST('_clear_all_cache')) { // Action: Clearing the cache 03453 $tce = t3lib_div::makeInstance('t3lib_TCEmain'); 03454 $tce->stripslashes_values = 0; 03455 $tce->start(Array(),Array()); 03456 $tce->clear_cacheCmd('all'); 03457 } else { // Show checkbox for clearing cache: 03458 $content.= ' 03459 <br /> 03460 <h3>Clear cache</h3> 03461 <p>This extension requests the cache to be cleared when it is installed/removed.<br /> 03462 Clear all cache: <input type="checkbox" name="_clear_all_cache" checked="checked" value="1" /><br /> 03463 </p> 03464 '; 03465 } 03466 } 03467 return $content; 03468 } 03469 03477 function checkUploadFolder($extKey,$extInfo) { 03478 03479 // Checking for upload folder: 03480 $uploadFolder = PATH_site.$this->ulFolder($extKey); 03481 if ($extInfo['EM_CONF']['uploadfolder'] && !@is_dir($uploadFolder)) { 03482 if (t3lib_div::_POST('_uploadfolder')) { // CREATE dir: 03483 t3lib_div::mkdir($uploadFolder); 03484 $indexContent = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> 03485 <HTML> 03486 <HEAD> 03487 <TITLE></TITLE> 03488 <META http-equiv=Refresh Content="0; Url=../../"> 03489 </HEAD> 03490 </HTML>'; 03491 t3lib_div::writeFile($uploadFolder.'index.html',$indexContent); 03492 } else { // Show checkbox / HTML for creation: 03493 $content.=' 03494 <br /><h3>Create upload folder</h3> 03495 <p>The extension requires the upload folder "'.$this->ulFolder($extKey).'" to exist.<br /> 03496 Create directory "'.$this->ulFolder($extKey).'": <input type="checkbox" name="_uploadfolder" checked="checked" value="1" /><br /> 03497 </p> 03498 '; 03499 } 03500 } 03501 03502 // Additional directories that should be created: 03503 if ($extInfo['EM_CONF']['createDirs']) { 03504 $createDirs = array_unique(t3lib_div::trimExplode(',',$extInfo['EM_CONF']['createDirs'],1)); 03505 03506 foreach($createDirs as $crDir) { 03507 if (!@is_dir(PATH_site.$crDir)) { 03508 if (t3lib_div::_POST('_createDir_'.md5($crDir))) { // CREATE dir: 03509 03510 // Initialize: 03511 $crDirStart = ''; 03512 $dirs_in_path = explode('/',ereg_replace('/$','',$crDir)); 03513 03514 // Traverse each part of the dir path and create it one-by-one: 03515 foreach($dirs_in_path as $dirP) { 03516 if (strcmp($dirP,'')) { 03517 $crDirStart.= $dirP.'/'; 03518 if (!@is_dir(PATH_site.$crDirStart)) { 03519 t3lib_div::mkdir(PATH_site.$crDirStart); 03520 $finalDir = PATH_site.$crDirStart; 03521 } 03522 } else { 03523 die('ERROR: The path "'.PATH_site.$crDir.'" could not be created.'); 03524 } 03525 } 03526 if ($finalDir) { 03527 $indexContent = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> 03528 <HTML> 03529 <HEAD> 03530 <TITLE></TITLE> 03531 <META http-equiv=Refresh Content="0; Url=/"> 03532 </HEAD> 03533 </HTML>'; 03534 t3lib_div::writeFile($finalDir.'index.html',$indexContent); 03535 } 03536 } else { // Show checkbox / HTML for creation: 03537 $content.=' 03538 <br /> 03539 <h3>Create folder</h3> 03540 <p>The extension requires the folder "'.$crDir.'" to exist.<br /> 03541 Create directory "'.$crDir.'": <input type="checkbox" name="_createDir_'.md5($crDir).'" checked="checked" value="1" /><br /> 03542 </p> 03543 '; 03544 } 03545 } 03546 } 03547 } 03548 03549 return $content; 03550 } 03551 03562 function checkDBupdates($extKey,$extInfo,$infoOnly=0) { 03563 03564 // Initializing Install Tool object: 03565 $instObj = new t3lib_install; 03566 $instObj->INSTALL = t3lib_div::_GP('TYPO3_INSTALL'); 03567 $dbStatus = array(); 03568 03569 // Updating tables and fields? 03570 if (in_array('ext_tables.sql',$extInfo['files'])) { 03571 $fileContent = t3lib_div::getUrl($this->getExtPath($extKey,$extInfo['type']).'ext_tables.sql'); 03572 03573 $FDfile = $instObj->getFieldDefinitions_sqlContent($fileContent); 03574 if (count($FDfile)) { 03575 $FDdb = $instObj->getFieldDefinitions_database(TYPO3_db); 03576 $diff = $instObj->getDatabaseExtra($FDfile, $FDdb); 03577 $update_statements = $instObj->getUpdateSuggestions($diff); 03578 03579 $dbStatus['structure']['tables_fields'] = $FDfile; 03580 $dbStatus['structure']['diff'] = $diff; 03581 03582 // Updating database... 03583 if (!$infoOnly && is_array($instObj->INSTALL['database_update'])) { 03584 $instObj->performUpdateQueries($update_statements['add'],$instObj->INSTALL['database_update']); 03585 $instObj->performUpdateQueries($update_statements['change'],$instObj->INSTALL['database_update']); 03586 $instObj->performUpdateQueries($update_statements['create_table'],$instObj->INSTALL['database_update']); 03587 } else { 03588 $content.=$instObj->generateUpdateDatabaseForm_checkboxes($update_statements['add'],'Add fields'); 03589 $content.=$instObj->generateUpdateDatabaseForm_checkboxes($update_statements['change'],'Changing fields',1,0,$update_statements['change_currentValue']); 03590 $content.=$instObj->generateUpdateDatabaseForm_checkboxes($update_statements['create_table'],'Add tables'); 03591 } 03592 } 03593 } 03594 03595 // Importing static tables? 03596 if (in_array('ext_tables_static+adt.sql',$extInfo['files'])) { 03597 $fileContent = t3lib_div::getUrl($this->getExtPath($extKey,$extInfo['type']).'ext_tables_static+adt.sql'); 03598 03599 $statements = $instObj->getStatementArray($fileContent,1); 03600 list($statements_table, $insertCount) = $instObj->getCreateTables($statements,1); 03601 03602 // Execute import of static table content: 03603 if (!$infoOnly && is_array($instObj->INSTALL['database_import'])) { 03604 03605 // Traverse the tables 03606 foreach($instObj->INSTALL['database_import'] as $table => $md5str) { 03607 if ($md5str == md5($statements_table[$table])) { 03608 $res = $GLOBALS['TYPO3_DB']->admin_query('DROP TABLE IF EXISTS '.$table); 03609 $res = $GLOBALS['TYPO3_DB']->admin_query($statements_table[$table]); 03610 03611 if ($insertCount[$table]) { 03612 $statements_insert = $instObj->getTableInsertStatements($statements, $table); 03613 03614 foreach($statements_insert as $k => $v) { 03615 $res = $GLOBALS['TYPO3_DB']->admin_query($v); 03616 } 03617 } 03618 } 03619 } 03620 } else { 03621 $whichTables = $instObj->getListOfTables(); 03622 if (count($statements_table)) { 03623 $out = ''; 03624 foreach($statements_table as $table => $definition) { 03625 $exist = isset($whichTables[$table]); 03626 03627 $dbStatus['static'][$table]['exists'] = $exist; 03628 $dbStatus['static'][$table]['count'] = $insertCount[$table]; 03629 03630 $out.= '<tr> 03631 <td><input type="checkbox" name="TYPO3_INSTALL[database_import]['.$table.']" checked="checked" value="'.md5($definition).'" /></td> 03632 <td><strong>'.$table.'</strong></td> 03633 <td><img src="clear.gif" width="10" height="1" alt="" /></td> 03634 <td nowrap="nowrap">'.($insertCount[$table]?'Rows: '.$insertCount[$table]:'').'</td> 03635 <td><img src="clear.gif" width="10" height="1" alt="" /></td> 03636 <td nowrap="nowrap">'.($exist?'<img src="'.$GLOBALS['BACK_PATH'].'t3lib/gfx/icon_warning.gif" width="18" height="16" align="top" alt="" />Table exists!':'').'</td> 03637 </tr>'; 03638 } 03639 $content.= ' 03640 <br /> 03641 <h3>Import static data</h3> 03642 <table border="0" cellpadding="0" cellspacing="0">'.$out.'</table>'; 03643 } 03644 } 03645 } 03646 03647 // Return array of information if $infoOnly, otherwise content. 03648 return $infoOnly ? $dbStatus : $content; 03649 } 03650 03661 function tsStyleConfigForm($extKey,$extInfo,$output=0,$script='',$addFields='') { 03662 global $TYPO3_CONF_VARS; 03663 03664 // Initialize: 03665 $absPath = $this->getExtPath($extKey,$extInfo['type']); 03666 $relPath = $this->typeRelPaths[$extInfo['type']].$extKey.'/'; 03667 03668 // Look for template file for form: 03669 if (@is_file($absPath.'ext_conf_template.txt')) { 03670 03671 // Load tsStyleConfig class and parse configuration template: 03672 $tsStyleConfig = t3lib_div::makeInstance('t3lib_tsStyleConfig'); 03673 $theConstants = $tsStyleConfig->ext_initTSstyleConfig( 03674 t3lib_div::getUrl($absPath.'ext_conf_template.txt'), 03675 $relPath, 03676 $absPath, 03677 $GLOBALS['BACK_PATH'] 03678 ); 03679 03680 // Load the list of resources. 03681 $tsStyleConfig->ext_loadResources($absPath.'res/'); 03682 03683 // Load current value: 03684 $arr = unserialize($TYPO3_CONF_VARS['EXT']['extConf'][$extKey]); 03685 $arr = is_array($arr) ? $arr : array(); 03686 03687 // Call processing function for constants config and data before write and form rendering: 03688 if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/mod/tools/em/index.php']['tsStyleConfigForm'])) { 03689 $_params = array('fields' => &$theConstants, 'data' => &$arr, 'extKey' => $extKey); 03690 foreach($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/mod/tools/em/index.php']['tsStyleConfigForm'] as $_funcRef) { 03691 t3lib_div::callUserFunction($_funcRef,$_params,$this); 03692 } 03693 unset($_params); 03694 } 03695 03696 // If saving operation is done: 03697 if (t3lib_div::_POST('submit')) { 03698 $tsStyleConfig->ext_procesInput(t3lib_div::_POST(),array(),$theConstants,array()); 03699 $arr = $tsStyleConfig->ext_mergeIncomingWithExisting($arr); 03700 $this->writeTsStyleConfig($extKey,$arr); 03701 } 03702 03703 // Setting value array 03704 $tsStyleConfig->ext_setValueArray($theConstants,$arr); 03705 03706 // Getting session data: 03707 $MOD_MENU = array(); 03708 $MOD_MENU['constant_editor_cat'] = $tsStyleConfig->ext_getCategoriesForModMenu(); 03709 $MOD_SETTINGS = t3lib_BEfunc::getModuleData($MOD_MENU, t3lib_div::_GP('SET'), 'xMod_test'); 03710 03711 // Resetting the menu (stop) 03712 if (count($MOD_MENU)>1) { 03713 $menu = 'Category: '.t3lib_BEfunc::getFuncMenu(0,'SET[constant_editor_cat]',$MOD_SETTINGS['constant_editor_cat'],$MOD_MENU['constant_editor_cat'],'','&CMD[showExt]='.$extKey); 03714 $this->content.=$this->doc->section('','<span class="nobr">'.$menu.'</span>'); 03715 $this->content.=$this->doc->spacer(10); 03716 } 03717 03718 // Category and constant editor config: 03719 $form = ' 03720 <table border="0" cellpadding="0" cellspacing="0" width="600"> 03721 <tr> 03722 <td>'.$tsStyleConfig->ext_getForm($MOD_SETTINGS['constant_editor_cat'],$theConstants,$script,$addFields).'</td> 03723 </tr> 03724 </table>'; 03725 if ($output) { 03726 return $form; 03727 } else { 03728 $this->content.=$this->doc->section('','</form>'.$form.'<form>'); 03729 } 03730 } 03731 } 03732 03733 03734 03735 03736 03737 03738 03739 03740 03741 03742 /******************************* 03743 * 03744 * Dumping database (MySQL compliant) 03745 * 03746 ******************************/ 03747 03755 function dumpTableAndFieldStructure($arr) { 03756 $tables = array(); 03757 03758 if (count($arr)) { 03759 03760 // Get file header comment: 03761 $tables[] = $this->dumpHeader(); 03762 03763 // Traverse tables, write each table/field definition: 03764 foreach($arr as $table => $fieldKeyInfo) { 03765 $tables[] = $this->dumpTableHeader($table,$fieldKeyInfo); 03766 } 03767 } 03768 03769 // Return result: 03770 return implode(chr(10).chr(10).chr(10),$tables); 03771 } 03772 03780 function dumpStaticTables($tableList) { 03781 $instObj = new t3lib_install; 03782 $dbFields = $instObj->getFieldDefinitions_database(TYPO3_db); 03783 03784 $out = ''; 03785 $parts = t3lib_div::trimExplode(',',$tableList,1); 03786 03787 // Traverse the table list and dump each: 03788 foreach($parts as $table) { 03789 if (is_array($dbFields[$table]['fields'])) { 03790 $dHeader = $this->dumpHeader(); 03791 $header = $this->dumpTableHeader($table,$dbFields[$table],1); 03792 $insertStatements = $this->dumpTableContent($table,$dbFields[$table]['fields']); 03793 03794 $out.= $dHeader.chr(10).chr(10).chr(10). 03795 $header.chr(10).chr(10).chr(10). 03796 $insertStatements.chr(10).chr(10).chr(10); 03797 } else { 03798 die('Fatal error: Table for dump not found in database...'); 03799 } 03800 } 03801 return $out; 03802 } 03803 03809 function dumpHeader() { 03810 return trim(' 03811 # TYPO3 Extension Manager dump 1.1 03812 # 03813 # Host: '.TYPO3_db_host.' Database: '.TYPO3_db.' 03814 #-------------------------------------------------------- 03815 '); 03816 } 03817 03826 function dumpTableHeader($table,$fieldKeyInfo,$dropTableIfExists=0) { 03827 $lines = array(); 03828 03829 // Create field definitions 03830 if (is_array($fieldKeyInfo['fields'])) { 03831 foreach($fieldKeyInfo['fields'] as $fieldN => $data) { 03832 $lines[]=' '.$fieldN.' '.$data; 03833 } 03834 } 03835 03836 // Create index key definitions 03837 if (is_array($fieldKeyInfo['keys'])) { 03838 foreach($fieldKeyInfo['keys'] as $fieldN => $data) { 03839 $lines[]=' '.$data; 03840 } 03841 } 03842 03843 // Compile final output: 03844 if (count($lines)) { 03845 return trim(' 03846 # 03847 # Table structure for table "'.$table.'" 03848 # 03849 '.($dropTableIfExists ? 'DROP TABLE IF EXISTS '.$table.'; 03850 ' : '').'CREATE TABLE '.$table.' ( 03851 '.implode(','.chr(10),$lines).' 03852 );' 03853 ); 03854 } 03855 } 03856 03865 function dumpTableContent($table,$fieldStructure) { 03866 03867 // Substitution of certain characters (borrowed from phpMySQL): 03868 $search = array('\\', '\'', "\x00", "\x0a", "\x0d", "\x1a"); 03869 $replace = array('\\\\', '\\\'', '\0', '\n', '\r', '\Z'); 03870 03871 $lines = array(); 03872 03873 // Select all rows from the table: 03874 $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, ''); 03875 03876 // Traverse the selected rows and dump each row as a line in the file: 03877 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) { 03878 $values = array(); 03879 reset($fieldStructure); 03880 while(list($field) = each($fieldStructure)) { 03881 $values[] = isset($row[$field]) ? "'".str_replace($search, $replace, $row[$field])."'" : 'NULL'; 03882 } 03883 $lines[] = 'INSERT INTO '.$table.' VALUES ('.implode(', ',$values).');'; 03884 } 03885 03886 // Free DB result: 03887 $GLOBALS['TYPO3_DB']->sql_free_result($result); 03888 03889 // Implode lines and return: 03890 return implode(chr(10),$lines); 03891 } 03892 03900 function getTableAndFieldStructure($parts) { 03901 // Instance of install tool 03902 $instObj = new t3lib_install; 03903 $dbFields = $instObj->getFieldDefinitions_database(TYPO3_db); 03904 03905 03906 $outTables = array(); 03907 foreach($parts as $table) { 03908 $tP = explode('.',$table); 03909 if ($tP[0] && isset($dbFields[$tP[0]])) { 03910 if ($tP[1]) { 03911 $kfP = explode('KEY:',$tP[1],2); 03912 if (count($kfP)==2 && !$kfP[0]) { // key: 03913 if (isset($dbFields[$tP[0]]['keys'][$kfP[1]])) $outTables[$tP[0]]['keys'][$kfP[1]] = $dbFields[$tP[0]]['keys'][$kfP[1]]; 03914 } else { 03915 if (isset($dbFields[$tP[0]]['fields'][$tP[1]])) $outTables[$tP[0]]['fields'][$tP[1]] = $dbFields[$tP[0]]['fields'][$tP[1]]; 03916 } 03917 } else { 03918 $outTables[$tP[0]] = $dbFields[$tP[0]]; 03919 } 03920 } 03921 } 03922 03923 return $outTables; 03924 } 03925 03926 03927 03928 03929 03930 03931 03932 03933 03934 03935 /******************************* 03936 * 03937 * TER Communication functions 03938 * 03939 ******************************/ 03940 03948 function fetchServerData($repositoryUrl) { 03949 03950 // Request data from remote: 03951 $ps1 = t3lib_div::milliseconds(); 03952 $externalData = t3lib_div::getUrl($repositoryUrl); 03953 $ps2 = t3lib_div::milliseconds()+1; 03954 #echo $externalData; exit; 03955 #debug(array($externalData));exit; 03956 // Compile statistics array: 03957 $stat = Array( 03958 ($ps2-$ps1), 03959 strlen($externalData), 03960 'Time: '.($ps2-$ps1).'ms', 03961 'Size: '.t3liB_div::formatSize(strlen($externalData)), 03962 'Transfer: '.t3liB_div::formatSize(strlen($externalData) / (($ps2-$ps1)/1000)).'/sec' 03963 ); 03964 03965 // Decode result and return: 03966 return $this->decodeServerData($externalData,$stat); 03967 } 03968 03978 function decodeServerData($externalData,$stat=array()) { 03979 $parts = explode(':',$externalData,4); 03980 $dat = base64_decode($parts[2]); 03981 // compare hashes ignoring any leading whitespace (This makes it work for some broken .t3x files that have leading white space. See bug #0000365. Thanks to Martin T. Kutschker <Martin-no5pam-Kutschker@blackbox.n0spam.net>) 03982 if (ereg_replace("^[\n\r\t ]+",'',$parts[0])==md5($dat)) { 03983 if ($parts[1]=='gzcompress') { 03984 if ($this->gzcompress) { 03985 $dat = gzuncompress($dat); 03986 } else return 'Decoding Error: No decompressor available for compressed content. gzcompress()/gzuncompress() functions are not available!'; 03987 } 03988 $listArr = unserialize($dat); 03989 03990 if (is_array($listArr)) { 03991 return array($listArr,$stat); 03992 } else { 03993 return 'Error: Unserialized information was not an array - strange!'; 03994 } 03995 } else return 'Error: MD5 hashes did not match!'; 03996 } 03997 04005 function decodeExchangeData($str) { 04006 $parts = explode(':',$str,3); 04007 if ($parts[1]=='gzcompress') { 04008 if ($this->gzcompress) { 04009 $parts[2] = gzuncompress($parts[2]); 04010 } else return 'Decoding Error: No decompressor available for compressed content. gzcompress()/gzuncompress() functions are not available!'; 04011 } 04012 if (md5($parts[2]) == $parts[0]) { 04013 $output = unserialize($parts[2]); 04014 if (is_array($output)) { 04015 return $output; 04016 } else return 'Error: Content could not be unserialized to an array. Strange (since MD5 hashes match!)'; 04017 } else return 'Error: MD5 mismatch. Maybe the extension file was downloaded and saved as a text file by the browser and thereby corrupted!? (Always select "All" filetype when saving extensions)'; 04018 } 04019 04027 function makeUploadDataFromArray($uploadArray,$local_gzcompress=-1) { 04028 if (is_array($uploadArray)) { 04029 $serialized = serialize($uploadArray); 04030 $md5 = md5($serialized); 04031 04032 $local_gzcompress = ($local_gzcompress>-1)?$local_gzcompress:$this->gzcompress; 04033 04034 $content = $md5.':'; 04035 if ($local_gzcompress) { 04036 $content.= 'gzcompress:'; 04037 $content.= gzcompress($serialized); 04038 } else { 04039 $content.= ':'; 04040 $content.= $serialized; 04041 } 04042 } 04043 return $content; 04044 } 04045 04052 function repTransferParams() { 04053 return '&tx_extrep[T3instID]='.rawurlencode($this->T3instID()). 04054 '&tx_extrep[TYPO3_ver]='.rawurlencode($GLOBALS['TYPO_VERSION']). 04055 '&tx_extrep[PHP_ver]='.rawurlencode(phpversion()). 04056 '&tx_extrep[returnUrl]='.rawurlencode($this->makeReturnUrl()). 04057 '&tx_extrep[gzcompress]='.$this->gzcompress. 04058 '&tx_extrep[user][fe_u]='.$this->fe_user['username']. 04059 '&tx_extrep[user][fe_p]='.$this->fe_user['password']; 04060 } 04061 04068 function makeReturnUrl() { 04069 return t3lib_div::getIndpEnv('TYPO3_REQUEST_URL'); 04070 } 04071 04078 function T3instID() { 04079 return $GLOBALS['TYPO3_CONF_VARS']['SYS']['T3instID']; 04080 } 04081 04089 function processRepositoryReturnData($TER_CMD) { 04090 switch((string)$TER_CMD['cmd']) { 04091 case 'EM_CONF': 04092 list($list)=$this->getInstalledExtensions(); 04093 $extKey = $TER_CMD['extKey']; 04094 04095 $data = $this->decodeServerData($TER_CMD['returnValue']); 04096 $EM_CONF = $data[0]; 04097 $EM_CONF['_md5_values_when_last_written'] = serialize($this->serverExtensionMD5Array($extKey,$list[$extKey])); 04098 $emConfFileContent = $this->construct_ext_emconf_file($extKey,$EM_CONF); 04099 if (is_array($list[$extKey]) && $emConfFileContent) { 04100 $absPath = $this->getExtPath($extKey,$list[$extKey]['type']); 04101 $emConfFileName = $absPath.'ext_emconf.php'; 04102 if (@is_file($emConfFileName)) { 04103 t3lib_div::writeFile($emConfFileName,$emConfFileContent); 04104 return '"'.substr($emConfFileName,strlen($absPath)).'" was updated with a cleaned up EM_CONF array.'; 04105 } else die('Error: No file "'.$emConfFileName.'" found.'); 04106 } else die('Error: No EM_CONF content prepared...'); 04107 break; 04108 } 04109 } 04110 04111 04112 04113 04114 04115 04116 04117 04118 04119 04120 /************************************ 04121 * 04122 * Various helper functions 04123 * 04124 ************************************/ 04125 04133 function listOrderTitle($listOrder,$key) { 04134 switch($listOrder) { 04135 case 'cat': 04136 return isset($this->categories[$key])?$this->categories[$key]:'<em>['.$key.']</em>'; 04137 break; 04138 case 'author_company': 04139 return $key; 04140 break; 04141 case 'dep': 04142 return $key; 04143 break; 04144 case 'state': 04145 return $this->states[$key]; 04146 break; 04147 case 'private': 04148 return $key?'Private (Password required to download from repository)':'Public (Everyone can download this from Extention repository)'; 04149 break; 04150 case 'type': 04151 return $this->typeDescr[$key]; 04152 break; 04153 } 04154 } 04155 04164 function makeVersion($v,$mode) { 04165 $vDat = $this->renderVersion($v); 04166 return $vDat['version_'.$mode]; 04167 } 04168 04176 function renderVersion($v,$raise='') { 04177 $parts = t3lib_div::intExplode('.',$v.'..'); 04178 $parts[0] = t3lib_div::intInRange($parts[0],0,999); 04179 $parts[1] = t3lib_div::intInRange($parts[1],0,999); 04180 $parts[2] = t3lib_div::intInRange($parts[2],0,999); 04181 04182 switch((string)$raise) { 04183 case 'main': 04184 $parts[0]++; 04185 $parts[1]=0; 04186 $parts[2]=0; 04187 break; 04188 case 'sub': 04189 $parts[1]++; 04190 $parts[2]=0; 04191 break; 04192 case 'dev': 04193 $parts[2]++; 04194 break; 04195 } 04196 04197 $res = array(); 04198 $res['version'] = $parts[0].'.'.$parts[1].'.'.$parts[2]; 04199 $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)); 04200 $res['version_main'] = $parts[0]; 04201 $res['version_sub'] = $parts[1]; 04202 $res['version_dev'] = $parts[2]; 04203 04204 return $res; 04205 } 04206 04213 function ulFolder($extKey) { 04214 return 'uploads/tx_'.str_replace('_','',$extKey).'/'; 04215 } 04216 04222 function importAtAll() { 04223 return ($GLOBALS['TYPO3_CONF_VARS']['EXT']['allowGlobalInstall'] || $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowLocalInstall']); 04224 } 04225 04233 function importAsType($type,$lockType='') { 04234 switch($type) { 04235 case 'G': 04236 return $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowGlobalInstall'] && (!$lockType || !strcmp($lockType,$type)); 04237 break; 04238 case 'L': 04239 return $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowLocalInstall'] && (!$lockType || !strcmp($lockType,$type)); 04240 break; 04241 case 'S': 04242 return $this->systemInstall; 04243 break; 04244 } 04245 } 04246 04253 function deleteAsType($type) { 04254 switch($type) { 04255 case 'G': 04256 return $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowGlobalInstall']; 04257 break; 04258 case 'L': 04259 return $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowLocalInstall']; 04260 break; 04261 } 04262 } 04263 04271 function getDocManual($extension_key,$loc='') { 04272 $res = FALSE; 04273 if ($GLOBALS['TYPO3_CONF_VARS']['EXT']['em_alwaysGetOOManual']) $res = TRUE; 04274 if ($loc && $this->typePaths[$loc] && @is_file(PATH_site.$this->typePaths[$loc].$extension_key.'/doc/manual.sxw')) $res = TRUE; 04275 04276 return $res; 04277 } 04278 04287 function versionDifference($v1,$v2,$div=1) { 04288 return floor($this->makeVersion($v1,'int')/$div) > floor($this->makeVersion($v2,'int')/$div); 04289 } 04290 04299 function first_in_array($str,$array,$caseInsensitive=FALSE) { 04300 if ($caseInsensitive) $str = strtolower($str); 04301 if (is_array($array)) { 04302 foreach($array as $cl) { 04303 if ($caseInsensitive) $cl = strtolower($cl); 04304 if (t3lib_div::isFirstPartOfStr($cl,$str)) return 1; 04305 } 04306 } 04307 } 04308 04316 function includeEMCONF($path,$_EXTKEY) { 04317 include($path); 04318 04319 return $EM_CONF[$_EXTKEY]; 04320 } 04321 } 04322 04323 // Include extension? 04324 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/mod/tools/em/index.php']) { 04325 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/mod/tools/em/index.php']); 04326 } 04327 04328 04329 04330 04331 04332 04333 04334 04335 04336 // Make instance: 04337 $SOBE = t3lib_div::makeInstance('SC_mod_tools_em_index'); 04338 $SOBE->init(); 04339 foreach($SOBE->include_once as $INC_FILE) { 04340 include_once($INC_FILE); 04341 } 04342 $SOBE->checkExtObj(); 04343 $SOBE->main(); 04344 $SOBE->printContent(); 04345 ?>