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