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