[FEATURE] Make table labels for import static clickable
[Packages/TYPO3.CMS.git] / typo3 / sysext / em / classes / install / class.tx_em_install.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2010 Steffen Kamper (info@sk-typo3.de)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Module: Extension manager, (un-)install extensions
29 *
30 * @author Steffen Kamper <info@sk-typo3.de>
31 */
32
33
34 class tx_em_Install {
35
36 /**
37 * Parent module object
38 *
39 * @var SC_mod_tools_em_index
40 */
41 protected $parentObject;
42
43 /**
44 * Instance of EM API
45 *
46 * @var tx_em_API
47 */
48 protected $api;
49
50 /**
51 *
52 * @var t3lib_install
53 */
54 public $install;
55
56
57 /**
58 * @var integer
59 */
60 protected $systemInstall = 0; // If "1" then installs in the sysext directory is allowed. Default: 0
61
62 /**
63 * @var boolean
64 */
65 protected $silentMode;
66
67 /**
68 * Constructor
69 *
70 * @param SC_mod_tools_em_index $parentObject
71 */
72 public function __construct($parentObject = NULL) {
73 $GLOBALS['LANG']->includeLLFile(t3lib_extMgm::extPath('em', 'language/locallang.xml'));
74 $this->parentObject = $parentObject;
75 $this->api = t3lib_div::makeInstance('tx_em_API');
76 $this->install = t3lib_div::makeInstance('t3lib_install');
77 $this->install->INSTALL = t3lib_div::_GP('TYPO3_INSTALL');
78 $this->systemInstall = isset($GLOBALS['TYPO3_CONF_VARS']['EXT']['allowSystemInstall']) && $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowSystemInstall'];
79 }
80
81 /**
82 * Set silent mode to prevent flashmessages
83 *
84 * @param boolean $silentMode
85 * @return void
86 */
87 public function setSilentMode($silentMode) {
88 $this->silentMode = $silentMode ? TRUE : FALSE;
89 }
90
91 /**
92 * Imports the data of an extension from upload
93 *
94 * @param $uploadedTempFile
95 * @param $location
96 * @param bool $uploadOverwrite
97 * @return array
98 */
99 public function uploadExtensionFile($uploadedTempFile, $location, $uploadOverwrite = FALSE) {
100 $error = '';
101 $fileContent = t3lib_div::getUrl($uploadedTempFile);
102 if (!$fileContent) {
103 return array(
104 'success' => FALSE,
105 'error' => $GLOBALS['LANG']->getLL('ext_import_file_empty')
106 );
107 }
108
109 // Decode file data:
110 $terConnection = t3lib_div::makeInstance('tx_em_Connection_Ter', $this);
111 $fetchData = $terConnection->decodeExchangeData($fileContent);
112 if (is_array($fetchData)) {
113 $extKey = $fetchData[0]['extKey'];
114 if ($extKey) {
115 if (!$uploadOverwrite) {
116 $comingExtPath = tx_em_Tools::typePath($location) . $extKey . '/';
117 if (@is_dir($comingExtPath)) {
118 $error = sprintf($GLOBALS['LANG']->getLL('ext_import_ext_present_no_overwrite'), $comingExtPath) .
119 '<br />' . $GLOBALS['LANG']->getLL('ext_import_ext_present_nothing_done');
120
121 } // ... else go on, install...
122 } // ... else go on, install...
123 } else {
124 $error = $GLOBALS['LANG']->getLL('ext_import_no_key');
125 }
126 } else {
127 $error = sprintf($GLOBALS['LANG']->getLL('ext_import_wrong_file_format'), $fetchData);
128 }
129
130 if ($error) {
131 return array(FALSE, $error);
132 } else {
133 return array(TRUE, $fetchData);
134 }
135
136 }
137
138 /**
139 * Installs an extension.
140 *
141 * @param $fetchData
142 * @param $loc
143 * @param $version
144 * @param $uploadedTempFile
145 * @param $dontDelete
146 * @return mixed|string
147 */
148 public function installExtension($fetchData, $loc, $version, $uploadedTempFile, $dontDelete) {
149 $xmlHandler =& $this->parentObject->xmlHandler;
150 $extensionList =& $this->parentObject->extensionList;
151 $extensionDetails =& $this->parentObject->extensionDetails;
152 $content = '';
153
154 if (tx_em_Tools::importAsType($loc)) {
155 if (is_array($fetchData)) { // There was some data successfully transferred
156 if ($fetchData[0]['extKey'] && is_array($fetchData[0]['FILES'])) {
157 $extKey = $fetchData[0]['extKey'];
158 if (!isset($fetchData[0]['EM_CONF']['constraints'])) {
159 $fetchData[0]['EM_CONF']['constraints'] = $xmlHandler->extensionsXML[$extKey]['versions'][$version]['dependencies'];
160 }
161 $EM_CONF = tx_em_Tools::fixEMCONF($fetchData[0]['EM_CONF']);
162 if (!$EM_CONF['lockType'] || !strcmp($EM_CONF['lockType'], $loc)) {
163 // check dependencies, act accordingly if ext is loaded
164 list($instExtInfo,) = $extensionList->getInstalledExtensions();
165 $depStatus = $this->checkDependencies($extKey, $EM_CONF, $instExtInfo);
166 if (t3lib_extMgm::isLoaded($extKey) && !$depStatus['returnCode']) {
167 $content .= $depStatus['html'];
168 if ($uploadedTempFile) {
169 $content .= '<input type="hidden" name="CMD[alreadyUploaded]" value="' . $uploadedTempFile . '" />';
170 }
171 } else {
172 $res = $this->clearAndMakeExtensionDir($fetchData[0], $loc, $dontDelete);
173 if (is_array($res)) {
174 $extDirPath = trim($res[0]);
175 if ($extDirPath && @is_dir($extDirPath) && substr($extDirPath, -1) == '/') {
176
177 $emConfFile = $extensionDetails->construct_ext_emconf_file($extKey, $EM_CONF);
178 $dirs = tx_em_Tools::extractDirsFromFileList(array_keys($fetchData[0]['FILES']));
179
180 $res = tx_em_Tools::createDirsInPath($dirs, $extDirPath);
181 if (!$res) {
182 $writeFiles = $fetchData[0]['FILES'];
183 $writeFiles['ext_emconf.php']['content'] = $emConfFile;
184 $writeFiles['ext_emconf.php']['content_md5'] = md5($emConfFile);
185
186 // Write files:
187 foreach ($writeFiles as $theFile => $fileData) {
188 t3lib_div::writeFile($extDirPath . $theFile, $fileData['content']);
189 if (!@is_file($extDirPath . $theFile)) {
190 if (!$this->silentMode) {
191 $flashMessage = t3lib_div::makeInstance(
192 't3lib_FlashMessage',
193 sprintf($GLOBALS['LANG']->getLL('ext_import_file_not_created'),
194 $extDirPath . $theFile),
195 '',
196 t3lib_FlashMessage::ERROR
197 );
198 $content .= $flashMessage->render();
199 } else {
200 if (!$this->silentMode) {
201 $flashMessage = t3lib_div::makeInstance(
202 't3lib_FlashMessage',
203 sprintf($GLOBALS['LANG']->getLL('ext_import_file_not_created'), $extDirPath . $theFile),
204 '',
205 t3lib_FlashMessage::ERROR
206 );
207 $content .= $flashMessage->render();
208 } else {
209 $content .= sprintf($GLOBALS['LANG']->getLL('ext_import_file_not_created'),
210 $extDirPath . $theFile) . '<br />';
211 }
212 }
213 } elseif (md5(t3lib_div::getUrl($extDirPath . $theFile)) != $fileData['content_md5']) {
214 $content .= sprintf($GLOBALS['LANG']->getLL('ext_import_file_corrupted'),
215 $extDirPath . $theFile) . '<br />';
216 }
217 }
218
219 t3lib_div::fixPermissions($extDirPath, TRUE);
220
221 // No content, no errors. Create success output here:
222 if (!$content) {
223 $messageContent = sprintf($GLOBALS['LANG']->getLL('ext_import_success_folder'), $extDirPath) . '<br />';
224
225 $uploadSucceed = TRUE;
226
227 // Fix TYPO3_MOD_PATH for backend modules in extension:
228 $modules = t3lib_div::trimExplode(',', $EM_CONF['module'], 1);
229 if (count($modules)) {
230 foreach ($modules as $mD) {
231 $confFileName = $extDirPath . $mD . '/conf.php';
232 if (@is_file($confFileName)) {
233 $messageContent .= tx_em_Tools::writeTYPO3_MOD_PATH($confFileName, $loc, $extKey . '/' . $mD . '/') . '<br />';
234 } else {
235 $messageContent .= sprintf($GLOBALS['LANG']->getLL('ext_import_no_conf_file'),
236 $confFileName) . '<br />';
237 }
238 }
239 }
240 // NOTICE: I used two hours trying to find out why a script, ext_emconf.php, written twice and in between included by PHP did not update correct the second time. Probably something with PHP-A cache and mtime-stamps.
241 // But this order of the code works.... (using the empty Array with type, EMCONF and files hereunder).
242
243 // Writing to ext_emconf.php:
244 $sEMD5A = $extensionDetails->serverExtensionMD5array($extKey, array('type' => $loc, 'EM_CONF' => array(), 'files' => array()));
245 $EM_CONF['_md5_values_when_last_written'] = serialize($sEMD5A);
246 $emConfFile = $extensionDetails->construct_ext_emconf_file($extKey, $EM_CONF);
247 t3lib_div::writeFile($extDirPath . 'ext_emconf.php', $emConfFile);
248
249 $messageContent .= 'ext_emconf.php: ' . $extDirPath . 'ext_emconf.php<br />';
250 $messageContent .= $GLOBALS['LANG']->getLL('ext_import_ext_type') . ' ';
251 $messageContent .= $this->api->typeLabels[$loc] . '<br />';
252 $messageContent .= '<br />';
253
254 // Remove cache files:
255 $updateContent = '';
256 if (t3lib_extMgm::isLoaded($extKey)) {
257 if (t3lib_extMgm::removeCacheFiles()) {
258 $messageContent .= $GLOBALS['LANG']->getLL('ext_import_cache_files_removed') . '<br />';
259 }
260
261 list($new_list) = $this->parentObject->extensionList->getInstalledExtensions();
262 $updateContent = $this->updatesForm($extKey, $new_list[$extKey], 1, t3lib_div::linkThisScript(array(
263 'CMD[showExt]' => $extKey,
264 'SET[singleDetails]' => 'info'
265 )));
266 }
267
268 if (!$this->silentMode) {
269 $flashMessage = t3lib_div::makeInstance(
270 't3lib_FlashMessage',
271 $messageContent,
272 $GLOBALS['LANG']->getLL('ext_import_success')
273 );
274 $content = $flashMessage->render();
275 } else {
276 $content = $updateContent;
277 }
278
279
280 // Install / Uninstall:
281 if (!$this->parentObject->CMD['standAlone']) {
282 $content .= '<h3>' . $GLOBALS['LANG']->getLL('ext_import_install_uninstall') . '</h3>';
283 $content .= $new_list[$extKey] ?
284 '<a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
285 'CMD[showExt]' => $extKey,
286 'CMD[remove]' => 1,
287 'CMD[clrCmd]' => 1,
288 'SET[singleDetails]' => 'info'
289 ))) . '">' .
290 tx_em_Tools::removeButton() . ' ' . $GLOBALS['LANG']->getLL('ext_import_uninstall') . '</a>' :
291 '<a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
292 'CMD[showExt]' => $extKey,
293 'CMD[load]' => 1,
294 'CMD[clrCmd]' => 1,
295 'SET[singleDetails]' => 'info'
296 ))) . '">' .
297 tx_em_Tools::installButton() . ' ' . $GLOBALS['LANG']->getLL('ext_import_install') . '</a>';
298 } else {
299 $content = $GLOBALS['LANG']->getLL('ext_import_imported') .
300 '<br /><br />';
301 if ($this->silentMode || t3lib_div::_GP('nodoc')) {
302 $content .= '<a id="closewindow" href="javascript:parent.TYPO3.EM.Tools.closeImportWindow();">' . $GLOBALS['LANG']->getLL('ext_import_close') . '</a>';
303 } else {
304 $content .= '<a href="javascript:opener.top.list.iframe.document.forms[0].submit();window.close();">' .
305 $GLOBALS['LANG']->getLL('ext_import_close_check') . '</a>';
306 }
307
308 }
309 }
310 } else {
311 if (!$this->silentMode) {
312 $flashMessage = t3lib_div::makeInstance(
313 't3lib_FlashMessage',
314 $res,
315 '',
316 t3lib_FlashMessage::ERROR
317 );
318 $content = $flashMessage->render();
319 } else {
320 $content = $res;
321 }
322 }
323 } else {
324 if (!$this->silentMode) {
325 $flashMessage = t3lib_div::makeInstance(
326 't3lib_FlashMessage',
327 sprintf($GLOBALS['LANG']->getLL('ext_import_ext_path_different'), $extDirPath),
328 '',
329 t3lib_FlashMessage::ERROR
330 );
331 $content = $flashMessage->render();
332 } else {
333 $content = sprintf($GLOBALS['LANG']->getLL('ext_import_ext_path_different'), $extDirPath);
334 }
335 }
336 } else {
337 if (!$this->silentMode) {
338 $flashMessage = t3lib_div::makeInstance(
339 't3lib_FlashMessage',
340 $res,
341 '',
342 t3lib_FlashMessage::ERROR
343 );
344 $content = $flashMessage->render();
345 } else {
346 $content = $res;
347 }
348 }
349 }
350 } else {
351 if (!$this->silentMode) {
352 $flashMessage = t3lib_div::makeInstance(
353 't3lib_FlashMessage',
354 sprintf($GLOBALS['LANG']->getLL('ext_import_ext_only_here'),
355 $this->typePaths[$EM_CONF['lockType']], $EM_CONF['lockType']),
356 '',
357 t3lib_FlashMessage::ERROR
358 );
359 $content = $flashMessage->render();
360 } else {
361 $content = sprintf($GLOBALS['LANG']->getLL('ext_import_ext_only_here'),
362 tx_em_Tools::typePath($EM_CONF['lockType']), $EM_CONF['lockType']);
363 }
364 }
365 } else {
366 if (!$this->silentMode) {
367 $flashMessage = t3lib_div::makeInstance(
368 't3lib_FlashMessage',
369 $GLOBALS['LANG']->getLL('ext_import_no_ext_key_files'),
370 '',
371 t3lib_FlashMessage::ERROR
372 );
373 $content = $flashMessage->render();
374 } else {
375 $content = $GLOBALS['LANG']->getLL('ext_import_no_ext_key_files');
376 }
377 }
378 } else {
379 if (!$this->silentMode) {
380 $flashMessage = t3lib_div::makeInstance(
381 't3lib_FlashMessage',
382 sprintf($GLOBALS['LANG']->getLL('ext_import_data_transfer'), $fetchData),
383 '',
384 t3lib_FlashMessage::ERROR
385 );
386 $content = $flashMessage->render();
387 } else {
388 $content = sprintf($GLOBALS['LANG']->getLL('ext_import_data_transfer'), $fetchData);
389 }
390 }
391 } else {
392 if (!$this->silentMode) {
393 $flashMessage = t3lib_div::makeInstance(
394 't3lib_FlashMessage',
395 sprintf($GLOBALS['LANG']->getLL('ext_import_no_install_here'), $this->typePaths[$loc]),
396 '',
397 t3lib_FlashMessage::ERROR
398 );
399 $content = $flashMessage->render();
400 } else {
401 $content = sprintf($GLOBALS['LANG']->getLL('ext_import_no_install_here'), tx_em_Tools::typePath($loc));
402 }
403 }
404
405 return $content;
406 }
407
408 /**
409 *Check extension dependencies
410 *
411 * @param string $extKey
412 * @param array $conf
413 * @param array $instExtInfo
414 * @return array
415 */
416 function checkDependencies($extKey, $conf, $instExtInfo) {
417 $content = '';
418 $depError = FALSE;
419 $depIgnore = FALSE;
420 $msg = array();
421 $depsolver = t3lib_div::_POST('depsolver');
422
423 if (isset($conf['constraints']['depends']) && is_array($conf['constraints']['depends'])) {
424 foreach ($conf['constraints']['depends'] as $depK => $depV) {
425 if ($depsolver['ignore'][$depK]) {
426 $msg[] = '<br />' . sprintf($GLOBALS['LANG']->getLL('checkDependencies_ignored'),
427 $depK) . '
428 <input type="hidden" value="1" name="depsolver[ignore][' . $depK . ']" />';
429 $depIgnore = TRUE;
430 continue;
431 }
432 if ($depK == 'php') {
433 if (!$depV) {
434 continue;
435 }
436 $versionRange = tx_em_Tools::splitVersionRange($depV);
437 $phpv = strstr(PHP_VERSION, '-') ? substr(PHP_VERSION, 0, strpos(PHP_VERSION, '-')) : PHP_VERSION; // Linux distributors like to add suffixes, like in 5.1.2-1. Those must be ignored!
438 if ($versionRange[0] != '0.0.0' && version_compare($phpv, $versionRange[0], '<')) {
439 $msg[] = '<br />' . sprintf($GLOBALS['LANG']->getLL('checkDependencies_php_too_low'),
440 $phpv, $versionRange[0]);
441 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore][' . $depK . ']" id="checkIgnore_' . $depK . '" />
442 <label for="checkIgnore_' . $depK . '">' . $GLOBALS['LANG']->getLL('checkDependencies_ignore_requirement') . '</label>';
443 $depError = TRUE;
444 continue;
445 } elseif ($versionRange[1] != '0.0.0' && version_compare($phpv, $versionRange[1], '>')) {
446 $msg[] = '<br />' . sprintf($GLOBALS['LANG']->getLL('checkDependencies_php_too_high'),
447 $phpv, $versionRange[1]);
448 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore][' . $depK . ']" id="checkIgnore_' . $depK . '" />
449 <label for="checkIgnore_' . $depK . '">' . $GLOBALS['LANG']->getLL('checkDependencies_ignore_requirement') . '</label>';
450 $depError = TRUE;
451 continue;
452 }
453
454 } elseif ($depK == 'typo3') {
455 if (!$depV) {
456 continue;
457 }
458
459 // if the current TYPO3 version is a development version (like TYPO3 4.4-dev),
460 // then it should behave like TYPO3 4.4.0
461 $t3version = TYPO3_version;
462 if (stripos($t3version, '-dev')
463 || stripos($t3version, '-alpha')
464 || stripos($t3version, '-beta')
465 || stripos($t3version, '-RC')) {
466 // find the last occurence of "-" and replace that part with a ".0"
467 $t3version = substr($t3version, 0, strrpos($t3version, '-')) . '.0';
468 }
469
470 $versionRange = tx_em_Tools::splitVersionRange($depV);
471 if ($versionRange[0] != '0.0.0' && version_compare($t3version, $versionRange[0], '<')) {
472 $msg[] = '<br />' . sprintf($GLOBALS['LANG']->getLL('checkDependencies_typo3_too_low'),
473 $t3version, $versionRange[0]);
474 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore][' . $depK . ']" id="checkIgnore_' . $depK . '" />
475 <label for="checkIgnore_' . $depK . '">' . $GLOBALS['LANG']->getLL('checkDependencies_ignore_requirement') . '</label>';
476 $depError = TRUE;
477 continue;
478 } elseif ($versionRange[1] != '0.0.0' && version_compare($t3version, $versionRange[1], '>')) {
479 $msg[] = '<br />' . sprintf($GLOBALS['LANG']->getLL('checkDependencies_typo3_too_high'),
480 $t3version, $versionRange[1]);
481 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore][' . $depK . ']" id="checkIgnore_' . $depK . '" />
482 <label for="checkIgnore_' . $depK . '">' . $GLOBALS['LANG']->getLL('checkDependencies_ignore_requirement') . '</label>';
483 $depError = TRUE;
484 continue;
485 }
486 } elseif (strlen($depK) && !t3lib_extMgm::isLoaded($depK)) { // strlen check for braindead empty dependencies coming from extensions...
487 if (!isset($instExtInfo[$depK])) {
488 $msg[] = '<br />' . sprintf($GLOBALS['LANG']->getLL('checkDependencies_ext_not_available'),
489 $depK);
490 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;' . t3lib_iconWorks::getSpriteIcon('actions-system-extension-import', array('title' => $GLOBALS['LANG']->getLL('checkDependencies_import_ext'))) . '&nbsp;
491 <a href="' . t3lib_div::linkThisUrl($this->parentObject->script, array(
492 'CMD[importExt]' => $depK,
493 'CMD[loc]' => 'L',
494 'CMD[standAlone]' => 1
495 )) . '" target="_blank">' . $GLOBALS['LANG']->getLL('checkDependencies_import_now') . '</a>';
496 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore][' . $depK . ']" id="checkIgnore_' . $depK . '" />
497 <label for="checkIgnore_' . $depK . '">' . $GLOBALS['LANG']->getLL('checkDependencies_ignore_ext_requirement') . '</label>';
498 } else {
499 $msg[] = '<br />' . sprintf($GLOBALS['LANG']->getLL('checkDependencies_ext_not_installed'),
500 $depK, $instExtInfo[$depK]['EM_CONF']['title']);
501 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;' . tx_em_Tools::installButton() . '&nbsp;
502 <a href="' . t3lib_div::linkThisUrl($this->parentObject->script, array(
503 'CMD[showExt]' => $depK,
504 'CMD[load]' => 1,
505 'CMD[clrCmd]' => 1,
506 'CMD[standAlone]' => 1,
507 'SET[singleDetails]' => 'info'
508 )) .
509 '" target="_blank">' . $GLOBALS['LANG']->getLL('checkDependencies_install_now') . '</a>';
510 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore][' . $depK . ']" id="checkIgnore_' . $depK . '" />
511 <label for="checkIgnore_' . $depK . '">' . $GLOBALS['LANG']->getLL('checkDependencies_ignore_ext_requirement') . '</label>';
512 }
513 $depError = TRUE;
514 } else {
515 $versionRange = tx_em_Tools::splitVersionRange($depV);
516 if ($versionRange[0] != '0.0.0' && version_compare($instExtInfo[$depK]['EM_CONF']['version'], $versionRange[0], '<')) {
517 $msg[] = '<br />' . sprintf($GLOBALS['LANG']->getLL('checkDependencies_ext_too_low'),
518 $depK, $instExtInfo[$depK]['EM_CONF']['version'], $versionRange[0]);
519 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore][' . $depK . ']" id="checkIgnore_' . $depK . '" />
520 <label for="checkIgnore_' . $depK . '">' . $GLOBALS['LANG']->getLL('checkDependencies_ignore_requirement') . '</label>';
521 $depError = TRUE;
522 continue;
523 } elseif ($versionRange[1] != '0.0.0' && version_compare($instExtInfo[$depK]['EM_CONF']['version'], $versionRange[1], '>')) {
524 $msg[] = '<br />' . sprintf($GLOBALS['LANG']->getLL('checkDependencies_ext_too_high'),
525 $depK, $instExtInfo[$depK]['EM_CONF']['version'], $versionRange[1]);
526 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore][' . $depK . ']" id="checkIgnore_' . $depK . '" />
527 <label for="checkIgnore_' . $depK . '">' . $GLOBALS['LANG']->getLL('checkDependencies_ignore_requirement') . '</label>';
528 $depError = TRUE;
529 continue;
530 }
531 }
532 }
533 }
534
535 if (($depError || $depIgnore) && $this->parentObject instanceof SC_mod_tools_em_index) {
536 $content .= $this->parentObject->doc->section(
537 $GLOBALS['LANG']->getLL('removeExtFromList_dependency_error'),
538 implode('<br />', $msg), 0, 1, 2
539 );
540 }
541
542 // Check conflicts with other extensions:
543 $conflictError = FALSE;
544 $conflictIgnore = FALSE;
545 $msg = array();
546
547 if (isset($conf['constraints']['conflicts']) && is_array($conf['constraints']['conflicts'])) {
548 foreach ((array) $conf['constraints']['conflicts'] as $conflictK => $conflictV) {
549 if ($depsolver['ignore'][$conflictK]) {
550 $msg[] = '<br />' . sprintf($GLOBALS['LANG']->getLL('checkDependencies_conflict_ignored'),
551 $conflictK) . '
552 <input type="hidden" value="1" name="depsolver[ignore][' . $conflictK . ']" />';
553 $conflictIgnore = TRUE;
554 continue;
555 }
556 if (t3lib_extMgm::isLoaded($conflictK)) {
557 $versionRange = tx_em_Tools::splitVersionRange($conflictV);
558 if ($versionRange[0] != '0.0.0' && version_compare($instExtInfo[$conflictK]['EM_CONF']['version'], $versionRange[0], '<')) {
559 continue;
560 }
561 elseif ($versionRange[1] != '0.0.0' && version_compare($instExtInfo[$conflictK]['EM_CONF']['version'], $versionRange[1], '>')) {
562 continue;
563 }
564 $msg[] = sprintf($GLOBALS['LANG']->getLL('checkDependencies_conflict_remove'),
565 $extKey, $conflictK, $instExtInfo[$conflictK]['EM_CONF']['title'], $conflictK, $extKey);
566 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;' . tx_em_Tools::removeButton() . '&nbsp;
567 <a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
568 'CMD[showExt]' => $conflictK,
569 'CMD[remove]' => 1,
570 'CMD[clrCmd]' => 1,
571 'CMD[standAlone]' => 1,
572 'SET[singleDetails]' => 'info'
573 ))) .
574 '" target="_blank">' . $GLOBALS['LANG']->getLL('checkDependencies_remove_now') . '</a>';
575 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore][' . $conflictK . ']" id="checkIgnore_' . $conflictK . '" />
576 <label for="checkIgnore_' . $conflictK . '">' . $GLOBALS['LANG']->getLL('checkDependencies_ignore_conflict') . '</label>';
577 $conflictError = TRUE;
578 }
579 }
580 }
581 if ($conflictError || $conflictIgnore) {
582 $content .= $this->parentObject->doc->section(
583 $GLOBALS['LANG']->getLL('checkDependencies_conflict_error'), implode('<br />', $msg), 0, 1, 2
584 );
585 }
586
587 // Check suggests on other extensions:
588 if (isset($conf['constraints']['suggests']) && is_array($conf['constraints']['suggests'])) {
589 $suggestion = FALSE;
590 $suggestionIgnore = FALSE;
591 $msg = array();
592 foreach ($conf['constraints']['suggests'] as $suggestK => $suggestV) {
593 if ($depsolver['ignore'][$suggestK]) {
594 $msg[] = '<br />' . sprintf($GLOBALS['LANG']->getLL('checkDependencies_suggestion_ignored'),
595 $suggestK) . '
596 <input type="hidden" value="1" name="depsolver[ignore][' . $suggestK . ']" />';
597 $suggestionIgnore = TRUE;
598 continue;
599 }
600 if (!t3lib_extMgm::isLoaded($suggestK)) {
601 if (!isset($instExtInfo[$suggestK])) {
602 $msg[] = sprintf($GLOBALS['LANG']->getLL('checkDependencies_suggest_import'),
603 $suggestK);
604 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;' . t3lib_iconWorks::getSpriteIcon('actions-system-extension-import', array('title' => $GLOBALS['LANG']->getLL('checkDependencies_import_ext'))) . '&nbsp;
605 <a href="' . t3lib_div::linkThisScript(array(
606 'CMD[importExt]' => $suggestK,
607 'CMD[loc]' => 'L',
608 'CMD[standAlone]' => 1
609 )) . '" target="_blank">' . $GLOBALS['LANG']->getLL('checkDependencies_import_now') . '</a>';
610 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore][' . $suggestK . ']" id="checkIgnore_' . $suggestK . '" />
611 <label for="checkIgnore_' . $suggestK . '">' . $GLOBALS['LANG']->getLL('checkDependencies_ignore_suggestion') . '</label>';
612 } else {
613 $msg[] = sprintf($GLOBALS['LANG']->getLL('checkDependencies_suggest_installation'),
614 $suggestK, $instExtInfo[$suggestK]['EM_CONF']['title']);
615 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;' . tx_em_Tools::installButton() . '&nbsp;
616 <a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
617 'CMD[showExt]' => $suggestK,
618 'CMD[load]' => 1,
619 'CMD[clrCmd]' => 1,
620 'CMD[standAlone]' => 1,
621 'SET[singleDetails]' => 'info'
622 ))) .
623 '" target="_blank">' . $GLOBALS['LANG']->getLL('checkDependencies_install_now') . '</a>';
624 $msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore][' . $suggestK . ']" id="checkIgnore_' . $suggestK . '" />
625 <label for="checkIgnore_' . $suggestK . '">' . $GLOBALS['LANG']->getLL('checkDependencies_ignore_suggestion') . '</label>';
626 }
627 $suggestion = TRUE;
628 }
629 }
630 if ($suggestion || $suggestionIgnore) {
631 $content .= $this->parentObject->doc->section(
632 sprintf($GLOBALS['LANG']->getLL('checkDependencies_exts_suggested_by_ext'), $extKey),
633 implode('<br />', $msg), 0, 1, 1
634 );
635 }
636 }
637
638 if ($depError || $conflictError || $suggestion) {
639 foreach ($this->parentObject->CMD as $k => $v) {
640 $content .= '<input type="hidden" name="CMD[' . $k . ']" value="' . $v . '" />';
641 }
642 $content .= '<br /><br /><input type="submit" value="' . $GLOBALS['LANG']->getLL('checkDependencies_try_again') . '" />';
643
644 if (t3lib_div::_GP('nodoc')) {
645 $content .= '<input type="hidden" name="nodoc" value="1" />';
646 }
647
648 return array(
649 'returnCode' => FALSE,
650 'html' => '<form action="' . $this->parentObject->script . '" method="post" name="depform">' . $content . '</form>');
651 }
652
653 return array(
654 'returnCode' => TRUE
655 );
656 }
657
658
659 /**
660 * Delete extension from the file system
661 *
662 * @param string Extension key
663 * @param array Extension info array
664 * @return string Returns message string about the status of the operation
665 */
666 function extDelete($extKey, $extInfo, $command) {
667 $content = '';
668 $absPath = tx_em_Tools::getExtPath($extKey, $extInfo['type']);
669 if (t3lib_extMgm::isLoaded($extKey)) {
670 return $GLOBALS['LANG']->getLL('extDelete_ext_active');
671 } elseif (!tx_em_Tools::deleteAsType($extInfo['type'])) {
672 return sprintf($GLOBALS['LANG']->getLL('extDelete_wrong_scope'),
673 $this->api->typeLabels[$extInfo['type']]
674 );
675 } elseif (t3lib_div::inList('G,L', $extInfo['type'])) {
676 if ($command['doDelete'] && !strcmp($absPath, urldecode($command['absPath']))) {
677 $res = $this->removeExtDirectory($absPath);
678 if ($res) {
679 if (!$this->silentMode) {
680 $flashMessage = t3lib_div::makeInstance(
681 't3lib_FlashMessage',
682 nl2br($res),
683 sprintf($GLOBALS['LANG']->getLL('extDelete_remove_dir_failed'), $absPath),
684 t3lib_FlashMessage::ERROR
685 );
686 return $flashMessage->render();
687 }
688 return '';
689 } else {
690 if (!$this->silentMode) {
691 $flashMessage = t3lib_div::makeInstance(
692 't3lib_FlashMessage',
693 sprintf($GLOBALS['LANG']->getLL('extDelete_removed'), $absPath),
694 $GLOBALS['LANG']->getLL('extDelete_removed_header'),
695 t3lib_FlashMessage::OK
696 );
697 return $flashMessage->render();
698 }
699 return '';
700 }
701 } else {
702 $areYouSure = $GLOBALS['LANG']->getLL('extDelete_sure');
703 $deleteFromServer = $GLOBALS['LANG']->getLL('extDelete_from_server');
704 $onClick = "if (confirm('$areYouSure')) {window.location.href='" . t3lib_div::linkThisScript(array(
705 'CMD[showExt]' => $extKey,
706 'CMD[doDelete]' => 1,
707 'CMD[absPath]' => rawurlencode($absPath)
708 )) . "';}";
709 $content .= '<a class="t3-link deleteLink" href="#" onclick="' . htmlspecialchars($onClick) .
710 ' return false;"><strong>' . $deleteFromServer . '</strong> ' .
711 sprintf($GLOBALS['LANG']->getLL('extDelete_from_location'),
712 $this->api->typeLabels[$extInfo['type']],
713 substr($absPath, strlen(PATH_site))
714 ) . '</a>';
715 $content .= '<br /><br />' . $GLOBALS['LANG']->getLL('extDelete_backup');
716 return $content;
717 }
718 } else {
719 return $GLOBALS['LANG']->getLL('extDelete_neither_global_nor_local');
720 }
721 }
722
723 /**
724 * Removes the extension directory (including content)
725 *
726 * @param string Extension directory to remove (with trailing slash)
727 * @param boolean If set, will leave the extension directory
728 * @return boolean False on success, otherwise error string.
729 */
730 function removeExtDirectory($removePath, $removeContentOnly = 0) {
731 $errors = array();
732 if (@is_dir($removePath) && substr($removePath, -1) == '/' && (
733 t3lib_div::isFirstPartOfStr($removePath, tx_em_Tools::typePath('G')) ||
734 t3lib_div::isFirstPartOfStr($removePath, tx_em_Tools::typePath('L')) ||
735 (t3lib_div::isFirstPartOfStr($removePath, tx_em_Tools::typePath('S')) && $this->systemInstall) ||
736 t3lib_div::isFirstPartOfStr($removePath, PATH_site . $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] . '_temp_/')) // Playing-around directory...
737 ) {
738
739 // All files in extension directory:
740 $fileArr = t3lib_div::getAllFilesAndFoldersInPath(array(), $removePath, '', 1);
741 if (is_array($fileArr)) {
742
743 // Remove files in dirs:
744 foreach ($fileArr as $removeFile) {
745 if (!@is_dir($removeFile)) {
746 if (@is_file($removeFile) && t3lib_div::isFirstPartOfStr($removeFile, $removePath) && strcmp($removeFile, $removePath)) { // ... we are very paranoid, so we check what cannot go wrong: that the file is in fact within the prefix path!
747 @unlink($removeFile);
748 clearstatcache();
749 if (@is_file($removeFile)) {
750 $errors[] = sprintf($GLOBALS['LANG']->getLL('rmExtDir_could_not_be_deleted'),
751 $removeFile
752 );
753 }
754 } else {
755 $errors[] = sprintf($GLOBALS['LANG']->getLL('rmExtDir_error_file'),
756 $removeFile, $removePath
757 );
758 }
759 }
760 }
761
762 // Remove directories:
763 $remDirs = tx_em_Tools::extractDirsFromFileList(t3lib_div::removePrefixPathFromList($fileArr, $removePath));
764 $remDirs = array_reverse($remDirs); // Must delete outer directories first...
765 foreach ($remDirs as $removeRelDir) {
766 $removeDir = $removePath . $removeRelDir;
767 if (@is_dir($removeDir)) {
768 @rmdir($removeDir);
769 clearstatcache();
770 if (@is_dir($removeDir)) {
771 $errors[] = sprintf($GLOBALS['LANG']->getLL('rmExtDir_error_files_left'),
772 $removeDir
773 );
774 }
775 } else {
776 $errors[] = sprintf($GLOBALS['LANG']->getLL('rmExtDir_error_no_dir'),
777 $removeDir
778 );
779 }
780 }
781
782 // If extension dir should also be removed:
783 if (!$removeContentOnly) {
784 @rmdir($removePath);
785 clearstatcache();
786 if (@is_dir($removePath)) {
787 $errors[] = sprintf($GLOBALS['LANG']->getLL('rmExtDir_error_folders_left'),
788 $removePath
789 );
790 }
791 }
792 } else {
793 $errors[] = $GLOBALS['LANG']->getLL('rmExtDir_error') . ' ' . $fileArr;
794 }
795 } else {
796 $errors[] = $GLOBALS['LANG']->getLL('rmExtDir_error_unallowed_path') . ' ' . $removePath;
797 }
798
799 // Return errors if any:
800 return implode(LF, $errors);
801 }
802
803 /**
804 * Validates the database according to extension requirements
805 * Prints form for changes if any. If none, returns blank. If an update is ordered, empty is returned as well.
806 * DBAL compliant (based on Install Tool code)
807 *
808 * @param string Extension key
809 * @param array Extension information array
810 * @param boolean If TRUE, returns array with info.
811 * @return mixed If $infoOnly, returns array with information. Otherwise performs update.
812 */
813 function checkDBupdates($extKey, $extInfo, $infoOnly = 0) {
814
815
816 $dbStatus = array();
817 $content = '';
818
819 // Updating tables and fields?
820 if (is_array($extInfo['files']) && in_array('ext_tables.sql', $extInfo['files'])) {
821 $path = tx_em_Tools::getExtPath($extKey, $extInfo['type']);
822 $fileContent = t3lib_div::getUrl($path . 'ext_tables.sql');
823
824 $FDfile = $this->install->getFieldDefinitions_fileContent($fileContent);
825 if (count($FDfile)) {
826 $FDdb = $this->install->getFieldDefinitions_database(TYPO3_db);
827 $diff = $this->install->getDatabaseExtra($FDfile, $FDdb);
828 $update_statements = $this->install->getUpdateSuggestions($diff);
829
830 $dbStatus['structure']['tables_fields'] = $FDfile;
831 $dbStatus['structure']['diff'] = $diff;
832
833 // Updating database...
834 if (!$infoOnly && is_array($this->install->INSTALL['database_update'])) {
835 $this->install->performUpdateQueries($update_statements['add'], $this->install->INSTALL['database_update']);
836 $this->install->performUpdateQueries($update_statements['change'], $this->install->INSTALL['database_update']);
837 $this->install->performUpdateQueries($update_statements['create_table'], $this->install->INSTALL['database_update']);
838 } else {
839 $content .= $this->install->generateUpdateDatabaseForm_checkboxes(
840 $update_statements['add'], $GLOBALS['LANG']->getLL('checkDBupdates_add_fields'));
841 $content .= $this->install->generateUpdateDatabaseForm_checkboxes(
842 $update_statements['change'], $GLOBALS['LANG']->getLL('checkDBupdates_changing_fields'), 1, 0, $update_statements['change_currentValue']);
843 $content .= $this->install->generateUpdateDatabaseForm_checkboxes(
844 $update_statements['create_table'], $GLOBALS['LANG']->getLL('checkDBupdates_add_tables'));
845 }
846 }
847 }
848
849 // Importing static tables?
850 if (is_array($extInfo['files']) && in_array('ext_tables_static+adt.sql', $extInfo['files'])) {
851 $fileContent = t3lib_div::getUrl(tx_em_Tools::getExtPath($extKey, $extInfo['type']) . 'ext_tables_static+adt.sql');
852
853 $statements = $this->install->getStatementarray($fileContent, 1);
854 list($statements_table, $insertCount) = $this->install->getCreateTables($statements, 1);
855
856 // Execute import of static table content:
857 if (!$infoOnly && is_array($this->install->INSTALL['database_import'])) {
858
859 // Traverse the tables
860 foreach ($this->install->INSTALL['database_import'] as $table => $md5str) {
861 if ($md5str == md5($statements_table[$table])) {
862 $GLOBALS['TYPO3_DB']->admin_query('DROP TABLE IF EXISTS ' . $table);
863 $GLOBALS['TYPO3_DB']->admin_query($statements_table[$table]);
864
865 if ($insertCount[$table]) {
866 $statements_insert = $this->install->getTableInsertStatements($statements, $table);
867
868 foreach ($statements_insert as $v) {
869 $GLOBALS['TYPO3_DB']->admin_query($v);
870 }
871 }
872 }
873 }
874 } else {
875 $whichTables = $this->install->getListOfTables();
876 if (count($statements_table)) {
877 $out = '';
878 foreach ($statements_table as $table => $definition) {
879 $exist = isset($whichTables[$table]);
880
881 $dbStatus['static'][$table]['exists'] = $exist;
882 $dbStatus['static'][$table]['count'] = $insertCount[$table];
883
884 $out .= '<tr>
885 <td><input type="checkbox" id="check_table_' . $table . '" name="TYPO3_INSTALL[database_import][' . $table . ']" checked="checked" value="' . md5($definition) . '" /></td>
886 <td><strong><label for="check_table_' . $table . '">' . $table . '</label></strong></td>
887 <td><img src="clear.gif" width="10" height="1" alt="" /></td>
888 <td nowrap="nowrap">' .
889 ($insertCount[$table] ?
890 $GLOBALS['LANG']->getLL('checkDBupdates_rows') . ' ' . $insertCount[$table]
891 : '') .
892 '</td>
893 <td><img src="clear.gif" width="10" height="1" alt="" /></td>
894 <td nowrap="nowrap">' .
895 ($exist ?
896 t3lib_iconWorks::getSpriteIcon('status-dialog-warning') .
897 $GLOBALS['LANG']->getLL('checkDBupdates_table_exists')
898 : '') .
899 '</td>
900 </tr>';
901 }
902 $content .= '
903 <br />
904 <h3>' . $GLOBALS['LANG']->getLL('checkDBupdates_import_static_data') . '</h3>
905 <table border="0" cellpadding="0" cellspacing="0">' . $out . '</table>
906 ';
907 }
908 }
909 }
910
911 // Return array of information if $infoOnly, otherwise content.
912 return $infoOnly ? $dbStatus : $content;
913 }
914
915 /**
916 * Removes the current extension of $type and creates the base folder for the new one (which is going to be imported)
917 *
918 * @param array Data for imported extension
919 * @param string Extension installation scope (L,G,S)
920 * @param boolean If set, nothing will be deleted (neither directory nor files)
921 * @return mixed Returns array on success (with extension directory), otherwise an error string.
922 */
923 function clearAndMakeExtensionDir($importedData, $type, $dontDelete = 0) {
924 if (!$importedData['extKey']) {
925 return $GLOBALS['LANG']->getLL('clearMakeExtDir_no_ext_key');
926 }
927
928 // Setting install path (L, G, S or fileadmin/_temp_/)
929 $path = '';
930 switch ((string) $type) {
931 case 'G':
932 case 'L':
933 $path = tx_em_Tools::typePath($type);
934 $suffix = '';
935
936 // Creates the typo3conf/ext/ directory if it does NOT already exist:
937 if ((string) $type == 'L' && !@is_dir($path)) {
938 t3lib_div::mkdir($path);
939 }
940 break;
941 default:
942 if ($this->systemInstall && (string) $type == 'S') {
943 $path = tx_em_Tools::typePath($type);
944 $suffix = '';
945 } else {
946 $path = PATH_site . $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] . '_temp_/';
947 $suffix = '_' . date('dmy-His');
948 }
949 break;
950 }
951
952 // If the install path is OK...
953 if ($path && @is_dir($path)) {
954
955 // Set extension directory:
956 $extDirPath = $path . $importedData['extKey'] . $suffix . '/';
957
958 // Install dir was found, remove it then:
959 if (@is_dir($extDirPath)) {
960 if ($dontDelete) {
961 return array($extDirPath);
962 }
963 $res = $this->removeExtDirectory($extDirPath);
964 if ($res) {
965 if (!$this->silentMode) {
966 $flashMessage = t3lib_div::makeInstance(
967 't3lib_FlashMessage',
968 nl2br($res),
969 sprintf($GLOBALS['LANG']->getLL('clearMakeExtDir_could_not_remove_dir'), $extDirPath),
970 t3lib_FlashMessage::ERROR
971 );
972 return $flashMessage->render();
973 }
974 return '';
975 }
976 }
977
978 // We go create...
979 t3lib_div::mkdir($extDirPath);
980 if (!is_dir($extDirPath)) {
981 return sprintf($GLOBALS['LANG']->getLL('clearMakeExtDir_could_not_create_dir'),
982 $extDirPath);
983 }
984 return array($extDirPath);
985 } else {
986 return sprintf($GLOBALS['LANG']->getLL('clearMakeExtDir_no_dir'),
987 $path);
988 }
989 }
990
991
992 /*******************************
993 *
994 * Extension analyzing (detailed information)
995 *
996 ******************************/
997
998 /**
999 * Perform a detailed, technical analysis of the available extension on server!
1000 * Includes all kinds of verifications
1001 * Takes some time to process, therfore use with care, in particular in listings.
1002 *
1003 * @param string Extension key
1004 * @param array Extension information
1005 * @param boolean If set, checks for validity of classes etc.
1006 * @return array Information in an array.
1007 */
1008 function makeDetailedExtensionAnalysis($extKey, $extInfo, $validity = 0) {
1009
1010 // Get absolute path of the extension
1011 $absPath = tx_em_Tools::getExtPath($extKey, $extInfo['type']);
1012 $extensionDetails = t3lib_div::makeInstance('tx_em_Extensions_Details', $this);
1013 $infoArray = array();
1014
1015 $table_class_prefix = substr($extKey, 0, 5) == 'user_' ? 'user_' : 'tx_' . str_replace('_', '', $extKey) . '_';
1016 $module_prefix = substr($extKey, 0, 5) == 'user_' ? 'u' : 'tx' . str_replace('_', '', $extKey);
1017
1018 // Database status:
1019 $dbInfo = $this->checkDBupdates($extKey, $extInfo, 1);
1020
1021 // Database structure required:
1022 if (is_array($dbInfo['structure']['tables_fields'])) {
1023 $modify_tables = t3lib_div::trimExplode(',', $extInfo['EM_CONF']['modify_tables'], 1);
1024 $infoArray['dump_tf'] = array();
1025
1026 foreach ($dbInfo['structure']['tables_fields'] as $tN => $d) {
1027 if (in_array($tN, $modify_tables)) {
1028 $infoArray['fields'][] = $tN . ': <i>' .
1029 (is_array($d['fields']) ? implode(', ', array_keys($d['fields'])) : '') .
1030 (is_array($d['keys']) ?
1031 ' + ' . count($d['keys']) . ' ' . $GLOBALS['LANG']->getLL('detailedExtAnalysis_keys') : '') .
1032 '</i>';
1033 if (is_array($d['fields'])) {
1034 foreach ($d['fields'] as $fN => $value) {
1035 $infoArray['dump_tf'][] = $tN . '.' . $fN;
1036 if (!t3lib_div::isFirstPartOfStr($fN, $table_class_prefix)) {
1037 $infoArray['NSerrors']['fields'][$fN] = $fN;
1038 } else {
1039 $infoArray['NSok']['fields'][$fN] = $fN;
1040 }
1041 }
1042 }
1043 if (is_array($d['keys'])) {
1044 foreach ($d['keys'] as $fN => $value) {
1045 $infoArray['dump_tf'][] = $tN . '.KEY:' . $fN;
1046 }
1047 }
1048 } else {
1049 $infoArray['dump_tf'][] = $tN;
1050 $infoArray['tables'][] = $tN;
1051 if (!t3lib_div::isFirstPartOfStr($tN, $table_class_prefix)) {
1052 $infoArray['NSerrors']['tables'][$tN] = $tN;
1053 } else {
1054 $infoArray['NSok']['tables'][$tN] = $tN;
1055 }
1056 }
1057 }
1058 if (count($dbInfo['structure']['diff']['diff']) || count($dbInfo['structure']['diff']['extra'])) {
1059 $msg = array();
1060 if (count($dbInfo['structure']['diff']['diff'])) {
1061 $msg[] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_tables_are_missing');
1062 }
1063 if (count($dbInfo['structure']['diff']['extra'])) {
1064 $msg[] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_tables_are_of_wrong_type');
1065 }
1066 $infoArray['tables_error'] = 1;
1067 if (t3lib_extMgm::isLoaded($extKey)) {
1068 $infoArray['errors'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_tables_are'),
1069 implode(' ' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:and') . ' ', $msg)
1070 );
1071 }
1072 }
1073 }
1074
1075 // Static tables?
1076 if (is_array($dbInfo['static'])) {
1077 $infoArray['static'] = array_keys($dbInfo['static']);
1078
1079 foreach ($dbInfo['static'] as $tN => $d) {
1080 if (!$d['exists']) {
1081 $infoArray['static_error'] = 1;
1082 if (t3lib_extMgm::isLoaded($extKey)) {
1083 $infoArray['errors'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_static_tables_missing');
1084 }
1085 if (!t3lib_div::isFirstPartOfStr($tN, $table_class_prefix)) {
1086 $infoArray['NSerrors']['tables'][$tN] = $tN;
1087 } else {
1088 $infoArray['NSok']['tables'][$tN] = $tN;
1089 }
1090 }
1091 }
1092 }
1093
1094 // Backend Module-check:
1095 $knownModuleList = t3lib_div::trimExplode(',', $extInfo['EM_CONF']['module'], 1);
1096 foreach ($knownModuleList as $mod) {
1097 if (@is_dir($absPath . $mod)) {
1098 if (@is_file($absPath . $mod . '/conf.php')) {
1099 $confFileInfo = $extensionDetails->modConfFileAnalysis($absPath . $mod . '/conf.php');
1100 if (is_array($confFileInfo['TYPO3_MOD_PATH'])) {
1101 $shouldBePath = tx_em_Tools::typeRelPath($extInfo['type']) . $extKey . '/' . $mod . '/';
1102 if (strcmp($confFileInfo['TYPO3_MOD_PATH'][1][1], $shouldBePath)) {
1103 $infoArray['errors'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_wrong_mod_path'),
1104 $confFileInfo['TYPO3_MOD_PATH'][1][1],
1105 $shouldBePath
1106 );
1107 }
1108 } else {
1109 // It seems like TYPO3_MOD_PATH and therefore also this warning is no longer needed.
1110 // $infoArray['errors'][] = 'No definition of TYPO3_MOD_PATH constant found inside!';
1111 }
1112 if (is_array($confFileInfo['MCONF_name'])) {
1113 $mName = $confFileInfo['MCONF_name'][1][1];
1114 $mNameParts = explode('_', $mName);
1115 $infoArray['moduleNames'][] = $mName;
1116 if (!t3lib_div::isFirstPartOfStr($mNameParts[0], $module_prefix) &&
1117 (!$mNameParts[1] || !t3lib_div::isFirstPartOfStr($mNameParts[1], $module_prefix))) {
1118 $infoArray['NSerrors']['modname'][] = $mName;
1119 } else {
1120 $infoArray['NSok']['modname'][] = $mName;
1121 }
1122 } else {
1123 $infoArray['errors'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_mconf_missing');
1124 }
1125 } else {
1126 $infoArray['errors'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_be_module_conf_missing'),
1127 $mod . '/conf.php'
1128 );
1129 }
1130 } else {
1131 $infoArray['errors'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_module_folder_missing'),
1132 $mod . '/'
1133 );
1134 }
1135 }
1136 $dirs = t3lib_div::get_dirs($absPath);
1137 if (is_array($dirs)) {
1138 reset($dirs);
1139 while (list(, $mod) = each($dirs)) {
1140 if (!in_array($mod, $knownModuleList) && @is_file($absPath . $mod . '/conf.php')) {
1141 $confFileInfo = $extensionDetails->modConfFileAnalysis($absPath . $mod . '/conf.php');
1142 if (is_array($confFileInfo)) {
1143 $infoArray['errors'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_unconfigured_module'),
1144 $mod . '/conf.php'
1145 );
1146 }
1147 }
1148 }
1149 }
1150
1151 // ext_tables.php:
1152 if (@is_file($absPath . 'ext_tables.php')) {
1153 $content = t3lib_div::getUrl($absPath . 'ext_tables.php');
1154 if (stristr($content, 't3lib_extMgm::addModule')) {
1155 $infoArray['flags'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_module');
1156 }
1157 if (stristr($content, 't3lib_extMgm::insertModuleFunction')) {
1158 $infoArray['flags'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_module_and_more');
1159 }
1160 if (stristr($content, 't3lib_div::loadTCA')) {
1161 $infoArray['flags'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_loadTCA');
1162 }
1163 if (stristr($content, '$TCA[')) {
1164 $infoArray['flags'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_TCA');
1165 }
1166 if (stristr($content, 't3lib_extMgm::addPlugin')) {
1167 $infoArray['flags'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_plugin');
1168 }
1169 }
1170
1171 // ext_localconf.php:
1172 if (@is_file($absPath . 'ext_localconf.php')) {
1173 $content = t3lib_div::getUrl($absPath . 'ext_localconf.php');
1174 if (stristr($content, 't3lib_extMgm::addPItoST43')) {
1175 $infoArray['flags'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_plugin_st43');
1176 }
1177 if (stristr($content, 't3lib_extMgm::addPageTSConfig')) {
1178 $infoArray['flags'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_page_ts');
1179 }
1180 if (stristr($content, 't3lib_extMgm::addUserTSConfig')) {
1181 $infoArray['flags'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_user_ts');
1182 }
1183 if (stristr($content, 't3lib_extMgm::addTypoScriptSetup')) {
1184 $infoArray['flags'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_ts_setup');
1185 }
1186 if (stristr($content, 't3lib_extMgm::addTypoScriptConstants')) {
1187 $infoArray['flags'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_ts_constants');
1188 }
1189 }
1190
1191 if (@is_file($absPath . 'ext_typoscript_constants.txt')) {
1192 $infoArray['TSfiles'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_constants');
1193 }
1194 if (@is_file($absPath . 'ext_typoscript_setup.txt')) {
1195 $infoArray['TSfiles'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_setup');
1196 }
1197 if (@is_file($absPath . 'ext_conf_template.txt')) {
1198 $infoArray['conf'] = 1;
1199 }
1200
1201 // Classes:
1202 if ($validity) {
1203 $filesInside = tx_em_Tools::getClassIndexLocallangFiles($absPath, $table_class_prefix, $extKey);
1204 if (is_array($filesInside['errors'])) {
1205 $infoArray['errors'] = array_merge((array) $infoArray['errors'], $filesInside['errors']);
1206 }
1207 if (is_array($filesInside['NSerrors'])) {
1208 $infoArray['NSerrors'] = array_merge((array) $infoArray['NSerrors'], $filesInside['NSerrors']);
1209 }
1210 if (is_array($filesInside['NSok'])) {
1211 $infoArray['NSok'] = array_merge((array) $infoArray['NSok'], $filesInside['NSok']);
1212 }
1213 $infoArray['locallang'] = $filesInside['locallang'];
1214 $infoArray['classes'] = $filesInside['classes'];
1215 }
1216
1217 // Upload folders
1218 if ($extInfo['EM_CONF']['uploadfolder']) {
1219 $infoArray['uploadfolder'] = tx_em_Tools::uploadFolder($extKey);
1220 if (!@is_dir(PATH_site . $infoArray['uploadfolder'])) {
1221 $infoArray['errors'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_no_upload_folder'),
1222 $infoArray['uploadfolder']
1223 );
1224 $infoArray['uploadfolder'] = '';
1225 }
1226 }
1227
1228 // Create directories:
1229 if ($extInfo['EM_CONF']['createDirs']) {
1230 $infoArray['createDirs'] = array_unique(t3lib_div::trimExplode(',', $extInfo['EM_CONF']['createDirs'], 1));
1231 foreach ($infoArray['createDirs'] as $crDir) {
1232 if (!@is_dir(PATH_site . $crDir)) {
1233 $infoArray['errors'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_no_upload_folder'),
1234 $crDir
1235 );
1236 }
1237 }
1238 }
1239
1240 // Return result array:
1241 return $infoArray;
1242 }
1243
1244
1245 /**
1246 * Produces the config form for an extension (if any template file, ext_conf_template.txt is found)
1247 *
1248 * @param string Extension key
1249 * @param array Extension information array
1250 * @param boolean If TRUE, the form HTML content is returned, otherwise the content is set in $this->content.
1251 * @param string Submit-to URL (supposedly)
1252 * @param string Additional form fields to include.
1253 * @return string Depending on $output. Can return the whole form.
1254 */
1255 function tsStyleConfigForm($extKey, $extInfo, $output = 0, $script = '', $addFields = '') {
1256 global $TYPO3_CONF_VARS;
1257
1258 // Initialize:
1259 $absPath = tx_em_Tools::getExtPath($extKey, $extInfo['type']);
1260 $relPath = tx_em_Tools::typeRelPath($extInfo['type']) . $extKey . '/';
1261
1262 $form = '';
1263
1264 // Look for template file for form:
1265 if (t3lib_extMgm::isLoaded($extKey) && @is_file($absPath . 'ext_conf_template.txt')) {
1266
1267 // Load tsStyleConfig class and parse configuration template:
1268 $tsStyleConfig = t3lib_div::makeInstance('t3lib_tsStyleConfig');
1269 $tsStyleConfig->doNotSortCategoriesBeforeMakingForm = TRUE;
1270 $theConstants = $tsStyleConfig->ext_initTSstyleConfig(
1271 t3lib_div::getUrl($absPath . 'ext_conf_template.txt'),
1272 $relPath,
1273 $absPath,
1274 $GLOBALS['BACK_PATH']
1275 );
1276
1277 // Load the list of resources.
1278 $tsStyleConfig->ext_loadResources($absPath . 'res/');
1279
1280 // Load current value:
1281 $arr = unserialize($TYPO3_CONF_VARS['EXT']['extConf'][$extKey]);
1282 $arr = is_array($arr) ? $arr : array();
1283
1284 // Call processing function for constants config and data before write and form rendering:
1285 if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/mod/tools/em/index.php']['tsStyleConfigForm'])) {
1286 $_params = array('fields' => &$theConstants, 'data' => &$arr, 'extKey' => $extKey);
1287 foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/mod/tools/em/index.php']['tsStyleConfigForm'] as $_funcRef) {
1288 t3lib_div::callUserFunction($_funcRef, $_params, $this);
1289 }
1290 unset($_params);
1291 }
1292
1293 // If saving operation is done:
1294 if (t3lib_div::_POST('submit')) {
1295 $tsStyleConfig->ext_procesInput(t3lib_div::_POST(), array(), $theConstants, array());
1296 $arr = $tsStyleConfig->ext_mergeIncomingWithExisting($arr);
1297 $this->writeTsStyleConfig($extKey, $arr);
1298 }
1299
1300 // Setting value array
1301 $tsStyleConfig->ext_setValuearray($theConstants, $arr);
1302
1303 // Getting session data:
1304 $MOD_MENU = array();
1305 $MOD_MENU['constant_editor_cat'] = $tsStyleConfig->ext_getCategoriesForModMenu();
1306 $MOD_SETTINGS = t3lib_BEfunc::getModuleData($MOD_MENU, t3lib_div::_GP('SET'), 'xMod_test');
1307
1308 // Resetting the menu (stop)
1309 if (count($MOD_MENU['constant_editor_cat']) > 1) {
1310 $menu = $GLOBALS['LANG']->getLL('extInfoArray_category') . ' ' .
1311 t3lib_BEfunc::getFuncMenu(0, 'SET[constant_editor_cat]', $MOD_SETTINGS['constant_editor_cat'], $MOD_MENU['constant_editor_cat'], '', '&CMD[showExt]=' . $extKey);
1312 // add class to select
1313 $menu = str_replace('<select', '<select class="mod-menu-template-select"', $menu);
1314 if ($this->silentMode) {
1315 $menu = str_replace('jumpToUrl', 'abc', $menu);
1316 }
1317
1318 if ($this->parentObject instanceof SC_mod_tools_em_index) {
1319 $this->parentObject->content .= $this->parentObject->doc->section('', '<span class="nobr">' . $menu . '</span>');
1320 $this->parentObject->content .= $this->parentObject->doc->spacer(10);
1321 } else {
1322 $form .= '<h3>' . '<span class="nobr">' . $menu . '</span></h3>';
1323 }
1324 }
1325
1326 // Category and constant editor config:
1327 $form .= '
1328 <table border="0" cellpadding="0" cellspacing="0" width="600">
1329 <tr>
1330 <td>' . $tsStyleConfig->ext_getForm(
1331 $MOD_SETTINGS['constant_editor_cat'],
1332 $theConstants,
1333 $script,
1334 $addFields,
1335 $extKey,
1336 !$this->silentMode
1337 ) . ($this->silentMode ? '' : '</form>') .'</td>
1338 </tr>
1339 </table>';
1340 } else {
1341 if (!$this->silentMode) {
1342 $flashMessage = t3lib_div::makeInstance(
1343 't3lib_FlashMessage',
1344 $GLOBALS['LANG']->getLL('tsStyleConfigForm_additional_config'),
1345 '',
1346 t3lib_FlashMessage::INFO
1347 );
1348 }
1349
1350 $form = '
1351 <table border="0" cellpadding="0" cellspacing="0" width="600">
1352 <tr>
1353 <td>
1354 <form action="' . htmlspecialchars($script) . '" method="post">' .
1355 $addFields .
1356 ($this->silentMode ? '' : $flashMessage->render()) .
1357 (t3lib_div::_GP('nodoc') ? '<input type="hidden" name="nodoc" value="1" />' : '') .
1358 '<br /><input type="submit" id="configuration-submit-' . $extKey . '" name="write" value="' . $GLOBALS['LANG']->getLL('updatesForm_make_updates') . '" />
1359 </form>
1360 </td>
1361 </tr>
1362 </table>';
1363 }
1364
1365
1366 return $form;
1367
1368 }
1369
1370 /**
1371 * Writes the TSstyleconf values to "localconf.php"
1372 * Removes the temp_CACHED* files before return.
1373 *
1374 * @param string Extension key
1375 * @param array Configuration array to write back
1376 * @return void
1377 */
1378 function writeTsStyleConfig($extKey, $arr) {
1379
1380 // Instance of install tool
1381 $instObj = new t3lib_install;
1382 $instObj->allowUpdateLocalConf = 1;
1383 $instObj->updateIdentity = 'TYPO3 Extension Manager';
1384
1385 // Get lines from localconf file
1386 $lines = $instObj->writeToLocalconf_control();
1387 $instObj->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'EXT\'][\'extConf\'][\'' . $extKey . '\']', serialize($arr)); // This will be saved only if there are no linebreaks in it !
1388 $instObj->writeToLocalconf_control($lines);
1389
1390 t3lib_extMgm::removeCacheFiles();
1391 }
1392
1393
1394 /**
1395 * Creates a form for an extension which contains all options for configuration, updates of database, clearing of cache etc.
1396 *
1397 * @param string $extKey Extension key
1398 * @param array $extInfo Extension information array
1399 * @param boolean $notSilent If set, the form will ONLY show if fields/tables should be updated (suppressing forms like general configuration and cache clearing).
1400 * @param string $script Alternative action=""-script
1401 * @param string $addFields Additional form fields
1402 * @param boolean $addFormTags TRUE if it shopuld be wrapped with form tag
1403 * @param boolean $excludeDatabaseCheck TRUE if no database check should be done
1404 * @return string
1405 */
1406 function updatesForm($extKey, $extInfo, $notSilent = FALSE, $script = '', $addFields = '', $addFormTag = TRUE, $excludeDatabaseCheck = FALSE) {
1407 $script = $script ? $script : t3lib_div::linkThisScript();
1408 if ($addFormTag) {
1409 $formWrap = array('<form action="' . htmlspecialchars($script) . '" method="POST">', '</form>');
1410 } else {
1411 $formWrap = array('', '');
1412 }
1413 $extensionDetails = t3lib_div::makeInstance('tx_em_Extensions_Details', $this);
1414 $updates = '';
1415
1416 if (!$excludeDatabaseCheck) {
1417 $updates .= $this->checkDBupdates($extKey, $extInfo);
1418 }
1419
1420 $uCache = $this->checkClearCache($extInfo);
1421 if ($notSilent) {
1422 $updates .= $uCache;
1423 }
1424 $updates .= $extensionDetails->checkUploadFolder($extKey, $extInfo);
1425
1426 $absPath = tx_em_Tools::getExtPath($extKey, $extInfo['type']);
1427 if ($notSilent && @is_file($absPath . 'ext_conf_template.txt')) {
1428 $configForm = $this->tsStyleConfigForm($extKey, $extInfo, 1, $script, $updates . $addFields . '<br />');
1429 }
1430
1431 if ($updates || $configForm) {
1432 if ($configForm) {
1433 $updates = $configForm;
1434 } else {
1435 $updates = $formWrap[0] . $updates . $addFields . '
1436 <br /><input type="submit" name="write" id="update-submit-' . $extKey . '" value="' . $GLOBALS['LANG']->getLL('updatesForm_make_updates') . '" />
1437 ' . $formWrap[1];
1438 }
1439 }
1440
1441 return $updates;
1442 }
1443
1444
1445 /**
1446 * Check if clear-cache should be performed, otherwise show form (for installation of extension)
1447 * Shown only if the extension has the clearCacheOnLoad flag set.
1448 *
1449 * @param string Extension key
1450 * @param array Extension information array
1451 * @return string HTML output (if form is shown)
1452 */
1453 function checkClearCache($extInfo) {
1454 $content = '';
1455 if ($extInfo['EM_CONF']['clearCacheOnLoad']) {
1456 if (t3lib_div::_POST('_clear_all_cache')) { // Action: Clearing the cache
1457 $tce = t3lib_div::makeInstance('t3lib_TCEmain');
1458 $tce->stripslashes_values = 0;
1459 $tce->start(array(), array());
1460 $tce->clear_cacheCmd('all');
1461 } else { // Show checkbox for clearing cache:
1462 $content .= '
1463 <br />
1464 <h3>' . $GLOBALS['LANG']->getLL('checkUploadFolder_clear_cache') . '</h3>
1465 <p>' . $GLOBALS['LANG']->getLL('checkUploadFolder_clear_cache_requested') . '<br />
1466 <label for="check_clear_all_cache">' . $GLOBALS['LANG']->getLL('checkUploadFolder_clear_all_cache') . '</label>
1467 <input type="checkbox" name="_clear_all_cache" id="check_clear_all_cache" checked="checked" value="1" /><br />
1468 </p>
1469 ';
1470 }
1471 }
1472 return $content;
1473 }
1474
1475 /**
1476 * Writes the extension list to "localconf.php" file
1477 * Removes the temp_CACHED* files before return.
1478 *
1479 * @param string List of extensions
1480 * @return void
1481 */
1482 function writeNewExtensionList($newExtList) {
1483 $strippedExtensionList = $this->stripNonFrontendExtensions($newExtList);
1484
1485 // Instance of install tool
1486 $instObj = new t3lib_install;
1487 $instObj->allowUpdateLocalConf = 1;
1488 $instObj->updateIdentity = 'TYPO3 Extension Manager';
1489
1490 // Get lines from localconf file
1491 $lines = $instObj->writeToLocalconf_control();
1492 $instObj->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'EXT\'][\'extList\']', $newExtList);
1493 $instObj->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'EXT\'][\'extList_FE\']', $strippedExtensionList);
1494 $instObj->writeToLocalconf_control($lines);
1495
1496 $GLOBALS['TYPO3_CONF_VARS']['EXT']['extList'] = $newExtList;
1497 $GLOBALS['TYPO3_CONF_VARS']['EXT']['extList_FE'] = $strippedExtensionList;
1498 t3lib_extMgm::removeCacheFiles();
1499 }
1500
1501 /**
1502 * Removes unneeded extensions from the frontend based on
1503 * EMCONF doNotLoadInFE = 1
1504 *
1505 * @param string $extList
1506 * @return string
1507 */
1508 function stripNonFrontendExtensions($extList) {
1509 $fullExtList = $this->parentObject->extensionList->getInstalledExtensions();
1510 $extListArray = t3lib_div::trimExplode(',', $extList);
1511 foreach ($extListArray as $arrayKey => $extKey) {
1512 if ($fullExtList[0][$extKey]['EM_CONF']['doNotLoadInFE'] == 1) {
1513 unset($extListArray[$arrayKey]);
1514 }
1515 }
1516 $nonFEList = implode(',', $extListArray);
1517 return $nonFEList;
1518 }
1519
1520 /**
1521 * Updates the database according to extension requirements
1522 * DBAL compliant (based on Install Tool code)
1523 *
1524 * @param string Extension key
1525 * @param array Extension information array
1526 * @return void
1527 */
1528 function forceDBupdates($extKey, $extInfo) {
1529 $instObj = new t3lib_install;
1530
1531 // Updating tables and fields?
1532 if (is_array($extInfo['files']) && in_array('ext_tables.sql', $extInfo['files'])) {
1533 $fileContent = t3lib_div::getUrl(tx_em_Tools::getExtPath($extKey, $extInfo['type']) . 'ext_tables.sql');
1534
1535 $FDfile = $instObj->getFieldDefinitions_fileContent($fileContent);
1536 if (count($FDfile)) {
1537 $FDdb = $instObj->getFieldDefinitions_database(TYPO3_db);
1538 $diff = $instObj->getDatabaseExtra($FDfile, $FDdb);
1539 $update_statements = $instObj->getUpdateSuggestions($diff);
1540
1541 foreach ((array) $update_statements['add'] as $string) {
1542 $GLOBALS['TYPO3_DB']->admin_query($string);
1543 }
1544 foreach ((array) $update_statements['change'] as $string) {
1545 $GLOBALS['TYPO3_DB']->admin_query($string);
1546 }
1547 foreach ((array) $update_statements['create_table'] as $string) {
1548 $GLOBALS['TYPO3_DB']->admin_query($string);
1549 }
1550 }
1551 }
1552
1553 // Importing static tables?
1554 if (is_array($extInfo['files']) && in_array('ext_tables_static+adt.sql', $extInfo['files'])) {
1555 $fileContent = t3lib_div::getUrl(tx_em_Tools::getExtPath($extKey, $extInfo['type']) . 'ext_tables_static+adt.sql');
1556
1557 $statements = $instObj->getStatementarray($fileContent, 1);
1558 list($statements_table, $insertCount) = $instObj->getCreateTables($statements, 1);
1559
1560 // Traverse the tables
1561 foreach ($statements_table as $table => $query) {
1562 $GLOBALS['TYPO3_DB']->admin_query('DROP TABLE IF EXISTS ' . $table);
1563 $GLOBALS['TYPO3_DB']->admin_query($query);
1564
1565 if ($insertCount[$table]) {
1566 $statements_insert = $instObj->getTableInsertStatements($statements, $table);
1567
1568 foreach ($statements_insert as $v) {
1569 $GLOBALS['TYPO3_DB']->admin_query($v);
1570 }
1571 }
1572 }
1573 }
1574 }
1575
1576 }
1577
1578 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/em/classes/install/class.tx_em_install.php'])) {
1579 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/em/classes/install/class.tx_em_install.php']);
1580 }
1581
1582 ?>