92fc52ff427b28220d99ecf0b86ba7bcb959791d
[Packages/TYPO3.CMS.git] / typo3 / sysext / em / classes / index.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2010 Kasper Skårhøj (kasperYYYY@typo3.com)
6 * (c) 2005-2010 Karsten Dambekalns <karsten@typo3.org>
7 * All rights reserved
8 *
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.
14 *
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.
19 *
20 *
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.
25 *
26 * This copyright notice MUST APPEAR in all copies of the script!
27 ***************************************************************/
28 /**
29 * Module: Extension manager
30 *
31 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
32 * @author Karsten Dambekalns <karsten@typo3.org>
33 * @author Steffen Kamper <info@sk-typo3.de>
34 */
35
36 $GLOBALS['LANG']->includeLLFile(t3lib_extMgm::extPath('em') . 'language/locallang.xml');
37
38 // from tx_ter by Robert Lemke
39 define('TX_TER_RESULT_EXTENSIONSUCCESSFULLYUPLOADED', '10504');
40
41 define('EM_INSTALL_VERSION_MIN', 1);
42 define('EM_INSTALL_VERSION_MAX', 2);
43 define('EM_INSTALL_VERSION_STRICT', 3);
44
45 unset($MCONF);
46 require('conf.php');
47
48 $BE_USER->modAccess($MCONF, 1);
49
50
51 /**
52 * Module: Extension manager
53 *
54 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
55 * @author Karsten Dambekalns <karsten@typo3.org>
56 * @package TYPO3
57 * @subpackage core
58 */
59 class SC_mod_tools_em_index extends t3lib_SCbase {
60
61 // Internal, static:
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
71
72
73 var $categories = array(); // Extension Categories (static var); see init()
74
75 var $states = array(); // Extension States; see init()
76
77 var $typeDescr = array();
78
79 var $detailCols = array(
80 0 => 2,
81 1 => 5,
82 2 => 6,
83 3 => 6,
84 4 => 4,
85 5 => 1
86 );
87
88 var $fe_user = array(
89 'username' => '',
90 'password' => '',
91 );
92
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';
97
98
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
103 /**
104 * Document Template Object
105 *
106 * @var noDoc
107 */
108 var $doc;
109 var $content; // Accumulated content
110
111 var $inst_keys = array(); // Storage of installed extensions
112 var $gzcompress = 0; // Is set TRUE, if system support compression.
113
114 /**
115 * Instance of EM API
116 *
117 * @var tx_em_API
118 */
119 protected $api;
120
121 /**
122 * Instance of TER connection handler
123 *
124 * @var tx_em_Connection_Ter
125 */
126 public $terConnection;
127
128 /**
129 * XML handling class for the TYPO3 Extension Manager
130 *
131 * @var tx_em_Tools_XmlHandler
132 */
133 public $xmlHandler;
134
135 /**
136 * Class for printing extension lists
137 *
138 * @var tx_em_Extensions_List
139 */
140 public $extensionList;
141
142 /**
143 * Class for extension details
144 *
145 * @var tx_em_Extensions_Details
146 */
147 public $extensionDetails;
148
149 /**
150 * Class for new ExtJs Extension Manager
151 *
152 * @var tx_em_ExtensionManager
153 */
154 public $extensionmanager;
155
156 /**
157 * Class for translation handling
158 *
159 * @var tx_em_Translations
160 */
161 public $translations;
162
163 /**
164 * Class for install extensions
165 *
166 * @var tx_em_Install
167 */
168 public $install;
169
170 /**
171 * Settings object
172 *
173 * @var tx_em_Settings
174 */
175 public $settings;
176
177 /**
178 * @var string
179 */
180 protected $excludeForPackaging;
181
182 /**
183 * @var string
184 */
185 protected $listRemote_search;
186
187 /**
188 * @var string
189 */
190 protected $descrTable;
191
192 var $JScode; // JavaScript code to be forwarded to $this->doc->JScode
193
194 // GPvars:
195 var $CMD = array(); // CMD array
196 var $listRemote; // If set, connects to remote repository
197 var $lookUpStr; // Search string when listing local extensions
198
199
200 protected $noDocHeader = 0;
201
202 /*********************************
203 *
204 * Standard module initialization
205 *
206 *********************************/
207
208 /**
209 * Standard init function of a module.
210 *
211 * @return void
212 */
213 function init() {
214 /**
215 * Extension Categories (static var)
216 * Content must be redundant with the same internal variable as in class.tx_extrep.php!
217 */
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')
228 );
229
230 /**
231 * Extension States
232 * Content must be redundant with the same internal variable as in class.tx_extrep.php!
233 */
234 $this->states = tx_em_Tools::getStates();
235
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>'
241 );
242 /** @var $flashMessage t3lib_FlashMessage */
243 $flashMessage = t3lib_div::makeInstance(
244 't3lib_FlashMessage',
245 $securityMessage,
246 $GLOBALS['LANG']->getLL('security_header'),
247 t3lib_FlashMessage::INFO
248 );
249 $this->securityHint = $flashMessage->render();
250
251 $this->excludeForPackaging = $GLOBALS['TYPO3_CONF_VARS']['EXT']['excludeForPackaging'];
252
253 // Setting module configuration:
254 $this->MCONF = $GLOBALS['MCONF'];
255
256 // Setting GPvars:
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);
262
263 $this->settings = t3lib_div::makeInstance('tx_em_Settings');
264 $this->install = t3lib_div::makeInstance('tx_em_Install', $this);
265
266 if (t3lib_div::_GP('silentMode') || $this->noDocHeader) {
267 $this->CMD['silentMode'] = 1;
268 $this->noDocHeader = 1;
269 }
270
271 if ($this->CMD['silentMode']) {
272 $this->install->setSilentMode(TRUE);
273 }
274
275 // Configure menu
276 $this->menuConfig();
277
278 // Setting internal static:
279
280 $this->requiredExt = t3lib_div::trimExplode(',', t3lib_extMgm::getRequiredExtensionList(), TRUE);
281
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');
286
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'];
291
292
293 $this->xmlHandler = t3lib_div::makeInstance('tx_em_Tools_XmlHandler');
294 $this->xmlHandler->useObsolete = $this->MOD_SETTINGS['display_obsolete'];
295
296
297 // Initialize newListing
298 if (isset($this->MOD_MENU['function']['extensionmanager'])) {
299 $this->extensionmanager = t3lib_div::makeInstance('tx_em_ExtensionManager', $this);
300 } else {
301 $this->extensionmanager = &$this;
302 }
303
304
305 // Output classes
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);
309
310
311 // the id is needed for getting same styles TODO: general table styles
312 $this->doc->bodyTagId = 'typo3-mod-tools-em-index-php';
313
314 // JavaScript
315 $this->doc->JScode = $this->doc->wrapScriptTags('
316 script_ended = 0;
317 function jumpToUrl(URL) { //
318 window.location.href = URL;
319 }
320 ');
321
322 // Reload left frame menu
323 if ($this->CMD['refreshMenu']) {
324 $this->doc->JScode .= $this->doc->wrapScriptTags('
325 if(top.refreshMenu) {
326 top.refreshMenu();
327 } else {
328 top.TYPO3ModuleMenu.refreshMenu();
329 }
330 ');
331 }
332
333
334 // Descriptions:
335 $this->descrTable = '_MOD_' . $this->MCONF['name'];
336 if ($GLOBALS['BE_USER']->uc['edit_showFieldHelp']) {
337 $GLOBALS['LANG']->loadSingleTableDescription($this->descrTable);
338 }
339
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'];
343 parent::init();
344 $this->handleExternalFunctionValue('singleDetails');
345 }
346
347 /**
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.
352 *
353 * @param string Mod-setting array key
354 * @param string Mod setting value, overriding the one in the key
355 * @return void
356 * @see t3lib_SCbase::handleExternalFunctionValue()
357 */
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());
363 }
364 if (is_array($this->extClassConf) && $this->extClassConf['path']) {
365 $this->include_once[] = $this->extClassConf['path'];
366 }
367 }
368
369 /**
370 * Configuration of which mod-menu items can be used
371 *
372 * @return void
373 */
374 function menuConfig() {
375 // MENU-ITEMS:
376 $this->MOD_MENU = $this->settings->MOD_MENU;
377 $globalSettings = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['em']);
378
379 if (!is_array($globalSettings)) {
380 // no settings saved yet, set default values
381 $globalSettings['inlineToWindow'] = 1;
382 $globalSettings['displayMyExtensions'] = 0;
383 }
384
385 unset(
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']
392 );
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());
395
396
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]);
402 }
403
404 // CLEANSE SETTINGS
405 $this->MOD_SETTINGS = t3lib_BEfunc::getModuleData($this->MOD_MENU, t3lib_div::_GP('SET'), $this->MCONF['name']);
406
407
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']);
416 }
417
418 $this->settings->saveSettings($this->MOD_SETTINGS);
419 parent::menuConfig();
420
421 $this->settings->saveSettings($this->MOD_SETTINGS);
422 }
423
424 /**
425 * Main function for Extension Manager module.
426 *
427 * @return void
428 */
429 public function main() {
430
431 $menu = '';
432
433 if (empty($this->MOD_SETTINGS['mirrorListURL'])) {
434 $this->MOD_SETTINGS['mirrorListURL'] = $GLOBALS['TYPO3_CONF_VARS']['EXT']['em_mirrorListURL'];
435 }
436
437 // Starting page:
438 $this->content .= $this->doc->header($GLOBALS['LANG']->getLL('header'));
439
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']);
447 if ($err) {
448 $this->content .= $this->doc->section('', tx_em_Tools::rfw($err));
449 }
450 if (!$err && $this->CMD['importExt']) {
451 $this->translations->installTranslationsForExtension($this->CMD['importExt'], $this->getMirrorURL());
452 }
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 .= '&nbsp;' . $GLOBALS['LANG']->getLL('group_by') . '&nbsp;' . t3lib_BEfunc::getFuncMenu(0, 'SET[listOrder]', $this->MOD_SETTINGS['listOrder'], $this->MOD_MENU['listOrder']) .
460 '&nbsp;&nbsp;' . $GLOBALS['LANG']->getLL('show') . '&nbsp;' . t3lib_BEfunc::getFuncMenu(0, 'SET[display_details]', $this->MOD_SETTINGS['display_details'], $this->MOD_MENU['display_details']) . '<br />';
461 }
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>&nbsp;&nbsp;' . t3lib_BEfunc::getFuncCheck(0, 'SET[display_shy]', $this->MOD_SETTINGS['display_shy'], '', '', 'id="checkDisplayShy"');
464 }
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>&nbsp;&nbsp;' . t3lib_BEfunc::getFuncCheck(0, 'SET[display_own]', $this->MOD_SETTINGS['display_own'], '', '', 'id="checkDisplayOwn"');
467 }
468 if (t3lib_div::inList('loaded_list,installed_list,import', $this->MOD_SETTINGS['function'])) {
469 $menu .= '&nbsp;&nbsp;<label for="checkDisplayObsolete">' . $GLOBALS['LANG']->getLL('show_obsolete') . '</label>&nbsp;&nbsp;' . t3lib_BEfunc::getFuncCheck(0, 'SET[display_obsolete]', $this->MOD_SETTINGS['display_obsolete'], '', '', 'id="checkDisplayObsolete"');
470 }
471
472 $this->content .= $menu ? $this->doc->section('', '<form action="' . $this->script . '" method="post" name="pageform"><span class="nobr">' . $menu . '</span></form>') : '';
473
474
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');
479 }
480
481 switch ($view) {
482 case 'loaded_list':
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();
487
488 $this->content .= $this->doc->section($headline, $content, FALSE, TRUE, FALSE, TRUE);
489 break;
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();
495
496 $this->content .= $this->doc->section($headline, $content, FALSE, TRUE, FALSE, TRUE);
497 break;
498 case 'import':
499 // Lists the extensions available from online rep.
500 $this->extensionList_import();
501 break;
502 case 'settings':
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();
507
508 $this->content .= $this->doc->section($headline, $content, FALSE, TRUE, FALSE, TRUE);
509 break;
510 case 'translations':
511 // Allows to set the translation preferences and check the status
512 $this->translations->translationHandling();
513 break;
514 case 'updates':
515 // Shows a list of extensions with updates in TER
516 $this->checkForUpdates();
517 break;
518 case 'extensionmanager':
519 $this->content .= $this->extensionmanager->render();
520 break;
521 default:
522 $this->extObjContent();
523 break;
524 }
525 }
526
527 // closing any form?
528 $formTags = substr_count($this->content, '<form') + substr_count($this->content, '</form');
529 if ($formTags % 2 > 0) {
530 $this->content .= '</form>';
531 }
532
533 if (!$this->noDocHeader) {
534 // Setting up the buttons and markers for docheader
535 $docHeaderButtons = $this->getButtons();
536 $markers = array(
537 'CSH' => $docHeaderButtons['csh'],
538 'FUNC_MENU' => $this->getFuncMenu(),
539 'CONTENT' => $this->content
540 );
541
542 // Build the <body> for the module
543 $this->content = $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $markers);
544 }
545 // Renders the module page
546 $this->content = $this->doc->render(
547 'Extension Manager',
548 $this->content
549 );
550
551 }
552
553 /**
554 * Print module content. Called as last thing in the global scope.
555 *
556 * @return void
557 */
558 function printContent() {
559 if ($this->doPrintContent) {
560 echo $this->content;
561 }
562 }
563
564 /**
565 * Create the function menu
566 *
567 * @return string HTML of the function menu
568 */
569 public function getFuncMenu() {
570 $funcMenu = '';
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']);
575 }
576 return $funcMenu;
577 }
578
579 /**
580 * Create the panel of buttons for submitting the form or otherwise perform operations.
581 *
582 * @return array all available buttons as an assoc. array
583 */
584 public function getButtons() {
585
586 $buttons = array(
587 'csh' => '',
588 'back' => '',
589 'shortcut' => ''
590 );
591
592 // Shortcut
593 if ($GLOBALS['BE_USER']->mayMakeShortcut()) {
594 $buttons['shortcut'] = $this->doc->makeShortcutIcon('CMD', 'function', $this->MCONF['name']);
595 }
596 // Back
597 if (($this->CMD['showExt'] && (!$this->CMD['standAlone'] && !t3lib_div::_GP('standAlone'))) || ($this->CMD['importExt'] || $this->CMD['uploadExt'] && (!$this->CMD['standAlone'])) || $this->CMD['importExtInfo']) {
598 $buttons['back'] = '<a href="' . t3lib_div::linkThisScript(array(
599 'CMD' => ''
600 )) . '" class="typo3-goBack" title="' . $GLOBALS['LANG']->getLL('go_back') . '">' .
601 t3lib_iconWorks::getSpriteIcon('actions-view-go-back') .
602 '</a>';
603 }
604
605 return $buttons;
606 }
607
608
609 /*********************************
610 *
611 * Function Menu Applications
612 *
613 *********************************/
614
615
616 /**
617 * Listing remote extensions from online repository
618 *
619 * @return void
620 */
621 function extensionList_import() {
622 $content = '';
623
624 // Listing from online repository:
625 if ($this->listRemote) {
626 list($inst_list,) = $this->extensionList->getInstalledExtensions();
627 $this->inst_keys = array_flip(array_keys($inst_list));
628
629 $this->detailCols[1] += 6;
630
631 // see if we have an extensionlist at all
632 $this->extensionCount = $this->xmlHandler->countExtensions();
633 if (!$this->extensionCount) {
634 $content .= $this->fetchMetaData('extensions');
635 }
636
637 if ($this->MOD_SETTINGS['listOrder'] == 'author_company') {
638 $this->listingLimit = $this->listingLimitAuthor;
639 }
640
641 $this->pointer = intval(t3lib_div::_GP('pointer'));
642 $offset = $this->listingLimit * $this->pointer;
643
644 if ($this->MOD_SETTINGS['display_own'] && strlen($this->fe_user['username'])) {
645 $this->xmlHandler->searchExtensionsXML($this->listRemote_search, $this->fe_user['username'], $this->MOD_SETTINGS['listOrder'], TRUE);
646 } else {
647 $this->xmlHandler->searchExtensionsXML($this->listRemote_search, '', $this->MOD_SETTINGS['listOrder'], TRUE, FALSE, $offset, $this->listingLimit);
648 }
649 if (count($this->xmlHandler->extensionsXML)) {
650 list($list, $cat) = $this->extensionList->prepareImportExtList(TRUE);
651
652 // Available extensions
653 if (is_array($cat[$this->MOD_SETTINGS['listOrder']])) {
654 $lines = array();
655 $lines[] = $this->extensionList->extensionListRowHeader(' class="t3-row-header"', array('<td><img src="clear.gif" width="18" height="1" alt="" /></td>'), 1);
656
657 foreach ($cat[$this->MOD_SETTINGS['listOrder']] as $catName => $extEkeys) {
658 if (count($extEkeys)) {
659 $lines[] = '<tr><td colspan="' . (3 + $this->detailCols[$this->MOD_SETTINGS['display_details']]) . '"><br /></td></tr>';
660 $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>';
661 natcasesort($extEkeys);
662 foreach ($extEkeys as $extKey => $value) {
663 $version = array_keys($list[$extKey]['versions']);
664 $version = end($version);
665 $ext = $list[$extKey]['versions'][$version];
666 $ext['downloadcounter_all'] = $list[$extKey]['downloadcounter'];
667 $ext['_ICON'] = $list[$extKey]['_ICON'];
668 $loadUnloadLink = '';
669 if ($inst_list[$extKey]['type'] != 'S' && (!isset($inst_list[$extKey]) || tx_em_Tools::versionDifference($version, $inst_list[$extKey]['EM_CONF']['version'], $this->versionDiffFactor))) {
670 if (isset($inst_list[$extKey])) {
671 // update
672 if ($inst_list[$extKey]['EM_CONF']['state'] != 'excludeFromUpdates') {
673 $loc = ($inst_list[$extKey]['type'] == 'G' ? 'G' : 'L');
674 $aUrl = t3lib_div::linkThisScript(array(
675 'CMD[importExt]' => $extKey,
676 'CMD[extVersion]' => $version,
677 'CMD[loc]' => $loc
678 ));
679 $loadUnloadLink .= '<a href="' . htmlspecialchars($aUrl) . '" title="' . sprintf($GLOBALS['LANG']->getLL('do_update'), ($loc == 'G' ? $GLOBALS['LANG']->getLL('global') : $GLOBALS['LANG']->getLL('local'))) . '">' .
680 t3lib_iconWorks::getSpriteIcon('actions-system-extension-update') .
681 '</a>';
682 } else {
683 // extension is marked as "excludeFromUpdates"
684 $loadUnloadLink .= t3lib_iconWorks::getSpriteIcon('status-dialog-warning', $GLOBALS['LANG']->getLL('excluded_from_updates'));
685 }
686 } else {
687 // import
688 $aUrl = t3lib_div::linkThisScript(array(
689 'CMD[importExt]' => $extKey,
690 'CMD[extVersion]' => $version,
691 'CMD[loc]' => 'L'
692 ));
693 $loadUnloadLink .= '<a href="' . htmlspecialchars($aUrl) . '" title="' . $GLOBALS['LANG']->getLL('import_to_local_dir') . '">' . t3lib_iconWorks::getSpriteIcon('actions-system-extension-import') . '</a>';
694 }
695 } else {
696 $loadUnloadLink = '&nbsp;';
697 }
698
699 if (isset($inst_list[$extKey])) {
700 $theRowClass = t3lib_extMgm::isLoaded($extKey) ? 'em-listbg1' : 'em-listbg2';
701 } else {
702 $theRowClass = 'em-listbg3';
703 }
704
705 $lines[] = $this->extensionList->extensionListRow(
706 $extKey, $ext, array(
707 '<td class="bgColor">' . $loadUnloadLink . '</td>'
708 ), $theRowClass, $inst_list, 1, t3lib_div::linkThisScript(array(
709 'CMD[importExtInfo]' => rawurlencode($extKey)
710 )));
711 unset($list[$extKey]);
712 }
713 }
714 }
715 unset($list);
716
717 // headline and CSH
718 $headline = $GLOBALS['LANG']->getLL('extensions_repository_group_by') . ' ' .
719 $this->MOD_MENU['listOrder'][$this->MOD_SETTINGS['listOrder']];
720 $headline = t3lib_BEfunc::wrapInHelp('_MOD_tools_em', 'import_ter', $headline);
721
722 $onsubmit = "window.location.href='" . $this->script . "&ter_connect=1&ter_search='+escape(this.elements['lookUp'].value);return false;";
723 $content .= '<form action="' . $this->script . '" method="post" onsubmit="' . htmlspecialchars($onsubmit) .
724 '"><label for="lookUp">' . $GLOBALS['LANG']->getLL('list_or_look_up_extensions') . '</label><br />
725 <input type="text" id="lookUp" name="lookUp" value="' . htmlspecialchars($this->listRemote_search) .
726 '" /> <input type="submit" value="' . $GLOBALS['LANG']->getLL('look_up_button') . '" /></form><br /><br />';
727
728 $content .= $this->browseLinks();
729
730 $content .= '
731
732 <!-- TER Extensions list -->
733 <table border="0" cellpadding="2" cellspacing="1">' . implode(LF, $lines) . '</table>';
734 $content .= '<br />' . $this->browseLinks();
735 $content .= '<br /><br />' . $this->securityHint;
736 $content .= '<br /><br /><strong>' . $GLOBALS['LANG']->getLL('privacy_notice_header') .
737 '</strong><br /> ' . $this->privacyNotice;
738
739 $this->content .= $this->doc->section($headline, $content, FALSE, TRUE, FALSE, TRUE);
740
741 // Plugins which are NOT uploaded to repository but present on this server.
742 $content = '';
743 $lines = array();
744 if (count($this->inst_keys)) {
745 foreach ($this->inst_keys as $extKey => $value) {
746 $this->xmlHandler->searchExtensionsXMLExact($extKey, '', '', TRUE, TRUE);
747 if ((strlen($this->listRemote_search) && !stristr($extKey, $this->listRemote_search)) || isset($this->xmlHandler->extensionsXML[$extKey])) {
748 continue;
749 }
750
751 $loadUnloadLink = t3lib_extMgm::isLoaded($extKey) ?
752 '<a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
753 'CMD[showExt]' => $extKey,
754 'CMD[remove]' => 1,
755 'CMD[clrCmd]' => 1,
756 'SET[singleDetails]' => 'info'
757 ))) . '">' . tx_em_Tools::removeButton() . '</a>' :
758 '<a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
759 'CMD[showExt]' => $extKey,
760 'CMD[load]' => 1,
761 'CMD[clrCmd]' => 1,
762 'SET[singleDetails]' => 'info'
763 ))) . '">' . tx_em_Tools::installButton() . '</a>';
764 if (in_array($extKey, $this->requiredExt)) {
765 $loadUnloadLink = '<strong>' . tx_em_Tools::rfw($GLOBALS['LANG']->getLL('extension_required_short')) . '</strong>';
766 }
767 $lines[] = $this->extensionList->extensionListRow($extKey, $inst_list[$extKey], array('<td class="bgColor">' . $loadUnloadLink . '</td>'), t3lib_extMgm::isLoaded($extKey) ? 'em-listbg1' : 'em-listbg2');
768 }
769 }
770 if (count($lines)) {
771 $content .= $GLOBALS['LANG']->getLL('list_of_local_extensions') .
772 '<br />' . $GLOBALS['LANG']->getLL('might_be_user_defined') . '<br /><br />';
773 $content .= '<table border="0" cellpadding="2" cellspacing="1">' .
774 $this->extensionList->extensionListRowHeader(' class="t3-row-header"', array('<td><img src="clear.gif" width="18" height="1" alt="" /></td>')) .
775 implode('', $lines) . '</table>';
776 $this->content .= $this->doc->spacer(20);
777 $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('only_on_this_server'), $content, 0, 1);
778 }
779 }
780 } else {
781 // headline and CSH
782 $headline = $GLOBALS['LANG']->getLL('extensions_repository_group_by') . ' ' .
783 $this->MOD_MENU['listOrder'][$this->MOD_SETTINGS['listOrder']];
784 $headline = t3lib_BEfunc::wrapInHelp('_MOD_tools_em', 'import_ter', $headline);
785
786 $onsubmit = "window.location.href='" . $this->script . "&ter_connect=1&ter_search='+escape(this.elements['lookUp'].value);return false;";
787 $content .= '<form action="' . $this->script . '" method="post" onsubmit="' . htmlspecialchars($onsubmit) .
788 '"><label for="lookUp">' .
789 $GLOBALS['LANG']->getLL('list_or_look_up_extensions') . '</label><br />
790 <input type="text" id="lookUp" name="lookUp" value="' . htmlspecialchars($this->listRemote_search) .
791 '" /> <input type="submit" value="' . $GLOBALS['LANG']->getLL('look_up_button') . '" /></form><br /><br />';
792
793 $content .= '<p><strong>' . $GLOBALS['LANG']->getLL('no_matching_extensions') . '</strong></p>';
794
795 $content .= '<br /><br /><strong>' . $GLOBALS['LANG']->getLL('privacy_notice_header') .
796 '</strong><br /> ' . $this->privacyNotice;
797 $this->content .= $this->doc->section($headline, $content, FALSE, TRUE, 0, TRUE);
798 }
799 } else {
800 // section headline and CSH
801 $headline = $GLOBALS['LANG']->getLL('in_repository');
802 $headline = t3lib_BEfunc::wrapInHelp('_MOD_tools_em', 'import', $headline);
803
804 $onsubmit = "window.location.href='" . $this->script . "&ter_connect=1&ter_search='+escape(this.elements['lookUp'].value);return false;";
805 $content .= '<form action="' . $this->script . '" method="post" onsubmit="' . htmlspecialchars($onsubmit) .
806 '"><label for="lookUp">' .
807 $GLOBALS['LANG']->getLL('list_or_look_up_extensions') . '</label><br />
808 <input type="text" id="lookUp" name="lookUp" value="" /> <input type="submit" value="' .
809 $GLOBALS['LANG']->getLL('look_up_button') . '" /><br /><br />';
810
811 if ($this->CMD['fetchMetaData']) { // fetches mirror/extension data from online rep.
812 $content .= $this->fetchMetaData($this->CMD['fetchMetaData']);
813 } else {
814 $onCLick = 'window.location.href="' . t3lib_div::linkThisScript(array(
815 'CMD[fetchMetaData]' => 'extensions'
816 )) . '";return false;';
817 $content .= $GLOBALS['LANG']->getLL('connect_to_ter') . '<br />
818 <input type="submit" value="' . $GLOBALS['LANG']->getLL('retrieve_update') .
819 '" onclick="' . htmlspecialchars($onCLick) . '" />';
820 if (is_file(PATH_site . 'typo3temp/extensions.xml.gz')) {
821 $dateFormat = $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'];
822 $timeFormat = $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'];
823 $content .= ' ' . sprintf($GLOBALS['LANG']->getLL('ext_list_last_updated') . ' ',
824 date(
825 $dateFormat . ', ' . $timeFormat,
826 filemtime(PATH_site . 'typo3temp/extensions.xml.gz')
827 ),
828 tx_em_Database::getExtensionCountFromRepository()
829 );
830 }
831 }
832 $content .= '</form><br /><br />' . $this->securityHint;
833 $content .= '<br /><br /><strong>' . $GLOBALS['LANG']->getLL('privacy_notice_header') .
834 '</strong><br />' . $this->privacyNotice;
835
836 $this->content .= $this->doc->section($headline, $content, FALSE, TRUE, FALSE, TRUE);
837 }
838
839 // Upload:
840 if ($this->importAtAll()) {
841 $content = '<form action="' . $this->script . '" enctype="' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['form_enctype'] . '" method="post">
842 <label for="upload_ext_file">' . $GLOBALS['LANG']->getLL('upload_t3x') . '</label><br />
843 <input type="file" size="60" id="upload_ext_file" name="upload_ext_file" /><br />' .
844 $GLOBALS['LANG']->getLL('upload_to_location') . '<br />
845 <select name="CMD[loc]">';
846 if (tx_em_Tools::importAsType('L')) {
847 $content .= '<option value="L">' . $GLOBALS['LANG']->getLL('local_folder') . '</option>';
848 }
849 if (tx_em_Tools::importAsType('G')) {
850 $content .= '<option value="G">' . $GLOBALS['LANG']->getLL('global_folder') . '</option>';
851 }
852 if (tx_em_Tools::importAsType('S')) {
853 $content .= '<option value="S">' . $GLOBALS['LANG']->getLL('system_folder') . '</option>';
854 }
855 $content .= '</select><br />
856 <input type="checkbox" value="1" name="CMD[uploadOverwrite]" id="checkUploadOverwrite" /> <label for="checkUploadOverwrite">' .
857 $GLOBALS['LANG']->getLL('overwrite_ext') . '</label><br />
858 <input type="submit" name="CMD[uploadExt]" value="' . $GLOBALS['LANG']->getLL('upload_ext_file') . '" /></form><br />
859 ';
860 } else {
861 $content = tx_em_Tools::noImportMsg();
862 }
863
864 $this->content .= $this->doc->spacer(20);
865 $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('upload_ext_directly'), $content, 0, 1);
866 }
867
868 /**
869 * Generates a link to the next page of extensions
870 *
871 * @return string
872 */
873 function browseLinks() {
874 $content = '';
875 if ($this->pointer) {
876 $content .= '<a href="' . t3lib_div::linkThisScript(array('pointer' => $this->pointer - 1)) .
877 '" class="typo3-prevPage"><img' . t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],
878 'gfx/pilleft_n.gif', 'width="14" height="14"') .
879 ' alt="' . $GLOBALS['LANG']->getLL('previous_page') . '" /> ' .
880 $GLOBALS['LANG']->getLL('previous_page') . '</a>';
881 }
882 if ($content) {
883 $content .= '&nbsp;&nbsp;&nbsp;';
884 }
885 if (intval($this->xmlHandler->matchingCount / $this->listingLimit) > $this->pointer) {
886 $content .= '<a href="' . t3lib_div::linkThisScript(array('pointer' => $this->pointer + 1)) .
887 '" class="typo3-nextPage"><img' . t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],
888 'gfx/pilright_n.gif', 'width="14" height="14"') .
889 ' alt="' . $GLOBALS['LANG']->getLL('next_page') . '" /> ' .
890 $GLOBALS['LANG']->getLL('next_page') . '</a>';
891 }
892 $upper = (($this->pointer + 1) * $this->listingLimit);
893 if ($upper > $this->xmlHandler->matchingCount) {
894 $upper = $this->xmlHandler->matchingCount;
895 }
896 if ($content) {
897 $content .= '<br /><br />' .
898 sprintf($GLOBALS['LANG']->getLL('showing_extensions_from_to'),
899 '<strong>' . ($this->pointer * $this->listingLimit + 1) . '</strong>',
900 '<strong>' . $upper . '</strong>'
901 );
902 }
903 if ($content) {
904 $content .= '<br /><br />';
905 }
906 return $content;
907 }
908
909 /**
910 * Allows changing of settings
911 *
912 * @return string
913 */
914 function alterSettings() {
915 $content = '';
916 // Prepare the HTML output:
917 $content .= '
918 <form action="' . $this->script . '" method="post" name="altersettings">
919 <fieldset><legend>' . $GLOBALS['LANG']->getLL('user_settings') . '</legend>
920 <table border="0" cellpadding="2" cellspacing="2">
921 <tr class="bgColor4">
922 <td><label for="set_fe_u">' . $GLOBALS['LANG']->getLL('enter_repository_username') . '</label></td>
923 <td><input type="text" id="set_fe_u" name="SET[fe_u]" value="' . htmlspecialchars($this->MOD_SETTINGS['fe_u']) . '" /></td>
924 </tr>
925 <tr class="bgColor4">
926 <td><label for="set_fe_p">' . $GLOBALS['LANG']->getLL('enter_repository_password') . '</label></td>
927 <td><input type="password" id="set_fe_p" name="SET[fe_p]" value="' . htmlspecialchars($this->MOD_SETTINGS['fe_p']) . '" /></td>
928 </tr>
929 </table>
930 <strong>' . $GLOBALS['LANG']->getLL('notice') . '</strong> ' .
931 $GLOBALS['LANG']->getLL('repository_password_info') . '
932 </fieldset>
933 <br />
934 <br />
935 <fieldset><legend>' . $GLOBALS['LANG']->getLL('mirror_selection') . '</legend>
936 <table border="0" cellpadding="2" cellspacing="2">
937 <tr class="bgColor4">
938 <td><label for="set_mirror_list_url">' . $GLOBALS['LANG']->getLL('mirror_list_url') . '</label></td>
939 <td><input type="text" size="50" id="set_mirror_list_url" name="SET[mirrorListURL]" value="' . htmlspecialchars($this->MOD_SETTINGS['mirrorListURL']) . '" /></td>
940 </tr>
941 </table>
942 </fieldset>
943 <br />
944 <p>' . $GLOBALS['LANG']->getLL('mirror_select') . '<br /><br /></p>
945 <fieldset><legend>' . $GLOBALS['LANG']->getLL('mirror_list') . '</legend>';
946 if (!empty($this->MOD_SETTINGS['mirrorListURL'])) {
947 if ($this->CMD['fetchMetaData']) { // fetches mirror/extension data from online rep.
948 $content .= $this->fetchMetaData($this->CMD['fetchMetaData']);
949 } else {
950 $content .= '<a href="' . t3lib_div::linkThisScript(array(
951 'CMD[fetchMetaData]' => 'mirrors'
952 )) . '">' . $GLOBALS['LANG']->getLL('mirror_list_reload') . '</a>';
953 }
954 }
955 $content .= '<br />
956 <table cellspacing="4" style="text-align:left; vertical-alignment:top;">
957 <tr>
958 <td>' . $GLOBALS['LANG']->getLL('mirror_use') . '</td>
959 <td>' . $GLOBALS['LANG']->getLL('mirror_name') . '</td>
960 <td>' . $GLOBALS['LANG']->getLL('mirror_url') . '</td>
961 <td>' . $GLOBALS['LANG']->getLL('mirror_country') . '</td>
962 <td>' . $GLOBALS['LANG']->getLL('mirror_sponsored_by') . '</td>
963 </tr>
964 ';
965
966 if (!strlen($this->MOD_SETTINGS['extMirrors'])) {
967 $this->fetchMetaData('mirrors');
968 }
969 $extMirrors = unserialize($this->MOD_SETTINGS['extMirrors']);
970 $extMirrors[''] = array('title' => $GLOBALS['LANG']->getLL('mirror_use_random'));
971 ksort($extMirrors);
972 if (is_array($extMirrors)) {
973 foreach ($extMirrors as $k => $v) {
974 if (isset($v['sponsor'])) {
975 $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 }
977 $selected = ($this->MOD_SETTINGS['selectedMirror'] == $k) ? 'checked="checked"' : '';
978 $content .= '<tr class="bgColor4">
979 <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>';
980 }
981 }
982 $content .= '
983 </table>
984 </fieldset>
985 <fieldset>
986 <br />
987 <table border="0" cellpadding="2" cellspacing="2">
988 <tr class="bgColor4">
989 <td><label for="set_rep_url">' . $GLOBALS['LANG']->getLL('enter_repository_url') . '</label></td>
990 <td><input type="text" size="50" id="set_rep_url" name="SET[rep_url]" value="' . htmlspecialchars($this->MOD_SETTINGS['rep_url']) . '" /></td>
991 </tr>
992 </table>
993
994 ' . $GLOBALS['LANG']->getLL('repository_url_hint') . '<br />
995 </fieldset>
996 <br />
997 <input type="submit" value="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_tsfe.xml:update') . '" />
998 </form>
999 ';
1000
1001 return $content;
1002 }
1003
1004 /*********************************
1005 *
1006 * Command Applications (triggered by GET var)
1007 *
1008 *********************************/
1009
1010 /**
1011 * Returns detailed info about an extension in the online repository
1012 *
1013 * @param string Extension repository uid + optional "private key": [uid]-[key].
1014 * @param [type] $version: ...
1015 * @return void
1016 */
1017 function importExtInfo($extKey, $version = '') {
1018
1019 $content = '<form action="' . $this->script . '" method="post" name="pageform">';
1020 $addUrl = '';
1021 if ($this->noDocHeader) {
1022 $content .= '<input type="hidden" name="nodoc" value="1" />';
1023 $addUrl = '&nodoc=1';
1024 }
1025 // Fetch remote data:
1026 $this->xmlHandler->searchExtensionsXMLExact($extKey, '', '', TRUE, TRUE);
1027 list($fetchData,) = $this->extensionList->prepareImportExtList(TRUE);
1028
1029 $versions = array_keys($fetchData[$extKey]['versions']);
1030 natsort($versions);
1031 $version = ($version == '') ? end($versions) : $version;
1032
1033 $opt = array();
1034 foreach ($versions as $ver) {
1035 $opt[] = '<option value="' . $ver . '"' . (($version == $ver) ? ' selected="selected"' : '') . '>' . $ver . '</option>';
1036 }
1037
1038 // "Select version" box:
1039 $onClick = 'window.location.href="' . $this->script . $addUrl . '&CMD[importExtInfo]=' . $extKey . '&CMD[extVersion]="+document.pageform.extVersion.options[document.pageform.extVersion.selectedIndex].value; return false;';
1040 $select = '<select name="extVersion">' . implode('', $opt) .
1041 '</select> <input type="submit" value="' . $GLOBALS['LANG']->getLL('ext_load_details_button') .
1042 '" onclick="' . htmlspecialchars($onClick) . '" />';
1043
1044 if ($this->importAtAll()) {
1045 // Check for write-protected extension
1046 list($inst_list,) = $this->extensionList->getInstalledExtensions();
1047 if ($inst_list[$extKey]['EM_CONF']['state'] != 'excludeFromUpdates') {
1048 $onClick = '
1049 window.location.href="' . $this->script . $addUrl . '&CMD[importExt]=' . $extKey . '"
1050 +"&CMD[extVersion]="+document.pageform.extVersion.options[document.pageform.extVersion.selectedIndex].value
1051 +"&CMD[loc]="+document.pageform.loc.options[document.pageform.loc.selectedIndex].value;
1052 return false;';
1053 $select .= ' ' . $GLOBALS['LANG']->getLL('ext_or') . '<br /><br />
1054 <input type="submit" value="' . $GLOBALS['LANG']->getLL('ext_import_update_button') .
1055 '" onclick="' . htmlspecialchars($onClick) . '" /> ' . $GLOBALS['LANG']->getLL('ext_import_update_to') . '
1056 <select name="loc">' .
1057 (tx_em_Tools::importAsType('G', $fetchData['emconf_lockType']) ?
1058 '<option value="G">' . $GLOBALS['LANG']->getLL('ext_import_global') . ' ' . tx_em_Tools::typePath('G') . $extKey . '/' .
1059 (@is_dir(tx_em_Tools::typePath('G') . $extKey) ?
1060 ' ' . $GLOBALS['LANG']->getLL('ext_import_overwrite') :
1061 ' ' . $GLOBALS['LANG']->getLL('ext_import_folder_empty')
1062 ) . '</option>' : ''
1063 ) .
1064 (tx_em_Tools::importAsType('L', $fetchData['emconf_lockType']) ?
1065 '<option value="L">' . $GLOBALS['LANG']->getLL('ext_import_local') . ' ' . tx_em_Tools::typePath('L') . $extKey . '/' .
1066 (@is_dir(tx_em_Tools::typePath('L') . $extKey) ?
1067 ' ' . $GLOBALS['LANG']->getLL('ext_import_overwrite') :
1068 ' ' . $GLOBALS['LANG']->getLL('ext_import_folder_empty')
1069 ) . '</option>' : ''
1070 ) .
1071 (tx_em_Tools::importAsType('S', $fetchData['emconf_lockType']) ?
1072 '<option value="S">' . $GLOBALS['LANG']->getLL('ext_import_system') . ' ' . tx_em_Tools::typePath('S') . $extKey . '/' .
1073 (@is_dir(tx_em_Tools::typePath('S') . $extKey) ?
1074 ' ' . $GLOBALS['LANG']->getLL('ext_import_overwrite') :
1075 ' ' . $GLOBALS['LANG']->getLL('ext_import_folder_empty')
1076 ) . '</option>' : ''
1077 ) .
1078 '</select>
1079 </form>';
1080 } else {
1081 $select .= '<br /><br />' . $GLOBALS['LANG']->getLL('ext_import_excluded_from_updates');
1082 }
1083 } else {
1084 $select .= '<br /><br />' . tx_em_Tools::noImportMsg();
1085 }
1086 $content .= $select;
1087 $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('ext_import_select_command'), $content, 0, 1);
1088
1089 // Details:
1090 $eInfo = $fetchData[$extKey]['versions'][$version];
1091 $content = '<strong>' . $fetchData[$extKey]['_ICON'] . ' &nbsp;' . $eInfo['EM_CONF']['title'] . ' (' . $extKey . ', ' . $version . ')</strong><br /><br />';
1092 $content .= $this->extensionDetails->extInformationarray($extKey, $eInfo, 1);
1093 $this->content .= $this->doc->spacer(10);
1094 $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('ext_import_remote_ext_details'), $content, 0, 1);
1095 }
1096
1097 /**
1098 * Fetches metadata and stores it to the corresponding place. This includes the mirror list,
1099 * extension XML files.
1100 *
1101 * @param string Type of data to fetch: (mirrors)
1102 * @param boolean If TRUE the method doesn't produce any output
1103 * @return string
1104 */
1105 function fetchMetaData($metaType) {
1106 $content = '';
1107 switch ($metaType) {
1108 case 'mirrors':
1109 $mfile = t3lib_div::tempnam('mirrors');
1110 $mirrorsFile = t3lib_div::getUrl($this->MOD_SETTINGS['mirrorListURL'], 0, array(TYPO3_user_agent));
1111 if ($mirrorsFile===FALSE) {
1112 t3lib_div::unlink_tempfile($mfile);
1113 $content = '<p>' .
1114 sprintf($GLOBALS['LANG']->getLL('ext_import_list_not_updated'),
1115 $this->MOD_SETTINGS['mirrorListURL']
1116 ) . ' ' .
1117 $GLOBALS['LANG']->getLL('translation_problems') . '</p>';
1118 } else {
1119 t3lib_div::writeFile($mfile, $mirrorsFile);
1120 $mirrors = implode('', gzfile($mfile));
1121 t3lib_div::unlink_tempfile($mfile);
1122
1123 $mirrors = $this->xmlHandler->parseMirrorsXML($mirrors);
1124 if (is_array($mirrors) && count($mirrors)) {
1125 t3lib_BEfunc::getModuleData($this->MOD_MENU, array('extMirrors' => serialize($mirrors)), $this->MCONF['name'], '', 'extMirrors');
1126 $this->MOD_SETTINGS['extMirrors'] = serialize($mirrors);
1127 $content = '<p>' .
1128 sprintf($GLOBALS['LANG']->getLL('ext_import_list_updated'),
1129 count($mirrors)
1130 ) . '</p>';
1131 }
1132 else {
1133 $content = '<p>' . $mirrors . '<br />' . $GLOBALS['LANG']->getLL('ext_import_list_empty') . '</p>';
1134 }
1135 }
1136 break;
1137 case 'extensions':
1138 $this->fetchMetaData('mirrors'); // if we fetch the extensions anyway, we can as well keep this up-to-date
1139
1140 $mirror = $this->getMirrorURL();
1141 $extfile = $mirror . 'extensions.xml.gz';
1142 $extmd5 = t3lib_div::getUrl($mirror . 'extensions.md5', 0, array(TYPO3_user_agent));
1143 $localmd5 = '';
1144 if (is_file(PATH_site . 'typo3temp/extensions.xml.gz')) {
1145 $localmd5 = md5_file(PATH_site . 'typo3temp/extensions.xml.gz');
1146 }
1147
1148 // count cached extensions. If cache is empty re-fill it
1149 $cacheCount = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('extkey', 'cache_extensions');
1150
1151 if ($extmd5 === FALSE) {
1152 $content .= '<p>' .
1153 sprintf($GLOBALS['LANG']->getLL('ext_import_md5_not_updated'),
1154 $mirror . 'extensions.md5'
1155 ) .
1156 $GLOBALS['LANG']->getLL('translation_problems') . '</p>';
1157 } elseif ($extmd5 == $localmd5 && $cacheCount) {
1158 /** @var $flashMessage t3lib_FlashMessage */
1159 $flashMessage = t3lib_div::makeInstance(
1160 't3lib_FlashMessage',
1161 $GLOBALS['LANG']->getLL('ext_import_list_unchanged'),
1162 $GLOBALS['LANG']->getLL('ext_import_list_unchanged_header'),
1163 t3lib_FlashMessage::INFO
1164 );
1165 $content .= $flashMessage->render();
1166 } else {
1167 $extXML = t3lib_div::getUrl($extfile, 0, array(TYPO3_user_agent));
1168 if ($extXML === FALSE) {
1169 $content .= '<p>' .
1170 sprintf($GLOBALS['LANG']->getLL('ext_import_list_unchanged'),
1171 $extfile
1172 ) . ' ' .
1173 $GLOBALS['LANG']->getLL('translation_problems') . '</p>';
1174 } else {
1175 t3lib_div::writeFile(PATH_site . 'typo3temp/extensions.xml.gz', $extXML);
1176 $content .= $this->xmlHandler->parseExtensionsXML(PATH_site . 'typo3temp/extensions.xml.gz');
1177 }
1178 }
1179 break;
1180 }
1181
1182 return $content;
1183 }
1184
1185 /**
1186 * Returns the base URL for the selected or a random mirror.
1187 *
1188 * @return string The URL for the selected or a random mirror
1189 */
1190 function getMirrorURL() {
1191 if (strlen($this->MOD_SETTINGS['rep_url'])) {
1192 return $this->MOD_SETTINGS['rep_url'];
1193 }
1194
1195 $mirrors = unserialize($this->MOD_SETTINGS['extMirrors']);
1196 if (!is_array($mirrors)) {
1197 $this->fetchMetaData('mirrors');
1198 $mirrors = unserialize($this->MOD_SETTINGS['extMirrors']);
1199 if (!is_array($mirrors)) {
1200 return FALSE;
1201 }
1202 }
1203 if ($this->MOD_SETTINGS['selectedMirror'] == '') {
1204 $rand = array_rand($mirrors);
1205 $url = 'http://' . $mirrors[$rand]['host'] . $mirrors[$rand]['path'];
1206 }
1207 else {
1208 $selectedMirror = NULL;
1209 foreach ($mirrors as $mirror) {
1210 if ($mirror['host'] === $this->MOD_SETTINGS['selectedMirror']) {
1211 $selectedMirror = $mirror;
1212 break;
1213 }
1214 }
1215 $url = 'http://' . $selectedMirror['host'] . $selectedMirror['path'];
1216 }
1217
1218 return $url;
1219 }
1220
1221
1222 /**
1223 * Installs (activates) an extension
1224 *
1225 * For $mode use the three constants EM_INSTALL_VERSION_MIN, EM_INSTALL_VERSION_MAX, EM_INSTALL_VERSION_STRICT
1226 *
1227 * If an extension is loaded or imported already and the version requirement is matched, it will not be
1228 * fetched from the repository. This means, if you use EM_INSTALL_VERSION_MIN, you will not always get the latest
1229 * version of an extension!
1230 *
1231 * @param string $extKey The extension key to install
1232 * @param string $version A version number that should be installed
1233 * @param int $mode If a version is requested, this determines if it is the min, max or strict version requested
1234 * @return [type] ...
1235 * @todo Make the method able to handle needed interaction somehow (unmatched dependencies)
1236 */
1237 function installExtension($extKey, $version = NULL, $mode = EM_INSTALL_VERSION_MIN) {
1238 list($inst_list,) = $this->extensionList->getInstalledExtensions();
1239
1240 // check if it is already installed and loaded with sufficient version
1241 if (isset($inst_list[$extKey])) {
1242 $currentVersion = $inst_list[$extKey]['EM_CONF']['version'];
1243
1244 if (t3lib_extMgm::isLoaded($extKey)) {
1245 if ($version===NULL) {
1246 return array(TRUE, $GLOBALS['LANG']->getLL('ext_import_ext_already_installed_loaded'));
1247 } else {
1248 switch ($mode) {
1249 case EM_INSTALL_VERSION_STRICT:
1250 if ($currentVersion == $version) {
1251 return array(TRUE, $GLOBALS['LANG']->getLL('ext_import_ext_already_installed_loaded'));
1252 }
1253 break;
1254 case EM_INSTALL_VERSION_MIN:
1255 if (version_compare($currentVersion, $version, '>=')) {
1256 return array(TRUE, $GLOBALS['LANG']->getLL('ext_import_ext_already_installed_loaded'));
1257 }
1258 break;
1259 case EM_INSTALL_VERSION_MAX:
1260 if (version_compare($currentVersion, $version, '<=')) {
1261 return array(TRUE, $GLOBALS['LANG']->getLL('ext_import_ext_already_installed_loaded'));
1262 }
1263 break;
1264 }
1265 }
1266 } else {
1267 if (!t3lib_extMgm::isLocalconfWritable()) {
1268 return array(FALSE, $GLOBALS['LANG']->getLL('ext_import_p_localconf'));
1269 }
1270 $newExtList = -1;
1271 switch ($mode) {
1272 case EM_INSTALL_VERSION_STRICT:
1273 if ($currentVersion == $version) {
1274 $newExtList = $this->extensionList->addExtToList($extKey, $inst_list);
1275 }
1276 break;
1277 case EM_INSTALL_VERSION_MIN:
1278 if (version_compare($currentVersion, $version, '>=')) {
1279 $newExtList = $this->extensionList->addExtToList($extKey, $inst_list);
1280 }
1281 break;
1282 case EM_INSTALL_VERSION_MAX:
1283 if (version_compare($currentVersion, $version, '<=')) {
1284 $newExtList = $this->extensionList->addExtToList($extKey, $inst_list);
1285 }
1286 break;
1287 }
1288 if ($newExtList != -1) {
1289 $this->install->writeNewExtensionList($newExtList);
1290 tx_em_Tools::refreshGlobalExtList();
1291 $this->install->forceDBupdates($extKey, $inst_list[$extKey]);
1292 return array(TRUE, $GLOBALS['LANG']->getLL('ext_import_ext_loaded'));
1293 }
1294 }
1295 }
1296
1297 // at this point we know we need to import (a matching version of) the extension from TER2
1298
1299 // see if we have an extension list at all
1300 if (!$this->xmlHandler->countExtensions()) {
1301 $this->fetchMetaData('extensions');
1302 }
1303 $this->xmlHandler->searchExtensionsXMLExact($extKey, '', '', TRUE);
1304
1305 // check if extension can be fetched
1306 if (isset($this->xmlHandler->extensionsXML[$extKey])) {
1307 $versions = array_keys($this->xmlHandler->extensionsXML[$extKey]['versions']);
1308 $latestVersion = end($versions);
1309 switch ($mode) {
1310 case EM_INSTALL_VERSION_STRICT:
1311 if (!isset($this->xmlHandler->extensionsXML[$extKey]['versions'][$version])) {
1312 return array(FALSE, $GLOBALS['LANG']->getLL('ext_import_ext_n_a'));
1313 }
1314 break;
1315 case EM_INSTALL_VERSION_MIN:
1316 if (version_compare($latestVersion, $version, '>=')) {
1317 $version = $latestVersion;
1318 } else {
1319 return array(FALSE, $GLOBALS['LANG']->getLL('ext_import_ext_n_a'));
1320 }
1321 break;
1322 case EM_INSTALL_VERSION_MAX:
1323 while (($v = array_pop($versions)) && version_compare($v, $version, '>=')) {
1324 // Loop until a version is found
1325 }
1326
1327 if ($v !== NULL && version_compare($v, $version, '<=')) {
1328 $version = $v;
1329 } else {
1330 return array(FALSE, $GLOBALS['LANG']->getLL('ext_import_ext_n_a'));
1331 }
1332 break;
1333 }
1334 $this->importExtFromRep($extKey, $version, 'L');
1335 $newExtList = $this->extensionList->addExtToList($extKey, $inst_list);
1336 if ($newExtList != -1) {
1337 $this->install->writeNewExtensionList($newExtList);
1338 tx_em_Tools::refreshGlobalExtList();
1339 $this->install->forceDBupdates($extKey, $inst_list[$extKey]);
1340 $this->translations->installTranslationsForExtension($extKey, $this->getMirrorURL());
1341 return array(TRUE, $GLOBALS['LANG']->getLL('ext_import_ext_imported'));
1342 } else {
1343 return array(FALSE, $GLOBALS['LANG']->getLL('ext_import_ext_not_loaded'));
1344 }
1345 } else {
1346 return array(FALSE, $GLOBALS['LANG']->getLL('ext_import_ext_n_a_rep'));
1347 }
1348 }
1349
1350
1351 /**
1352 * Imports an extensions from the online repository
1353 * NOTICE: in version 4.0 this changed from "importExtFromRep_old($extRepUid,$loc,$uploadFlag=0,$directInput='',$recentTranslations=0,$incManual=0,$dontDelete=0)"
1354 *
1355 * @param string Extension key
1356 * @param string Version
1357 * @param string Install scope: "L" or "G" or "S"
1358 * @param boolean If TRUE, extension is uploaded as file
1359 * @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.
1360 * @param array Direct input array (like from kickstarter)
1361 * @return string Return FALSE on success, returns error message if error.
1362 */
1363 function importExtFromRep($extKey, $version, $loc, $uploadFlag = 0, $dontDelete = 0, $directInput = '') {
1364
1365 $uploadSucceed = FALSE;
1366 $uploadedTempFile = '';
1367 if (is_array($directInput)) {
1368 $fetchData = array($directInput, '');
1369 $loc = ($loc==='G' || $loc==='S') ? $loc : 'L';
1370 } elseif ($uploadFlag) {
1371 if (($uploadedTempFile = $this->CMD['alreadyUploaded']) || $_FILES['upload_ext_file']['tmp_name']) {
1372
1373 // Read uploaded file:
1374 if (!$uploadedTempFile) {
1375 if (!is_uploaded_file($_FILES['upload_ext_file']['tmp_name'])) {
1376 t3lib_div::sysLog('Possible file upload attack: ' . $_FILES['upload_ext_file']['tmp_name'], 'Extension Manager', 3);
1377
1378 /** @var $flashMessage t3lib_FlashMessage */
1379 $flashMessage = t3lib_div::makeInstance(
1380 't3lib_FlashMessage',
1381 $GLOBALS['LANG']->getLL('ext_import_file_not_uploaded'),
1382 '',
1383 t3lib_FlashMessage::ERROR
1384 );
1385 return $flashMessage->render();
1386 }
1387
1388 $uploadedTempFile = t3lib_div::upload_to_tempfile($_FILES['upload_ext_file']['tmp_name']);
1389 }
1390 $fileContent = t3lib_div::getUrl($uploadedTempFile);
1391
1392 if (!$fileContent) {
1393 $flashMessage = t3lib_div::makeInstance(
1394 't3lib_FlashMessage',
1395 $GLOBALS['LANG']->getLL('ext_import_file_empty'),
1396 '',
1397 t3lib_FlashMessage::ERROR
1398 );
1399 return $flashMessage->render();
1400 }
1401
1402 // Decode file data:
1403 $fetchData = $this->terConnection->decodeExchangeData($fileContent);
1404
1405 if (is_array($fetchData)) {
1406 $extKey = $fetchData[0]['extKey'];
1407 if ($extKey) {
1408 if (!$this->CMD['uploadOverwrite']) {
1409 $loc = ($loc==='G' || $loc==='S') ? $loc : 'L';
1410 $comingExtPath = tx_em_Tools::typePath($loc) . $extKey . '/';
1411 if (@is_dir($comingExtPath)) {
1412 $flashMessage = t3lib_div::makeInstance(
1413 't3lib_FlashMessage',
1414 sprintf($GLOBALS['LANG']->getLL('ext_import_ext_present_no_overwrite'), $comingExtPath) .
1415 '<br />' . $GLOBALS['LANG']->getLL('ext_import_ext_present_nothing_done'),
1416 '',
1417 t3lib_FlashMessage::ERROR
1418 );
1419 return $flashMessage->render();
1420 } // ... else go on, install...
1421 } // ... else go on, install...
1422 } else {
1423 $flashMessage = t3lib_div::makeInstance(
1424 't3lib_FlashMessage',
1425 $GLOBALS['LANG']->getLL('ext_import_no_key'),
1426 '',
1427 t3lib_FlashMessage::ERROR
1428 );
1429 return $flashMessage->render();
1430 }
1431 } else {
1432 $flashMessage = t3lib_div::makeInstance(
1433 't3lib_FlashMessage',
1434 sprintf($GLOBALS['LANG']->getLL('ext_import_wrong_file_format'), $fetchData),
1435 '',
1436 t3lib_FlashMessage::ERROR
1437 );
1438 return $flashMessage->render();
1439 }
1440 } else {
1441 $flashMessage = t3lib_div::makeInstance(
1442 't3lib_FlashMessage',
1443 $GLOBALS['LANG']->getLL('ext_import_no_file'),
1444 '',
1445 t3lib_FlashMessage::ERROR
1446 );
1447 return $flashMessage->render();
1448 }
1449 } else {
1450 $this->xmlHandler->searchExtensionsXMLExact($extKey, '', '', TRUE, TRUE);
1451
1452 // Fetch extension from TER:
1453 if (!strlen($version)) {
1454 $versions = array_keys($this->xmlHandler->extensionsXML[$extKey]['versions']);
1455 // sort version numbers ascending to pick the highest version
1456 natsort($versions);
1457 $version = end($versions);
1458 }
1459 $fetchData = $this->terConnection->fetchExtension($extKey, $version, $this->xmlHandler->extensionsXML[$extKey]['versions'][$version]['t3xfilemd5'], $this->getMirrorURL());
1460 }
1461
1462 // At this point the extension data should be present; so we want to write it to disc:
1463 $content = $this->install->installExtension($fetchData, $loc, $version, $uploadedTempFile, $dontDelete);
1464
1465 $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('ext_import_results'), $content, 0, 1);
1466
1467 if ($uploadSucceed && $uploadedTempFile) {
1468 t3lib_div::unlink_tempfile($uploadedTempFile);
1469 }
1470
1471 return FALSE;
1472 }
1473
1474 /**
1475 * Display extensions details.
1476 *
1477 * @param string Extension key
1478 * @return void Writes content to $this->content
1479 */
1480 function showExtDetails($extKey) {
1481 $theOutput = '';
1482 $dependencyUpdates = '';
1483 list($list,) = $this->extensionList->getInstalledExtensions();
1484 $absPath = tx_em_Tools::getExtPath($extKey, $list[$extKey]['type']);
1485
1486 // Check updateModule:
1487 if (isset($list[$extKey]) && @is_file($absPath . 'class.ext_update.php')) {
1488 require_once($absPath . 'class.ext_update.php');
1489 $updateObj = new ext_update;
1490 if (!$updateObj->access()) {
1491 unset($this->MOD_MENU['singleDetails']['updateModule']);
1492 }
1493 } else {
1494 unset($this->MOD_MENU['singleDetails']['updateModule']);
1495 }
1496
1497 if ($this->CMD['doDelete']) {
1498 $this->MOD_MENU['singleDetails'] = array();
1499 }
1500
1501 // Function menu here:
1502 if (!$this->CMD['standAlone'] && !t3lib_div::_GP('standAlone')) {
1503 $content = $GLOBALS['LANG']->getLL('ext_details_ext') . '&nbsp;<strong>' .
1504 $this->extensionTitleIconHeader($extKey, $list[$extKey]) . '</strong> (' . htmlspecialchars($extKey) . ')';
1505 $this->content .= $this->doc->section('', $content);
1506 }
1507
1508 // Show extension details:
1509 if ($list[$extKey]) {
1510
1511 // Checking if a command for install/uninstall is executed:
1512 if (($this->CMD['remove'] || $this->CMD['load']) && !in_array($extKey, $this->requiredExt)) {
1513
1514 // Install / Uninstall extension here:
1515 if (t3lib_extMgm::isLocalconfWritable()) {
1516 // Check dependencies:
1517 $depStatus = $this->install->checkDependencies($extKey, $list[$extKey]['EM_CONF'], $list);
1518
1519 if (!$this->CMD['remove'] && !$depStatus['returnCode']) {
1520 $this->content .= $depStatus['html'];
1521 $newExtList = -1;
1522 } elseif ($this->CMD['remove']) {
1523 $newExtList = $this->extensionList->removeExtFromList($extKey, $list);
1524 } else {
1525 $newExtList = $this->extensionList->addExtToList($extKey, $list);
1526 }
1527
1528 // Successful installation:
1529 if ($newExtList != -1) {
1530 $updates = '';
1531 if ($this->CMD['load']) {
1532 if ($_SERVER['REQUEST_METHOD'] == 'POST') {
1533 $script = t3lib_div::linkThisScript(array(
1534 'CMD[showExt]' => $extKey,
1535 'CMD[load]' => 1,
1536 'CMD[clrCmd]' => $this->CMD['clrCmd'],
1537 'SET[singleDetails]' => 'info'
1538 ));
1539 } else {
1540 $script = '';
1541 }
1542 $standaloneUpdates = '';
1543 if ($this->CMD['standAlone']) {
1544 $standaloneUpdates .= '<input type="hidden" name="standAlone" value="1" />';
1545 }
1546 if ($this->CMD['silendMode']) {
1547 $standaloneUpdates .= '<input type="hidden" name="silendMode" value="1" />';
1548 }
1549 $depsolver = t3lib_div::_POST('depsolver');
1550 if (is_array($depsolver['ignore'])) {
1551 foreach ($depsolver['ignore'] as $depK => $depV) {
1552 $dependencyUpdates .= '<input type="hidden" name="depsolver[ignore][' . $depK . ']" value="1" />';
1553 }
1554 }
1555 $updatesForm = $this->install->updatesForm(
1556 $extKey,
1557 $list[$extKey],
1558 1,
1559 $script,
1560 $dependencyUpdates . $standaloneUpdates . '<input type="hidden" name="_do_install" value="1" /><input type="hidden" name="_clrCmd" value="' . $this->CMD['clrCmd'] . '" />',
1561 TRUE
1562 );
1563 if ($updatesForm) {
1564 $updates = $GLOBALS['LANG']->getLL('ext_details_new_tables_fields') . '<br />' .
1565 $GLOBALS['LANG']->getLL('ext_details_new_tables_fields_select') . $updatesForm;
1566 $labelDBUpdate = $GLOBALS['LANG']->csConvObj->conv_case(
1567 $GLOBALS['LANG']->charSet,
1568 $GLOBALS['LANG']->getLL('ext_details_db_needs_update'),
1569 'toUpper'
1570 );
1571 $this->content .= $this->doc->section(
1572 sprintf($GLOBALS['LANG']->getLL('ext_details_installing') . ' ',
1573 $this->extensionTitleIconHeader($extKey, $list[$extKey])
1574 ) . ' ' .
1575 $labelDBUpdate,
1576 $updates, 1, 1, 1, 1
1577 );
1578 }
1579 } elseif ($this->CMD['remove']) {
1580 $updates .= $this->install->checkClearCache($list[$extKey]);
1581 if ($updates) {
1582 $updates = '
1583 <form action="' . $this->script . '" method="post">' . $updates . '
1584 <br /><input type="submit" name="write" value="' .
1585 $GLOBALS['LANG']->getLL('ext_details_remove_ext') . '" />
1586 <input type="hidden" name="_do_install" value="1" />
1587 <input type="hidden" name="_clrCmd" value="' . $this->CMD['clrCmd'] . '" />
1588 <input type="hidden" name="CMD[showExt]" value="' . $this->CMD['showExt'] . '" />
1589 <input type="hidden" name="CMD[remove]" value="' . $this->CMD['remove'] . '" />
1590 <input type="hidden" name="standAlone" value="' . $this->CMD['standAlone'] . '" />
1591 <input type="hidden" name="silentMode" value="' . $this->CMD['silentMode'] . '" />
1592 ' . ($this->noDocHeader ? '<input type="hidden" name="nodoc" value="1" />' : '') . '
1593 </form>';
1594 $labelDBUpdate = $GLOBALS['LANG']->csConvObj->conv_case(
1595 $GLOBALS['LANG']->charSet,
1596 $GLOBALS['LANG']->getLL('ext_details_db_needs_update'),
1597 'toUpper'
1598 );
1599 $this->content .= $this->doc->section(
1600 sprintf($GLOBALS['LANG']->getLL('ext_details_removing') . ' ',
1601 $this->extensionTitleIconHeader($extKey, $list[$extKey])
1602 ) . ' ' .
1603 $labelDBUpdate,
1604 $updates, 1, 1, 1, 1
1605 );
1606 }
1607 }
1608 if (!$updates || t3lib_div::_GP('_do_install') || ($this->noDocHeader && $this->CMD['remove'])) {
1609 $this->install->writeNewExtensionList($newExtList);
1610 $action = $this->CMD['load'] ? 'installed' : 'removed';
1611 $GLOBALS['BE_USER']->writelog(5, 1, 0, 0, 'Extension list has been changed, extension %s has been %s', array($extKey, $action));
1612
1613 if (!t3lib_div::_GP('silentMode') && !$this->CMD['standAlone']) {
1614 $messageLabel = 'ext_details_ext_' . $action . '_with_key';
1615 $flashMessage = t3lib_div::makeInstance(
1616 't3lib_FlashMessage',
1617 sprintf($GLOBALS['LANG']->getLL($messageLabel), $extKey),
1618 '',
1619 t3lib_FlashMessage::OK,
1620 TRUE
1621 );
1622 t3lib_FlashMessageQueue::addMessage($flashMessage);
1623 }
1624 $techInfo = $this->install->makeDetailedExtensionAnalysis($extKey, $list[$extKey]);
1625 if ($this->CMD['clrCmd'] || t3lib_div::_GP('_clrCmd')) {
1626 if ($this->CMD['load'] && @is_file($absPath . 'ext_conf_template.txt')) {
1627 $vA = array('CMD' => array('showExt' => $extKey));
1628 } elseif ($this->CMD['load'] && $techInfo['hasCacheConfiguration']) {
1629 $vA = array('CMD' => array('showExt' => $extKey));
1630 } else {
1631 $vA = array('CMD' => '');
1632 }
1633 } else {
1634 $vA = array('CMD' => array('showExt' => $extKey));
1635 }
1636
1637 if ($this->CMD['standAlone'] || t3lib_div::_GP('standAlone')) {
1638 $this->content .= sprintf($GLOBALS['LANG']->getLL('ext_details_ext_installed_removed'),
1639 ($this->CMD['load'] ?
1640 $GLOBALS['LANG']->getLL('ext_details_installed') :
1641 $GLOBALS['LANG']->getLL('ext_details_removed')
1642 )
1643 ) .
1644 '<br /><br />' . $this->getSubmitAndOpenerCloseLink();
1645 } else {
1646 // Determine if new modules were installed:
1647 if (($this->CMD['load'] || $this->CMD['remove']) && is_array($techInfo['flags']) && in_array('Module', $techInfo['flags'], TRUE)) {
1648 $vA['CMD']['refreshMenu'] = 1;
1649 }
1650 t3lib_utility_Http::redirect(t3lib_div::linkThisScript($vA));
1651 exit;
1652 }
1653 }
1654 }
1655 } else {
1656 $writeAccessError = $GLOBALS['LANG']->csConvObj->conv_case(
1657 $GLOBALS['LANG']->charSet,
1658 $GLOBALS['LANG']->getLL('ext_details_write_access_error'),
1659 'toUpper'
1660 );
1661 $this->content .= $this->doc->section(
1662 sprintf($GLOBALS['LANG']->getLL('ext_details_installing') . ' ',
1663 $this->extensionTitleIconHeader($extKey, $list[$extKey])
1664 ) . ' ' .
1665 $writeAccessError,
1666 $GLOBALS['LANG']->getLL('ext_details_write_error_localconf'),
1667 1, 1, 2, 1
1668 );
1669 }
1670
1671 } elseif ($this->CMD['downloadFile'] && !in_array($extKey, $this->requiredExt)) {
1672
1673 // Link for downloading extension has been clicked - deliver content stream:
1674 $dlFile = urldecode($this->CMD['downloadFile']);
1675 if (t3lib_div::isAllowedAbsPath($dlFile) && t3lib_div::isFirstPartOfStr($dlFile, PATH_site) && t3lib_div::isFirstPartOfStr($dlFile, $absPath) && @is_file($dlFile)) {
1676 $mimeType = 'application/octet-stream';
1677 Header('Content-Type: ' . $mimeType);
1678 Header('Content-Disposition: attachment; filename=' . basename($dlFile));
1679 echo t3lib_div::getUrl($dlFile);
1680 exit;
1681 } else {
1682 throw new RuntimeException(
1683 'TYPO3 Fatal Error: ' . $GLOBALS['LANG']->getLL('ext_details_error_downloading'),
1684 1270853980
1685 );
1686 }
1687
1688 } elseif ($this->CMD['editFile'] && !in_array($extKey, $this->requiredExt)) {
1689
1690 // Editing extension file:
1691 $editFile = rawurldecode($this->CMD['editFile']);
1692 if (t3lib_div::isAllowedAbsPath($editFile) && t3lib_div::isFirstPartOfStr($editFile, $absPath)) {
1693
1694 $fI = t3lib_div::split_fileref($editFile);
1695 if (@is_file($editFile) && t3lib_div::inList($this->editTextExtensions, ($fI['fileext'] ? $fI['fileext'] : $fI['filebody']))) {
1696 if (filesize($editFile) < ($this->kbMax * 1024)) {
1697 $outCode = '<form action="' . $this->script . '" method="post" name="editfileform">';
1698 $info = '';
1699 $submittedContent = t3lib_div::_POST('edit');
1700 $saveFlag = 0;
1701
1702 if (isset($submittedContent['file']) && !$GLOBALS['TYPO3_CONF_VARS']['EXT']['noEdit']) { // Check referer here?
1703 $oldFileContent = t3lib_div::getUrl($editFile);
1704 if ($oldFileContent != $submittedContent['file']) {
1705 $oldMD5 = md5(str_replace(CR, '', $oldFileContent));
1706 $info .= sprintf(
1707 $GLOBALS['LANG']->getLL('ext_details_md5_previous'),
1708 '<strong>' . $oldMD5 . '</strong>'
1709 ) . '<br />';
1710 t3lib_div::writeFile($editFile, $submittedContent['file']);
1711 $saveFlag = 1;
1712 } else {
1713 $info .= $GLOBALS['LANG']->getLL('ext_details_no_changes') . '<br />';
1714 }
1715 }
1716
1717 $fileContent = t3lib_div::getUrl($editFile);
1718
1719 $outCode .= sprintf(
1720 $GLOBALS['LANG']->getLL('ext_details_file'),
1721 '<strong>' . substr($editFile, strlen($absPath)) . '</strong> (' .
1722 t3lib_div::formatSize(filesize($editFile)) . ')<br />'
1723 );
1724 $fileMD5 = md5(str_replace(CR, '', $fileContent));
1725 $info .= sprintf(
1726 $GLOBALS['LANG']->getLL('ext_details_md5_current'),
1727 '<strong>' . $fileMD5 . '</strong>'
1728 ) . '<br />';
1729 if ($saveFlag) {
1730 $saveMD5 = md5(str_replace(CR, '', $submittedContent['file']));
1731 $info .= sprintf(
1732 $GLOBALS['LANG']->getLL('ext_details_md5_submitted'),
1733 '<strong>' . $saveMD5 . '</strong>'
1734 ) . '<br />';
1735 if ($fileMD5 != $saveMD5) {
1736 $info .= tx_em_Tools::rfw(
1737 '<br /><strong>' . $GLOBALS['LANG']->getLL('ext_details_saving_failed_changes_lost') . '</strong>'
1738 ) . '<br />';
1739 }
1740 else {
1741 $info .= tx_em_Tools::rfw(
1742 '<br /><strong>' . $GLOBALS['LANG']->getLL('ext_details_file_saved') . '</strong>'
1743 ) . '<br />';
1744 }
1745 }
1746
1747 $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>';
1748 $outCode .= '<input type="hidden" name="edit[filename]" value="' . $editFile . '" />';
1749 $outCode .= '<input type="hidden" name="CMD[editFile]" value="' . htmlspecialchars($editFile) . '" />';
1750 $outCode .= '<input type="hidden" name="CMD[showExt]" value="' . $extKey . '" />';
1751 $outCode .= $info;
1752
1753 if (!$GLOBALS['TYPO3_CONF_VARS']['EXT']['noEdit']) {
1754 $outCode .= '<br /><input type="submit" name="save_file" value="' .
1755 $GLOBALS['LANG']->getLL('ext_details_file_save_button') . '" />';
1756 }
1757 else {
1758 $outCode .= tx_em_Tools::rfw(
1759 '<br />' . $GLOBALS['LANG']->getLL('ext_details_saving_disabled') . ' '
1760 );
1761 }
1762
1763 $onClick = 'window.location.href="' . t3lib_div::linkThisScript(array(
1764 'CMD[showExt]' => $extKey
1765 )) . '";return false;';
1766 $outCode .= '<input type="submit" name="cancel" value="' .
1767 $GLOBALS['LANG']->getLL('ext_details_cancel_button') . '" onclick="' .
1768 htmlspecialchars($onClick) . '" /></form>';
1769
1770 $theOutput .= $this->doc->spacer(15);
1771 $theOutput .= $this->doc->section($GLOBALS['LANG']->getLL('ext_details_edit_file'), '', 0, 1);
1772 $theOutput .= $this->doc->sectionEnd() . $outCode;
1773 $this->content .= $theOutput;
1774 } else {
1775 $theOutput .= $this->doc->spacer(15);
1776 $theOutput .= $this->doc->section(
1777 sprintf(
1778 $GLOBALS['LANG']->getLL('ext_details_filesize_exceeded_kb'),
1779 $this->kbMax
1780 ),
1781 sprintf(
1782 $GLOBALS['LANG']->getLL('ext_details_file_too_large'),
1783 $this->kbMax
1784 )
1785 );
1786 $this->content .= $theOutput;
1787 }
1788 }
1789 } else {
1790 die (sprintf($GLOBALS['LANG']->getLL('ext_details_fatal_edit_error'),
1791 htmlspecialchars($editFile)
1792 )
1793 );
1794 }
1795 } else {
1796
1797 // MAIN:
1798 switch ((string) $this->MOD_SETTINGS['singleDetails']) {
1799 case 'info':
1800 // Loaded / Not loaded:
1801 if (!in_array($extKey, $this->requiredExt)) {
1802 if ($GLOBALS['TYPO3_LOADED_EXT'][$extKey]) {
1803 $content = '<strong>' . $GLOBALS['LANG']->getLL('ext_details_loaded_and_running') . '</strong><br />' .
1804 '<a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
1805 'CMD[showExt]' => $extKey,
1806 'CMD[remove]' => 1
1807 ))) .
1808 '">' . $GLOBALS['LANG']->getLL('ext_details_remove_button') . ' ' . tx_em_Tools::removeButton() . '</a>';
1809 } else {
1810 $content = $GLOBALS['LANG']->getLL('ext_details_not_loaded') . '<br />' .
1811 '<a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
1812 'CMD[showExt]' => $extKey,
1813 'CMD[load]' => 1
1814 ))) .
1815 '">' . $GLOBALS['LANG']->getLL('ext_details_install_button') . ' ' . tx_em_Tools::installButton() . '</a>';
1816 }
1817 } else {
1818 $content = $GLOBALS['LANG']->getLL('ext_details_always_loaded');
1819 }
1820 $this->content .= $this->doc->spacer(10);
1821 $this->content .= $this->doc->section(
1822 $GLOBALS['LANG']->getLL('ext_details_current_status'), $content, 0, 1
1823 );
1824
1825 if (t3lib_extMgm::isLoaded($extKey)) {
1826 $updates = $this->install->updatesForm($extKey, $list[$extKey]);
1827 if ($updates) {
1828 $this->content .= $this->doc->spacer(10);
1829 $this->content .= $this->doc->section(
1830 $GLOBALS['LANG']->getLL('ext_details_update_needed'),
1831 $updates . '<br /><br />' . $GLOBALS['LANG']->getLL('ext_details_notice_static_data'),
1832 0, 1
1833 );
1834 }
1835 }
1836
1837 // Config:
1838 if (@is_file($absPath . 'ext_conf_template.txt')) {
1839 $this->content .= $this->doc->spacer(10);
1840 $this->content .= $this->doc->section(
1841 $GLOBALS['LANG']->getLL('ext_details_configuration'),
1842 $GLOBALS['LANG']->getLL('ext_details_notice_clear_cache') . '<br /><br />',
1843 0, 1
1844 );
1845
1846 $this->content .= $this->install->tsStyleConfigForm($extKey, $list[$extKey]);
1847 }
1848
1849 // Show details:
1850 $headline = $GLOBALS['LANG']->getLL('ext_details_details');
1851 $headline = t3lib_BEfunc::wrapInHelp('_MOD_tools_em', 'info', $headline);
1852 $content = $this->extensionDetails->extInformationarray($extKey, $list[$extKey]);
1853
1854
1855 $this->content .= $this->doc->spacer(10);
1856 $this->content .= $this->doc->section($headline, $content, FALSE, TRUE, FALSE, TRUE);
1857 break;
1858 case 'upload':
1859 $em = t3lib_div::_POST('em');
1860 $headline = '';
1861 $eC = 0;
1862 if ($em['action'] == 'doUpload') {
1863 $em['extKey'] = $extKey;
1864 $em['extInfo'] = $list[$extKey];
1865 $content = $this->extensionDetails->uploadExtensionToTER($em);
1866 $content .= $this->doc->spacer(10);
1867 // Must reload this, because EM_CONF information has been updated!
1868 list($list,) = $this->extensionList->getInstalledExtensions();
1869 } else {
1870 // headline and CSH
1871 $headline = $GLOBALS['LANG']->getLL('ext_details_upload_to_ter');
1872 $headline = t3lib_BEfunc::wrapInHelp('_MOD_tools_em', 'upload', $headline);
1873
1874 // Upload:
1875 if (substr($extKey, 0, 5) != 'user_') {
1876 $content = $this->getRepositoryUploadForm($extKey, $list[$extKey]);
1877 $eC = 0;
1878 } else {
1879 $content = $GLOBALS['LANG']->getLL('ext_details_no_unique_ext');
1880 $eC = 2;
1881 }
1882 if (!$this->fe_user['username']) {
1883 /** @var $flashMessage t3lib_FlashMessage */
1884 $flashMessage = t3lib_div::makeInstance(
1885 't3lib_FlashMessage',
1886 sprintf($GLOBALS['LANG']->getLL('ext_details_no_username'),
1887 '<a href="' . t3lib_div::linkThisScript(array(
1888 'SET[function]' => 3
1889 )) . '">', '</a>'
1890 ),
1891 '',
1892 t3lib_FlashMessage::INFO
1893 );
1894 $content .= '<br />' . $flashMessage->render();
1895
1896 }
1897 }
1898 $this->content .= $this->doc->section($headline, $content, 0, 1, $eC, TRUE);
1899 break;
1900 case 'backup':
1901 if ($this->CMD['doDelete']) {
1902 $content = $this->install->extDelete($extKey, $list[$extKey], $this->CMD);
1903 $this->content .= $this->doc->section(
1904 $GLOBALS['LANG']->getLL('ext_details_delete'),
1905 $GLOBALS['LANG']->getLL('ext_details_delete'),
1906 $content, 0, 1
1907 );
1908 } else {
1909 // headline and CSH
1910 $headline = $GLOBALS['LANG']->getLL('ext_details_backup');
1911 $headline = t3lib_BEfunc::wrapInHelp('_MOD_tools_em', 'backup_delete', $headline);
1912
1913 $content = $this->extBackup($extKey, $list[$extKey]);
1914 $this->content .= $this->doc->section($headline, $content, 0, 1, 0, 1);
1915
1916 $content = $this->install->extDelete($extKey, $list[$extKey], $this->CMD);
1917 $this->content .= $this->doc->section(
1918 $GLOBALS['LANG']->getLL('ext_details_delete'),
1919 $content, 0, 1
1920 );
1921
1922 $content = $this->extUpdateEMCONF($extKey, $list[$extKey]);
1923 $this->content .= $this->doc->section(
1924 $GLOBALS['LANG']->getLL('ext_details_update_em_conf'),
1925 $content, 0, 1
1926 );
1927 }
1928 break;
1929 case 'dump':
1930 $this->extDumpTables($extKey, $list[$extKey]);
1931 break;
1932 case 'edit':
1933 // headline and CSH
1934 $headline = $GLOBALS['LANG']->getLL('ext_details_ext_files');
1935 $headline = t3lib_BEfunc::wrapInHelp('_MOD_tools_em', 'editfiles', $headline);
1936
1937 $content = $this->getFileListOfExtension($extKey, $list[$extKey]);
1938
1939 $this->content .= $this->doc->section($headline, $content, FALSE, TRUE, FALSE, TRUE);
1940 break;
1941 case 'updateModule':
1942 $this->content .= $this->doc->section(
1943 $GLOBALS['LANG']->getLL('ext_details_update'),
1944 is_object($updateObj) ?
1945 $updateObj->main() :
1946 $GLOBALS['LANG']->getLL('ext_details_no_update_object'),
1947 0, 1
1948 );
1949 break;
1950 default:
1951 $this->extObjContent();
1952 break;
1953 }
1954 }
1955 }
1956 }
1957
1958 /**
1959 * Outputs a screen from where you can install multiple extensions in one go
1960 * This can be called from external modules with "...index.php?CMD[requestInstallExtensions]=
1961 *
1962 * @param string Comma list of extension keys to install. Renders a screen with checkboxes for all extensions not already imported or installed
1963 * @return void
1964 */
1965 function requestInstallExtensions($extList) {
1966
1967 // Return URL:
1968 $returnUrl = t3lib_div::sanitizeLocalUrl(t3lib_div::_GP('returnUrl'));
1969 $installOrImportExtension = t3lib_div::_POST('installOrImportExtension');
1970
1971 // Extension List:
1972 $extArray = explode(',', $extList);
1973 $outputRow = array();
1974 $outputRow[] = '
1975 <tr class="t3-row-header tableheader">
1976 <td>' . $GLOBALS['LANG']->getLL('reqInstExt_install_import') . '</td>
1977 <td>' . $GLOBALS['LANG']->getLL('reqInstExt_ext_key') . '</td>
1978 </tr>
1979 ';
1980
1981 foreach ($extArray as $extKey) {
1982
1983 // Check for the request:
1984 if ($installOrImportExtension[$extKey]) {
1985 $this->installExtension($extKey);
1986 }
1987
1988 // Display:
1989 if (!t3lib_extMgm::isLoaded($extKey)) {
1990 $outputRow[] = '
1991 <tr class="bgColor4">
1992 <td><input type="checkbox" name="' . htmlspecialchars('installOrImportExtension[' . $extKey . ']') . '" value="1" checked="checked" id="check_' . $extKey . '" /></td>
1993 <td><label for="check_' . $extKey . '">' . htmlspecialchars($extKey) . '</label></td>
1994 </tr>
1995 ';
1996 }
1997 }
1998
1999 if (count($outputRow) > 1 || !$returnUrl) {
2000 $content = '
2001 <!-- ending page form ... -->
2002 <form action="' . htmlspecialchars(t3lib_div::getIndpEnv('REQUEST_URI')) . '" method="post">
2003 <table border="0" cellpadding="1" cellspacing="1">' . implode('', $outputRow) . '</table>
2004 <input type="submit" name="_" value="' . $GLOBALS['LANG']->getLL('reqInstExt_import_install_selected') . '" />
2005 </form>';
2006
2007 if ($returnUrl) {
2008 $content .= '
2009 <br />
2010 <br />
2011 <a href="' . htmlspecialchars($returnUrl) . '">' . $GLOBALS['LANG']->getLL('reqInstExt_return') . '</a>
2012 ';
2013 }
2014
2015 $this->content .= $this->doc->section(
2016 $GLOBALS['LANG']->getLL('reqInstExt_imp_inst_ext'), $content, 0, 1
2017 );
2018 } else {
2019 t3lib_utility_Http::redirect($returnUrl);
2020 }
2021 }
2022
2023
2024 /***********************************
2025 *
2026 * Application Sub-functions (HTML parts)
2027 *
2028 **********************************/
2029
2030
2031 /**
2032 * Creates view for dumping static tables and table/fields structures...
2033 *
2034 * @param string Extension key
2035 * @param array Extension information array
2036 * @return void
2037 */
2038 function extDumpTables($extKey, $extInfo) {
2039
2040 // Get dbInfo which holds the structure known from the tables.sql file
2041 $techInfo = $this->install->makeDetailedExtensionAnalysis($extKey, $extInfo);
2042 $absPath = tx_em_Tools::getExtPath($extKey, $extInfo['type']);
2043
2044 // Static tables:
2045 if (is_array($techInfo['static'])) {
2046 if ($this->CMD['writeSTATICdump']) { // Writing static dump:
2047 $writeFile = $absPath . 'ext_tables_static+adt.sql';
2048 if (@is_file($writeFile)) {
2049 $dump_static = tx_em_Database::dumpStaticTables(implode(',', $techInfo['static']));
2050 t3lib_div::writeFile($writeFile, $dump_static);
2051 $this->content .= $this->doc->section(
2052 $GLOBALS['LANG']->getLL('extDumpTables_tables_fields'),
2053 sprintf($GLOBALS['LANG']->getLL('extDumpTables_bytes_written_to'),
2054 t3lib_div::formatSize(strlen($dump_static)),
2055 substr($writeFile, strlen(PATH_site))
2056 ),
2057 0, 1
2058 );
2059 }
2060 } else { // Showing info about what tables to dump - and giving the link to execute it.
2061 $msg = $GLOBALS['LANG']->getLL('extDumpTables_dumping_content') . '<br />';
2062 $msg .= '<br />' . implode('<br />', $techInfo['static']) . '<br />';
2063
2064 // ... then feed that to this function which will make new CREATE statements of the same fields but based on the current database content.
2065 $this->content .= $this->doc->section(
2066 $GLOBALS['LANG']->getLL('extDumpTables_static_tables'),
2067 $msg . '<hr /><strong><a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
2068 'CMD[showExt]' => $extKey,
2069 'CMD[writeSTATICdump]' => 1
2070 ))) . '">' . $GLOBALS['LANG']->getLL('extDumpTables_write_static') . '</a></strong>',
2071 0, 1
2072 );
2073 $this->content .= $this->doc->spacer(20);
2074 }
2075 }
2076
2077 // Table and field definitions:
2078 if (is_array($techInfo['dump_tf'])) {
2079 $dump_tf_array = tx_em_Database::getTableAndFieldStructure($techInfo['dump_tf']);
2080 $dump_tf = tx_em_Database::dumpTableAndFieldStructure($dump_tf_array);
2081 if ($this->CMD['writeTFdump']) {
2082 $writeFile = $absPath . 'ext_tables.sql';
2083 if (@is_file($writeFile)) {
2084 t3lib_div::writeFile($writeFile, $dump_tf);
2085 $this->content .= $this->doc->section(
2086 $GLOBALS['LANG']->getLL('extDumpTables_tables_fields'),
2087 sprintf($GLOBALS['LANG']->getLL('extDumpTables_bytes_written_to'),
2088 t3lib_div::formatSize(strlen($dump_tf)),
2089 substr($writeFile, strlen(PATH_site))
2090 ),
2091 0, 1
2092 );
2093 }
2094 } else {
2095 $msg = $GLOBALS['LANG']->getLL('extDumpTables_dumping_db_structure') . '<br />';
2096 if (is_array($techInfo['tables'])) {
2097 $msg .= '<br /><strong>' . $GLOBALS['LANG']->getLL('extDumpTables_tables') . '</strong><br />' .
2098 implode('<br />', $techInfo['tables']) . '<br />';
2099 }
2100 if (is_array($techInfo['fields'])) {
2101 $msg .= '<br /><strong>' . $GLOBALS['LANG']->getLL('extDumpTables_solo_fields') . '</strong><br />' .
2102 implode('<br />', $techInfo['fields']) . '<br />';
2103 }
2104
2105 // ... then feed that to this function which will make new CREATE statements of the same fields but based on the current database content.
2106 $this->content .= $this->doc->section(
2107 $GLOBALS['LANG']->getLL('extDumpTables_tables_fields'),
2108 $msg . '<hr /><strong><a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
2109 'CMD[showExt]' => $extKey,
2110 'CMD[writeTFdump]' => 1
2111 ))) .
2112 '">' . $GLOBALS['LANG']->getLL('extDumpTables_write_dump') . '</a></strong><hr />
2113 <pre>' . htmlspecialchars($dump_tf) . '</pre>',
2114 0, 1
2115 );
2116
2117
2118 $details = ' ' . $GLOBALS['LANG']->getLL('extDumpTables_based_on') . '<br />
2119 <ul>
2120 <li>' . $GLOBALS['LANG']->getLL('extDumpTables_based_on_one') . '</li>
2121 <li>' . $GLOBALS['LANG']->getLL('extDumpTables_based_on_two') . '</li>
2122 </ul>
2123 ' . $GLOBALS['LANG']->getLL('extDumpTables_bottomline') . '<br />';
2124 $this->content .= $this->doc->section('', $details);
2125 }
2126 }
2127 }
2128
2129 /**
2130 * Returns file-listing of an extension
2131 *
2132 * @param string Extension key
2133 * @param array Extension information array
2134 * @return string HTML table.
2135 */
2136 function getFileListOfExtension($extKey, $conf) {
2137 $content = '';
2138 $extPath = tx_em_Tools::getExtPath($extKey, $conf['type']);
2139
2140 if ($extPath) {
2141 // Read files:
2142 $fileArr = array();
2143 $fileArr = t3lib_div::getAllFilesAndFoldersInPath($fileArr, $extPath, '', 0, 99, $this->excludeForPackaging);
2144
2145 // Start table:
2146 $lines = array();
2147 $totalSize = 0;
2148
2149 // Header:
2150 $lines[] = '
2151 <tr class="t3-row-header">
2152 <td>' . $GLOBALS['LANG']->getLL('extFileList_file') . '</td>
2153 <td>' . $GLOBALS['LANG']->getLL('extFileList_size') . '</td>
2154 <td>' . $GLOBALS['LANG']->getLL('extFileList_edit') . '</td>
2155 </tr>';
2156
2157 foreach ($fileArr as $file) {
2158 $fI = t3lib_div::split_fileref($file);
2159 $lines[] = '
2160 <tr class="bgColor4">
2161 <td><a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
2162 'CMD[showExt]' => $extKey,
2163 'CMD[downloadFile]' => rawurlencode($file)
2164 ))) . '" title="' . $GLOBALS['LANG']->getLL('extFileList_download') . '">' .
2165 substr($file, strlen($extPath)) . '</a></td>
2166 <td>' . t3lib_div::formatSize(filesize($file)) . '</td>
2167 <td>' . (!in_array($extKey, $this->requiredExt) &&
2168 t3lib_div::inList($this->editTextExtensions,
2169 ($fI['fileext'] ? $fI['fileext'] : $fI['filebody'])) ?
2170 '<a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
2171 'CMD[showExt]' => $extKey,
2172 'CMD[editFile]' => rawurlencode($file)
2173 ))) . '">' .
2174 $GLOBALS['LANG']->getLL('extFileList_edit_file') . '</a>' : ''
2175 ) . '</td>
2176 </tr>';
2177 $totalSize += filesize($file);
2178 }
2179
2180 $lines[] = '
2181 <tr class="bgColor6">
2182 <td><strong>' . $GLOBALS['LANG']->getLL('extFileList_total') . '</strong></td>
2183 <td><strong>' . t3lib_div::formatSize($totalSize) . '</strong></td>
2184 <td>&nbsp;</td>
2185 </tr>';
2186
2187 $content = '
2188 Path: ' . $extPath . '<br /><br />
2189 <table border="0" cellpadding="1" cellspacing="2">' . implode('', $lines) . '</table>';
2190 }
2191
2192 return $content;
2193 }
2194
2195
2196 /**
2197 * Update extension EM_CONF...
2198 *
2199 * @param string Extension key
2200 * @param array Extension information array
2201 * @return string HTML content.
2202 */
2203 function extUpdateEMCONF($extKey, $extInfo) {
2204 $absPath = tx_em_Tools::getExtPath($extKey, $extInfo['type']);
2205 $content = '';
2206
2207 if ($this->CMD['doUpdateEMCONF']) {
2208 return $this->extensionDetails->updateLocalEM_CONF($extKey, $extInfo);
2209 } else {
2210 $sure = $GLOBALS['LANG']->getLL('extUpdateEMCONF_sure');
2211 $updateEMConf = $GLOBALS['LANG']->getLL('extUpdateEMCONF_file');
2212 $onClick = "if (confirm('$sure')) {window.location.href='" . t3lib_div::linkThisScript(array(
2213 'CMD[showExt]' => $extKey,
2214 'CMD[doUpdateEMCONF]' => 1
2215 )) . "';}";
2216 $content .= $GLOBALS['LANG']->getLL('extUpdateEMCONF_info_changes') . '<br />'
2217 . $GLOBALS['LANG']->getLL('extUpdateEMCONF_info_reset') . '<br /><br />';
2218 $content .= '<a class="t3-link" href="#" onclick="' . htmlspecialchars($onClick) .
2219 ' return false;"><strong>' . $updateEMConf . '</strong> ' .
2220 sprintf($GLOBALS['LANG']->getLL('extDelete_from_location'),
2221 $this->typeLabels[$extInfo['type']],
2222 substr($absPath, strlen(PATH_site))
2223 ) . '</a>';
2224 return $content;
2225 }
2226 }
2227
2228 /**
2229 * Download extension as file / make backup
2230 *
2231 * @param string Extension key
2232 * @param array Extension information array
2233 * @return string HTML content
2234 */
2235 function extBackup($extKey, $extInfo) {
2236 $uArr = $this->extensionDetails->makeUploadarray($extKey, $extInfo);
2237 if (is_array($uArr)) {
2238 $backUpData = $this->terConnection->makeUploadDataFromarray($uArr);
2239 $filename = 'T3X_' . $extKey . '-' . str_replace('.', '_', $extInfo['EM_CONF']['version']) . '-z-' . date('YmdHi') . '.t3x';
2240 if (intval($this->CMD['doBackup']) == 1) {
2241 t3lib_div::cleanOutputBuffers();
2242 header('Content-Type: application/octet-stream');
2243 header('Content-Disposition: attachment; filename=' . $filename);
2244 echo $backUpData;
2245 exit;
2246 } elseif ($this->CMD['dumpTables']) {
2247 $filename = 'T3X_' . $extKey;
2248 $cTables = count(explode(',', $this->CMD['dumpTables']));
2249 if ($cTables > 1) {
2250 $filename .= '-' . $cTables . 'tables';
2251 } else {
2252 $filename .= '-' . $this->CMD['dumpTables'];
2253 }
2254 $filename .= '+adt.sql';
2255
2256 header('Content-Type: application/octet-stream');
2257 header('Content-Disposition: attachment; filename=' . $filename);
2258 echo tx_em_Database::dumpStaticTables($this->CMD['dumpTables']);
2259 exit;
2260 } else {
2261 $techInfo = $this->install->makeDetailedExtensionAnalysis($extKey, $extInfo);
2262 $lines = array();
2263 $lines[] = '<tr class="t3-row-header"><td colspan="2">' .
2264 $GLOBALS['LANG']->getLL('extBackup_select') . '</td></tr>';
2265 $lines[] = '<tr class="bgColor4"><td><strong>' .
2266 $GLOBALS['LANG']->getLL('extBackup_files') . '</strong></td><td>' .
2267 '<a class="t3-link" href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
2268 'CMD[doBackup]' => 1,
2269 'CMD[showExt]' => $extKey
2270 ))) .
2271 '">' . sprintf($GLOBALS['LANG']->getLL('extBackup_download'),
2272 $extKey
2273 ) . '</a><br />
2274 (' . $filename . ', <br />' .
2275 t3lib_div::formatSize(strlen($backUpData)) . ', <br />' .
2276 $GLOBALS['LANG']->getLL('extBackup_md5') . ' ' . md5($backUpData) . ')
2277 <br /></td></tr>';
2278
2279 if (is_array($techInfo['tables'])) {
2280 $lines[] = '<tr class="bgColor4"><td><strong>' . $GLOBALS['LANG']->getLL('extBackup_data_tables') .
2281 '</strong></td><td>' . tx_em_Database::dumpDataTablesLine($techInfo['tables'], $extKey) . '</td></tr>';
2282 }
2283 if (is_array($techInfo['static'])) {
2284 $lines[] = '<tr class="bgColor4"><td><strong>' . $GLOBALS['LANG']->getLL('extBackup_static_tables') .
2285 '</strong></td><td>' . tx_em_Database::dumpDataTablesLine($techInfo['static'], $extKey) . '</td></tr>';
2286 }
2287
2288 $content = '<table border="0" cellpadding="2" cellspacing="2">' . implode('', $lines) . '</table>';
2289 return $content;
2290 }
2291 } else {
2292 throw new RuntimeException(
2293 'TYPO3 Fatal Error: ' . $GLOBALS['LANG']->getLL('extBackup_unexpected_error'),
2294 1270853981
2295 );
2296 }
2297 }
2298
2299
2300
2301 /**
2302 * Prints the upload form for extensions
2303 *
2304 * @param string Extension key
2305 * @param array Extension information array
2306 * @return string HTML content.
2307 */
2308 function getRepositoryUploadForm($extKey, $extInfo) {
2309 $content = '<form action="' . $this->script . '" method="post" name="repuploadform">
2310 <input type="hidden" name="CMD[showExt]" value="' . $extKey . '" />
2311 <input type="hidden" name="em[action]" value="doUpload" />
2312 <table border="0" cellpadding="2" cellspacing="1">
2313 <tr class="bgColor4">
2314 <td>' . $GLOBALS['LANG']->getLL('repositoryUploadForm_username') . '</td>
2315 <td><input' . $this->doc->formWidth(20) . ' type="text" name="em[user][fe_u]" value="' . $this->fe_user['username'] . '" /></td>
2316 </tr>
2317 <tr class="bgColor4">
2318 <td>' . $GLOBALS['LANG']->getLL('repositoryUploadForm_password') . '</td>
2319 <td><input' . $this->doc->formWidth(20) . ' type="password" name="em[user][fe_p]" value="' . $this->fe_user['password'] . '" /></td>
2320 </tr>
2321 <tr class="bgColor4">
2322 <td>' . $GLOBALS['LANG']->getLL('repositoryUploadForm_changelog') . '</td>
2323 <td><textarea' . $this->doc->formWidth(30, 1) . ' rows="5" name="em[upload][comment]"></textarea></td>
2324 </tr>
2325 <tr class="bgColor4">
2326 <td>' . $GLOBALS['LANG']->getLL('repositoryUploadForm_command') . '</td>
2327 <td nowrap="nowrap">
2328 <input type="radio" name="em[upload][mode]" id="new_dev" value="new_dev" checked="checked" />
2329 <label for="new_dev">' . sprintf($GLOBALS['LANG']->getLL('repositoryUploadForm_new_bugfix'),
2330 'x.x.<strong>' . tx_em_Tools::rfw('x+1') . '</strong>'
2331 ) . '</label><br />
2332 <input type="radio" name="em[upload][mode]" id="new_sub" value="new_sub" />
2333 <label for="new_sub">' . sprintf($GLOBALS['LANG']->getLL('repositoryUploadForm_new_sub_version'),
2334 'x.<strong>' . tx_em_Tools::rfw('x+1') . '</strong>.0'
2335 ) . '</label><br />
2336 <input type="radio" name="em[upload][mode]" id="new_main" value="new_main" />
2337 <label for="new_main">' . sprintf($GLOBALS['LANG']->getLL('repositoryUploadForm_new_main_version'),
2338 '<strong>' . tx_em_Tools::rfw('x+1') . '</strong>.0.0'
2339 ) . '</label><br />
2340 </td>
2341 </tr>
2342 <tr class="bgColor4">
2343 <td>&nbsp;</td>
2344 <td><input type="submit" name="submit" value="' . $GLOBALS['LANG']->getLL('repositoryUploadForm_upload') . '" />
2345 </td>
2346 </tr>
2347 </table>
2348 </form>';
2349
2350 return $content;
2351 }
2352
2353
2354 /************************************
2355 *
2356 * Output helper functions
2357 *
2358 ************************************/
2359
2360
2361 /**
2362 * Returns a header for an extensions including icon if any
2363 *
2364 * @param string Extension key
2365 * @param array Extension information array
2366 * @param string align-attribute value (for <img> tag)
2367 * @return string HTML; Extension title and image.
2368 */
2369 function extensionTitleIconHeader($extKey, $extInfo, $align = 'top') {
2370 $imgInfo = @getImageSize(tx_em_Tools::getExtPath($extKey, $extInfo['type']) . '/ext_icon.gif');
2371 $out = '';
2372 if (is_array($imgInfo)) {
2373 $out .= '<img src="' . $GLOBALS['BACK_PATH'] . tx_em_Tools::typeRelPath($extInfo['type']) . $extKey . '/ext_icon.gif" ' . $imgInfo[3] . ' align="' . $align . '" alt="" />';
2374 }
2375 $out .= $extInfo['EM_CONF']['title'] ? htmlspecialchars(t3lib_div::fixed_lgd_cs($extInfo['EM_CONF']['title'], 40)) : '<em>' . htmlspecialchars($extKey) . '</em>';
2376 return $out;
2377 }
2378
2379
2380
2381
2382
2383
2384
2385
2386 /************************************
2387 *
2388 * Various helper functions
2389 *
2390 ************************************/
2391
2392 /**
2393 * Returns subtitles for the extension listings
2394 *
2395 * @param string List order type
2396 * @param string Key value
2397 * @return string output.
2398 */
2399 function listOrderTitle($listOrder, $key) {
2400 switch ($listOrder) {
2401 case 'cat':
2402 return isset($this->categories[$key]) ? $this->categories[$key] : '[' . $key . ']';
2403 break;
2404 case 'author_company':
2405 return $key;
2406 break;
2407 case 'state':
2408 return $this->states[$key];
2409 break;
2410 case 'type':
2411 return $this->typeDescr[$key];
2412 break;
2413 }
2414 }
2415
2416
2417 /**
2418 * Returns TRUE if global OR local installation of extensions is allowed/possible.
2419 *
2420 * @return boolean Returns TRUE if global OR local installation of extensions is allowed/possible.
2421 */
2422 function importAtAll() {
2423 return ($GLOBALS['TYPO3_CONF_VARS']['EXT']['allowGlobalInstall'] || $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowLocalInstall']);
2424 }
2425
2426
2427 /**
2428 * Searches for ->lookUpStr in extension and returns TRUE if found (or if no search string is set)
2429 *
2430 * @param string Extension key
2431 * @param array Extension content
2432 * @return boolean If TRUE, display extension in list
2433 */
2434 function searchExtension($extKey, $row) {
2435 if ($this->lookUpStr) {
2436 return (
2437 stristr($extKey, $this->lookUpStr) ||
2438 stristr($row['EM_CONF']['title'], $this->lookUpStr) ||
2439 stristr($row['EM_CONF']['description'], $this->lookUpStr) ||
2440 stristr($row['EM_CONF']['author'], $this->lookUpStr) ||
2441 stristr($row['EM_CONF']['author_company'], $this->lookUpStr)
2442 );
2443 } else {
2444 return TRUE;
2445 }
2446 }
2447
2448
2449 /**
2450 * Checks if there are newer versions of installed extensions in the TER
2451 * integrated from the extension "ter_update_check" for TYPO3 4.2 by Christian Welzel
2452 *
2453 * @return nothing
2454 */
2455 function checkForUpdates() {
2456 $content = '';
2457
2458 $count = intval(tx_em_Database::getExtensionCountFromRepository());
2459 if ($count > 0) {
2460 $content = $this->extensionList->showExtensionsToUpdate()
2461 . t3lib_BEfunc::getFuncCheck(0, 'SET[display_installed]', $this->MOD_SETTINGS['display_installed'], '', '', 'id="checkDisplayInstalled"')
2462 . '&nbsp;<label for="checkDisplayInstalled">' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:display_nle') . '</label><br />'
2463 . t3lib_BEfunc::getFuncCheck(0, 'SET[display_files]', $this->MOD_SETTINGS['display_files'], '', '', 'id="checkDisplayFiles"')
2464 . '&nbsp;<label for="checkDisplayFiles">' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:display_files') . '</label>';
2465 $this->content .= $this->doc->section($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:header_upd_ext'), $content, 0, 1);
2466
2467 $dateFormat = $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'];
2468 $timeFormat = $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'];
2469 $content = sprintf($GLOBALS['LANG']->getLL('note_last_update_new'),
2470 date(
2471 $dateFormat . ', ' . $timeFormat,
2472 filemtime(PATH_site . 'typo3temp/extensions.xml.gz')
2473 )
2474 ) . '<br />';
2475 }
2476
2477 $content .= sprintf($GLOBALS['LANG']->getLL('note_last_update2_new'),
2478 '<a href="' . t3lib_div::linkThisScript(array(
2479 'SET[function]' => 2
2480 )) . '">', '</a>');
2481 $this->content .= $this->doc->section($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:header_vers_ret'), $content, 0, 1);
2482 }
2483
2484
2485 function showRepositoryUpdateForm() {
2486 $content = '<div class="em-repupdate"><strong>Repository:</strong>';
2487
2488 // print registered repositories
2489 /** @var $settings tx_em_Settings */
2490 $settings = t3lib_div::makeInstance('tx_em_Settings');
2491 $registeredRepos = $settings->getRegisteredRepositories();
2492 $content .= '<select>';
2493 foreach ($registeredRepos as $repository) {
2494 $content .= '<option>' . $repository->getTitle() . '</option>';
2495 }
2496 $content .= '</select>';
2497
2498 $selectedRepo = $settings->getSelectedRepository();
2499 /** @var $repoUtility tx_em_Repository_Utility */
2500 $repoUtility = t3lib_div::makeInstance('tx_em_Repository_Utility');
2501 $repoUtility->setRepository($selectedRepo);
2502
2503 $onCLick = 'window.location.href="' . t3lib_div::linkThisScript(array(
2504 'CMD[fetchMetaData]' => 'extensions'
2505 )) . '";return false;';
2506 $content .= '
2507 <input type="button" value="' . $GLOBALS['LANG']->getLL('retrieve_update') .
2508 '" onclick="' . htmlspecialchars($onCLick) . '" />';
2509 if (is_file($repoUtility->getLocalExtListFile())) {
2510 $dateFormat = $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'];
2511 $timeFormat = $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'];
2512
2513 $count = tx_em_Database::getExtensionCountFromRepository($repoUtility->getRepositoryUID());
2514 $content .= '<span style="margin-left:10px;padding-right: 50px;" class="typo3-message message-notice">' .
2515 sprintf($GLOBALS['LANG']->getLL('ext_list_last_updated'),
2516 date(
2517 $dateFormat . ', ' . $timeFormat,
2518 filemtime($repoUtility->getLocalExtListFile())
2519 ), $count) . '</span>';
2520 } else {
2521 $content .= '<span style="margin-left:10px;padding-right: 50px;" class="typo3-message message-error">There are no extensions available, please update!</span>';
2522 }
2523 $content .= '<br>&nbsp;<br>';
2524
2525 if ($this->CMD['fetchMetaData'] && $this->CMD['fetchMetaData'] == 'extensions') { // fetches mirror/extension data from online rep.
2526 $content .= $repoUtility->updateExtList(TRUE)->render();
2527 }
2528
2529 $content .= '</div>';
2530 return $content;
2531 }
2532
2533
2534 // Function wrappers for compatibility
2535
2536 /**
2537 * Reports back if installation in a certain scope is possible.
2538 *
2539 * @param string Scope: G, L, S
2540 * @param string Extension lock-type (eg. "L" or "G")
2541 * @return boolean TRUE if installation is allowed.
2542 */
2543 public static function importAsType($type, $lockType = '') {
2544 return tx_em_Tools::importAsType($type, $lockType);
2545 }
2546
2547 /**
2548 * Returns the list of available (installed) extensions
2549 *
2550 * @return array Array with two arrays, list array (all extensions with info) and category index
2551 * @wrapper for compatibility
2552 */
2553 public function getInstalledExtensions() {
2554 return $this->extensionList->getInstalledExtensions();
2555 }
2556
2557
2558 /**
2559 * @return string
2560 */
2561 protected function getSubmitAndOpenerCloseLink() {
2562 if (!$this->CMD['standAlone'] && !$this->noDocHeader && ($this->CMD['standAlone'] || t3lib_div::_GP('standAlone'))) {
2563 $link = '<a href="javascript:opener.top.list.iframe.document.forms[0].submit();window.close();">' .
2564 $GLOBALS['LANG']->getLL('ext_import_close_check') . '</a>';
2565 return $link;
2566 } else {
2567 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>';
2568 }
2569 }
2570
2571
2572 /* Compatibility wrappers */
2573
2574
2575 /**
2576 * Returns the absolute path where the extension $extKey is installed (based on 'type' (SGL))
2577 *
2578 * @param string Extension key
2579 * @param string Install scope type: L, G, S
2580 * @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.
2581 */
2582 public function getExtPath($extKey, $type, $returnWithoutExtKey = FALSE) {
2583 return tx_em_Tools::getExtPath($extKey, $type, $returnWithoutExtKey);
2584 }
2585 }
2586
2587
2588 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['em/index.php']) {
2589 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['em/index.php']);
2590 }
2591
2592 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/em/classes/index.php'])) {
2593 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/em/classes/index.php']);
2594 }
2595
2596
2597 // Make instance:
2598 /** @var $SOBE SC_mod_tools_em_index */
2599 $SOBE = t3lib_div::makeInstance('SC_mod_tools_em_index');
2600 $SOBE->init();
2601 foreach ($SOBE->include_once as $INC_FILE) {
2602 include_once($INC_FILE);
2603 }
2604 $SOBE->checkExtObj();
2605
2606 $SOBE->main();
2607 $SOBE->printContent();
2608
2609 ?>