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