[BUGFIX] Unify table layouts
[Packages/TYPO3.CMS.git] / typo3 / sysext / em / classes / extensions / class.tx_em_extensions_list.php
1 <?php
2 /* **************************************************************
3 * Copyright notice
4 *
5 * (c) webservices.nl
6 * (c) 2006-2010 Karsten Dambekalns <karsten@typo3.org>
7 * All rights reserved
8 *
9 * This script is part of the TYPO3 project. The TYPO3 project is
10 * free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * The GNU General Public License can be found at
16 * http://www.gnu.org/copyleft/gpl.html.
17 * A copy is found in the textfile GPL.txt and important notices to the license
18 * from the author is found in LICENSE.txt distributed with these scripts.
19 *
20 *
21 * This script is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * This copyright notice MUST APPEAR in all copies of the script!
27 ***************************************************************/
28
29 /**
30 * This class handles extension listings
31 *
32 */
33 class tx_em_Extensions_List {
34
35
36 protected $parentObject;
37
38 /** @var tx_em_Tools_XmlHandler */
39 protected $xmlHandler;
40
41 protected $categories;
42 protected $types;
43 protected $states;
44
45 /**
46 * Constructor
47 *
48 * @param object $parentObject
49 * @return void
50 */
51 public function __construct($parentObject = NULL) {
52 $this->parentObject = $parentObject;
53 $this->install = t3lib_div::makeInstance('tx_em_Install', $this);
54 $this->xmlHandler = t3lib_div::makeInstance('tx_em_Tools_XmlHandler');
55
56 $this->categories = array(
57 'be' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_BE'),
58 'module' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_BE_modules'),
59 'fe' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_FE'),
60 'plugin' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_FE_plugins'),
61 'misc' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_miscellanous'),
62 'services' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_services'),
63 'templates' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_templates'),
64 'example' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_examples'),
65 'doc' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_documentation')
66 );
67 $this->types = array(
68 'S' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:type_system'),
69 'G' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:type_global'),
70 'L' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:type_local'),
71 );
72 $this->states = tx_em_Tools::getStates();
73 }
74
75
76 /**
77 * Returns the list of available (installed) extensions
78 *
79 * @param boolean if set, function will return a flat list only
80 * @return array Array with two arrays, list array (all extensions with info) and category index
81 * @see getInstExtList()
82 */
83 function getInstalledExtensions($flatList = FALSE) {
84 $list = array();
85
86 if ($flatList) {
87 $path = PATH_typo3 . 'sysext/';
88 $this->getFlatInstExtList($path, $list, 'S');
89
90 $path = PATH_typo3 . 'ext/';
91 $this->getFlatInstExtList($path, $list, 'G');
92
93 $path = PATH_typo3conf . 'ext/';
94 $this->getFlatInstExtList($path, $list, 'L');
95
96 return $list;
97 } else {
98 $cat = tx_em_Tools::getDefaultCategory();
99
100 $path = PATH_typo3 . 'sysext/';
101 $this->getInstExtList($path, $list, $cat, 'S');
102
103 $path = PATH_typo3 . 'ext/';
104 $this->getInstExtList($path, $list, $cat, 'G');
105
106 $path = PATH_typo3conf . 'ext/';
107 $this->getInstExtList($path, $list, $cat, 'L');
108
109 return array($list, $cat);
110 }
111 }
112
113 /**
114 * Gathers all extensions in $path
115 *
116 * @param string Absolute path to local, global or system extensions
117 * @param array Array with information for each extension key found. Notice: passed by reference
118 * @param array Categories index: Contains extension titles grouped by various criteria.
119 * @param string Path-type: L, G or S
120 * @return void "Returns" content by reference
121 * @see getInstalledExtensions()
122 */
123 function getInstExtList($path, &$list, &$cat, $type) {
124
125 if (@is_dir($path)) {
126 $extList = t3lib_div::get_dirs($path);
127 if (is_array($extList)) {
128 foreach ($extList as $extKey) {
129 if (@is_file($path . $extKey . '/ext_emconf.php')) {
130 $emConf = tx_em_Tools::includeEMCONF($path . $extKey . '/ext_emconf.php', $extKey);
131 if (is_array($emConf)) {
132 if (is_array($list[$extKey])) {
133 $list[$extKey] = array('doubleInstall' => $list[$extKey]['doubleInstall']);
134 }
135 $list[$extKey]['extkey'] = $extKey;
136 $list[$extKey]['doubleInstall'] .= $type;
137 $list[$extKey]['type'] = $type;
138 $list[$extKey]['installed'] = t3lib_extMgm::isLoaded($extKey);
139 $list[$extKey]['EM_CONF'] = $emConf;
140 $list[$extKey]['files'] = t3lib_div::getFilesInDir($path . $extKey, '', 0, '', $this->excludeForPackaging);
141
142 tx_em_Tools::setCat($cat, $list[$extKey], $extKey);
143 }
144 }
145 }
146 }
147 }
148 }
149
150 /**
151 * Gathers all extensions in $path
152 *
153 * @param string Absolute path to local, global or system extensions
154 * @param array Array with information for each extension key found. Notice: passed by reference
155 * @param array Categories index: Contains extension titles grouped by various criteria.
156 * @param string Path-type: L, G or S
157 * @return void "Returns" content by reference
158 * @access private
159 * @see getInstalledExtensions()
160 */
161 function getFlatInstExtList($path, &$list, $type) {
162
163
164 if (@is_dir($path)) {
165 $extList = t3lib_div::get_dirs($path);
166 if (is_array($extList)) {
167 foreach ($extList as $extKey) {
168 $this->singleExtInfo($extKey, $path, $list, $type);
169 }
170 }
171 }
172 }
173
174 /**
175 * Gets a single extension info
176 *
177 * @param $extKey
178 * @param $path
179 * @param $list
180 * @param string $type
181 * @return void
182 */
183 public function singleExtInfo($extKey, $path, &$list, $type = '') {
184 if (@is_file($path . $extKey . '/ext_emconf.php')) {
185 $relPath = '../' . substr($path, strlen(PATH_site));
186 $directLink = 'mod.php?M=tools_em';
187 $emConf = tx_em_Tools::includeEMCONF($path . $extKey . '/ext_emconf.php', $extKey);
188 $manual = $path . $extKey . '/doc/manual.sxw';
189 $manualRelPath = $relPath . $extKey . '/doc/manual.sxw';
190
191 if ($type === '') {
192 $type = tx_em_Tools::getExtTypeFromPath($path);
193 }
194
195 if (is_array($emConf)) {
196 $key = count($list);
197 $loaded = t3lib_extMgm::isLoaded($extKey);
198
199
200
201 $exist = $this->findIndex($extKey, $list);
202 if ($exist !== FALSE) {
203 $key = $exist;
204 $list[$key] = array(
205 'doubleInstall' => $list[$key]['doubleInstall'],
206 'doubleInstallShort' => $list[$key]['doubleInstallShort'],
207 );
208
209 }
210 $list[$key]['extkey'] = $extKey;
211 $list[$key]['path'] = $path . $extKey;
212 $list[$key]['nodePath'] = substr($path . $extKey, strlen(PATH_site));
213 $list[$key]['doubleInstall'] = $list[$key]['doubleInstall'] ? $list[$key]['doubleInstall'] . '/' . $this->types[$type] : $this->types[$type];
214 $list[$key]['doubleInstallShort'] .= $type;
215
216 $list[$key] = t3lib_div::array_merge_recursive_overrule($list[$key], $emConf);
217
218 if (@is_file($path . $extKey . '/class.ext_update.php')) {
219 $list[$key]['updateModule'] = TRUE;
220 } else {
221 $list[$key]['updateModule'] = FALSE;
222 }
223 $list[$key]['type'] = $this->types[$type];
224 $list[$key]['typeShort'] = $type;
225 $list[$key]['installed'] = $loaded ? 1 : 0;
226
227
228 $state = htmlspecialchars($emConf['state']);
229 $list[$key]['state'] = $this->states[$state];
230 $list[$key]['stateCls'] = 'state-' . $state;
231 $list[$key]['title'] = htmlspecialchars($list[$key]['title']);
232 $list[$key]['description'] = htmlspecialchars($list[$key]['description']);
233 $list[$key]['author'] = htmlspecialchars($list[$key]['author']);
234 $list[$key]['author_email'] = htmlspecialchars($list[$key]['author_email']);
235 $list[$key]['files'] = t3lib_div::getFilesInDir($path . $extKey, '', 0, '', $this->excludeForPackaging);
236 $list[$key]['reviewstate'] = $this->xmlHandler->getReviewState($extKey, $list[$key]['version']);
237
238 $list[$key]['download'] = '<a href="' . htmlspecialchars(
239 $directLink .'&CMD[doBackup]=1&SET[singleDetails]=backup&CMD[showExt]=' . $extKey
240 ) . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:download') . '">' .
241 t3lib_iconWorks::getSpriteIcon('actions-system-extension-download') . '</a>';
242
243 $list[$key]['doc'] = '';
244 if ($list[$key]['docPath']) {
245 $manual = $path . $extKey . '/' . $list[$key]['docPath'] . '/manual.sxw';
246 $manualRelPath = $relPath . $extKey . '/' . $list[$key]['docPath'] . '/manual.sxw';
247 }
248
249 if (@is_file($manual)) {
250 $list[$key]['doc'] = '<a href="' . htmlspecialchars($manualRelPath) . '" target="_blank">'
251 . t3lib_iconWorks::getSpriteIcon('actions-system-extension-documentation') . '</a>';
252 }
253 $list[$key]['icon'] = @is_file($path . $extKey . '/ext_icon.gif') ? '<img src="' . $relPath . $extKey . '/ext_icon.gif" alt="" height="16" />' : '<img src="clear.gif" alt="" width="16" height="16" />';
254
255 $list[$key]['categoryShort'] = $list[$key]['category'];
256 $list[$key]['category'] = isset($this->categories[$list[$key]['category']]) ? $this->categories[$list[$key]['category']] : $list[$key]['category'];
257 $list[$key]['required'] = t3lib_div::inList(t3lib_extMgm::getRequiredExtensionList(), $extKey);
258
259 $constraints = $this->humanizeConstraints($list[$key]['constraints']);
260 $list[$key]['depends'] = $constraints['depends'];
261 $list[$key]['conflicts'] = $constraints['conflicts'];
262 $list[$key]['suggests'] = $constraints['suggests'];
263
264
265 unset($list[$key]['_md5_values_when_last_written']);
266 }
267 }
268 }
269
270 /**
271 * Make constraints readable
272 *
273 * @param array $constraints
274 * @return array
275 */
276 public function humanizeConstraints($constraints) {
277 $depends = $conflicts = $suggests = array();
278 $result = array(
279 'depends' => '',
280 'conflicts' => '',
281 'suggests' => ''
282 );
283
284 if (is_array($constraints) && count($constraints)) {
285 if (is_array($constraints['depends']) && count($constraints['depends'])) {
286 foreach ($constraints['depends'] as $key => $value) {
287 if ($value) {
288 $tmp = t3lib_div::trimExplode('-', $value, TRUE);
289 if (trim($tmp[1]) && trim($tmp[1]) !== '0.0.0') {
290 $value = $tmp[0] . ' - ' . $tmp[1];
291 } else {
292 $value = $tmp[0];
293 }
294 }
295 $depends[] = $key . ($value ? ' (' . $value . ')' : '');
296 }
297 }
298 if (is_array($constraints['conflicts']) && count($constraints['conflicts'])) {
299 foreach ($constraints['conflicts'] as $key => $value) {
300 if ($value) {
301 $tmp = t3lib_div::trimExplode('-', $value, TRUE);
302 if (trim($tmp[1]) && trim($tmp[1]) !== '0.0.0') {
303 $value = $tmp[0] . ' - ' . $tmp[1];
304 } else {
305 $value = $tmp[0];
306 }
307 }
308 $conflicts[] = $key . ($value ? ' (' . $value . ')' : '');
309 }
310 }
311 if (is_array($constraints['suggests']) && count($constraints['suggests'])) {
312 foreach ($constraints['suggests'] as $key => $value) {
313 if ($value) {
314 $tmp = t3lib_div::trimExplode('-', $value, TRUE);
315 if (trim($tmp[1]) && trim($tmp[1]) !== '0.0.0') {
316 $value = $tmp[0] . ' - ' . $tmp[1];
317 } else {
318 $value = $tmp[0];
319 }
320 }
321 $suggests[] = $key . ($value ? ' (' . $value . ')' : '');
322 }
323 }
324 if (count($depends)) {
325 $result['depends'] = htmlspecialchars(implode(', ', $depends));
326 }
327 if (count($conflicts)) {
328 $result['conflicts'] = htmlspecialchars(implode(', ', $conflicts));
329 }
330 if (count($suggests)) {
331 $result['suggests'] = htmlspecialchars(implode(', ', $suggests));
332 }
333 }
334 return $result;
335 }
336
337 /**
338 * Listing of loaded (installed) extensions
339 *
340 * @return void
341 */
342 function extensionList_loaded() {
343 global $TYPO3_LOADED_EXT;
344
345 list($list, $cat) = $this->getInstalledExtensions();
346
347 // Loaded extensions
348 $content = '';
349 $lines = array();
350
351 // Available extensions
352 if (is_array($cat[$this->parentObject->MOD_SETTINGS['listOrder']])) {
353 $content = '';
354 $lines = array();
355 $lines[] = $this->extensionListRowHeader(' class="t3-row-header"', array('<td><img src="clear.gif" width="1" height="1" alt="" /></td>'));
356
357 foreach ($cat[$this->parentObject->MOD_SETTINGS['listOrder']] as $catName => $extEkeys) {
358
359 natcasesort($extEkeys);
360 $extensions = array();
361 foreach ($extEkeys as $extKey => $data) {
362 if (array_key_exists($extKey, $TYPO3_LOADED_EXT) && ($this->parentObject->MOD_SETTINGS['display_shy'] || !$list[$extKey]['EM_CONF']['shy']) && $this->parentObject->searchExtension($extKey, $list[$extKey])) {
363 if (in_array($extKey, $this->parentObject->requiredExt)) {
364 $loadUnloadLink = '<strong>' . tx_em_Tools::rfw($GLOBALS['LANG']->getLL('extension_required_short')) . '</strong>';
365 } else {
366 $loadUnloadLink = '<a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
367 'CMD[showExt]' => $extKey,
368 'CMD[remove]' => 1
369 ))) . '">' . tx_em_Tools::removeButton() . '</a>';
370 }
371
372 $extensions[] = $this->extensionListRow($extKey, $list[$extKey], array('<td class="bgColor">' . $loadUnloadLink . '</td>'));
373
374 }
375 }
376 if (count($extensions)) {
377 $lines[] = '<tr><td colspan="' . (3 + $this->parentObject->detailCols[$this->parentObject->MOD_SETTINGS['display_details']]) . '"><br /></td></tr>';
378 $lines[] = '<tr><td colspan="' . (3 + $this->parentObject->detailCols[$this->parentObject->MOD_SETTINGS['display_details']]) . '">' . t3lib_iconWorks::getSpriteIcon('apps-filetree-folder-default') . '<strong>' . htmlspecialchars($this->parentObject->listOrderTitle($this->parentObject->MOD_SETTINGS['listOrder'], $catName)) . '</strong></td></tr>';
379 $lines[] = implode(LF, $extensions);
380 }
381 }
382 }
383
384 $content .= '<form action="' . $this->parentObject->script . '" method="post" name="lookupform">';
385 $content .= '<label for="lookUp">' . $GLOBALS['LANG']->getLL('look_up') . '</label> <input type="text" id="lookUp" name="lookUp" value="' . htmlspecialchars($this->lookUpStr) . '" /><input type="submit" value="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:search') . '" /><br /><br />';
386
387 $content .= '</form>
388
389 <!-- Loaded Extensions List -->
390 <table cellspacing="0" class="t3-em-extension-list t3-em-extension-list-loaded">' . implode('', $lines) . '</table>';
391
392 return $content;
393 }
394
395 /**
396 * Listing of available (installed) extensions
397 *
398 * @return void
399 */
400 function extensionList_installed() {
401
402 list($list, $cat) = $this->getInstalledExtensions();
403
404 // Available extensions
405 if (is_array($cat[$this->parentObject->MOD_SETTINGS['listOrder']])) {
406 $content = '';
407 $lines = array();
408 $lines[] = $this->extensionListRowHeader(' class="t3-row-header"', array('<td><img src="clear.gif" width="18" height="1" alt="" /></td>'));
409
410 $allKeys = array();
411 foreach ($cat[$this->parentObject->MOD_SETTINGS['listOrder']] as $catName => $extEkeys) {
412 if (!$this->parentObject->MOD_SETTINGS['display_obsolete'] && $catName == 'obsolete') {
413 continue;
414 }
415
416 $allKeys[] = '';
417 $allKeys[] = 'TYPE: ' . $catName;
418
419 natcasesort($extEkeys);
420 $extensions = array();
421 foreach ($extEkeys as $extKey => $value) {
422 $allKeys[] = $extKey;
423 if ((!$list[$extKey]['EM_CONF']['shy'] || $this->parentObject->MOD_SETTINGS['display_shy']) &&
424 ($list[$extKey]['EM_CONF']['state'] != 'obsolete' || $this->parentObject->MOD_SETTINGS['display_obsolete'])
425 && $this->parentObject->searchExtension($extKey, $list[$extKey])) {
426 $loadUnloadLink = t3lib_extMgm::isLoaded($extKey) ?
427 '<a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
428 'CMD[showExt]' => $extKey,
429 'CMD[remove]' => 1,
430 'CMD[clrCmd]' => 1,
431 'SET[singleDetails]' => 'info'
432 ))) . '">' . tx_em_Tools::removeButton() . '</a>' :
433 '<a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
434 'CMD[showExt]' => $extKey,
435 'CMD[load]' => 1,
436 'CMD[clrCmd]' => 1,
437 'SET[singleDetails]' => 'info'
438 ))) . '">' . tx_em_Tools::installButton() . '</a>';
439 if (in_array($extKey, $this->parentObject->requiredExt)) {
440 $loadUnloadLink = '<strong>' . tx_em_Tools::rfw($GLOBALS['LANG']->getLL('extension_required_short')) . '</strong>';
441 }
442 $theRowClass = t3lib_extMgm::isLoaded($extKey) ? 'em-listbg1' : 'em-listbg2';
443 $extensions[] = $this->extensionListRow($extKey, $list[$extKey], array('<td class="bgColor">' . $loadUnloadLink . '</td>'), $theRowClass);
444 }
445 }
446 if (count($extensions)) {
447 $lines[] = '<tr><td colspan="' . (3 + $this->parentObject->detailCols[$this->parentObject->MOD_SETTINGS['display_details']]) . '"><br /></td></tr>';
448 $lines[] = '<tr><td colspan="' . (3 + $this->parentObject->detailCols[$this->parentObject->MOD_SETTINGS['display_details']]) . '">' . t3lib_iconWorks::getSpriteIcon('apps-filetree-folder-default') . '<strong>' . htmlspecialchars($this->parentObject->listOrderTitle($this->parentObject->MOD_SETTINGS['listOrder'], $catName)) . '</strong></td></tr>';
449 $lines[] = implode(LF, $extensions);
450 }
451 }
452
453 $content .= '
454
455
456 <!--
457 EXTENSION KEYS:
458
459 ' . trim(implode(LF, $allKeys)) . '
460
461 -->
462
463 ';
464
465 $content .= sprintf($GLOBALS['LANG']->getLL('how_to_install'), tx_em_Tools::installButton()) . ' <br />' .
466 sprintf($GLOBALS['LANG']->getLL('how_to_uninstall'), tx_em_Tools::removeButton()) . ' <br /><br />';
467 $content .= '<form action="' . $this->parentObject->script . '" method="post" name="lookupform">';
468 $content .= '<label for="lookUp">' . $GLOBALS['LANG']->getLL('look_up') . '</label> <input type="text" id="lookUp" name="lookUp" value="' . htmlspecialchars($this->parentObject->lookUpStr) . '" /><input type="submit" value="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:search') . '" /></form><br /><br />';
469 $content .= $this->securityHint . '<br /><br />';
470
471 $content .= '<table cellspacing="0" class="t3-em-extension-list t3-em-extension-list-installed">' . implode('', $lines) . '</table>';
472
473 return $content;
474 }
475 }
476
477
478 /**
479 * Prints the header row for the various listings
480 *
481 * @param string Attributes for the <tr> tag
482 * @param array Preset cells in the beginning of the row. Typically a blank cell with a clear-gif
483 * @param boolean If set, the list is coming from remote server.
484 * @return string HTML <tr> table row
485 */
486 function extensionListRowHeader($trAttrib, $cells, $import = 0) {
487 $cells[] = '<td></td>';
488 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_title') . '</td>';
489
490 if (!$this->parentObject->MOD_SETTINGS['display_details']) {
491 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_description') . '</td>';
492 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_author') . '</td>';
493 } elseif ($this->parentObject->MOD_SETTINGS['display_details'] == 2) {
494 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_priority') . '</td>';
495 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_modifies_tables_short') . '</td>';
496 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_modules') . '</td>';
497 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_clear_cache_short') . '</td>';
498 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_internal') . '</td>';
499 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_shy') . '</td>';
500 } elseif ($this->parentObject->MOD_SETTINGS['display_details'] == 3) {
501 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_tables_fields') . '</td>';
502 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_ts_files') . '</td>';
503 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_affects') . '</td>';
504 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_modules') . '</td>';
505 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_config') . '</td>';
506 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_code_warnings') . '</td>';
507 } elseif ($this->parentObject->MOD_SETTINGS['display_details'] == 4) {
508 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_locallang') . '</td>';
509 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_classes') . '</td>';
510 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_code_warnings') . '</td>';
511 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_annoyances') . '</td>';
512 } elseif ($this->parentObject->MOD_SETTINGS['display_details'] == 5) {
513 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_changed_files') . '</td>';
514 } else {
515 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_ext_key') . '</td>';
516 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_version') . '</td>';
517 if (!$import) {
518 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_download_short') . '</td>';
519 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_documentation_short') . '</td>';
520 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_type') . '</td>';
521 } else {
522 $cells[] = '<td' . tx_em_Tools::labelInfo($GLOBALS['LANG']->getLL('listRowHeader_title_upload_date')) . '>' .
523 $GLOBALS['LANG']->getLL('listRowHeader_upload_date') . '</td>';
524 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_author') . '</td>';
525 $cells[] = '<td' . tx_em_Tools::labelInfo($GLOBALS['LANG']->getLL('listRowHeader_title_current_version')) . '>' .
526 $GLOBALS['LANG']->getLL('listRowHeader_current_version') . '</td>';
527 $cells[] = '<td' . tx_em_Tools::labelInfo($GLOBALS['LANG']->getLL('listRowHeader_title_current_type')) . '>' .
528 $GLOBALS['LANG']->getLL('listRowHeader_current_type') . '</td>';
529 $cells[] = '<td' . tx_em_Tools::labelInfo($GLOBALS['LANG']->getLL('listRowHeader_title_number_of_downloads')) . '>' .
530 $GLOBALS['LANG']->getLL('listRowHeader_download_short') . '</td>';
531 }
532 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_state') . '</td>';
533 }
534 return '
535 <tr' . $trAttrib . '>
536 ' . implode('
537 ', $cells) . '
538 </tr>';
539 }
540
541
542 /**
543 * Prints a row with data for the various extension listings
544 *
545 * @param string Extension key
546 * @param array Extension information array
547 * @param array Preset table cells, eg. install/uninstall icons.
548 * @param string <tr> tag class
549 * @param array Array with installed extension keys (as keys)
550 * @param boolean If set, the list is coming from remote server.
551 * @param string Alternative link URL
552 * @return string HTML <tr> content
553 */
554 function extensionListRow($extKey, $extInfo, $cells, $bgColorClass = '', $inst_list = array(), $import = 0, $altLinkUrl = '') {
555 $stateColors = tx_em_Tools::getStateColors();
556
557 // Icon:
558 $imgInfo = @getImageSize(tx_em_Tools::getExtPath($extKey, $extInfo['type']) . '/ext_icon.gif');
559 if (is_array($imgInfo)) {
560 $cells[] = '<td><img src="' . $GLOBALS['BACK_PATH'] . tx_em_Tools::typeRelPath($extInfo['type']) . $extKey . '/ext_icon.gif' . '" ' . $imgInfo[3] . ' alt="" /></td>';
561 } elseif ($extInfo['_ICON']) {
562 $cells[] = '<td>' . $extInfo['_ICON'] . '</td>';
563 } else {
564 $cells[] = '<td><img src="clear.gif" width="1" height="1" alt="" /></td>';
565 }
566
567 // Extension title:
568 $cells[] = '<td nowrap="nowrap"><a href="' . htmlspecialchars($altLinkUrl ? $altLinkUrl : t3lib_div::linkThisScript(array(
569 'CMD[showExt]' => $extKey,
570 'SET[singleDetails]' => 'info'
571 ))) . '" title="' . htmlspecialchars($extInfo['EM_CONF']['description']) . '">'
572 . t3lib_div::fixed_lgd_cs($extInfo['EM_CONF']['title'] ? htmlspecialchars($extInfo['EM_CONF']['title']) : '<em>' . $extKey . '</em>', 40) . '</a></td>';
573
574 // Based on the display mode you will see more or less details:
575 if (!$this->parentObject->MOD_SETTINGS['display_details']) {
576 $cells[] = '<td>' . htmlspecialchars(t3lib_div::fixed_lgd_cs($extInfo['EM_CONF']['description'], 400)) . '<br /><img src="clear.gif" width="300" height="1" alt="" /></td>';
577 $cells[] = '<td nowrap="nowrap">' . ($extInfo['EM_CONF']['author_email'] ? '<a href="mailto:' . htmlspecialchars($extInfo['EM_CONF']['author_email']) . '">' : '') . htmlspecialchars($extInfo['EM_CONF']['author']) . (htmlspecialchars($extInfo['EM_CONF']['author_email']) ? '</a>' : '') . ($extInfo['EM_CONF']['author_company'] ? '<br />' . htmlspecialchars($extInfo['EM_CONF']['author_company']) : '') . '</td>';
578 } elseif ($this->parentObject->MOD_SETTINGS['display_details'] == 2) {
579 $cells[] = '<td nowrap="nowrap">' . $extInfo['EM_CONF']['priority'] . '</td>';
580 $cells[] = '<td nowrap="nowrap">' . implode('<br />', t3lib_div::trimExplode(',', $extInfo['EM_CONF']['modify_tables'], 1)) . '</td>';
581 $cells[] = '<td nowrap="nowrap">' . $extInfo['EM_CONF']['module'] . '</td>';
582 $cells[] = '<td nowrap="nowrap">' . ($extInfo['EM_CONF']['clearCacheOnLoad'] ? $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:yes') : '') . '</td>';
583 $cells[] = '<td nowrap="nowrap">' . ($extInfo['EM_CONF']['internal'] ? $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:yes') : '') . '</td>';
584 $cells[] = '<td nowrap="nowrap">' . ($extInfo['EM_CONF']['shy'] ? $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:yes') : '') . '</td>';
585 } elseif ($this->parentObject->MOD_SETTINGS['display_details'] == 3) {
586 $techInfo = $this->install->makeDetailedExtensionAnalysis($extKey, $extInfo);
587
588 $cells[] = '<td>' . $this->parentObject->extensionDetails->extInformationArray_dbReq($techInfo) .
589 '</td>';
590 $cells[] = '<td nowrap="nowrap">' . (is_array($techInfo['TSfiles']) ? implode('<br />', $techInfo['TSfiles']) : '') . '</td>';
591 $cells[] = '<td nowrap="nowrap">' . (is_array($techInfo['flags']) ? implode('<br />', $techInfo['flags']) : '') . '</td>';
592 $cells[] = '<td nowrap="nowrap">' . (is_array($techInfo['moduleNames']) ? implode('<br />', $techInfo['moduleNames']) : '') . '</td>';
593 $cells[] = '<td nowrap="nowrap">' . ($techInfo['conf'] ? $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:yes') : '') . '</td>';
594 $cells[] = '<td>' .
595 tx_em_Tools::rfw((t3lib_extMgm::isLoaded($extKey) && $techInfo['tables_error'] ?
596 '<strong>' . $GLOBALS['LANG']->getLL('extInfoArray_table_error') . '</strong><br />' .
597 $GLOBALS['LANG']->getLL('extInfoArray_missing_fields') : '') .
598 (t3lib_extMgm::isLoaded($extKey) && $techInfo['static_error'] ?
599 '<strong>' . $GLOBALS['LANG']->getLL('extInfoArray_static_table_error') . '</strong><br />' .
600 $GLOBALS['LANG']->getLL('extInfoArray_static_tables_missing_empty') : '')) .
601 '</td>';
602 } elseif ($this->parentObject->MOD_SETTINGS['display_details'] == 4) {
603 $techInfo = $this->install->makeDetailedExtensionAnalysis($extKey, $extInfo, 1);
604
605 $cells[] = '<td>' . (is_array($techInfo['locallang']) ? implode('<br />', $techInfo['locallang']) : '') . '</td>';
606 $cells[] = '<td>' . (is_array($techInfo['classes']) ? implode('<br />', $techInfo['classes']) : '') . '</td>';
607 $cells[] = '<td>' . (is_array($techInfo['errors']) ? tx_em_Tools::rfw(implode('<hr />', $techInfo['errors'])) : '') . '</td>';
608 $cells[] = '<td>' . (is_array($techInfo['NSerrors']) ?
609 (!t3lib_div::inList($this->parentObject->nameSpaceExceptions, $extKey) ?
610 t3lib_utility_Debug::viewarray($techInfo['NSerrors']) :
611 tx_em_Tools::dfw($GLOBALS['LANG']->getLL('extInfoArray_exception'))) : '') . '</td>';
612 } elseif ($this->parentObject->MOD_SETTINGS['display_details'] == 5) {
613 $currentMd5Array = $this->parentObject->extensionDetails->serverExtensionMD5array($extKey, $extInfo);
614 $affectedFiles = '';
615 $msgLines = array();
616 $msgLines[] = $GLOBALS['LANG']->getLL('listRow_files') . ' ' . count($currentMd5Array);
617 if (strcmp($extInfo['EM_CONF']['_md5_values_when_last_written'], serialize($currentMd5Array))) {
618 $msgLines[] = tx_em_Tools::rfw('<br /><strong>' . $GLOBALS['LANG']->getLL('extInfoArray_difference_detected') . '</strong>');
619 $affectedFiles = tx_em_Tools::findMD5ArrayDiff($currentMd5Array, unserialize($extInfo['EM_CONF']['_md5_values_when_last_written']));
620 if (count($affectedFiles)) {
621 $msgLines[] = '<br /><strong>' . $GLOBALS['LANG']->getLL('extInfoArray_modified_files') . '</strong><br />' .
622 tx_em_Tools::rfw(implode('<br />', $affectedFiles));
623 }
624 }
625 $cells[] = '<td>' . implode('<br />', $msgLines) . '</td>';
626 } else {
627 // Default view:
628 $verDiff = $inst_list[$extKey] && tx_em_Tools::versionDifference($extInfo['EM_CONF']['version'], $inst_list[$extKey]['EM_CONF']['version'], $this->parentObject->versionDiffFactor);
629
630 $cells[] = '<td nowrap="nowrap"><em>' . $extKey . '</em></td>';
631 $cells[] = '<td nowrap="nowrap">' . ($verDiff ? '<strong>' . tx_em_Tools::rfw(htmlspecialchars($extInfo['EM_CONF']['version'])) . '</strong>' : $extInfo['EM_CONF']['version']) . '</td>';
632 if (!$import) { // Listing extension on LOCAL server:
633 // Extension Download:
634 $cells[] = '<td nowrap="nowrap"><a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
635 'CMD[doBackup]' => 1,
636 'SET[singleDetails]' => 'backup',
637 'CMD[showExt]' => $extKey
638 ))) . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:download') . '">' .
639 t3lib_iconWorks::getSpriteIcon('actions-system-extension-download') .
640 '</a></td>';
641
642 // Manual download
643 $manual = tx_em_Tools::typePath($extInfo['type']) . $extKey . '/doc/manual.sxw';
644 $manualRelPath = t3lib_div::resolveBackPath($this->parentObject->doc->backPath . tx_em_Tools::typeRelPath($extInfo['type'])) . $extKey . '/doc/manual.sxw';
645 if ($extInfo['EM_CONF']['docPath']) {
646 $manual = tx_em_Tools::typePath($extInfo['type']) . $extKey . '/' . $extInfo['EM_CONF']['docPath'] . '/manual.sxw';
647 $manualRelPath = t3lib_div::resolveBackPath($this->parentObject->doc->backPath . tx_em_Tools::typeRelPath($extInfo['type'])) . $extKey . '/' . $extInfo['EM_CONF']['docPath'] . '/manual.sxw';
648 }
649 $cells[] = '<td nowrap="nowrap">' .
650 (tx_em_Tools::typePath($extInfo['type']) && @is_file($manual) ?
651 '<a href="' . htmlspecialchars($manualRelPath) . '" target="_blank" title="' . $GLOBALS['LANG']->getLL('listRow_local_manual') . '">' .
652 t3lib_iconWorks::getSpriteIcon('actions-system-extension-documentation') . '</a>' : '') .
653 '</td>';
654
655 // Double installation (inclusion of an extension in more than one of system, global or local scopes)
656 $doubleInstall = '';
657 if (strlen($extInfo['doubleInstall']) > 1) {
658 // Separate the "SL" et al. string into an array and replace L by Local, G by Global etc.
659 $doubleInstallations = str_replace(
660 array('S', 'G', 'L'),
661 array(
662 $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:sysext'),
663 $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:globalext'),
664 $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:localext')
665 ),
666 str_split($extInfo['doubleInstall'])
667 );
668 // Last extension is the one actually used
669 $usedExtension = array_pop($doubleInstallations);
670 // Next extension is overridden
671 $overriddenExtensions = array_pop($doubleInstallations);
672 // If the array is not yet empty, the extension is actually installed 3 times (SGL)
673 if (count($doubleInstallations) > 0) {
674 $lastExtension = array_pop($doubleInstallations);
675 $overriddenExtensions .= ' ' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:and') . ' ' . $lastExtension;
676 }
677 $doubleInstallTitle = sprintf(
678 $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:double_inclusion'),
679 $usedExtension,
680 $overriddenExtensions
681 );
682 $doubleInstall = ' <strong><abbr title="' . $doubleInstallTitle . '">' . tx_em_Tools::rfw($extInfo['doubleInstall']) . '</abbr></strong>';
683 }
684 $cells[] = '<td nowrap="nowrap">' . $this->types[$extInfo['type']] . $doubleInstall . '</td>';
685 } else { // Listing extensions from REMOTE repository:
686 $inst_curVer = $inst_list[$extKey]['EM_CONF']['version'];
687 if (isset($inst_list[$extKey])) {
688 if ($verDiff) {
689 $inst_curVer = '<strong>' . tx_em_Tools::rfw($inst_curVer) . '</strong>';
690 }
691 }
692 $cells[] = '<td nowrap="nowrap">' . t3lib_befunc::date($extInfo['EM_CONF']['lastuploaddate']) . '</td>';
693 $cells[] = '<td nowrap="nowrap">' . htmlspecialchars(t3lib_div::fixed_lgd_cs($extInfo['EM_CONF']['author'], $GLOBALS['BE_USER']->uc[titleLen])) . '</td>';
694 $cells[] = '<td nowrap="nowrap">' . $inst_curVer . '</td>';
695 $cells[] = '<td nowrap="nowrap">' . $this->api->typeLabels[$inst_list[$extKey]['type']] . (strlen($inst_list[$extKey]['doubleInstall']) > 1 ? '<strong> ' . tx_em_Tools::rfw($inst_list[$extKey]['doubleInstall']) . '</strong>' : '') . '</td>';
696 $cells[] = '<td nowrap="nowrap">' . ($extInfo['downloadcounter_all'] ? $extInfo['downloadcounter_all'] : '&nbsp;&nbsp;') . '/' . ($extInfo['downloadcounter'] ? $extInfo['downloadcounter'] : '&nbsp;') . '</td>';
697 }
698 $cells[] = '<td nowrap="nowrap" class="extstate" style="background-color:' . $stateColors[$extInfo['EM_CONF']['state']] . ';">' . $this->states[$extInfo['EM_CONF']['state']] . '</td>';
699 }
700
701 // show a different background through a different class for insecure (-1) extensions,
702 // for unreviewed (0) and reviewed extensions (1), just use the regular class
703 if ($this->xmlHandler->getReviewState($extKey, $extInfo['EM_CONF']['version']) < 0) {
704 $bgclass = ' class="unsupported-ext"';
705 } else {
706 $bgclass = ' class="' . ($bgColorClass ? $bgColorClass : 'em-listbg1') . '"';
707 }
708
709 return '
710 <tr' . $bgclass . '>
711 ' . implode('
712 ', $cells) . '
713 </tr>';
714 }
715
716
717 /**
718 * Displays a list of extensions where a newer version is available
719 * in the TER than the one that is installed right now
720 * integrated from the extension "ter_update_check" for TYPO3 4.2 by Christian Welzel
721 *
722 * @return string
723 */
724 function showExtensionsToUpdate() {
725 global $LANG;
726 $extList = $this->getInstalledExtensions();
727
728 $content = '<table cellspacing="0" class="t3-em-extension-list t3-em-extension-list-to-update">' .
729 '<tr class="t3-row-header">' .
730 '<td></td>' .
731 '<td>' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:tab_mod_name') . '</td>' .
732 '<td>' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:tab_mod_key') . '</td>' .
733 '<td>' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:tab_mod_loc_ver') . '</td>' .
734 '<td>' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:tab_mod_rem_ver') . '</td>' .
735 '<td>' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:tab_mod_location') . '</td>' .
736 '<td>' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:tab_mod_comment') . '</td>' .
737 '</tr>';
738
739 foreach ($extList[0] as $name => $data) {
740 $this->xmlHandler->searchExtensionsXMLExact($name, '', '', TRUE, TRUE);
741 if (!is_array($this->xmlHandler->extensionsXML[$name])) {
742 continue;
743 }
744
745 $v = $this->xmlHandler->extensionsXML[$name]['versions'];
746 $versions = array_keys($v);
747 natsort($versions);
748 $lastversion = end($versions);
749
750 if ((t3lib_extMgm::isLoaded($name) || $this->parentObject->MOD_SETTINGS['display_installed']) &&
751 ($data['EM_CONF']['shy'] == 0 || $this->parentObject->MOD_SETTINGS['display_shy']) &&
752 tx_em_Tools::versionDifference($lastversion, $data['EM_CONF']['version'], 1)) {
753
754 $imgInfo = @getImageSize(tx_em_Tools::getExtPath($name, $data['type']) . '/ext_icon.gif');
755 if (is_array($imgInfo)) {
756 $icon = '<img src="' . $GLOBALS['BACK_PATH'] . tx_em_Tools::typeRelPath($data['type']) . $name . '/ext_icon.gif' . '" ' . $imgInfo[3] . ' alt="" />';
757 } elseif ($data['_ICON']) { //TODO: see if this can be removed, seems to be wrong in this context
758 $icon = $data['_ICON'];
759 } else {
760 $icon = '<img src="clear.gif" width="1" height="1" alt="" />';
761 }
762 $comment = '<table cellpadding="0" cellspacing="0" width="100%">';
763 foreach ($versions as $vk) {
764 $va = & $v[$vk];
765 if (t3lib_utility_VersionNumber::convertVersionNumberToInteger($vk) <= t3lib_utility_VersionNumber::convertVersionNumberToInteger($data['EM_CONF']['version'])) {
766 continue;
767 }
768 $comment .= '<tr><td valign="top" style="padding-right:2px;border-bottom:1px dotted gray">' . $vk . '</td>' . '<td valign="top" style="border-bottom:1px dotted gray">' . nl2br($va[uploadcomment]) . '</td></tr>';
769 }
770 $comment .= '</table>';
771
772 $serverMD5Array = $this->parentObject->extensionDetails->serverExtensionMD5array($name, $data);
773 if (is_array($serverMD5Array)) {
774 ksort($serverMD5Array);
775 }
776 $currentMD5Array = unserialize($data['EM_CONF']['_md5_values_when_last_written']);
777 if (is_array($currentMD5Array)) {
778 @ksort($currentMD5Array);
779 }
780 $warn = '';
781 if (strcmp(serialize($currentMD5Array), serialize($serverMD5Array))) {
782 $warn = '<tr class="bgColor4" style="color:red"><td colspan="7">' . tx_em_Tools::rfw('<br /><strong>' . $name . ': ' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:msg_warn_diff') . '</strong>') . '</td></tr>' . LF;
783 if ($this->parentObject->MOD_SETTINGS['display_files'] == 1) {
784 $affectedFiles = tx_em_Tools::findMD5ArrayDiff($serverMD5Array, $currentMD5Array);
785 if (count($affectedFiles)) {
786 $warn .= '<tr class="bgColor4"><td colspan="7"><strong>' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:msg_modified') . '</strong><br />' . tx_em_Tools::rfw(implode('<br />', $affectedFiles)) . '</td></tr>' . LF;
787 }
788 }
789 }
790
791 $content .= '<tr class="bgColor4"><td valign="top">' . $icon . '</td>' .
792 '<td valign="top">' . ($data['EM_CONF']['state'] == 'excludeFromUpdates'
793 ? '<span style="color:#cf7307">' . $data['EM_CONF']['title'] . ' ' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:write_protected') . '</span>'
794 : '<a href="' . t3lib_div::linkThisScript(array(
795 'CMD[importExtInfo]' => $name
796 )) . '">' . $data[EM_CONF][title] . '</a>') . '</td>' .
797 '<td valign="top">' . $name . '</td>' .
798 '<td valign="top" align="right">' . $data[EM_CONF][version] . '</td>' .
799 '<td valign="top" align="right">' . $lastversion . '</td>' .
800 '<td valign="top" nowrap="nowrap">' . $this->api->typeLabels[$data['type']] . (strlen($data['doubleInstall']) > 1 ? '<strong> ' . tx_em_Tools::rfw($data['doubleInstall']) . '</strong>' : '') . '</td>' .
801 '<td valign="top">' . $comment . '</td></tr>' . LF .
802 $warn .
803 '<tr class="bgColor4"><td colspan="7"><hr style="margin:0px" /></td></tr>' . LF;
804 }
805 }
806
807 return $content . '</table><br />';
808 }
809
810 /**
811 * Maps remote extensions information into $cat/$list arrays for listing
812 *
813 * @param boolean If set the info in the internal extensionsXML array will be unset before returning the result.
814 * @return array List array and category index as key 0 / 1 in an array.
815 */
816 function prepareImportExtList($unsetProc = FALSE) {
817 $list = array();
818 $cat = tx_em_Tools::getDefaultCategory();
819 $filepath = $this->parentObject->getMirrorURL();
820
821 foreach ($this->parentObject->xmlHandler->extensionsXML as $extKey => $data) {
822 $GLOBALS['LANG']->csConvObj->convarray($data, 'utf-8', $GLOBALS['LANG']->charSet); // is there a better place for conversion?
823 $list[$extKey]['type'] = '_';
824 $version = array_keys($data['versions']);
825 $extPath = t3lib_div::strtolower($extKey);
826 $list[$extKey]['_ICON'] = '<img alt="" src="' . $filepath . $extPath{0} . '/' . $extPath{1} . '/' . $extPath . '_' . end($version) . '.gif" />';
827 $list[$extKey]['downloadcounter'] = $data['downloadcounter'];
828
829 foreach (array_keys($data['versions']) as $version) {
830 $list[$extKey]['versions'][$version]['downloadcounter'] = $data['versions'][$version]['downloadcounter'];
831
832 $list[$extKey]['versions'][$version]['EM_CONF'] = array(
833 'version' => $version,
834 'title' => $data['versions'][$version]['title'],
835 'description' => $data['versions'][$version]['description'],
836 'category' => $data['versions'][$version]['category'],
837 'constraints' => $data['versions'][$version]['dependencies'],
838 'state' => $data['versions'][$version]['state'],
839 'reviewstate' => $data['versions'][$version]['reviewstate'],
840 'lastuploaddate' => $data['versions'][$version]['lastuploaddate'],
841 'author' => $data['versions'][$version]['authorname'],
842 'author_email' => $data['versions'][$version]['authoremail'],
843 'author_company' => $data['versions'][$version]['authorcompany'],
844 );
845 }
846 tx_em_Tools::setCat($cat, $list[$extKey]['versions'][$version], $extKey);
847 if ($unsetProc) {
848 unset($this->parentObject->xmlHandler->extensionsXML[$extKey]);
849 }
850 }
851
852 return array($list, $cat);
853 }
854
855
856 /**
857 * Adds extension to extension list and returns new list. If -1 is returned, an error happend.
858 * Checks dependencies etc.
859 *
860 * @param string Extension key
861 * @param array Extension information array - information about installed extensions
862 * @return string New list of installed extensions or -1 if error
863 * @see showExtDetails()
864 */
865 function addExtToList($extKey, $instExtInfo) {
866 global $TYPO3_LOADED_EXT;
867
868 // ext_emconf.php information:
869 $conf = $instExtInfo[$extKey]['EM_CONF'];
870
871 // Get list of installed extensions and add this one.
872 $listArr = array_keys($TYPO3_LOADED_EXT);
873 if ($conf['priority'] == 'top') {
874 array_unshift($listArr, $extKey);
875 } else {
876 $listArr[] = $extKey;
877 }
878
879 // Manage other circumstances:
880 $listArr = tx_em_Tools::managesPriorities($listArr, $instExtInfo);
881 $listArr = $this->removeRequiredExtFromListArr($listArr);
882
883 // Implode unique list of extensions to load and return:
884 $list = implode(',', array_unique($listArr));
885
886 return $list;
887 }
888
889 /**
890 * Remove extension key from the list of currently installed extensions and return list. If -1 is returned, an error happend.
891 * Checks dependencies etc.
892 *
893 * @param string Extension key
894 * @param array Extension information array - information about installed extensions
895 * @return string New list of installed extensions or -1 if error
896 * @see showExtDetails()
897 */
898 function removeExtFromList($extKey, $instExtInfo) {
899 global $TYPO3_LOADED_EXT;
900
901 // Initialize:
902 $depList = array();
903 $listArr = array_keys($TYPO3_LOADED_EXT);
904
905 // Traverse all installed extensions to check if any of them have this extension as dependency since if that is the case it will not work out!
906 foreach ($listArr as $k => $ext) {
907 if ($instExtInfo[$ext]['EM_CONF']['dependencies']) {
908 $dep = t3lib_div::trimExplode(',', $instExtInfo[$ext]['EM_CONF']['dependencies'], 1);
909 if (in_array($extKey, $dep)) {
910 $depList[] = $ext;
911 }
912 }
913 if (!strcmp($ext, $extKey)) {
914 unset($listArr[$k]);
915 }
916 }
917
918 // Returns either error or the new list
919 if (count($depList)) {
920 $msg = sprintf($GLOBALS['LANG']->getLL('removeExtFromList_dependency'),
921 implode(', ', $depList)
922 );
923 $this->parentObject->content .= $this->parentObject->doc->section($GLOBALS['LANG']->getLL('removeExtFromList_dependency_error'), $msg, 0, 1, 2);
924 return -1;
925 } else {
926 $listArr = $this->removeRequiredExtFromListArr($listArr);
927 $list = implode(',', array_unique($listArr));
928 return $list;
929 }
930 }
931
932 /**
933 * This removes any required extensions from the $listArr - they should NOT be added to the common extension list, because they are found already in "requiredExt" list
934 *
935 * @param array Array of extension keys as values
936 * @return array Modified array
937 * @see removeExtFromList(), addExtToList()
938 */
939 function removeRequiredExtFromListArr($listArr) {
940 $requiredExtensions = t3lib_div::trimExplode(',', t3lib_extMgm::getRequiredExtensionList(), 1);
941 foreach ($listArr as $k => $ext) {
942 if (in_array($ext, $requiredExtensions) || !strcmp($ext, '_CACHEFILE')) {
943 unset($listArr[$k]);
944 }
945 }
946 return $listArr;
947 }
948
949 /**
950 * Returns array index of extKey entry
951 *
952 * @param string $extKey
953 * @param array $list
954 * @return intval|bool index of array or FALSE if not found
955 */
956 protected function findIndex($extKey, $list) {
957 foreach ($list as $key => $value) {
958 if ($value['extkey'] === $extKey) {
959 return $key;
960 }
961 }
962 return FALSE;
963 }
964 }
965
966 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/em/classes/extensions/class.tx_em_extensions_list.php'])) {
967 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/em/classes/extensions/class.tx_em_extensions_list.php']);
968 }
969
970 ?>