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