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