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