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