2 /***************************************************************
5 * (c) 1999-2010 Kasper Skårhøj (kasperYYYY@typo3.com)
6 * (c) 2005-2010 Karsten Dambekalns <karsten@typo3.org>
9 * This script is part of the TYPO3 project. The TYPO3 project is
10 * free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * The GNU General Public License can be found at
16 * http://www.gnu.org/copyleft/gpl.html.
17 * A copy is found in the textfile GPL.txt and important notices to the license
18 * from the author is found in LICENSE.txt distributed with these scripts.
21 * This script is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * This copyright notice MUST APPEAR in all copies of the script!
27 ***************************************************************/
29 * Module: Extension manager
31 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
32 * @author Karsten Dambekalns <karsten@typo3.org>
33 * @author Steffen Kamper <info@sk-typo3.de>
36 $GLOBALS['LANG']->includeLLFile(t3lib_extMgm
::extPath('em') . 'language/locallang.xml');
38 // from tx_ter by Robert Lemke
39 define('TX_TER_RESULT_EXTENSIONSUCCESSFULLYUPLOADED', '10504');
41 define('EM_INSTALL_VERSION_MIN', 1);
42 define('EM_INSTALL_VERSION_MAX', 2);
43 define('EM_INSTALL_VERSION_STRICT', 3);
48 $BE_USER->modAccess($MCONF, 1);
52 * Module: Extension manager
54 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
55 * @author Karsten Dambekalns <karsten@typo3.org>
59 class SC_mod_tools_em_index
extends t3lib_SCbase
{
62 var $versionDiffFactor = 1; // This means that version difference testing for import is detected for sub-versions only, not dev-versions. Default: 1000
63 var $systemInstall = 0; // If "1" then installs in the sysext directory is allowed. Default: 0
64 var $requiredExt = ''; // List of required extension (from TYPO3_CONF_VARS)
65 var $maxUploadSize = 31457280; // Max size in bytes of extension upload to repository
66 var $kbMax = 500; // Max size in kilobytes for files to be edited.
67 var $doPrintContent = TRUE; // If set (default), the function printContent() will echo the content which was collected in $this->content. You can set this to FALSE in order to echo content from elsewhere, fx. when using outbut buffering
68 var $listingLimit = 500; // List that many extension maximally at one time (fixing memory problems)
69 var $listingLimitAuthor = 250; // List that many extension maximally at one time (fixing memory problems)
70 var $script = ''; //URL to this script
73 var $categories = array(); // Extension Categories (static var); see init()
75 var $states = array(); // Extension States; see init()
77 var $typeDescr = array();
79 var $detailCols = array(
93 var $privacyNotice; // Set in init()
94 var $securityHint; // Set in init()
95 var $editTextExtensions = 'html,htm,txt,css,tmpl,inc,php,sql,conf,cnf,pl,pm,sh,xml,ChangeLog';
96 var $nameSpaceExceptions = 'beuser_tracking,design_components,impexp,static_file_edit,cms,freesite,quickhelp,classic_welcome,indexed_search,sys_action,sys_workflows,sys_todos,sys_messages,direct_mail,sys_stat,tt_address,tt_board,tt_calender,tt_guest,tt_links,tt_news,tt_poll,tt_rating,tt_products,setup,taskcenter,tsconfig_help,context_help,sys_note,tstemplate,lowlevel,install,belog,beuser,phpmyadmin,aboutmodules,imagelist,setup,taskcenter,sys_notepad,viewpage,adodb';
99 // Default variables for backend modules
100 var $MCONF = array(); // Module configuration
101 var $MOD_MENU = array(); // Module menu items
102 var $MOD_SETTINGS = array(); // Module session settings
104 * Document Template Object
109 var $content; // Accumulated content
111 var $inst_keys = array(); // Storage of installed extensions
112 var $gzcompress = 0; // Is set TRUE, if system support compression.
122 * Instance of TER connection handler
124 * @var tx_em_Connection_Ter
126 public $terConnection;
129 * XML handling class for the TYPO3 Extension Manager
131 * @var tx_em_Tools_XmlHandler
136 * Class for printing extension lists
138 * @var tx_em_Extensions_List
140 public $extensionList;
143 * Class for extension details
145 * @var tx_em_Extensions_Details
147 public $extensionDetails;
150 * Class for new ExtJs Extension Manager
152 * @var tx_em_ExtensionManager
154 public $extensionmanager;
157 * Class for translation handling
159 * @var tx_em_Translations
161 public $translations;
164 * Class for install extensions
173 * @var tx_em_Settings
180 protected $excludeForPackaging;
185 protected $listRemote_search;
190 protected $descrTable;
192 var $JScode; // JavaScript code to be forwarded to $this->doc->JScode
195 var $CMD = array(); // CMD array
196 var $listRemote; // If set, connects to remote repository
197 var $lookUpStr; // Search string when listing local extensions
200 protected $noDocHeader = 0;
202 /*********************************
204 * Standard module initialization
206 *********************************/
209 * Standard init function of a module.
215 * Extension Categories (static var)
216 * Content must be redundant with the same internal variable as in class.tx_extrep.php!
218 $this->categories
= array(
219 'be' => $GLOBALS['LANG']->getLL('category_BE'),
220 'module' => $GLOBALS['LANG']->getLL('category_BE_modules'),
221 'fe' => $GLOBALS['LANG']->getLL('category_FE'),
222 'plugin' => $GLOBALS['LANG']->getLL('category_FE_plugins'),
223 'misc' => $GLOBALS['LANG']->getLL('category_miscellanous'),
224 'services' => $GLOBALS['LANG']->getLL('category_services'),
225 'templates' => $GLOBALS['LANG']->getLL('category_templates'),
226 'example' => $GLOBALS['LANG']->getLL('category_examples'),
227 'doc' => $GLOBALS['LANG']->getLL('category_documentation')
232 * Content must be redundant with the same internal variable as in class.tx_extrep.php!
234 $this->states
= tx_em_Tools
::getStates();
236 $this->script
= 'mod.php?M=tools_em';
237 $this->privacyNotice
= $GLOBALS['LANG']->getLL('privacy_notice');
238 $securityMessage = $GLOBALS['LANG']->getLL('security_warning_extensions') .
239 '<br /><br />' . sprintf($GLOBALS['LANG']->getLL('security_descr'),
240 '<a href="http://typo3.org/teams/security/" target="_blank">', '</a>'
242 /** @var $flashMessage t3lib_FlashMessage */
243 $flashMessage = t3lib_div
::makeInstance(
244 't3lib_FlashMessage',
246 $GLOBALS['LANG']->getLL('security_header'),
247 t3lib_FlashMessage
::INFO
249 $this->securityHint
= $flashMessage->render();
251 $this->excludeForPackaging
= $GLOBALS['TYPO3_CONF_VARS']['EXT']['excludeForPackaging'];
253 // Setting module configuration:
254 $this->MCONF
= $GLOBALS['MCONF'];
257 $this->CMD
= is_array(t3lib_div
::_GP('CMD')) ? t3lib_div
::_GP('CMD') : array();
258 $this->lookUpStr
= trim(t3lib_div
::_GP('lookUp'));
259 $this->listRemote
= t3lib_div
::_GP('ter_connect');
260 $this->listRemote_search
= trim(t3lib_div
::_GP('ter_search'));
261 $this->noDocHeader
= intval(t3lib_div
::_GP('nodoc') > 0);
263 $this->settings
= t3lib_div
::makeInstance('tx_em_Settings');
264 $this->install
= t3lib_div
::makeInstance('tx_em_Install', $this);
266 if (t3lib_div
::_GP('silentMode') ||
$this->noDocHeader
) {
267 $this->CMD
['silentMode'] = 1;
268 $this->noDocHeader
= 1;
271 if ($this->CMD
['silentMode']) {
272 $this->install
->setSilentMode(TRUE);
278 // Setting internal static:
280 $this->requiredExt
= t3lib_div
::trimExplode(',', t3lib_extMgm
::getRequiredExtensionList(), TRUE);
282 // Initialize Document Template object:
283 $this->doc
= t3lib_div
::makeInstance('template');
284 $this->doc
->backPath
= $GLOBALS['BACK_PATH'];
285 $this->doc
->setModuleTemplate('templates/em_index.html');
287 // Initialize helper objects
288 $this->api
= t3lib_div
::makeInstance('tx_em_API');
289 $this->terConnection
= t3lib_div
::makeInstance('tx_em_Connection_Ter', $this);
290 $this->terConnection
->wsdlURL
= $GLOBALS['TYPO3_CONF_VARS']['EXT']['em_wsdlURL'];
293 $this->xmlHandler
= t3lib_div
::makeInstance('tx_em_Tools_XmlHandler');
294 $this->xmlHandler
->useObsolete
= $this->MOD_SETTINGS
['display_obsolete'];
297 // Initialize newListing
298 if (isset($this->MOD_MENU
['function']['extensionmanager'])) {
299 $this->extensionmanager
= t3lib_div
::makeInstance('tx_em_ExtensionManager', $this);
301 $this->extensionmanager
= &$this;
306 $this->extensionList
= t3lib_div
::makeInstance('tx_em_Extensions_List', $this);
307 $this->extensionDetails
= t3lib_div
::makeInstance('tx_em_Extensions_Details', $this);
308 $this->translations
= t3lib_div
::makeInstance('tx_em_Translations', $this);
311 // the id is needed for getting same styles TODO: general table styles
312 $this->doc
->bodyTagId
= 'typo3-mod-tools-em-index-php';
315 $this->doc
->JScode
= $this->doc
->wrapScriptTags('
317 function jumpToUrl(URL) { //
318 window.location.href = URL;
322 // Reload left frame menu
323 if ($this->CMD
['refreshMenu']) {
324 $this->doc
->JScode
.= $this->doc
->wrapScriptTags('
325 if(top.refreshMenu) {
328 top.TYPO3ModuleMenu.refreshMenu();
335 $this->descrTable
= '_MOD_' . $this->MCONF
['name'];
336 if ($GLOBALS['BE_USER']->uc
['edit_showFieldHelp']) {
337 $GLOBALS['LANG']->loadSingleTableDescription($this->descrTable
);
340 // Setting username/password etc. for upload-user:
341 $this->fe_user
['username'] = $this->MOD_SETTINGS
['fe_u'];
342 $this->fe_user
['password'] = $this->MOD_SETTINGS
['fe_p'];
344 $this->handleExternalFunctionValue('singleDetails');
348 * This function is a copy of the same function in t3lib_SCbase with one modification:
349 * In contrast to t3lib_SCbase::handleExternalFunctionValue() this function merges the $this->extClassConf array
350 * instead of overwriting it. That was necessary for including the Kickstarter as a submodule into the 'singleDetails'
351 * selectorbox as well as in the main 'function' selectorbox.
353 * @param string Mod-setting array key
354 * @param string Mod setting value, overriding the one in the key
356 * @see t3lib_SCbase::handleExternalFunctionValue()
358 function handleExternalFunctionValue($MM_key = 'function', $MS_value = NULL) {
359 $MS_value = is_null($MS_value) ?
$this->MOD_SETTINGS
[$MM_key] : $MS_value;
360 $externalItems = $this->getExternalItemConfig($this->MCONF
['name'], $MM_key, $MS_value);
361 if (is_array($externalItems)) {
362 $this->extClassConf
= array_merge($externalItems, is_array($this->extClassConf
) ?
$this->extClassConf
: array());
364 if (is_array($this->extClassConf
) && $this->extClassConf
['path']) {
365 $this->include_once[] = $this->extClassConf
['path'];
370 * Configuration of which mod-menu items can be used
374 function menuConfig() {
376 $this->MOD_MENU
= $this->settings
->MOD_MENU
;
377 $globalSettings = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['em']);
379 if (!is_array($globalSettings)) {
380 // no settings saved yet, set default values
381 $globalSettings['inlineToWindow'] = 1;
382 $globalSettings['displayMyExtensions'] = 0;
386 $this->MOD_MENU
['function']['loaded_list'],
387 $this->MOD_MENU
['function']['installed_list'],
388 $this->MOD_MENU
['function']['import'],
389 $this->MOD_MENU
['function']['translations'],
390 $this->MOD_MENU
['function']['settings'],
391 $this->MOD_MENU
['function']['updates']
393 $this->MOD_MENU
['singleDetails'] = $this->mergeExternalItems($this->MCONF
['name'], 'singleDetails', $this->MOD_MENU
['singleDetails']);
394 $this->MOD_MENU
['extensionInfo'] = $this->mergeExternalItems($this->MCONF
['name'], 'singleDetails', array());
397 // page/be_user TSconfig settings and blinding of menu-items
398 if (!$GLOBALS['BE_USER']->getTSConfigVal('mod.' . $this->MCONF
['name'] . '.allowTVlisting')) {
399 unset($this->MOD_MENU
['display_details'][3]);
400 unset($this->MOD_MENU
['display_details'][4]);
401 unset($this->MOD_MENU
['display_details'][5]);
405 $this->MOD_SETTINGS
= t3lib_BEfunc
::getModuleData($this->MOD_MENU
, t3lib_div
::_GP('SET'), $this->MCONF
['name']);
408 if ($this->MOD_SETTINGS
['function'] == 2) {
409 // If listing from online repository, certain items are removed though:
410 unset($this->MOD_MENU
['listOrder']['type']);
411 unset($this->MOD_MENU
['display_details'][2]);
412 unset($this->MOD_MENU
['display_details'][3]);
413 unset($this->MOD_MENU
['display_details'][4]);
414 unset($this->MOD_MENU
['display_details'][5]);
415 $this->MOD_SETTINGS
= t3lib_BEfunc
::getModuleData($this->MOD_MENU
, t3lib_div
::_GP('SET'), $this->MCONF
['name']);
418 $this->settings
->saveSettings($this->MOD_SETTINGS
);
419 parent
::menuConfig();
421 $this->settings
->saveSettings($this->MOD_SETTINGS
);
425 * Main function for Extension Manager module.
429 public function main() {
433 if (empty($this->MOD_SETTINGS
['mirrorListURL'])) {
434 $this->MOD_SETTINGS
['mirrorListURL'] = $GLOBALS['TYPO3_CONF_VARS']['EXT']['em_mirrorListURL'];
438 $this->content
.= $this->doc
->header($GLOBALS['LANG']->getLL('header'));
440 // Command given which is executed regardless of main menu setting:
441 if ($this->CMD
['showExt']) { // Show details for a single extension
442 $this->showExtDetails($this->CMD
['showExt']);
443 } elseif ($this->CMD
['requestInstallExtensions']) { // Show details for a single extension
444 $this->requestInstallExtensions($this->CMD
['requestInstallExtensions']);
445 } elseif ($this->CMD
['importExt'] ||
$this->CMD
['uploadExt']) { // Imports an extension from online rep.
446 $err = $this->importExtFromRep($this->CMD
['importExt'], $this->CMD
['extVersion'], $this->CMD
['loc'], $this->CMD
['uploadExt']);
448 $this->content
.= $this->doc
->section('', tx_em_Tools
::rfw($err));
450 if (!$err && $this->CMD
['importExt']) {
451 $this->translations
->installTranslationsForExtension($this->CMD
['importExt'], $this->getMirrorURL());
453 } elseif ($this->CMD
['importExtInfo']) { // Gets detailed information of an extension from online rep.
454 $this->importExtInfo($this->CMD
['importExtInfo'], $this->CMD
['extVersion']);
455 } elseif ($this->CMD
['downloadExtFile']) {
456 tx_em_Tools
::sendFile($this->CMD
['downloadExtFile']);
457 } else { // No command - we show what the menu setting tells us:
458 if (t3lib_div
::inList('loaded_list,installed_list,import', $this->MOD_SETTINGS
['function'])) {
459 $menu .= ' ' . $GLOBALS['LANG']->getLL('group_by') . ' ' . t3lib_BEfunc
::getFuncMenu(0, 'SET[listOrder]', $this->MOD_SETTINGS
['listOrder'], $this->MOD_MENU
['listOrder']) .
460 ' ' . $GLOBALS['LANG']->getLL('show') . ' ' . t3lib_BEfunc
::getFuncMenu(0, 'SET[display_details]', $this->MOD_SETTINGS
['display_details'], $this->MOD_MENU
['display_details']) . '<br />';
462 if (t3lib_div
::inList('loaded_list,installed_list,updates', $this->MOD_SETTINGS
['function'])) {
463 $menu .= '<label for="checkDisplayShy">' . $GLOBALS['LANG']->getLL('display_shy') . '</label> ' . t3lib_BEfunc
::getFuncCheck(0, 'SET[display_shy]', $this->MOD_SETTINGS
['display_shy'], '', '', 'id="checkDisplayShy"');
465 if (t3lib_div
::inList('import', $this->MOD_SETTINGS
['function']) && strlen($this->fe_user
['username'])) {
466 $menu .= '<label for="checkDisplayOwn">' . $GLOBALS['LANG']->getLL('only_my_ext') . '</label> ' . t3lib_BEfunc
::getFuncCheck(0, 'SET[display_own]', $this->MOD_SETTINGS
['display_own'], '', '', 'id="checkDisplayOwn"');
468 if (t3lib_div
::inList('loaded_list,installed_list,import', $this->MOD_SETTINGS
['function'])) {
469 $menu .= ' <label for="checkDisplayObsolete">' . $GLOBALS['LANG']->getLL('show_obsolete') . '</label> ' . t3lib_BEfunc
::getFuncCheck(0, 'SET[display_obsolete]', $this->MOD_SETTINGS
['display_obsolete'], '', '', 'id="checkDisplayObsolete"');
472 $this->content
.= $menu ?
$this->doc
->section('', '<form action="' . $this->script
. '" method="post" name="pageform"><span class="nobr">' . $menu . '</span></form>') : '';
475 $view = $this->MOD_SETTINGS
['function'];
476 if (t3lib_div
::_GP('view')) {
477 // temporary overwrite the view with GP var. Used from ExtJS without changing the submodule
478 $view = t3lib_div
::_GP('view');
483 // Lists loaded (installed) extensions
484 $headline = $GLOBALS['LANG']->getLL('loaded_exts');
485 $headline = t3lib_BEfunc
::wrapInHelp('_MOD_tools_em', 'loaded', $headline);
486 $content = $this->extensionList
->extensionList_loaded();
488 $this->content
.= $this->doc
->section($headline, $content, FALSE, TRUE, FALSE, TRUE);
490 case 'installed_list':
491 // Lists the installed (available) extensions
492 $headline = sprintf($GLOBALS['LANG']->getLL('available_extensions'), $this->MOD_MENU
['listOrder'][$this->MOD_SETTINGS
['listOrder']]);
493 $headline = t3lib_BEfunc
::wrapInHelp('_MOD_tools_em', 'avail', $headline);
494 $content = $this->extensionList
->extensionList_installed();
496 $this->content
.= $this->doc
->section($headline, $content, FALSE, TRUE, FALSE, TRUE);
499 // Lists the extensions available from online rep.
500 $this->extensionList_import();
503 // Shows the settings screen
504 $headline = $GLOBALS['LANG']->getLL('repository_settings');
505 $headline = t3lib_BEfunc
::wrapInHelp('_MOD_tools_em', 'settings', $headline);
506 $content = $this->alterSettings();
508 $this->content
.= $this->doc
->section($headline, $content, FALSE, TRUE, FALSE, TRUE);
511 // Allows to set the translation preferences and check the status
512 $this->translations
->translationHandling();
515 // Shows a list of extensions with updates in TER
516 $this->checkForUpdates();
518 case 'extensionmanager':
519 $this->content
.= $this->extensionmanager
->render();
522 $this->extObjContent();
528 $formTags = substr_count($this->content
, '<form') +
substr_count($this->content
, '</form');
529 if ($formTags %
2 > 0) {
530 $this->content
.= '</form>';
533 if (!$this->noDocHeader
) {
534 // Setting up the buttons and markers for docheader
535 $docHeaderButtons = $this->getButtons();
537 'CSH' => $docHeaderButtons['csh'],
538 'FUNC_MENU' => $this->getFuncMenu(),
539 'CONTENT' => $this->content
542 // Build the <body> for the module
543 $this->content
= $this->doc
->moduleBody($this->pageinfo
, $docHeaderButtons, $markers);
545 // Renders the module page
546 $this->content
= $this->doc
->render(
554 * Print module content. Called as last thing in the global scope.
558 function printContent() {
559 if ($this->doPrintContent
) {
565 * Create the function menu
567 * @return string HTML of the function menu
569 public function getFuncMenu() {
571 if (!$this->CMD
['showExt'] && !$this->CMD
['requestInstallExtensions'] && !$this->CMD
['importExt'] && !$this->CMD
['uploadExt'] && !$this->CMD
['importExtInfo']) {
572 $funcMenu = t3lib_BEfunc
::getFuncMenu(0, 'SET[function]', $this->MOD_SETTINGS
['function'], $this->MOD_MENU
['function']);
573 } elseif ($this->CMD
['showExt'] && (!$this->CMD
['standAlone'] && !t3lib_div
::_GP('standAlone'))) {
574 $funcMenu = t3lib_BEfunc
::getFuncMenu(0, 'SET[singleDetails]', $this->MOD_SETTINGS
['singleDetails'], $this->MOD_MENU
['singleDetails'], '', '&CMD[showExt]=' . $this->CMD
['showExt']);
580 * Create the panel of buttons for submitting the form or otherwise perform operations.
582 * @return array all available buttons as an assoc. array
584 public function getButtons() {
585 $uploadButton = '<a href="#" onclick="TYPO3.EM.Tools.uploadExtension(); return false;" title="' . $GLOBALS['LANG']->getLL('upload_ext_directly') . '">' .
586 t3lib_iconWorks
::getSpriteIcon('actions-edit-upload') . '</a>';
592 'upload' => $uploadButton
596 if ($GLOBALS['BE_USER']->mayMakeShortcut()) {
597 $buttons['shortcut'] = $this->doc
->makeShortcutIcon('CMD', 'function', $this->MCONF
['name']);
601 if (($this->CMD
['showExt'] && (!$this->CMD
['standAlone'] && !t3lib_div
::_GP('standAlone'))) ||
($this->CMD
['importExt'] ||
$this->CMD
['uploadExt'] && (!$this->CMD
['standAlone'])) ||
$this->CMD
['importExtInfo']) {
602 $buttons['back'] = '<a href="' . t3lib_div
::linkThisScript(array(
604 )) . '" class="typo3-goBack" title="' . $GLOBALS['LANG']->getLL('go_back') . '">' .
605 t3lib_iconWorks
::getSpriteIcon('actions-view-go-back') .
613 /*********************************
615 * Function Menu Applications
617 *********************************/
621 * Listing remote extensions from online repository
625 function extensionList_import() {
628 // Listing from online repository:
629 if ($this->listRemote
) {
630 list($inst_list,) = $this->extensionList
->getInstalledExtensions();
631 $this->inst_keys
= array_flip(array_keys($inst_list));
633 $this->detailCols
[1] +
= 6;
635 // see if we have an extensionlist at all
636 $this->extensionCount
= $this->xmlHandler
->countExtensions();
637 if (!$this->extensionCount
) {
638 $content .= $this->fetchMetaData('extensions');
641 if ($this->MOD_SETTINGS
['listOrder'] == 'author_company') {
642 $this->listingLimit
= $this->listingLimitAuthor
;
645 $this->pointer
= intval(t3lib_div
::_GP('pointer'));
646 $offset = $this->listingLimit
* $this->pointer
;
648 if ($this->MOD_SETTINGS
['display_own'] && strlen($this->fe_user
['username'])) {
649 $this->xmlHandler
->searchExtensionsXML($this->listRemote_search
, $this->fe_user
['username'], $this->MOD_SETTINGS
['listOrder'], TRUE);
651 $this->xmlHandler
->searchExtensionsXML($this->listRemote_search
, '', $this->MOD_SETTINGS
['listOrder'], TRUE, FALSE, $offset, $this->listingLimit
);
653 if (count($this->xmlHandler
->extensionsXML
)) {
654 list($list, $cat) = $this->extensionList
->prepareImportExtList(TRUE);
656 // Available extensions
657 if (is_array($cat[$this->MOD_SETTINGS
['listOrder']])) {
659 $lines[] = $this->extensionList
->extensionListRowHeader(' class="t3-row-header"', array('<td><img src="clear.gif" width="18" height="1" alt="" /></td>'), 1);
661 foreach ($cat[$this->MOD_SETTINGS
['listOrder']] as $catName => $extEkeys) {
662 if (count($extEkeys)) {
663 $lines[] = '<tr><td colspan="' . (3 +
$this->detailCols
[$this->MOD_SETTINGS
['display_details']]) . '"><br /></td></tr>';
664 $lines[] = '<tr><td colspan="' . (3 +
$this->detailCols
[$this->MOD_SETTINGS
['display_details']]) . '">' . t3lib_iconWorks
::getSpriteIcon('apps-filetree-folder-default') . '<strong>' . htmlspecialchars($this->listOrderTitle($this->MOD_SETTINGS
['listOrder'], $catName)) . '</strong></td></tr>';
665 natcasesort($extEkeys);
666 foreach ($extEkeys as $extKey => $value) {
667 $version = array_keys($list[$extKey]['versions']);
668 $version = end($version);
669 $ext = $list[$extKey]['versions'][$version];
670 $ext['downloadcounter_all'] = $list[$extKey]['downloadcounter'];
671 $ext['_ICON'] = $list[$extKey]['_ICON'];
672 $loadUnloadLink = '';
673 if ($inst_list[$extKey]['type'] != 'S' && (!isset($inst_list[$extKey]) || tx_em_Tools
::versionDifference($version, $inst_list[$extKey]['EM_CONF']['version'], $this->versionDiffFactor
))) {
674 if (isset($inst_list[$extKey])) {
676 if ($inst_list[$extKey]['EM_CONF']['state'] != 'excludeFromUpdates') {
677 $loc = ($inst_list[$extKey]['type'] == 'G' ?
'G' : 'L');
678 $aUrl = t3lib_div
::linkThisScript(array(
679 'CMD[importExt]' => $extKey,
680 'CMD[extVersion]' => $version,
683 $loadUnloadLink .= '<a href="' . htmlspecialchars($aUrl) . '" title="' . sprintf($GLOBALS['LANG']->getLL('do_update'), ($loc == 'G' ?
$GLOBALS['LANG']->getLL('global') : $GLOBALS['LANG']->getLL('local'))) . '">' .
684 t3lib_iconWorks
::getSpriteIcon('actions-system-extension-update') .
687 // extension is marked as "excludeFromUpdates"
688 $loadUnloadLink .= t3lib_iconWorks
::getSpriteIcon('status-dialog-warning', $GLOBALS['LANG']->getLL('excluded_from_updates'));
692 $aUrl = t3lib_div
::linkThisScript(array(
693 'CMD[importExt]' => $extKey,
694 'CMD[extVersion]' => $version,
697 $loadUnloadLink .= '<a href="' . htmlspecialchars($aUrl) . '" title="' . $GLOBALS['LANG']->getLL('import_to_local_dir') . '">' . t3lib_iconWorks
::getSpriteIcon('actions-system-extension-import') . '</a>';
700 $loadUnloadLink = ' ';
703 if (isset($inst_list[$extKey])) {
704 $theRowClass = t3lib_extMgm
::isLoaded($extKey) ?
'em-listbg1' : 'em-listbg2';
706 $theRowClass = 'em-listbg3';
709 $lines[] = $this->extensionList
->extensionListRow(
710 $extKey, $ext, array(
711 '<td class="bgColor">' . $loadUnloadLink . '</td>'
712 ), $theRowClass, $inst_list, 1, t3lib_div
::linkThisScript(array(
713 'CMD[importExtInfo]' => rawurlencode($extKey)
715 unset($list[$extKey]);
722 $headline = $GLOBALS['LANG']->getLL('extensions_repository_group_by') . ' ' .
723 $this->MOD_MENU
['listOrder'][$this->MOD_SETTINGS
['listOrder']];
724 $headline = t3lib_BEfunc
::wrapInHelp('_MOD_tools_em', 'import_ter', $headline);
726 $onsubmit = "window.location.href='" . $this->script
. "&ter_connect=1&ter_search='+escape(this.elements['lookUp'].value);return false;";
727 $content .= '<form action="' . $this->script
. '" method="post" onsubmit="' . htmlspecialchars($onsubmit) .
728 '"><label for="lookUp">' . $GLOBALS['LANG']->getLL('list_or_look_up_extensions') . '</label><br />
729 <input type="text" id="lookUp" name="lookUp" value="' . htmlspecialchars($this->listRemote_search
) .
730 '" /> <input type="submit" value="' . $GLOBALS['LANG']->getLL('look_up_button') . '" /></form><br /><br />';
732 $content .= $this->browseLinks();
736 <!-- TER Extensions list -->
737 <table border="0" cellpadding="2" cellspacing="1">' . implode(LF
, $lines) . '</table>';
738 $content .= '<br />' . $this->browseLinks();
739 $content .= '<br /><br />' . $this->securityHint
;
740 $content .= '<br /><br /><strong>' . $GLOBALS['LANG']->getLL('privacy_notice_header') .
741 '</strong><br /> ' . $this->privacyNotice
;
743 $this->content
.= $this->doc
->section($headline, $content, FALSE, TRUE, FALSE, TRUE);
745 // Plugins which are NOT uploaded to repository but present on this server.
748 if (count($this->inst_keys
)) {
749 foreach ($this->inst_keys
as $extKey => $value) {
750 $this->xmlHandler
->searchExtensionsXMLExact($extKey, '', '', TRUE, TRUE);
751 if ((strlen($this->listRemote_search
) && !stristr($extKey, $this->listRemote_search
)) ||
isset($this->xmlHandler
->extensionsXML
[$extKey])) {
755 $loadUnloadLink = t3lib_extMgm
::isLoaded($extKey) ?
756 '<a href="' . htmlspecialchars(t3lib_div
::linkThisScript(array(
757 'CMD[showExt]' => $extKey,
760 'SET[singleDetails]' => 'info'
761 ))) . '">' . tx_em_Tools
::removeButton() . '</a>' :
762 '<a href="' . htmlspecialchars(t3lib_div
::linkThisScript(array(
763 'CMD[showExt]' => $extKey,
766 'SET[singleDetails]' => 'info'
767 ))) . '">' . tx_em_Tools
::installButton() . '</a>';
768 if (in_array($extKey, $this->requiredExt
)) {
769 $loadUnloadLink = '<strong>' . tx_em_Tools
::rfw($GLOBALS['LANG']->getLL('extension_required_short')) . '</strong>';
771 $lines[] = $this->extensionList
->extensionListRow($extKey, $inst_list[$extKey], array('<td class="bgColor">' . $loadUnloadLink . '</td>'), t3lib_extMgm
::isLoaded($extKey) ?
'em-listbg1' : 'em-listbg2');
775 $content .= $GLOBALS['LANG']->getLL('list_of_local_extensions') .
776 '<br />' . $GLOBALS['LANG']->getLL('might_be_user_defined') . '<br /><br />';
777 $content .= '<table border="0" cellpadding="2" cellspacing="1">' .
778 $this->extensionList
->extensionListRowHeader(' class="t3-row-header"', array('<td><img src="clear.gif" width="18" height="1" alt="" /></td>')) .
779 implode('', $lines) . '</table>';
780 $this->content
.= $this->doc
->spacer(20);
781 $this->content
.= $this->doc
->section($GLOBALS['LANG']->getLL('only_on_this_server'), $content, 0, 1);
786 $headline = $GLOBALS['LANG']->getLL('extensions_repository_group_by') . ' ' .
787 $this->MOD_MENU
['listOrder'][$this->MOD_SETTINGS
['listOrder']];
788 $headline = t3lib_BEfunc
::wrapInHelp('_MOD_tools_em', 'import_ter', $headline);
790 $onsubmit = "window.location.href='" . $this->script
. "&ter_connect=1&ter_search='+escape(this.elements['lookUp'].value);return false;";
791 $content .= '<form action="' . $this->script
. '" method="post" onsubmit="' . htmlspecialchars($onsubmit) .
792 '"><label for="lookUp">' .
793 $GLOBALS['LANG']->getLL('list_or_look_up_extensions') . '</label><br />
794 <input type="text" id="lookUp" name="lookUp" value="' . htmlspecialchars($this->listRemote_search
) .
795 '" /> <input type="submit" value="' . $GLOBALS['LANG']->getLL('look_up_button') . '" /></form><br /><br />';
797 $content .= '<p><strong>' . $GLOBALS['LANG']->getLL('no_matching_extensions') . '</strong></p>';
799 $content .= '<br /><br /><strong>' . $GLOBALS['LANG']->getLL('privacy_notice_header') .
800 '</strong><br /> ' . $this->privacyNotice
;
801 $this->content
.= $this->doc
->section($headline, $content, FALSE, TRUE, 0, TRUE);
804 // section headline and CSH
805 $headline = $GLOBALS['LANG']->getLL('in_repository');
806 $headline = t3lib_BEfunc
::wrapInHelp('_MOD_tools_em', 'import', $headline);
808 $onsubmit = "window.location.href='" . $this->script
. "&ter_connect=1&ter_search='+escape(this.elements['lookUp'].value);return false;";
809 $content .= '<form action="' . $this->script
. '" method="post" onsubmit="' . htmlspecialchars($onsubmit) .
810 '"><label for="lookUp">' .
811 $GLOBALS['LANG']->getLL('list_or_look_up_extensions') . '</label><br />
812 <input type="text" id="lookUp" name="lookUp" value="" /> <input type="submit" value="' .
813 $GLOBALS['LANG']->getLL('look_up_button') . '" /><br /><br />';
815 if ($this->CMD
['fetchMetaData']) { // fetches mirror/extension data from online rep.
816 $content .= $this->fetchMetaData($this->CMD
['fetchMetaData']);
818 $onCLick = 'window.location.href="' . t3lib_div
::linkThisScript(array(
819 'CMD[fetchMetaData]' => 'extensions'
820 )) . '";return false;';
821 $content .= $GLOBALS['LANG']->getLL('connect_to_ter') . '<br />
822 <input type="submit" value="' . $GLOBALS['LANG']->getLL('retrieve_update') .
823 '" onclick="' . htmlspecialchars($onCLick) . '" />';
824 if (is_file(PATH_site
. 'typo3temp/extensions.xml.gz')) {
825 $content .= ' ' . sprintf($GLOBALS['LANG']->getLL('ext_list_last_updated') . ' ',
826 t3lib_BEfunc
::datetime(filemtime(PATH_site
. 'typo3temp/extensions.xml.gz')),
827 tx_em_Database
::getExtensionCountFromRepository()
831 $content .= '</form><br /><br />' . $this->securityHint
;
832 $content .= '<br /><br /><strong>' . $GLOBALS['LANG']->getLL('privacy_notice_header') .
833 '</strong><br />' . $this->privacyNotice
;
835 $this->content
.= $this->doc
->section($headline, $content, FALSE, TRUE, FALSE, TRUE);
839 if ($this->importAtAll()) {
840 $content = '<form action="' . $this->script
. '" enctype="' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['form_enctype'] . '" method="post">
841 <label for="upload_ext_file">' . $GLOBALS['LANG']->getLL('upload_t3x') . '</label><br />
842 <input type="file" size="60" id="upload_ext_file" name="upload_ext_file" /><br />' .
843 $GLOBALS['LANG']->getLL('upload_to_location') . '<br />
844 <select name="CMD[loc]">';
845 if (tx_em_Tools
::importAsType('L')) {
846 $content .= '<option value="L">' . $GLOBALS['LANG']->getLL('local_folder') . '</option>';
848 if (tx_em_Tools
::importAsType('G')) {
849 $content .= '<option value="G">' . $GLOBALS['LANG']->getLL('global_folder') . '</option>';
851 if (tx_em_Tools
::importAsType('S')) {
852 $content .= '<option value="S">' . $GLOBALS['LANG']->getLL('system_folder') . '</option>';
854 $content .= '</select><br />
855 <input type="checkbox" value="1" name="CMD[uploadOverwrite]" id="checkUploadOverwrite" /> <label for="checkUploadOverwrite">' .
856 $GLOBALS['LANG']->getLL('overwrite_ext') . '</label><br />
857 <input type="submit" name="CMD[uploadExt]" value="' . $GLOBALS['LANG']->getLL('upload_ext_file') . '" /></form><br />
860 $content = tx_em_Tools
::noImportMsg();
863 $this->content
.= $this->doc
->spacer(20);
864 $this->content
.= $this->doc
->section($GLOBALS['LANG']->getLL('upload_ext_directly'), $content, 0, 1);
868 * Generates a link to the next page of extensions
872 function browseLinks() {
874 if ($this->pointer
) {
875 $content .= '<a href="' . t3lib_div
::linkThisScript(array('pointer' => $this->pointer
- 1)) .
876 '" class="typo3-prevPage"><img' . t3lib_iconWorks
::skinImg($GLOBALS['BACK_PATH'],
877 'gfx/pilleft_n.gif', 'width="14" height="14"') .
878 ' alt="' . $GLOBALS['LANG']->getLL('previous_page') . '" /> ' .
879 $GLOBALS['LANG']->getLL('previous_page') . '</a>';
882 $content .= ' ';
884 if (intval($this->xmlHandler
->matchingCount
/ $this->listingLimit
) > $this->pointer
) {
885 $content .= '<a href="' . t3lib_div
::linkThisScript(array('pointer' => $this->pointer +
1)) .
886 '" class="typo3-nextPage"><img' . t3lib_iconWorks
::skinImg($GLOBALS['BACK_PATH'],
887 'gfx/pilright_n.gif', 'width="14" height="14"') .
888 ' alt="' . $GLOBALS['LANG']->getLL('next_page') . '" /> ' .
889 $GLOBALS['LANG']->getLL('next_page') . '</a>';
891 $upper = (($this->pointer +
1) * $this->listingLimit
);
892 if ($upper > $this->xmlHandler
->matchingCount
) {
893 $upper = $this->xmlHandler
->matchingCount
;
896 $content .= '<br /><br />' .
897 sprintf($GLOBALS['LANG']->getLL('showing_extensions_from_to'),
898 '<strong>' . ($this->pointer
* $this->listingLimit +
1) . '</strong>',
899 '<strong>' . $upper . '</strong>'
903 $content .= '<br /><br />';
909 * Allows changing of settings
913 function alterSettings() {
915 // Prepare the HTML output:
917 <form action="' . $this->script
. '" method="post" name="altersettings">
918 <fieldset><legend>' . $GLOBALS['LANG']->getLL('user_settings') . '</legend>
919 <table border="0" cellpadding="2" cellspacing="2">
920 <tr class="bgColor4">
921 <td><label for="set_fe_u">' . $GLOBALS['LANG']->getLL('enter_repository_username') . '</label></td>
922 <td><input type="text" id="set_fe_u" name="SET[fe_u]" value="' . htmlspecialchars($this->MOD_SETTINGS
['fe_u']) . '" /></td>
924 <tr class="bgColor4">
925 <td><label for="set_fe_p">' . $GLOBALS['LANG']->getLL('enter_repository_password') . '</label></td>
926 <td><input type="password" id="set_fe_p" name="SET[fe_p]" value="' . htmlspecialchars($this->MOD_SETTINGS
['fe_p']) . '" /></td>
929 <strong>' . $GLOBALS['LANG']->getLL('notice') . '</strong> ' .
930 $GLOBALS['LANG']->getLL('repository_password_info') . '
934 <fieldset><legend>' . $GLOBALS['LANG']->getLL('mirror_selection') . '</legend>
935 <table border="0" cellpadding="2" cellspacing="2">
936 <tr class="bgColor4">
937 <td><label for="set_mirror_list_url">' . $GLOBALS['LANG']->getLL('mirror_list_url') . '</label></td>
938 <td><input type="text" size="50" id="set_mirror_list_url" name="SET[mirrorListURL]" value="' . htmlspecialchars($this->MOD_SETTINGS
['mirrorListURL']) . '" /></td>
943 <p>' . $GLOBALS['LANG']->getLL('mirror_select') . '<br /><br /></p>
944 <fieldset><legend>' . $GLOBALS['LANG']->getLL('mirror_list') . '</legend>';
945 if (!empty($this->MOD_SETTINGS
['mirrorListURL'])) {
946 if ($this->CMD
['fetchMetaData']) { // fetches mirror/extension data from online rep.
947 $content .= $this->fetchMetaData($this->CMD
['fetchMetaData']);
949 $content .= '<a href="' . t3lib_div
::linkThisScript(array(
950 'CMD[fetchMetaData]' => 'mirrors'
951 )) . '">' . $GLOBALS['LANG']->getLL('mirror_list_reload') . '</a>';
955 <table cellspacing="4" style="text-align:left; vertical-alignment:top;">
957 <td>' . $GLOBALS['LANG']->getLL('mirror_use') . '</td>
958 <td>' . $GLOBALS['LANG']->getLL('mirror_name') . '</td>
959 <td>' . $GLOBALS['LANG']->getLL('mirror_url') . '</td>
960 <td>' . $GLOBALS['LANG']->getLL('mirror_country') . '</td>
961 <td>' . $GLOBALS['LANG']->getLL('mirror_sponsored_by') . '</td>
965 if (!strlen($this->MOD_SETTINGS
['extMirrors'])) {
966 $this->fetchMetaData('mirrors');
968 $extMirrors = unserialize($this->MOD_SETTINGS
['extMirrors']);
969 $extMirrors[''] = array('title' => $GLOBALS['LANG']->getLL('mirror_use_random'));
971 if (is_array($extMirrors)) {
972 foreach ($extMirrors as $k => $v) {
973 if (isset($v['sponsor'])) {
974 $sponsor = '<a href="' . htmlspecialchars($v['sponsor']['link']) . '" target="_blank"><img src="' . $v['sponsor']['logo'] . '" title="' . htmlspecialchars($v['sponsor']['name']) . '" alt="' . htmlspecialchars($v['sponsor']['name']) . '" /></a>';
976 $selected = ($this->MOD_SETTINGS
['selectedMirror'] == $k) ?
'checked="checked"' : '';
977 $content .= '<tr class="bgColor4">
978 <td><input type="radio" name="SET[selectedMirror]" id="selectedMirror' . $k . '" value="' . $k . '" ' . $selected . '/></td><td><label for="selectedMirror' . $k . '">' . htmlspecialchars($v['title']) . '</label></td><td>' . htmlspecialchars($v['host'] . $v['path']) . '</td><td>' . $v['country'] . '</td><td>' . $sponsor . '</td></tr>';
986 <table border="0" cellpadding="2" cellspacing="2">
987 <tr class="bgColor4">
988 <td><label for="set_rep_url">' . $GLOBALS['LANG']->getLL('enter_repository_url') . '</label></td>
989 <td><input type="text" size="50" id="set_rep_url" name="SET[rep_url]" value="' . htmlspecialchars($this->MOD_SETTINGS
['rep_url']) . '" /></td>
993 ' . $GLOBALS['LANG']->getLL('repository_url_hint') . '<br />
996 <input type="submit" value="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_tsfe.xml:update') . '" />
1003 /*********************************
1005 * Command Applications (triggered by GET var)
1007 *********************************/
1010 * Returns detailed info about an extension in the online repository
1012 * @param string Extension repository uid + optional "private key": [uid]-[key].
1013 * @param [type] $version: ...
1016 function importExtInfo($extKey, $version = '') {
1018 $content = '<form action="' . $this->script
. '" method="post" name="pageform">';
1020 if ($this->noDocHeader
) {
1021 $content .= '<input type="hidden" name="nodoc" value="1" />';
1022 $addUrl = '&nodoc=1';
1024 // Fetch remote data:
1025 $this->xmlHandler
->searchExtensionsXMLExact($extKey, '', '', TRUE, TRUE);
1026 list($fetchData,) = $this->extensionList
->prepareImportExtList(TRUE);
1028 $versions = array_keys($fetchData[$extKey]['versions']);
1030 $version = ($version == '') ?
end($versions) : $version;
1033 foreach ($versions as $ver) {
1034 $opt[] = '<option value="' . $ver . '"' . (($version == $ver) ?
' selected="selected"' : '') . '>' . $ver . '</option>';
1037 // "Select version" box:
1038 $onClick = 'window.location.href="' . $this->script
. $addUrl . '&CMD[importExtInfo]=' . $extKey . '&CMD[extVersion]="+document.pageform.extVersion.options[document.pageform.extVersion.selectedIndex].value; return false;';
1039 $select = '<select name="extVersion">' . implode('', $opt) .
1040 '</select> <input type="submit" value="' . $GLOBALS['LANG']->getLL('ext_load_details_button') .
1041 '" onclick="' . htmlspecialchars($onClick) . '" />';
1043 if ($this->importAtAll()) {
1044 // Check for write-protected extension
1045 list($inst_list,) = $this->extensionList
->getInstalledExtensions();
1046 if ($inst_list[$extKey]['EM_CONF']['state'] != 'excludeFromUpdates') {
1048 window.location.href="' . $this->script
. $addUrl . '&CMD[importExt]=' . $extKey . '"
1049 +"&CMD[extVersion]="+document.pageform.extVersion.options[document.pageform.extVersion.selectedIndex].value
1050 +"&CMD[loc]="+document.pageform.loc.options[document.pageform.loc.selectedIndex].value;
1052 $select .= ' ' . $GLOBALS['LANG']->getLL('ext_or') . '<br /><br />
1053 <input type="submit" value="' . $GLOBALS['LANG']->getLL('ext_import_update_button') .
1054 '" onclick="' . htmlspecialchars($onClick) . '" /> ' . $GLOBALS['LANG']->getLL('ext_import_update_to') . '
1055 <select name="loc">' .
1056 (tx_em_Tools
::importAsType('G', $fetchData['emconf_lockType']) ?
1057 '<option value="G">' . $GLOBALS['LANG']->getLL('ext_import_global') . ' ' . tx_em_Tools
::typePath('G') . $extKey . '/' .
1058 (@is_dir
(tx_em_Tools
::typePath('G') . $extKey) ?
1059 ' ' . $GLOBALS['LANG']->getLL('ext_import_overwrite') :
1060 ' ' . $GLOBALS['LANG']->getLL('ext_import_folder_empty')
1061 ) . '</option>' : ''
1063 (tx_em_Tools
::importAsType('L', $fetchData['emconf_lockType']) ?
1064 '<option value="L">' . $GLOBALS['LANG']->getLL('ext_import_local') . ' ' . tx_em_Tools
::typePath('L') . $extKey . '/' .
1065 (@is_dir
(tx_em_Tools
::typePath('L') . $extKey) ?
1066 ' ' . $GLOBALS['LANG']->getLL('ext_import_overwrite') :
1067 ' ' . $GLOBALS['LANG']->getLL('ext_import_folder_empty')
1068 ) . '</option>' : ''
1070 (tx_em_Tools
::importAsType('S', $fetchData['emconf_lockType']) ?
1071 '<option value="S">' . $GLOBALS['LANG']->getLL('ext_import_system') . ' ' . tx_em_Tools
::typePath('S') . $extKey . '/' .
1072 (@is_dir
(tx_em_Tools
::typePath('S') . $extKey) ?
1073 ' ' . $GLOBALS['LANG']->getLL('ext_import_overwrite') :
1074 ' ' . $GLOBALS['LANG']->getLL('ext_import_folder_empty')
1075 ) . '</option>' : ''
1080 $select .= '<br /><br />' . $GLOBALS['LANG']->getLL('ext_import_excluded_from_updates');
1083 $select .= '<br /><br />' . tx_em_Tools
::noImportMsg();
1085 $content .= $select;
1086 $this->content
.= $this->doc
->section($GLOBALS['LANG']->getLL('ext_import_select_command'), $content, 0, 1);
1089 $eInfo = $fetchData[$extKey]['versions'][$version];
1090 $content = '<strong>' . $fetchData[$extKey]['_ICON'] . ' ' . $eInfo['EM_CONF']['title'] . ' (' . $extKey . ', ' . $version . ')</strong><br /><br />';
1091 $content .= $this->extensionDetails
->extInformationarray($extKey, $eInfo, 1);
1092 $this->content
.= $this->doc
->spacer(10);
1093 $this->content
.= $this->doc
->section($GLOBALS['LANG']->getLL('ext_import_remote_ext_details'), $content, 0, 1);
1097 * Fetches metadata and stores it to the corresponding place. This includes the mirror list,
1098 * extension XML files.
1100 * @param string Type of data to fetch: (mirrors)
1101 * @param boolean If TRUE the method doesn't produce any output
1104 function fetchMetaData($metaType) {
1106 switch ($metaType) {
1108 $mfile = t3lib_div
::tempnam('mirrors');
1109 $mirrorsFile = t3lib_div
::getUrl($this->MOD_SETTINGS
['mirrorListURL'], 0, array(TYPO3_user_agent
));
1110 if ($mirrorsFile===FALSE) {
1111 t3lib_div
::unlink_tempfile($mfile);
1113 sprintf($GLOBALS['LANG']->getLL('ext_import_list_not_updated'),
1114 $this->MOD_SETTINGS
['mirrorListURL']
1116 $GLOBALS['LANG']->getLL('translation_problems') . '</p>';
1118 t3lib_div
::writeFile($mfile, $mirrorsFile);
1119 $mirrors = implode('', gzfile($mfile));
1120 t3lib_div
::unlink_tempfile($mfile);
1122 $mirrors = $this->xmlHandler
->parseMirrorsXML($mirrors);
1123 if (is_array($mirrors) && count($mirrors)) {
1124 t3lib_BEfunc
::getModuleData($this->MOD_MENU
, array('extMirrors' => serialize($mirrors)), $this->MCONF
['name'], '', 'extMirrors');
1125 $this->MOD_SETTINGS
['extMirrors'] = serialize($mirrors);
1127 sprintf($GLOBALS['LANG']->getLL('ext_import_list_updated'),
1132 $content = '<p>' . $mirrors . '<br />' . $GLOBALS['LANG']->getLL('ext_import_list_empty') . '</p>';
1137 $this->fetchMetaData('mirrors'); // if we fetch the extensions anyway, we can as well keep this up-to-date
1139 $mirror = $this->getMirrorURL();
1140 $extfile = $mirror . 'extensions.xml.gz';
1141 $extmd5 = t3lib_div
::getUrl($mirror . 'extensions.md5', 0, array(TYPO3_user_agent
));
1143 if (is_file(PATH_site
. 'typo3temp/extensions.xml.gz')) {
1144 $localmd5 = md5_file(PATH_site
. 'typo3temp/extensions.xml.gz');
1147 // count cached extensions. If cache is empty re-fill it
1148 $cacheCount = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('extkey', 'cache_extensions');
1150 if ($extmd5 === FALSE) {
1152 sprintf($GLOBALS['LANG']->getLL('ext_import_md5_not_updated'),
1153 $mirror . 'extensions.md5'
1155 $GLOBALS['LANG']->getLL('translation_problems') . '</p>';
1156 } elseif ($extmd5 == $localmd5 && $cacheCount) {
1157 /** @var $flashMessage t3lib_FlashMessage */
1158 $flashMessage = t3lib_div
::makeInstance(
1159 't3lib_FlashMessage',
1160 $GLOBALS['LANG']->getLL('ext_import_list_unchanged'),
1161 $GLOBALS['LANG']->getLL('ext_import_list_unchanged_header'),
1162 t3lib_FlashMessage
::INFO
1164 $content .= $flashMessage->render();
1166 $extXML = t3lib_div
::getUrl($extfile, 0, array(TYPO3_user_agent
));
1167 if ($extXML === FALSE) {
1169 sprintf($GLOBALS['LANG']->getLL('ext_import_list_unchanged'),
1172 $GLOBALS['LANG']->getLL('translation_problems') . '</p>';
1174 t3lib_div
::writeFile(PATH_site
. 'typo3temp/extensions.xml.gz', $extXML);
1175 $content .= $this->xmlHandler
->parseExtensionsXML(PATH_site
. 'typo3temp/extensions.xml.gz');
1185 * Returns the base URL for the selected or a random mirror.
1187 * @return string The URL for the selected or a random mirror
1189 function getMirrorURL() {
1190 if (strlen($this->MOD_SETTINGS
['rep_url'])) {
1191 return $this->MOD_SETTINGS
['rep_url'];
1194 $mirrors = unserialize($this->MOD_SETTINGS
['extMirrors']);
1195 if (!is_array($mirrors)) {
1196 $this->fetchMetaData('mirrors');
1197 $mirrors = unserialize($this->MOD_SETTINGS
['extMirrors']);
1198 if (!is_array($mirrors)) {
1202 if ($this->MOD_SETTINGS
['selectedMirror'] == '') {
1203 $rand = array_rand($mirrors);
1204 $url = 'http://' . $mirrors[$rand]['host'] . $mirrors[$rand]['path'];
1207 $selectedMirror = NULL;
1208 foreach ($mirrors as $mirror) {
1209 if ($mirror['host'] === $this->MOD_SETTINGS
['selectedMirror']) {
1210 $selectedMirror = $mirror;
1214 $url = 'http://' . $selectedMirror['host'] . $selectedMirror['path'];
1222 * Installs (activates) an extension
1224 * For $mode use the three constants EM_INSTALL_VERSION_MIN, EM_INSTALL_VERSION_MAX, EM_INSTALL_VERSION_STRICT
1226 * If an extension is loaded or imported already and the version requirement is matched, it will not be
1227 * fetched from the repository. This means, if you use EM_INSTALL_VERSION_MIN, you will not always get the latest
1228 * version of an extension!
1230 * @param string $extKey The extension key to install
1231 * @param string $version A version number that should be installed
1232 * @param int $mode If a version is requested, this determines if it is the min, max or strict version requested
1233 * @return [type] ...
1234 * @todo Make the method able to handle needed interaction somehow (unmatched dependencies)
1236 function installExtension($extKey, $version = NULL, $mode = EM_INSTALL_VERSION_MIN
) {
1237 list($inst_list,) = $this->extensionList
->getInstalledExtensions();
1239 // check if it is already installed and loaded with sufficient version
1240 if (isset($inst_list[$extKey])) {
1241 $currentVersion = $inst_list[$extKey]['EM_CONF']['version'];
1243 if (t3lib_extMgm
::isLoaded($extKey)) {
1244 if ($version===NULL) {
1245 return array(TRUE, $GLOBALS['LANG']->getLL('ext_import_ext_already_installed_loaded'));
1248 case EM_INSTALL_VERSION_STRICT
:
1249 if ($currentVersion == $version) {
1250 return array(TRUE, $GLOBALS['LANG']->getLL('ext_import_ext_already_installed_loaded'));
1253 case EM_INSTALL_VERSION_MIN
:
1254 if (version_compare($currentVersion, $version, '>=')) {
1255 return array(TRUE, $GLOBALS['LANG']->getLL('ext_import_ext_already_installed_loaded'));
1258 case EM_INSTALL_VERSION_MAX
:
1259 if (version_compare($currentVersion, $version, '<=')) {
1260 return array(TRUE, $GLOBALS['LANG']->getLL('ext_import_ext_already_installed_loaded'));
1266 if (!t3lib_extMgm
::isLocalconfWritable()) {
1267 return array(FALSE, $GLOBALS['LANG']->getLL('ext_import_p_localconf'));
1271 case EM_INSTALL_VERSION_STRICT
:
1272 if ($currentVersion == $version) {
1273 $newExtList = $this->extensionList
->addExtToList($extKey, $inst_list);
1276 case EM_INSTALL_VERSION_MIN
:
1277 if (version_compare($currentVersion, $version, '>=')) {
1278 $newExtList = $this->extensionList
->addExtToList($extKey, $inst_list);
1281 case EM_INSTALL_VERSION_MAX
:
1282 if (version_compare($currentVersion, $version, '<=')) {
1283 $newExtList = $this->extensionList
->addExtToList($extKey, $inst_list);
1287 if ($newExtList != -1) {
1288 $this->install
->writeNewExtensionList($newExtList);
1289 tx_em_Tools
::refreshGlobalExtList();
1290 $this->install
->forceDBupdates($extKey, $inst_list[$extKey]);
1291 return array(TRUE, $GLOBALS['LANG']->getLL('ext_import_ext_loaded'));
1296 // at this point we know we need to import (a matching version of) the extension from TER2
1298 // see if we have an extension list at all
1299 if (!$this->xmlHandler
->countExtensions()) {
1300 $this->fetchMetaData('extensions');
1302 $this->xmlHandler
->searchExtensionsXMLExact($extKey, '', '', TRUE);
1304 // check if extension can be fetched
1305 if (isset($this->xmlHandler
->extensionsXML
[$extKey])) {
1306 $versions = array_keys($this->xmlHandler
->extensionsXML
[$extKey]['versions']);
1307 $latestVersion = end($versions);
1309 case EM_INSTALL_VERSION_STRICT
:
1310 if (!isset($this->xmlHandler
->extensionsXML
[$extKey]['versions'][$version])) {
1311 return array(FALSE, $GLOBALS['LANG']->getLL('ext_import_ext_n_a'));
1314 case EM_INSTALL_VERSION_MIN
:
1315 if (version_compare($latestVersion, $version, '>=')) {
1316 $version = $latestVersion;
1318 return array(FALSE, $GLOBALS['LANG']->getLL('ext_import_ext_n_a'));
1321 case EM_INSTALL_VERSION_MAX
:
1322 while (($v = array_pop($versions)) && version_compare($v, $version, '>=')) {
1323 // Loop until a version is found
1326 if ($v !== NULL && version_compare($v, $version, '<=')) {
1329 return array(FALSE, $GLOBALS['LANG']->getLL('ext_import_ext_n_a'));
1333 $this->importExtFromRep($extKey, $version, 'L');
1334 $newExtList = $this->extensionList
->addExtToList($extKey, $inst_list);
1335 if ($newExtList != -1) {
1336 $this->install
->writeNewExtensionList($newExtList);
1337 tx_em_Tools
::refreshGlobalExtList();
1338 $this->install
->forceDBupdates($extKey, $inst_list[$extKey]);
1339 $this->translations
->installTranslationsForExtension($extKey, $this->getMirrorURL());
1340 return array(TRUE, $GLOBALS['LANG']->getLL('ext_import_ext_imported'));
1342 return array(FALSE, $GLOBALS['LANG']->getLL('ext_import_ext_not_loaded'));
1345 return array(FALSE, $GLOBALS['LANG']->getLL('ext_import_ext_n_a_rep'));
1351 * Imports an extensions from the online repository
1352 * NOTICE: in version 4.0 this changed from "importExtFromRep_old($extRepUid,$loc,$uploadFlag=0,$directInput='',$recentTranslations=0,$incManual=0,$dontDelete=0)"
1354 * @param string Extension key
1355 * @param string Version
1356 * @param string Install scope: "L" or "G" or "S"
1357 * @param boolean If TRUE, extension is uploaded as file
1358 * @param boolean If TRUE, extension directory+files will not be deleted before writing the new ones. That way custom files stored in the extension folder will be kept.
1359 * @param array Direct input array (like from kickstarter)
1360 * @return string Return FALSE on success, returns error message if error.
1362 function importExtFromRep($extKey, $version, $loc, $uploadFlag = 0, $dontDelete = 0, $directInput = '') {
1364 $uploadSucceed = FALSE;
1365 $uploadedTempFile = '';
1366 if (is_array($directInput)) {
1367 $fetchData = array($directInput, '');
1368 $loc = ($loc==='G' ||
$loc==='S') ?
$loc : 'L';
1369 } elseif ($uploadFlag) {
1370 if (($uploadedTempFile = $this->CMD
['alreadyUploaded']) ||
$_FILES['upload_ext_file']['tmp_name']) {
1372 // Read uploaded file:
1373 if (!$uploadedTempFile) {
1374 if (!is_uploaded_file($_FILES['upload_ext_file']['tmp_name'])) {
1375 t3lib_div
::sysLog('Possible file upload attack: ' . $_FILES['upload_ext_file']['tmp_name'], 'Extension Manager', 3);
1377 /** @var $flashMessage t3lib_FlashMessage */
1378 $flashMessage = t3lib_div
::makeInstance(
1379 't3lib_FlashMessage',
1380 $GLOBALS['LANG']->getLL('ext_import_file_not_uploaded'),
1382 t3lib_FlashMessage
::ERROR
1384 return $flashMessage->render();
1387 $uploadedTempFile = t3lib_div
::upload_to_tempfile($_FILES['upload_ext_file']['tmp_name']);
1389 $fileContent = t3lib_div
::getUrl($uploadedTempFile);
1391 if (!$fileContent) {
1392 $flashMessage = t3lib_div
::makeInstance(
1393 't3lib_FlashMessage',
1394 $GLOBALS['LANG']->getLL('ext_import_file_empty'),
1396 t3lib_FlashMessage
::ERROR
1398 return $flashMessage->render();
1401 // Decode file data:
1402 $fetchData = $this->terConnection
->decodeExchangeData($fileContent);
1404 if (is_array($fetchData)) {
1405 $extKey = $fetchData[0]['extKey'];
1407 if (!$this->CMD
['uploadOverwrite']) {
1408 $loc = ($loc==='G' ||
$loc==='S') ?
$loc : 'L';
1409 $comingExtPath = tx_em_Tools
::typePath($loc) . $extKey . '/';
1410 if (@is_dir
($comingExtPath)) {
1411 $flashMessage = t3lib_div
::makeInstance(
1412 't3lib_FlashMessage',
1413 sprintf($GLOBALS['LANG']->getLL('ext_import_ext_present_no_overwrite'), $comingExtPath) .
1414 '<br />' . $GLOBALS['LANG']->getLL('ext_import_ext_present_nothing_done'),
1416 t3lib_FlashMessage
::ERROR
1418 return $flashMessage->render();
1419 } // ... else go on, install...
1420 } // ... else go on, install...
1422 $flashMessage = t3lib_div
::makeInstance(
1423 't3lib_FlashMessage',
1424 $GLOBALS['LANG']->getLL('ext_import_no_key'),
1426 t3lib_FlashMessage
::ERROR
1428 return $flashMessage->render();
1431 $flashMessage = t3lib_div
::makeInstance(
1432 't3lib_FlashMessage',
1433 sprintf($GLOBALS['LANG']->getLL('ext_import_wrong_file_format'), $fetchData),
1435 t3lib_FlashMessage
::ERROR
1437 return $flashMessage->render();
1440 $flashMessage = t3lib_div
::makeInstance(
1441 't3lib_FlashMessage',
1442 $GLOBALS['LANG']->getLL('ext_import_no_file'),
1444 t3lib_FlashMessage
::ERROR
1446 return $flashMessage->render();
1449 $this->xmlHandler
->searchExtensionsXMLExact($extKey, '', '', TRUE, TRUE);
1451 // Fetch extension from TER:
1452 if (!strlen($version)) {
1453 $versions = array_keys($this->xmlHandler
->extensionsXML
[$extKey]['versions']);
1454 // sort version numbers ascending to pick the highest version
1456 $version = end($versions);
1458 $fetchData = $this->terConnection
->fetchExtension($extKey, $version, $this->xmlHandler
->extensionsXML
[$extKey]['versions'][$version]['t3xfilemd5'], $this->getMirrorURL());
1461 // At this point the extension data should be present; so we want to write it to disc:
1462 $content = $this->install
->installExtension($fetchData, $loc, $version, $uploadedTempFile, $dontDelete);
1464 $this->content
.= $this->doc
->section($GLOBALS['LANG']->getLL('ext_import_results'), $content, 0, 1);
1466 if ($uploadSucceed && $uploadedTempFile) {
1467 t3lib_div
::unlink_tempfile($uploadedTempFile);
1474 * Display extensions details.
1476 * @param string Extension key
1477 * @return void Writes content to $this->content
1479 function showExtDetails($extKey) {
1481 $dependencyUpdates = '';
1482 list($list,) = $this->extensionList
->getInstalledExtensions();
1483 $absPath = tx_em_Tools
::getExtPath($extKey, $list[$extKey]['type']);
1485 // Check updateModule:
1486 if (isset($list[$extKey]) && @is_file
($absPath . 'class.ext_update.php')) {
1487 require_once($absPath . 'class.ext_update.php');
1488 $updateObj = new ext_update
;
1489 if (!$updateObj->access()) {
1490 unset($this->MOD_MENU
['singleDetails']['updateModule']);
1493 unset($this->MOD_MENU
['singleDetails']['updateModule']);
1496 if ($this->CMD
['doDelete']) {
1497 $this->MOD_MENU
['singleDetails'] = array();
1500 // Function menu here:
1501 if (!$this->CMD
['standAlone'] && !t3lib_div
::_GP('standAlone')) {
1502 $content = $GLOBALS['LANG']->getLL('ext_details_ext') . ' <strong>' .
1503 $this->extensionTitleIconHeader($extKey, $list[$extKey]) . '</strong> (' . htmlspecialchars($extKey) . ')';
1504 $this->content
.= $this->doc
->section('', $content);
1507 // Show extension details:
1508 if ($list[$extKey]) {
1510 // Checking if a command for install/uninstall is executed:
1511 if (($this->CMD
['remove'] ||
$this->CMD
['load']) && !in_array($extKey, $this->requiredExt
)) {
1513 // Install / Uninstall extension here:
1514 if (t3lib_extMgm
::isLocalconfWritable()) {
1515 // Check dependencies:
1516 $depStatus = $this->install
->checkDependencies($extKey, $list[$extKey]['EM_CONF'], $list);
1518 if (!$this->CMD
['remove'] && !$depStatus['returnCode']) {
1519 $this->content
.= $depStatus['html'];
1521 } elseif ($this->CMD
['remove']) {
1522 $newExtList = $this->extensionList
->removeExtFromList($extKey, $list);
1524 $newExtList = $this->extensionList
->addExtToList($extKey, $list);
1527 // Successful installation:
1528 if ($newExtList != -1) {
1530 if ($this->CMD
['load']) {
1531 if ($_SERVER['REQUEST_METHOD'] == 'POST') {
1532 $script = t3lib_div
::linkThisScript(array(
1533 'CMD[showExt]' => $extKey,
1535 'CMD[clrCmd]' => $this->CMD
['clrCmd'],
1536 'SET[singleDetails]' => 'info'
1541 $standaloneUpdates = '';
1542 if ($this->CMD
['standAlone']) {
1543 $standaloneUpdates .= '<input type="hidden" name="standAlone" value="1" />';
1545 if ($this->CMD
['silendMode']) {
1546 $standaloneUpdates .= '<input type="hidden" name="silendMode" value="1" />';
1548 $depsolver = t3lib_div
::_POST('depsolver');
1549 if (is_array($depsolver['ignore'])) {
1550 foreach ($depsolver['ignore'] as $depK => $depV) {
1551 $dependencyUpdates .= '<input type="hidden" name="depsolver[ignore][' . $depK . ']" value="1" />';
1554 $updatesForm = $this->install
->updatesForm(
1559 $dependencyUpdates . $standaloneUpdates . '<input type="hidden" name="_do_install" value="1" /><input type="hidden" name="_clrCmd" value="' . $this->CMD
['clrCmd'] . '" />',
1563 $updates = $GLOBALS['LANG']->getLL('ext_details_new_tables_fields') . '<br />' .
1564 $GLOBALS['LANG']->getLL('ext_details_new_tables_fields_select') . $updatesForm;
1565 $labelDBUpdate = $GLOBALS['LANG']->csConvObj
->conv_case(
1566 $GLOBALS['LANG']->charSet
,
1567 $GLOBALS['LANG']->getLL('ext_details_db_needs_update'),
1570 $this->content
.= $this->doc
->section(
1571 sprintf($GLOBALS['LANG']->getLL('ext_details_installing') . ' ',
1572 $this->extensionTitleIconHeader($extKey, $list[$extKey])
1575 $updates, 1, 1, 1, 1
1578 } elseif ($this->CMD
['remove']) {
1579 $updates .= $this->install
->checkClearCache($list[$extKey]);
1582 <form action="' . $this->script
. '" method="post">' . $updates . '
1583 <br /><input type="submit" name="write" value="' .
1584 $GLOBALS['LANG']->getLL('ext_details_remove_ext') . '" />
1585 <input type="hidden" name="_do_install" value="1" />
1586 <input type="hidden" name="_clrCmd" value="' . $this->CMD
['clrCmd'] . '" />
1587 <input type="hidden" name="CMD[showExt]" value="' . $this->CMD
['showExt'] . '" />
1588 <input type="hidden" name="CMD[remove]" value="' . $this->CMD
['remove'] . '" />
1589 <input type="hidden" name="standAlone" value="' . $this->CMD
['standAlone'] . '" />
1590 <input type="hidden" name="silentMode" value="' . $this->CMD
['silentMode'] . '" />
1591 ' . ($this->noDocHeader ?
'<input type="hidden" name="nodoc" value="1" />' : '') . '
1593 $labelDBUpdate = $GLOBALS['LANG']->csConvObj
->conv_case(
1594 $GLOBALS['LANG']->charSet
,
1595 $GLOBALS['LANG']->getLL('ext_details_db_needs_update'),
1598 $this->content
.= $this->doc
->section(
1599 sprintf($GLOBALS['LANG']->getLL('ext_details_removing') . ' ',
1600 $this->extensionTitleIconHeader($extKey, $list[$extKey])
1603 $updates, 1, 1, 1, 1
1607 if (!$updates || t3lib_div
::_GP('_do_install') ||
($this->noDocHeader
&& $this->CMD
['remove'])) {
1608 $this->install
->writeNewExtensionList($newExtList);
1609 $action = $this->CMD
['load'] ?
'installed' : 'removed';
1610 $GLOBALS['BE_USER']->writelog(5, 1, 0, 0, 'Extension list has been changed, extension %s has been %s', array($extKey, $action));
1612 if (!t3lib_div
::_GP('silentMode') && !$this->CMD
['standAlone']) {
1613 $messageLabel = 'ext_details_ext_' . $action . '_with_key';
1614 $flashMessage = t3lib_div
::makeInstance(
1615 't3lib_FlashMessage',
1616 sprintf($GLOBALS['LANG']->getLL($messageLabel), $extKey),
1618 t3lib_FlashMessage
::OK
,
1621 t3lib_FlashMessageQueue
::addMessage($flashMessage);
1623 $techInfo = $this->install
->makeDetailedExtensionAnalysis($extKey, $list[$extKey]);
1624 if ($this->CMD
['clrCmd'] || t3lib_div
::_GP('_clrCmd')) {
1625 if ($this->CMD
['load'] && @is_file
($absPath . 'ext_conf_template.txt')) {
1626 $vA = array('CMD' => array('showExt' => $extKey));
1627 } elseif ($this->CMD
['load'] && $techInfo['hasCacheConfiguration']) {
1628 $vA = array('CMD' => array('showExt' => $extKey));
1630 $vA = array('CMD' => '');
1633 $vA = array('CMD' => array('showExt' => $extKey));
1636 if ($this->CMD
['standAlone'] || t3lib_div
::_GP('standAlone')) {
1637 $this->content
.= sprintf($GLOBALS['LANG']->getLL('ext_details_ext_installed_removed'),
1638 ($this->CMD
['load'] ?
1639 $GLOBALS['LANG']->getLL('ext_details_installed') :
1640 $GLOBALS['LANG']->getLL('ext_details_removed')
1643 '<br /><br />' . $this->getSubmitAndOpenerCloseLink();
1645 // Determine if new modules were installed:
1646 if (($this->CMD
['load'] ||
$this->CMD
['remove']) && is_array($techInfo['flags']) && in_array('Module', $techInfo['flags'], TRUE)) {
1647 $vA['CMD']['refreshMenu'] = 1;
1649 t3lib_utility_Http
::redirect(t3lib_div
::linkThisScript($vA));
1655 $writeAccessError = $GLOBALS['LANG']->csConvObj
->conv_case(
1656 $GLOBALS['LANG']->charSet
,
1657 $GLOBALS['LANG']->getLL('ext_details_write_access_error'),
1660 $this->content
.= $this->doc
->section(
1661 sprintf($GLOBALS['LANG']->getLL('ext_details_installing') . ' ',
1662 $this->extensionTitleIconHeader($extKey, $list[$extKey])
1665 $GLOBALS['LANG']->getLL('ext_details_write_error_localconf'),
1670 } elseif ($this->CMD
['downloadFile'] && !in_array($extKey, $this->requiredExt
)) {
1672 // Link for downloading extension has been clicked - deliver content stream:
1673 $dlFile = urldecode($this->CMD
['downloadFile']);
1674 if (t3lib_div
::isAllowedAbsPath($dlFile) && t3lib_div
::isFirstPartOfStr($dlFile, PATH_site
) && t3lib_div
::isFirstPartOfStr($dlFile, $absPath) && @is_file
($dlFile)) {
1675 $mimeType = 'application/octet-stream';
1676 Header('Content-Type: ' . $mimeType);
1677 Header('Content-Disposition: attachment; filename=' . basename($dlFile));
1678 echo t3lib_div
::getUrl($dlFile);
1681 throw new RuntimeException(
1682 'TYPO3 Fatal Error: ' . $GLOBALS['LANG']->getLL('ext_details_error_downloading'),
1687 } elseif ($this->CMD
['editFile'] && !in_array($extKey, $this->requiredExt
)) {
1689 // Editing extension file:
1690 $editFile = rawurldecode($this->CMD
['editFile']);
1691 if (t3lib_div
::isAllowedAbsPath($editFile) && t3lib_div
::isFirstPartOfStr($editFile, $absPath)) {
1693 $fI = t3lib_div
::split_fileref($editFile);
1694 if (@is_file
($editFile) && t3lib_div
::inList($this->editTextExtensions
, ($fI['fileext'] ?
$fI['fileext'] : $fI['filebody']))) {
1695 if (filesize($editFile) < ($this->kbMax
* 1024)) {
1696 $outCode = '<form action="' . $this->script
. '" method="post" name="editfileform">';
1698 $submittedContent = t3lib_div
::_POST('edit');
1701 if (isset($submittedContent['file']) && !$GLOBALS['TYPO3_CONF_VARS']['EXT']['noEdit']) { // Check referer here?
1702 $oldFileContent = t3lib_div
::getUrl($editFile);
1703 if ($oldFileContent != $submittedContent['file']) {
1704 $oldMD5 = md5(str_replace(CR
, '', $oldFileContent));
1706 $GLOBALS['LANG']->getLL('ext_details_md5_previous'),
1707 '<strong>' . $oldMD5 . '</strong>'
1709 t3lib_div
::writeFile($editFile, $submittedContent['file']);
1712 $info .= $GLOBALS['LANG']->getLL('ext_details_no_changes') . '<br />';
1716 $fileContent = t3lib_div
::getUrl($editFile);
1718 $outCode .= sprintf(
1719 $GLOBALS['LANG']->getLL('ext_details_file'),
1720 '<strong>' . substr($editFile, strlen($absPath)) . '</strong> (' .
1721 t3lib_div
::formatSize(filesize($editFile)) . ')<br />'
1723 $fileMD5 = md5(str_replace(CR
, '', $fileContent));
1725 $GLOBALS['LANG']->getLL('ext_details_md5_current'),
1726 '<strong>' . $fileMD5 . '</strong>'
1729 $saveMD5 = md5(str_replace(CR
, '', $submittedContent['file']));
1731 $GLOBALS['LANG']->getLL('ext_details_md5_submitted'),
1732 '<strong>' . $saveMD5 . '</strong>'
1734 if ($fileMD5 != $saveMD5) {
1735 $info .= tx_em_Tools
::rfw(
1736 '<br /><strong>' . $GLOBALS['LANG']->getLL('ext_details_saving_failed_changes_lost') . '</strong>'
1740 $info .= tx_em_Tools
::rfw(
1741 '<br /><strong>' . $GLOBALS['LANG']->getLL('ext_details_file_saved') . '</strong>'
1746 $outCode .= '<textarea name="edit[file]" rows="35" wrap="off"' . $this->doc
->formWidthText(48, 'width:98%;height:70%', 'off') . ' class="fixed-font enable-tab">' . t3lib_div
::formatForTextarea($fileContent) . '</textarea>';
1747 $outCode .= '<input type="hidden" name="edit[filename]" value="' . $editFile . '" />';
1748 $outCode .= '<input type="hidden" name="CMD[editFile]" value="' . htmlspecialchars($editFile) . '" />';
1749 $outCode .= '<input type="hidden" name="CMD[showExt]" value="' . $extKey . '" />';
1752 if (!$GLOBALS['TYPO3_CONF_VARS']['EXT']['noEdit']) {
1753 $outCode .= '<br /><input type="submit" name="save_file" value="' .
1754 $GLOBALS['LANG']->getLL('ext_details_file_save_button') . '" />';
1757 $outCode .= tx_em_Tools
::rfw(
1758 '<br />' . $GLOBALS['LANG']->getLL('ext_details_saving_disabled') . ' '
1762 $onClick = 'window.location.href="' . t3lib_div
::linkThisScript(array(
1763 'CMD[showExt]' => $extKey
1764 )) . '";return false;';
1765 $outCode .= '<input type="submit" name="cancel" value="' .
1766 $GLOBALS['LANG']->getLL('ext_details_cancel_button') . '" onclick="' .
1767 htmlspecialchars($onClick) . '" /></form>';
1769 $theOutput .= $this->doc
->spacer(15);
1770 $theOutput .= $this->doc
->section($GLOBALS['LANG']->getLL('ext_details_edit_file'), '', 0, 1);
1771 $theOutput .= $this->doc
->sectionEnd() . $outCode;
1772 $this->content
.= $theOutput;
1774 $theOutput .= $this->doc
->spacer(15);
1775 $theOutput .= $this->doc
->section(
1777 $GLOBALS['LANG']->getLL('ext_details_filesize_exceeded_kb'),
1781 $GLOBALS['LANG']->getLL('ext_details_file_too_large'),
1785 $this->content
.= $theOutput;
1789 die (sprintf($GLOBALS['LANG']->getLL('ext_details_fatal_edit_error'),
1790 htmlspecialchars($editFile)
1797 switch ((string) $this->MOD_SETTINGS
['singleDetails']) {
1799 // Loaded / Not loaded:
1800 if (!in_array($extKey, $this->requiredExt
)) {
1801 if ($GLOBALS['TYPO3_LOADED_EXT'][$extKey]) {
1802 $content = '<strong>' . $GLOBALS['LANG']->getLL('ext_details_loaded_and_running') . '</strong><br />' .
1803 '<a href="' . htmlspecialchars(t3lib_div
::linkThisScript(array(
1804 'CMD[showExt]' => $extKey,
1807 '">' . $GLOBALS['LANG']->getLL('ext_details_remove_button') . ' ' . tx_em_Tools
::removeButton() . '</a>';
1809 $content = $GLOBALS['LANG']->getLL('ext_details_not_loaded') . '<br />' .
1810 '<a href="' . htmlspecialchars(t3lib_div
::linkThisScript(array(
1811 'CMD[showExt]' => $extKey,
1814 '">' . $GLOBALS['LANG']->getLL('ext_details_install_button') . ' ' . tx_em_Tools
::installButton() . '</a>';
1817 $content = $GLOBALS['LANG']->getLL('ext_details_always_loaded');
1819 $this->content
.= $this->doc
->spacer(10);
1820 $this->content
.= $this->doc
->section(
1821 $GLOBALS['LANG']->getLL('ext_details_current_status'), $content, 0, 1
1824 if (t3lib_extMgm
::isLoaded($extKey)) {
1825 $updates = $this->install
->updatesForm($extKey, $list[$extKey]);
1827 $this->content
.= $this->doc
->spacer(10);
1828 $this->content
.= $this->doc
->section(
1829 $GLOBALS['LANG']->getLL('ext_details_update_needed'),
1830 $updates . '<br /><br />' . $GLOBALS['LANG']->getLL('ext_details_notice_static_data'),
1837 if (@is_file
($absPath . 'ext_conf_template.txt')) {
1838 $this->content
.= $this->doc
->spacer(10);
1839 $this->content
.= $this->doc
->section(
1840 $GLOBALS['LANG']->getLL('ext_details_configuration'),
1841 $GLOBALS['LANG']->getLL('ext_details_notice_clear_cache') . '<br /><br />',
1845 $this->content
.= $this->install
->tsStyleConfigForm($extKey, $list[$extKey]);
1849 $headline = $GLOBALS['LANG']->getLL('ext_details_details');
1850 $headline = t3lib_BEfunc
::wrapInHelp('_MOD_tools_em', 'info', $headline);
1851 $content = $this->extensionDetails
->extInformationarray($extKey, $list[$extKey]);
1854 $this->content
.= $this->doc
->spacer(10);
1855 $this->content
.= $this->doc
->section($headline, $content, FALSE, TRUE, FALSE, TRUE);
1858 $em = t3lib_div
::_POST('em');
1861 if ($em['action'] == 'doUpload') {
1862 $em['extKey'] = $extKey;
1863 $em['extInfo'] = $list[$extKey];
1864 $content = $this->extensionDetails
->uploadExtensionToTER($em);
1865 $content .= $this->doc
->spacer(10);
1866 // Must reload this, because EM_CONF information has been updated!
1867 list($list,) = $this->extensionList
->getInstalledExtensions();
1870 $headline = $GLOBALS['LANG']->getLL('ext_details_upload_to_ter');
1871 $headline = t3lib_BEfunc
::wrapInHelp('_MOD_tools_em', 'upload', $headline);
1874 if (substr($extKey, 0, 5) != 'user_') {
1875 $content = $this->getRepositoryUploadForm($extKey, $list[$extKey]);
1878 $content = $GLOBALS['LANG']->getLL('ext_details_no_unique_ext');
1881 if (!$this->fe_user
['username']) {
1882 /** @var $flashMessage t3lib_FlashMessage */
1883 $flashMessage = t3lib_div
::makeInstance(
1884 't3lib_FlashMessage',
1885 sprintf($GLOBALS['LANG']->getLL('ext_details_no_username'),
1886 '<a href="' . t3lib_div
::linkThisScript(array(
1887 'SET[function]' => 3
1891 t3lib_FlashMessage
::INFO
1893 $content .= '<br />' . $flashMessage->render();
1897 $this->content
.= $this->doc
->section($headline, $content, 0, 1, $eC, TRUE);
1900 if ($this->CMD
['doDelete']) {
1901 $content = $this->install
->extDelete($extKey, $list[$extKey], $this->CMD
);
1902 $this->content
.= $this->doc
->section(
1903 $GLOBALS['LANG']->getLL('ext_details_delete'),
1904 $GLOBALS['LANG']->getLL('ext_details_delete'),
1909 $headline = $GLOBALS['LANG']->getLL('ext_details_backup');
1910 $headline = t3lib_BEfunc
::wrapInHelp('_MOD_tools_em', 'backup_delete', $headline);
1912 $content = $this->extBackup($extKey, $list[$extKey]);
1913 $this->content
.= $this->doc
->section($headline, $content, 0, 1, 0, 1);
1915 $content = $this->install
->extDelete($extKey, $list[$extKey], $this->CMD
);
1916 $this->content
.= $this->doc
->section(
1917 $GLOBALS['LANG']->getLL('ext_details_delete'),
1921 $content = $this->extUpdateEMCONF($extKey, $list[$extKey]);
1922 $this->content
.= $this->doc
->section(
1923 $GLOBALS['LANG']->getLL('ext_details_update_em_conf'),
1929 $this->extDumpTables($extKey, $list[$extKey]);
1933 $headline = $GLOBALS['LANG']->getLL('ext_details_ext_files');
1934 $headline = t3lib_BEfunc
::wrapInHelp('_MOD_tools_em', 'editfiles', $headline);
1936 $content = $this->getFileListOfExtension($extKey, $list[$extKey]);
1938 $this->content
.= $this->doc
->section($headline, $content, FALSE, TRUE, FALSE, TRUE);
1940 case 'updateModule':
1941 $this->content
.= $this->doc
->section(
1942 $GLOBALS['LANG']->getLL('ext_details_update'),
1943 is_object($updateObj) ?
1944 $updateObj->main() :
1945 $GLOBALS['LANG']->getLL('ext_details_no_update_object'),
1950 $this->extObjContent();
1958 * Outputs a screen from where you can install multiple extensions in one go
1959 * This can be called from external modules with "...index.php?CMD[requestInstallExtensions]=
1961 * @param string Comma list of extension keys to install. Renders a screen with checkboxes for all extensions not already imported or installed
1964 function requestInstallExtensions($extList) {
1967 $returnUrl = t3lib_div
::sanitizeLocalUrl(t3lib_div
::_GP('returnUrl'));
1968 $installOrImportExtension = t3lib_div
::_POST('installOrImportExtension');
1971 $extArray = explode(',', $extList);
1972 $outputRow = array();
1974 <tr class="t3-row-header tableheader">
1975 <td>' . $GLOBALS['LANG']->getLL('reqInstExt_install_import') . '</td>
1976 <td>' . $GLOBALS['LANG']->getLL('reqInstExt_ext_key') . '</td>
1980 foreach ($extArray as $extKey) {
1982 // Check for the request:
1983 if ($installOrImportExtension[$extKey]) {
1984 $this->installExtension($extKey);
1988 if (!t3lib_extMgm
::isLoaded($extKey)) {
1990 <tr class="bgColor4">
1991 <td><input type="checkbox" name="' . htmlspecialchars('installOrImportExtension[' . $extKey . ']') . '" value="1" checked="checked" id="check_' . $extKey . '" /></td>
1992 <td><label for="check_' . $extKey . '">' . htmlspecialchars($extKey) . '</label></td>
1998 if (count($outputRow) > 1 ||
!$returnUrl) {
2000 <!-- ending page form ... -->
2001 <form action="' . htmlspecialchars(t3lib_div
::getIndpEnv('REQUEST_URI')) . '" method="post">
2002 <table border="0" cellpadding="1" cellspacing="1">' . implode('', $outputRow) . '</table>
2003 <input type="submit" name="_" value="' . $GLOBALS['LANG']->getLL('reqInstExt_import_install_selected') . '" />
2010 <a href="' . htmlspecialchars($returnUrl) . '">' . $GLOBALS['LANG']->getLL('reqInstExt_return') . '</a>
2014 $this->content
.= $this->doc
->section(
2015 $GLOBALS['LANG']->getLL('reqInstExt_imp_inst_ext'), $content, 0, 1
2018 t3lib_utility_Http
::redirect($returnUrl);
2023 /***********************************
2025 * Application Sub-functions (HTML parts)
2027 **********************************/
2031 * Creates view for dumping static tables and table/fields structures...
2033 * @param string Extension key
2034 * @param array Extension information array
2037 function extDumpTables($extKey, $extInfo) {
2039 // Get dbInfo which holds the structure known from the tables.sql file
2040 $techInfo = $this->install
->makeDetailedExtensionAnalysis($extKey, $extInfo);
2041 $absPath = tx_em_Tools
::getExtPath($extKey, $extInfo['type']);
2044 if (is_array($techInfo['static'])) {
2045 if ($this->CMD
['writeSTATICdump']) { // Writing static dump:
2046 $writeFile = $absPath . 'ext_tables_static+adt.sql';
2047 if (@is_file
($writeFile)) {
2048 $dump_static = tx_em_Database
::dumpStaticTables(implode(',', $techInfo['static']));
2049 t3lib_div
::writeFile($writeFile, $dump_static);
2050 $this->content
.= $this->doc
->section(
2051 $GLOBALS['LANG']->getLL('extDumpTables_tables_fields'),
2052 sprintf($GLOBALS['LANG']->getLL('extDumpTables_bytes_written_to'),
2053 t3lib_div
::formatSize(strlen($dump_static)),
2054 substr($writeFile, strlen(PATH_site
))
2059 } else { // Showing info about what tables to dump - and giving the link to execute it.
2060 $msg = $GLOBALS['LANG']->getLL('extDumpTables_dumping_content') . '<br />';
2061 $msg .= '<br />' . implode('<br />', $techInfo['static']) . '<br />';
2063 // ... then feed that to this function which will make new CREATE statements of the same fields but based on the current database content.
2064 $this->content
.= $this->doc
->section(
2065 $GLOBALS['LANG']->getLL('extDumpTables_static_tables'),
2066 $msg . '<hr /><strong><a href="' . htmlspecialchars(t3lib_div
::linkThisScript(array(
2067 'CMD[showExt]' => $extKey,
2068 'CMD[writeSTATICdump]' => 1
2069 ))) . '">' . $GLOBALS['LANG']->getLL('extDumpTables_write_static') . '</a></strong>',
2072 $this->content
.= $this->doc
->spacer(20);
2076 // Table and field definitions:
2077 if (is_array($techInfo['dump_tf'])) {
2078 $dump_tf_array = tx_em_Database
::getTableAndFieldStructure($techInfo['dump_tf']);
2079 $dump_tf = tx_em_Database
::dumpTableAndFieldStructure($dump_tf_array);
2080 if ($this->CMD
['writeTFdump']) {
2081 $writeFile = $absPath . 'ext_tables.sql';
2082 if (@is_file
($writeFile)) {
2083 t3lib_div
::writeFile($writeFile, $dump_tf);
2084 $this->content
.= $this->doc
->section(
2085 $GLOBALS['LANG']->getLL('extDumpTables_tables_fields'),
2086 sprintf($GLOBALS['LANG']->getLL('extDumpTables_bytes_written_to'),
2087 t3lib_div
::formatSize(strlen($dump_tf)),
2088 substr($writeFile, strlen(PATH_site
))
2094 $msg = $GLOBALS['LANG']->getLL('extDumpTables_dumping_db_structure') . '<br />';
2095 if (is_array($techInfo['tables'])) {
2096 $msg .= '<br /><strong>' . $GLOBALS['LANG']->getLL('extDumpTables_tables') . '</strong><br />' .
2097 implode('<br />', $techInfo['tables']) . '<br />';
2099 if (is_array($techInfo['fields'])) {
2100 $msg .= '<br /><strong>' . $GLOBALS['LANG']->getLL('extDumpTables_solo_fields') . '</strong><br />' .
2101 implode('<br />', $techInfo['fields']) . '<br />';
2104 // ... then feed that to this function which will make new CREATE statements of the same fields but based on the current database content.
2105 $this->content
.= $this->doc
->section(
2106 $GLOBALS['LANG']->getLL('extDumpTables_tables_fields'),
2107 $msg . '<hr /><strong><a href="' . htmlspecialchars(t3lib_div
::linkThisScript(array(
2108 'CMD[showExt]' => $extKey,
2109 'CMD[writeTFdump]' => 1
2111 '">' . $GLOBALS['LANG']->getLL('extDumpTables_write_dump') . '</a></strong><hr />
2112 <pre>' . htmlspecialchars($dump_tf) . '</pre>',
2117 $details = ' ' . $GLOBALS['LANG']->getLL('extDumpTables_based_on') . '<br />
2119 <li>' . $GLOBALS['LANG']->getLL('extDumpTables_based_on_one') . '</li>
2120 <li>' . $GLOBALS['LANG']->getLL('extDumpTables_based_on_two') . '</li>
2122 ' . $GLOBALS['LANG']->getLL('extDumpTables_bottomline') . '<br />';
2123 $this->content
.= $this->doc
->section('', $details);
2129 * Returns file-listing of an extension
2131 * @param string Extension key
2132 * @param array Extension information array
2133 * @return string HTML table.
2135 function getFileListOfExtension($extKey, $conf) {
2137 $extPath = tx_em_Tools
::getExtPath($extKey, $conf['type']);
2142 $fileArr = t3lib_div
::getAllFilesAndFoldersInPath($fileArr, $extPath, '', 0, 99, $this->excludeForPackaging
);
2150 <tr class="t3-row-header">
2151 <td>' . $GLOBALS['LANG']->getLL('extFileList_file') . '</td>
2152 <td>' . $GLOBALS['LANG']->getLL('extFileList_size') . '</td>
2153 <td>' . $GLOBALS['LANG']->getLL('extFileList_edit') . '</td>
2156 foreach ($fileArr as $file) {
2157 $fI = t3lib_div
::split_fileref($file);
2159 <tr class="bgColor4">
2160 <td><a href="' . htmlspecialchars(t3lib_div
::linkThisScript(array(
2161 'CMD[showExt]' => $extKey,
2162 'CMD[downloadFile]' => rawurlencode($file)
2163 ))) . '" title="' . $GLOBALS['LANG']->getLL('extFileList_download') . '">' .
2164 substr($file, strlen($extPath)) . '</a></td>
2165 <td>' . t3lib_div
::formatSize(filesize($file)) . '</td>
2166 <td>' . (!in_array($extKey, $this->requiredExt
) &&
2167 t3lib_div
::inList($this->editTextExtensions
,
2168 ($fI['fileext'] ?
$fI['fileext'] : $fI['filebody'])) ?
2169 '<a href="' . htmlspecialchars(t3lib_div
::linkThisScript(array(
2170 'CMD[showExt]' => $extKey,
2171 'CMD[editFile]' => rawurlencode($file)
2173 $GLOBALS['LANG']->getLL('extFileList_edit_file') . '</a>' : ''
2176 $totalSize +
= filesize($file);
2180 <tr class="bgColor6">
2181 <td><strong>' . $GLOBALS['LANG']->getLL('extFileList_total') . '</strong></td>
2182 <td><strong>' . t3lib_div
::formatSize($totalSize) . '</strong></td>
2187 Path: ' . $extPath . '<br /><br />
2188 <table border="0" cellpadding="1" cellspacing="2">' . implode('', $lines) . '</table>';
2196 * Update extension EM_CONF...
2198 * @param string Extension key
2199 * @param array Extension information array
2200 * @return string HTML content.
2202 function extUpdateEMCONF($extKey, $extInfo) {
2203 $absPath = tx_em_Tools
::getExtPath($extKey, $extInfo['type']);
2206 if ($this->CMD
['doUpdateEMCONF']) {
2207 return $this->extensionDetails
->updateLocalEM_CONF($extKey, $extInfo);
2209 $sure = $GLOBALS['LANG']->getLL('extUpdateEMCONF_sure');
2210 $updateEMConf = $GLOBALS['LANG']->getLL('extUpdateEMCONF_file');
2211 $onClick = "if (confirm('$sure')) {window.location.href='" . t3lib_div
::linkThisScript(array(
2212 'CMD[showExt]' => $extKey,
2213 'CMD[doUpdateEMCONF]' => 1
2215 $content .= $GLOBALS['LANG']->getLL('extUpdateEMCONF_info_changes') . '<br />'
2216 . $GLOBALS['LANG']->getLL('extUpdateEMCONF_info_reset') . '<br /><br />';
2217 $content .= '<a class="t3-link" href="#" onclick="' . htmlspecialchars($onClick) .
2218 ' return false;"><strong>' . $updateEMConf . '</strong> ' .
2219 sprintf($GLOBALS['LANG']->getLL('extDelete_from_location'),
2220 $this->typeLabels
[$extInfo['type']],
2221 substr($absPath, strlen(PATH_site
))
2228 * Download extension as file / make backup
2230 * @param string Extension key
2231 * @param array Extension information array
2232 * @return string HTML content
2234 function extBackup($extKey, $extInfo) {
2235 $uArr = $this->extensionDetails
->makeUploadarray($extKey, $extInfo);
2236 if (is_array($uArr)) {
2237 $backUpData = $this->terConnection
->makeUploadDataFromarray($uArr);
2238 $filename = 'T3X_' . $extKey . '-' . str_replace('.', '_', $extInfo['EM_CONF']['version']) . '-z-' . date('YmdHi') . '.t3x';
2239 if (intval($this->CMD
['doBackup']) == 1) {
2240 t3lib_div
::cleanOutputBuffers();
2241 header('Content-Type: application/octet-stream');
2242 header('Content-Disposition: attachment; filename=' . $filename);
2245 } elseif ($this->CMD
['dumpTables']) {
2246 $filename = 'T3X_' . $extKey;
2247 $cTables = count(explode(',', $this->CMD
['dumpTables']));
2249 $filename .= '-' . $cTables . 'tables';
2251 $filename .= '-' . $this->CMD
['dumpTables'];
2253 $filename .= '+adt.sql';
2255 header('Content-Type: application/octet-stream');
2256 header('Content-Disposition: attachment; filename=' . $filename);
2257 echo tx_em_Database
::dumpStaticTables($this->CMD
['dumpTables']);
2260 $techInfo = $this->install
->makeDetailedExtensionAnalysis($extKey, $extInfo);
2262 $lines[] = '<tr class="t3-row-header"><td colspan="2">' .
2263 $GLOBALS['LANG']->getLL('extBackup_select') . '</td></tr>';
2264 $lines[] = '<tr class="bgColor4"><td><strong>' .
2265 $GLOBALS['LANG']->getLL('extBackup_files') . '</strong></td><td>' .
2266 '<a class="t3-link" href="' . htmlspecialchars(t3lib_div
::linkThisScript(array(
2267 'CMD[doBackup]' => 1,
2268 'CMD[showExt]' => $extKey
2270 '">' . sprintf($GLOBALS['LANG']->getLL('extBackup_download'),
2273 (' . $filename . ', <br />' .
2274 t3lib_div
::formatSize(strlen($backUpData)) . ', <br />' .
2275 $GLOBALS['LANG']->getLL('extBackup_md5') . ' ' . md5($backUpData) . ')
2278 if (is_array($techInfo['tables'])) {
2279 $lines[] = '<tr class="bgColor4"><td><strong>' . $GLOBALS['LANG']->getLL('extBackup_data_tables') .
2280 '</strong></td><td>' . tx_em_Database
::dumpDataTablesLine($techInfo['tables'], $extKey) . '</td></tr>';
2282 if (is_array($techInfo['static'])) {
2283 $lines[] = '<tr class="bgColor4"><td><strong>' . $GLOBALS['LANG']->getLL('extBackup_static_tables') .
2284 '</strong></td><td>' . tx_em_Database
::dumpDataTablesLine($techInfo['static'], $extKey) . '</td></tr>';
2287 $content = '<table border="0" cellpadding="2" cellspacing="2">' . implode('', $lines) . '</table>';
2291 throw new RuntimeException(
2292 'TYPO3 Fatal Error: ' . $GLOBALS['LANG']->getLL('extBackup_unexpected_error'),
2301 * Prints the upload form for extensions
2303 * @param string Extension key
2304 * @param array Extension information array
2305 * @return string HTML content.
2307 function getRepositoryUploadForm($extKey, $extInfo) {
2308 $content = '<form action="' . $this->script
. '" method="post" name="repuploadform">
2309 <input type="hidden" name="CMD[showExt]" value="' . $extKey . '" />
2310 <input type="hidden" name="em[action]" value="doUpload" />
2311 <table border="0" cellpadding="2" cellspacing="1">
2312 <tr class="bgColor4">
2313 <td>' . $GLOBALS['LANG']->getLL('repositoryUploadForm_username') . '</td>
2314 <td><input' . $this->doc
->formWidth(20) . ' type="text" name="em[user][fe_u]" value="' . $this->fe_user
['username'] . '" /></td>
2316 <tr class="bgColor4">
2317 <td>' . $GLOBALS['LANG']->getLL('repositoryUploadForm_password') . '</td>
2318 <td><input' . $this->doc
->formWidth(20) . ' type="password" name="em[user][fe_p]" value="' . $this->fe_user
['password'] . '" /></td>
2320 <tr class="bgColor4">
2321 <td>' . $GLOBALS['LANG']->getLL('repositoryUploadForm_changelog') . '</td>
2322 <td><textarea' . $this->doc
->formWidth(30, 1) . ' rows="5" name="em[upload][comment]"></textarea></td>
2324 <tr class="bgColor4">
2325 <td>' . $GLOBALS['LANG']->getLL('repositoryUploadForm_command') . '</td>
2326 <td nowrap="nowrap">
2327 <input type="radio" name="em[upload][mode]" id="new_dev" value="new_dev" checked="checked" />
2328 <label for="new_dev">' . sprintf($GLOBALS['LANG']->getLL('repositoryUploadForm_new_bugfix'),
2329 'x.x.<strong>' . tx_em_Tools
::rfw('x+1') . '</strong>'
2331 <input type="radio" name="em[upload][mode]" id="new_sub" value="new_sub" />
2332 <label for="new_sub">' . sprintf($GLOBALS['LANG']->getLL('repositoryUploadForm_new_sub_version'),
2333 'x.<strong>' . tx_em_Tools
::rfw('x+1') . '</strong>.0'
2335 <input type="radio" name="em[upload][mode]" id="new_main" value="new_main" />
2336 <label for="new_main">' . sprintf($GLOBALS['LANG']->getLL('repositoryUploadForm_new_main_version'),
2337 '<strong>' . tx_em_Tools
::rfw('x+1') . '</strong>.0.0'
2341 <tr class="bgColor4">
2343 <td><input type="submit" name="submit" value="' . $GLOBALS['LANG']->getLL('repositoryUploadForm_upload') . '" />
2353 /************************************
2355 * Output helper functions
2357 ************************************/
2361 * Returns a header for an extensions including icon if any
2363 * @param string Extension key
2364 * @param array Extension information array
2365 * @param string align-attribute value (for <img> tag)
2366 * @return string HTML; Extension title and image.
2368 function extensionTitleIconHeader($extKey, $extInfo, $align = 'top') {
2369 $imgInfo = @getImageSize
(tx_em_Tools
::getExtPath($extKey, $extInfo['type']) . '/ext_icon.gif');
2371 if (is_array($imgInfo)) {
2372 $out .= '<img src="' . $GLOBALS['BACK_PATH'] . tx_em_Tools
::typeRelPath($extInfo['type']) . $extKey . '/ext_icon.gif" ' . $imgInfo[3] . ' align="' . $align . '" alt="" />';
2374 $out .= $extInfo['EM_CONF']['title'] ?
htmlspecialchars(t3lib_div
::fixed_lgd_cs($extInfo['EM_CONF']['title'], 40)) : '<em>' . htmlspecialchars($extKey) . '</em>';
2385 /************************************
2387 * Various helper functions
2389 ************************************/
2392 * Returns subtitles for the extension listings
2394 * @param string List order type
2395 * @param string Key value
2396 * @return string output.
2398 function listOrderTitle($listOrder, $key) {
2399 switch ($listOrder) {
2401 return isset($this->categories
[$key]) ?
$this->categories
[$key] : '[' . $key . ']';
2403 case 'author_company':
2407 return $this->states
[$key];
2410 return $this->typeDescr
[$key];
2417 * Returns TRUE if global OR local installation of extensions is allowed/possible.
2419 * @return boolean Returns TRUE if global OR local installation of extensions is allowed/possible.
2421 function importAtAll() {
2422 return ($GLOBALS['TYPO3_CONF_VARS']['EXT']['allowGlobalInstall'] ||
$GLOBALS['TYPO3_CONF_VARS']['EXT']['allowLocalInstall']);
2427 * Searches for ->lookUpStr in extension and returns TRUE if found (or if no search string is set)
2429 * @param string Extension key
2430 * @param array Extension content
2431 * @return boolean If TRUE, display extension in list
2433 function searchExtension($extKey, $row) {
2434 if ($this->lookUpStr
) {
2436 stristr($extKey, $this->lookUpStr
) ||
2437 stristr($row['EM_CONF']['title'], $this->lookUpStr
) ||
2438 stristr($row['EM_CONF']['description'], $this->lookUpStr
) ||
2439 stristr($row['EM_CONF']['author'], $this->lookUpStr
) ||
2440 stristr($row['EM_CONF']['author_company'], $this->lookUpStr
)
2449 * Checks if there are newer versions of installed extensions in the TER
2450 * integrated from the extension "ter_update_check" for TYPO3 4.2 by Christian Welzel
2454 function checkForUpdates() {
2457 $count = intval(tx_em_Database
::getExtensionCountFromRepository());
2459 $content = $this->extensionList
->showExtensionsToUpdate()
2460 . t3lib_BEfunc
::getFuncCheck(0, 'SET[display_installed]', $this->MOD_SETTINGS
['display_installed'], '', '', 'id="checkDisplayInstalled"')
2461 . ' <label for="checkDisplayInstalled">' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:display_nle') . '</label><br />'
2462 . t3lib_BEfunc
::getFuncCheck(0, 'SET[display_files]', $this->MOD_SETTINGS
['display_files'], '', '', 'id="checkDisplayFiles"')
2463 . ' <label for="checkDisplayFiles">' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:display_files') . '</label>';
2464 $this->content
.= $this->doc
->section($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:header_upd_ext'), $content, 0, 1);
2466 $content = sprintf($GLOBALS['LANG']->getLL('note_last_update_new'),
2467 t3lib_BEfunc
::datetime(filemtime(PATH_site
. 'typo3temp/extensions.xml.gz'))
2471 $content .= sprintf($GLOBALS['LANG']->getLL('note_last_update2_new'),
2472 '<a href="' . t3lib_div
::linkThisScript(array(
2473 'SET[function]' => 2
2475 $this->content
.= $this->doc
->section($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:header_vers_ret'), $content, 0, 1);
2479 function showRepositoryUpdateForm() {
2480 $content = '<div class="em-repupdate"><strong>Repository:</strong>';
2482 // print registered repositories
2483 /** @var $settings tx_em_Settings */
2484 $settings = t3lib_div
::makeInstance('tx_em_Settings');
2485 $registeredRepos = $settings->getRegisteredRepositories();
2486 $content .= '<select>';
2487 foreach ($registeredRepos as $repository) {
2488 $content .= '<option>' . $repository->getTitle() . '</option>';
2490 $content .= '</select>';
2492 $selectedRepo = $settings->getSelectedRepository();
2493 /** @var $repoUtility tx_em_Repository_Utility */
2494 $repoUtility = t3lib_div
::makeInstance('tx_em_Repository_Utility');
2495 $repoUtility->setRepository($selectedRepo);
2497 $onCLick = 'window.location.href="' . t3lib_div
::linkThisScript(array(
2498 'CMD[fetchMetaData]' => 'extensions'
2499 )) . '";return false;';
2501 <input type="button" value="' . $GLOBALS['LANG']->getLL('retrieve_update') .
2502 '" onclick="' . htmlspecialchars($onCLick) . '" />';
2503 if (is_file($repoUtility->getLocalExtListFile())) {
2504 $count = tx_em_Database
::getExtensionCountFromRepository($repoUtility->getRepositoryUID());
2505 $content .= '<span style="margin-left:10px;padding-right: 50px;" class="typo3-message message-notice">' .
2506 sprintf($GLOBALS['LANG']->getLL('ext_list_last_updated'),
2507 t3lib_BEfunc
::datetime(filemtime($repoUtility->getLocalExtListFile())), $count) . '</span>';
2509 $content .= '<span style="margin-left:10px;padding-right: 50px;" class="typo3-message message-error">There are no extensions available, please update!</span>';
2511 $content .= '<br> <br>';
2513 if ($this->CMD
['fetchMetaData'] && $this->CMD
['fetchMetaData'] == 'extensions') { // fetches mirror/extension data from online rep.
2514 $content .= $repoUtility->updateExtList(TRUE)->render();
2517 $content .= '</div>';
2522 // Function wrappers for compatibility
2525 * Reports back if installation in a certain scope is possible.
2527 * @param string Scope: G, L, S
2528 * @param string Extension lock-type (eg. "L" or "G")
2529 * @return boolean TRUE if installation is allowed.
2531 public static function importAsType($type, $lockType = '') {
2532 return tx_em_Tools
::importAsType($type, $lockType);
2536 * Returns the list of available (installed) extensions
2538 * @return array Array with two arrays, list array (all extensions with info) and category index
2539 * @wrapper for compatibility
2541 public function getInstalledExtensions() {
2542 return $this->extensionList
->getInstalledExtensions();
2549 protected function getSubmitAndOpenerCloseLink() {
2550 if (!$this->CMD
['standAlone'] && !$this->noDocHeader
&& ($this->CMD
['standAlone'] || t3lib_div
::_GP('standAlone'))) {
2551 $link = '<a href="javascript:opener.top.list.iframe.document.forms[0].submit();window.close();">' .
2552 $GLOBALS['LANG']->getLL('ext_import_close_check') . '</a>';
2555 return '<a id="closewindow" href="javascript:if (parent.TYPO3.EM && top.frames.length) {parent.TYPO3.EM.Tools.closeImportWindow();} else {window.close();}">' . $GLOBALS['LANG']->getLL('ext_import_close') . '</a>';
2560 /* Compatibility wrappers */
2564 * Returns the absolute path where the extension $extKey is installed (based on 'type' (SGL))
2566 * @param string Extension key
2567 * @param string Install scope type: L, G, S
2568 * @return string Returns the absolute path to the install scope given by input $type variable. It is checked if the path is a directory. Slash is appended.
2570 public function getExtPath($extKey, $type, $returnWithoutExtKey = FALSE) {
2571 return tx_em_Tools
::getExtPath($extKey, $type, $returnWithoutExtKey);
2576 /** @var $SOBE SC_mod_tools_em_index */
2577 $SOBE = t3lib_div
::makeInstance('SC_mod_tools_em_index');
2579 foreach ($SOBE->include_once as $INC_FILE) {
2580 include_once($INC_FILE);
2582 $SOBE->checkExtObj();
2585 $SOBE->printContent();