2 /* **************************************************************
6 * (c) 2006-2010 Karsten Dambekalns <karsten@typo3.org>
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.
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.
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.
26 * This copyright notice MUST APPEAR in all copies of the script!
27 ***************************************************************/
28 /* $Id: class.tx_em_extensions_list.php 2084 2010-03-22 01:46:37Z steffenk $ */
31 * This class handles extension listings
34 class tx_em_Extensions_List
{
37 protected $parentObject;
46 protected $categories;
52 * @param object $parentObject
55 public function __construct($parentObject = NULL) {
56 $this->parentObject
= $parentObject;
57 $this->api
= t3lib_div
::makeInstance('tx_em_API');
58 $this->install
= t3lib_div
::makeInstance('tx_em_Install', $this);
60 $this->categories
= array(
61 'be' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_BE'),
62 'module' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_BE_modules'),
63 'fe' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_FE'),
64 'plugin' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_FE_plugins'),
65 'misc' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_miscellanous'),
66 'services' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_services'),
67 'templates' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_templates'),
68 'example' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_examples'),
69 'doc' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_documentation')
72 'S' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:type_system'),
73 'G' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:type_global'),
74 'L' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:type_local'),
80 * Returns the list of available (installed) extensions
82 * @return array Array with two arrays, list array (all extensions with info) and category index
83 * @see getInstExtList()
85 function getInstalledExtensions($new = FALSE) {
89 $cat = $this->parentObject
->defaultCategories
;
91 $path = PATH_typo3
. 'sysext/';
92 $this->getInstExtList($path, $list, $cat, 'S');
94 $path = PATH_typo3
. 'ext/';
95 $this->getInstExtList($path, $list, $cat, 'G');
97 $path = PATH_typo3conf
. 'ext/';
98 $this->getInstExtList($path, $list, $cat, 'L');
100 return array($list, $cat);
102 $path = PATH_typo3
. 'sysext/';
103 $this->getFlatInstExtList($path, $list, 'S');
105 $path = PATH_typo3
. 'ext/';
106 $this->getFlatInstExtList($path, $list, 'G');
108 $path = PATH_typo3conf
. 'ext/';
109 $this->getFlatInstExtList($path, $list, 'L');
116 * Gathers all extensions in $path
118 * @param string Absolute path to local, global or system extensions
119 * @param array Array with information for each extension key found. Notice: passed by reference
120 * @param array Categories index: Contains extension titles grouped by various criteria.
121 * @param string Path-type: L, G or S
122 * @return void "Returns" content by reference
123 * @see getInstalledExtensions()
125 function getInstExtList($path, &$list, &$cat, $type) {
127 if (@is_dir
($path)) {
128 $extList = t3lib_div
::get_dirs($path);
129 if (is_array($extList)) {
130 foreach ($extList as $extKey) {
131 if (@is_file
($path . $extKey . '/ext_emconf.php')) {
132 $emConf = tx_em_Tools
::includeEMCONF($path . $extKey . '/ext_emconf.php', $extKey);
133 if (is_array($emConf)) {
134 if (is_array($list[$extKey])) {
135 $list[$extKey] = array('doubleInstall' => $list[$extKey]['doubleInstall']);
137 $list[$extKey]['extkey'] = $extKey;
138 $list[$extKey]['doubleInstall'] .= $type;
139 $list[$extKey]['type'] = $type;
140 $list[$extKey]['installed'] = t3lib_extMgm
::isLoaded($extKey);
141 $list[$extKey]['EM_CONF'] = $emConf;
142 $list[$extKey]['files'] = t3lib_div
::getFilesInDir($path . $extKey, '', 0, '', $this->excludeForPackaging
);
144 tx_em_Tools
::setCat($cat, $list[$extKey], $extKey);
153 * Gathers all extensions in $path
155 * @param string Absolute path to local, global or system extensions
156 * @param array Array with information for each extension key found. Notice: passed by reference
157 * @param array Categories index: Contains extension titles grouped by various criteria.
158 * @param string Path-type: L, G or S
159 * @return void "Returns" content by reference
161 * @see getInstalledExtensions()
163 function getFlatInstExtList($path, &$list, $type) {
166 if (@is_dir
($path)) {
167 $extList = t3lib_div
::get_dirs($path);
168 if (is_array($extList)) {
169 foreach ($extList as $extKey) {
170 $this->singleExtInfo($extKey, $path, $list, $type);
177 * Gets a single extension info
182 * @param string $type
185 public function singleExtInfo($extKey, $path, &$list, $type = '') {
186 if (@is_file
($path . $extKey . '/ext_emconf.php')) {
187 $relPath = '../../../../' . substr($path, strlen(PATH_site
));
188 $emConf = tx_em_Tools
::includeEMCONF($path . $extKey . '/ext_emconf.php', $extKey);
189 $manual = $path . $extKey . '/doc/manual.sxw';
191 $type = tx_em_Tools
::getExtTypeFromPath($path);
193 if (is_array($emConf)) {
195 $loaded = t3lib_extMgm
::isLoaded($extKey);
196 if (is_array($list[$key])) {
197 $list[$key] = array('doubleInstall' => $list[$key]['doubleInstall']);
199 $list[$key]['extkey'] = $extKey;
200 $list[$key]['path'] = $path . $extKey;
201 $list[$key]['nodePath'] = substr($path . $extKey, strlen(PATH_site
));
202 $list[$key]['doubleInstall'] .= $this->types
[$type];
204 $list[$key]['type'] = $this->types
[$type];
205 $list[$key]['typeShort'] = $type;
206 $list[$key]['installed'] = $loaded ?
1 : 0;
207 // FIXME: raises PHP warning
208 // "Core: Error handler (BE): PHP Warning: htmlspecialchars() expects parameter 1 to be string, array given in [...]/typo3/mod/tools/em/classes/class.tx_em_extensions_list.php line 185
209 $list[$key] = t3lib_div
::array_merge_recursive_overrule($list[$key], $emConf);
210 $list[$key]['title'] = htmlspecialchars($list[$key]['title']);
211 $list[$key]['description'] = htmlspecialchars($list[$key]['description']);
212 $list[$key]['files'] = t3lib_div
::getFilesInDir($path . $extKey, '', 0, '', $this->excludeForPackaging
);
213 $list[$key]['install'] = $loaded ?
'<a href="' . htmlspecialchars(t3lib_div
::linkThisScript(array(
214 'CMD[showExt]' => $extKey,
217 'SET[singleDetails]' => 'info'
218 ))) . '">' . tx_em_Tools
::removeButton() . '</a>' :
219 '<a href="' . htmlspecialchars(t3lib_div
::linkThisScript(array(
220 'CMD[showExt]' => $extKey,
223 'SET[singleDetails]' => 'info'
224 ))) . '">' . tx_em_Tools
::installButton() . '</a>';
226 $list[$key]['install'] = $loaded ? tx_em_Tools
::removeButton() : tx_em_Tools
::installButton();
228 $list[$key]['download'] = '<a href="' . htmlspecialchars(t3lib_div
::linkThisScript(array(
229 'CMD[doBackup]' => 1,
230 'SET[singleDetails]' => 'backup',
231 'CMD[showExt]' => $extKey
233 t3lib_iconWorks
::getSpriteIcon('actions-system-extension-download') . ' title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:download') . '" alt=""></a>';
235 $list[$key]['doc'] = '';
236 if (@is_file
($manual)) {
237 $list[$key]['doc'] = '<a href="' . htmlspecialchars($relPath . $extKey . '/doc/manual.sxw') . '" target="_blank">
238 <img src="res/icons/oodoc.gif" width="13" height="16" title="' . $GLOBALS['LANG']->getLL('listRow_local_manual') . '" alt="" /></a>';
240 $list[$key]['icon'] = @is_file
($path . $extKey . '/ext_icon.gif') ?
'<img src="' . $relPath . $extKey . '/ext_icon.gif" alt="" width="16" height="16" />' : '<img src="clear.gif" alt="" width="16" height="16" />';
242 $list[$key]['categoryShort'] = $list[$key]['category'];
243 $list[$key]['category'] = $this->categories
[$list[$key]['category']];
245 unset($list[$key]['_md5_values_when_last_written']);
252 * Listing of loaded (installed) extensions
256 function extensionList_loaded() {
257 global $TYPO3_LOADED_EXT;
259 list($list, $cat) = $this->getInstalledExtensions();
265 // Available extensions
266 if (is_array($cat[$this->parentObject
->MOD_SETTINGS
['listOrder']])) {
269 $lines[] = $this->extensionListRowHeader(' class="t3-row-header"', array('<td><img src="clear.gif" width="1" height="1" alt="" /></td>'));
271 foreach ($cat[$this->parentObject
->MOD_SETTINGS
['listOrder']] as $catName => $extEkeys) {
273 natcasesort($extEkeys);
274 $extensions = array();
275 foreach ($extEkeys as $extKey => $data) {
276 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])) {
277 if (in_array($extKey, $this->parentObject
->requiredExt
)) {
278 $loadUnloadLink = '<strong>' . tx_em_Tools
::rfw($GLOBALS['LANG']->getLL('extension_required_short')) . '</strong>';
280 $loadUnloadLink = '<a href="' . htmlspecialchars(t3lib_div
::linkThisScript(array(
281 'CMD[showExt]' => $extKey,
283 ))) . '">' . tx_em_Tools
::removeButton() . '</a>';
286 $extensions[] = $this->extensionListRow($extKey, $list[$extKey], array('<td class="bgColor">' . $loadUnloadLink . '</td>'));
290 if (count($extensions)) {
291 $lines[] = '<tr><td colspan="' . (3 +
$this->parentObject
->detailCols
[$this->parentObject
->MOD_SETTINGS
['display_details']]) . '"><br /></td></tr>';
292 $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>';
293 $lines[] = implode(LF
, $extensions);
298 $content .= '<form action="' . $this->parentObject
->script
. '" method="post" name="lookupform">';
299 $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 />';
303 <!-- Loaded Extensions List -->
304 <table border="0" cellpadding="2" cellspacing="1">' . implode('', $lines) . '</table>';
310 * Listing of available (installed) extensions
314 function extensionList_installed() {
316 list($list, $cat) = $this->getInstalledExtensions();
318 // Available extensions
319 if (is_array($cat[$this->parentObject
->MOD_SETTINGS
['listOrder']])) {
322 $lines[] = $this->extensionListRowHeader(' class="t3-row-header"', array('<td><img src="clear.gif" width="18" height="1" alt="" /></td>'));
325 foreach ($cat[$this->parentObject
->MOD_SETTINGS
['listOrder']] as $catName => $extEkeys) {
326 if (!$this->parentObject
->MOD_SETTINGS
['display_obsolete'] && $catName == 'obsolete') {
331 $allKeys[] = 'TYPE: ' . $catName;
333 natcasesort($extEkeys);
334 $extensions = array();
335 foreach ($extEkeys as $extKey => $value) {
336 $allKeys[] = $extKey;
337 if ((!$list[$extKey]['EM_CONF']['shy'] ||
$this->parentObject
->MOD_SETTINGS
['display_shy']) &&
338 ($list[$extKey]['EM_CONF']['state'] != 'obsolete' ||
$this->parentObject
->MOD_SETTINGS
['display_obsolete'])
339 && $this->parentObject
->searchExtension($extKey, $list[$extKey])) {
340 $loadUnloadLink = t3lib_extMgm
::isLoaded($extKey) ?
341 '<a href="' . htmlspecialchars(t3lib_div
::linkThisScript(array(
342 'CMD[showExt]' => $extKey,
345 'SET[singleDetails]' => 'info'
346 ))) . '">' . tx_em_Tools
::removeButton() . '</a>' :
347 '<a href="' . htmlspecialchars(t3lib_div
::linkThisScript(array(
348 'CMD[showExt]' => $extKey,
351 'SET[singleDetails]' => 'info'
352 ))) . '">' . tx_em_Tools
::installButton() . '</a>';
353 if (in_array($extKey, $this->parentObject
->requiredExt
)) {
354 $loadUnloadLink = '<strong>' . tx_em_Tools
::rfw($GLOBALS['LANG']->getLL('extension_required_short')) . '</strong>';
356 $theRowClass = t3lib_extMgm
::isLoaded($extKey) ?
'em-listbg1' : 'em-listbg2';
357 $extensions[] = $this->extensionListRow($extKey, $list[$extKey], array('<td class="bgColor">' . $loadUnloadLink . '</td>'), $theRowClass);
360 if (count($extensions)) {
361 $lines[] = '<tr><td colspan="' . (3 +
$this->parentObject
->detailCols
[$this->parentObject
->MOD_SETTINGS
['display_details']]) . '"><br /></td></tr>';
362 $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>';
363 $lines[] = implode(LF
, $extensions);
373 ' . trim(implode(LF
, $allKeys)) . '
379 $content .= sprintf($GLOBALS['LANG']->getLL('how_to_install'), tx_em_Tools
::installButton()) . ' <br />' .
380 sprintf($GLOBALS['LANG']->getLL('how_to_uninstall'), tx_em_Tools
::removeButton()) . ' <br /><br />';
381 $content .= '<form action="' . $this->parentObject
->script
. '" method="post" name="lookupform">';
382 $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 />';
383 $content .= $this->securityHint
. '<br /><br />';
385 $content .= '<table border="0" cellpadding="2" cellspacing="1">' . implode('', $lines) . '</table>';
393 * Prints the header row for the various listings
395 * @param string Attributes for the <tr> tag
396 * @param array Preset cells in the beginning of the row. Typically a blank cell with a clear-gif
397 * @param boolean If set, the list is coming from remote server.
398 * @return string HTML <tr> table row
400 function extensionListRowHeader($trAttrib, $cells, $import = 0) {
401 $cells[] = '<td></td>';
402 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_title') . '</td>';
404 if (!$this->parentObject
->MOD_SETTINGS
['display_details']) {
405 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_description') . '</td>';
406 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_author') . '</td>';
407 } elseif ($this->parentObject
->MOD_SETTINGS
['display_details'] == 2) {
408 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_priority') . '</td>';
409 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_modifies_tables_short') . '</td>';
410 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_modules') . '</td>';
411 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_clear_cache_short') . '</td>';
412 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_internal') . '</td>';
413 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_shy') . '</td>';
414 } elseif ($this->parentObject
->MOD_SETTINGS
['display_details'] == 3) {
415 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_tables_fields') . '</td>';
416 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_ts_files') . '</td>';
417 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_affects') . '</td>';
418 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_modules') . '</td>';
419 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_config') . '</td>';
420 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_code_warnings') . '</td>';
421 } elseif ($this->parentObject
->MOD_SETTINGS
['display_details'] == 4) {
422 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_locallang') . '</td>';
423 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_classes') . '</td>';
424 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_code_warnings') . '</td>';
425 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_annoyances') . '</td>';
426 } elseif ($this->parentObject
->MOD_SETTINGS
['display_details'] == 5) {
427 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_changed_files') . '</td>';
429 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_ext_key') . '</td>';
430 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_version') . '</td>';
432 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_download_short') . '</td>';
433 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_documentation_short') . '</td>';
434 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_type') . '</td>';
436 $cells[] = '<td' . tx_em_Tools
::labelInfo($GLOBALS['LANG']->getLL('listRowHeader_title_upload_date')) . '>' .
437 $GLOBALS['LANG']->getLL('listRowHeader_upload_date') . '</td>';
438 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_author') . '</td>';
439 $cells[] = '<td' . tx_em_Tools
::labelInfo($GLOBALS['LANG']->getLL('listRowHeader_title_current_version')) . '>' .
440 $GLOBALS['LANG']->getLL('listRowHeader_current_version') . '</td>';
441 $cells[] = '<td' . tx_em_Tools
::labelInfo($GLOBALS['LANG']->getLL('listRowHeader_title_current_type')) . '>' .
442 $GLOBALS['LANG']->getLL('listRowHeader_current_type') . '</td>';
443 $cells[] = '<td' . tx_em_Tools
::labelInfo($GLOBALS['LANG']->getLL('listRowHeader_title_number_of_downloads')) . '>' .
444 $GLOBALS['LANG']->getLL('listRowHeader_download_short') . '</td>';
446 $cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_state') . '</td>';
449 <tr' . $trAttrib . '>
457 * Prints a row with data for the various extension listings
459 * @param string Extension key
460 * @param array Extension information array
461 * @param array Preset table cells, eg. install/uninstall icons.
462 * @param string <tr> tag class
463 * @param array Array with installed extension keys (as keys)
464 * @param boolean If set, the list is coming from remote server.
465 * @param string Alternative link URL
466 * @return string HTML <tr> content
468 function extensionListRow($extKey, $extInfo, $cells, $bgColorClass = '', $inst_list = array(), $import = 0, $altLinkUrl = '') {
470 $imgInfo = @getImageSize
(tx_em_Tools
::getExtPath($extKey, $extInfo['type']) . '/ext_icon.gif');
471 if (is_array($imgInfo)) {
472 $cells[] = '<td><img src="' . $GLOBALS['BACK_PATH'] . tx_em_Tools
::typeRelPath($extInfo['type']) . $extKey . '/ext_icon.gif' . '" ' . $imgInfo[3] . ' alt="" /></td>';
473 } elseif ($extInfo['_ICON']) {
474 $cells[] = '<td>' . $extInfo['_ICON'] . '</td>';
476 $cells[] = '<td><img src="clear.gif" width="1" height="1" alt="" /></td>';
480 $cells[] = '<td nowrap="nowrap"><a href="' . htmlspecialchars($altLinkUrl ?
$altLinkUrl : t3lib_div
::linkThisScript(array(
481 'CMD[showExt]' => $extKey,
482 'SET[singleDetails]' => 'info'
483 ))) . '" title="' . htmlspecialchars($extInfo['EM_CONF']['description']) . '">'
484 . t3lib_div
::fixed_lgd_cs($extInfo['EM_CONF']['title'] ?
htmlspecialchars($extInfo['EM_CONF']['title']) : '<em>' . $extKey . '</em>', 40) . '</a></td>';
486 // Based on the display mode you will see more or less details:
487 if (!$this->parentObject
->MOD_SETTINGS
['display_details']) {
488 $cells[] = '<td>' . htmlspecialchars(t3lib_div
::fixed_lgd_cs($extInfo['EM_CONF']['description'], 400)) . '<br /><img src="clear.gif" width="300" height="1" alt="" /></td>';
489 $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>';
490 } elseif ($this->parentObject
->MOD_SETTINGS
['display_details'] == 2) {
491 $cells[] = '<td nowrap="nowrap">' . $extInfo['EM_CONF']['priority'] . '</td>';
492 $cells[] = '<td nowrap="nowrap">' . implode('<br />', t3lib_div
::trimExplode(',', $extInfo['EM_CONF']['modify_tables'], 1)) . '</td>';
493 $cells[] = '<td nowrap="nowrap">' . $extInfo['EM_CONF']['module'] . '</td>';
494 $cells[] = '<td nowrap="nowrap">' . ($extInfo['EM_CONF']['clearCacheOnLoad'] ?
$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:yes') : '') . '</td>';
495 $cells[] = '<td nowrap="nowrap">' . ($extInfo['EM_CONF']['internal'] ?
$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:yes') : '') . '</td>';
496 $cells[] = '<td nowrap="nowrap">' . ($extInfo['EM_CONF']['shy'] ?
$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:yes') : '') . '</td>';
497 } elseif ($this->parentObject
->MOD_SETTINGS
['display_details'] == 3) {
498 $techInfo = $this->install
->makeDetailedExtensionAnalysis($extKey, $extInfo);
500 $cells[] = '<td>' . $this->parentObject
->extensionDetails
->extInformationArray_dbReq($techInfo) .
502 $cells[] = '<td nowrap="nowrap">' . (is_array($techInfo['TSfiles']) ?
implode('<br />', $techInfo['TSfiles']) : '') . '</td>';
503 $cells[] = '<td nowrap="nowrap">' . (is_array($techInfo['flags']) ?
implode('<br />', $techInfo['flags']) : '') . '</td>';
504 $cells[] = '<td nowrap="nowrap">' . (is_array($techInfo['moduleNames']) ?
implode('<br />', $techInfo['moduleNames']) : '') . '</td>';
505 $cells[] = '<td nowrap="nowrap">' . ($techInfo['conf'] ?
$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:yes') : '') . '</td>';
507 tx_em_Tools
::rfw((t3lib_extMgm
::isLoaded($extKey) && $techInfo['tables_error'] ?
508 '<strong>' . $GLOBALS['LANG']->getLL('extInfoArray_table_error') . '</strong><br />' .
509 $GLOBALS['LANG']->getLL('extInfoArray_missing_fields') : '') .
510 (t3lib_extMgm
::isLoaded($extKey) && $techInfo['static_error'] ?
511 '<strong>' . $GLOBALS['LANG']->getLL('extInfoArray_static_table_error') . '</strong><br />' .
512 $GLOBALS['LANG']->getLL('extInfoArray_static_tables_missing_empty') : '')) .
514 } elseif ($this->parentObject
->MOD_SETTINGS
['display_details'] == 4) {
515 $techInfo = $this->install
->makeDetailedExtensionAnalysis($extKey, $extInfo, 1);
517 $cells[] = '<td>' . (is_array($techInfo['locallang']) ?
implode('<br />', $techInfo['locallang']) : '') . '</td>';
518 $cells[] = '<td>' . (is_array($techInfo['classes']) ?
implode('<br />', $techInfo['classes']) : '') . '</td>';
519 $cells[] = '<td>' . (is_array($techInfo['errors']) ? tx_em_Tools
::rfw(implode('<hr />', $techInfo['errors'])) : '') . '</td>';
520 $cells[] = '<td>' . (is_array($techInfo['NSerrors']) ?
521 (!t3lib_div
::inList($this->parentObject
->nameSpaceExceptions
, $extKey) ?
522 t3lib_utility_Debug
::viewarray($techInfo['NSerrors']) :
523 tx_em_Tools
::dfw($GLOBALS['LANG']->getLL('extInfoArray_exception'))) : '') . '</td>';
524 } elseif ($this->parentObject
->MOD_SETTINGS
['display_details'] == 5) {
525 $currentMd5Array = $this->parentObject
->extensionDetails
->serverExtensionMD5array($extKey, $extInfo);
528 $msgLines[] = $GLOBALS['LANG']->getLL('listRow_files') . ' ' . count($currentMd5Array);
529 if (strcmp($extInfo['EM_CONF']['_md5_values_when_last_written'], serialize($currentMd5Array))) {
530 $msgLines[] = tx_em_Tools
::rfw('<br /><strong>' . $GLOBALS['LANG']->getLL('extInfoArray_difference_detected') . '</strong>');
531 $affectedFiles = tx_em_Tools
::findMD5ArrayDiff($currentMd5Array, unserialize($extInfo['EM_CONF']['_md5_values_when_last_written']));
532 if (count($affectedFiles)) {
533 $msgLines[] = '<br /><strong>' . $GLOBALS['LANG']->getLL('extInfoArray_modified_files') . '</strong><br />' .
534 tx_em_Tools
::rfw(implode('<br />', $affectedFiles));
537 $cells[] = '<td>' . implode('<br />', $msgLines) . '</td>';
540 $verDiff = $inst_list[$extKey] && tx_em_Tools
::versionDifference($extInfo['EM_CONF']['version'], $inst_list[$extKey]['EM_CONF']['version'], $this->parentObject
->versionDiffFactor
);
542 $cells[] = '<td nowrap="nowrap"><em>' . $extKey . '</em></td>';
543 $cells[] = '<td nowrap="nowrap">' . ($verDiff ?
'<strong>' . tx_em_Tools
::rfw(htmlspecialchars($extInfo['EM_CONF']['version'])) . '</strong>' : $extInfo['EM_CONF']['version']) . '</td>';
544 if (!$import) { // Listing extension on LOCAL server:
545 // Extension Download:
546 $cells[] = '<td nowrap="nowrap"><a href="' . htmlspecialchars(t3lib_div
::linkThisScript(array(
547 'CMD[doBackup]' => 1,
548 'SET[singleDetails]' => 'backup',
549 'CMD[showExt]' => $extKey
550 ))) . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:download') . '">' .
551 t3lib_iconWorks
::getSpriteIcon('actions-system-extension-download') .
555 $fileP = PATH_site
. tx_em_Tools
::typePath($extInfo['type']) . $extKey . '/doc/manual.sxw';
556 $cells[] = '<td nowrap="nowrap">' .
557 (tx_em_Tools
::typePath($extInfo['type']) && @is_file
($fileP) ?
558 '<a href="' . htmlspecialchars(t3lib_div
::resolveBackPath($this->parentObject
->doc
->backPath
. '../' .
559 tx_em_Tools
::typePath($extInfo['type']) . $extKey . '/doc/manual.sxw')) . '" target="_blank" title="' . $GLOBALS['LANG']->getLL('listRow_local_manual') . '">' .
560 t3lib_iconWorks
::getSpriteIcon('actions-system-extension-documentation') . '</a>' : '') .
563 // Double installation (inclusion of an extension in more than one of system, global or local scopes)
565 if (strlen($extInfo['doubleInstall']) > 1) {
566 // Separate the "SL" et al. string into an array and replace L by Local, G by Global etc.
567 $doubleInstallations = str_replace(
568 array('S', 'G', 'L'),
570 $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:sysext'),
571 $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:globalext'),
572 $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:localext')
574 str_split($extInfo['doubleInstall'])
576 // Last extension is the one actually used
577 $usedExtension = array_pop($doubleInstallations);
578 // Next extension is overridden
579 $overriddenExtensions = array_pop($doubleInstallations);
580 // If the array is not yet empty, the extension is actually installed 3 times (SGL)
581 if (count($doubleInstallations) > 0) {
582 $lastExtension = array_pop($doubleInstallations);
583 $overriddenExtensions .= ' ' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:and') . ' ' . $lastExtension;
585 $doubleInstallTitle = sprintf(
586 $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:double_inclusion'),
588 $overriddenExtensions
590 $doubleInstall = ' <strong><abbr title="' . $doubleInstallTitle . '">' . tx_em_Tools
::rfw($extInfo['doubleInstall']) . '</abbr></strong>';
592 $cells[] = '<td nowrap="nowrap">' . $this->api
->typeLabels
[$extInfo['type']] . $doubleInstall . '</td>';
593 } else { // Listing extensions from REMOTE repository:
594 $inst_curVer = $inst_list[$extKey]['EM_CONF']['version'];
595 if (isset($inst_list[$extKey])) {
597 $inst_curVer = '<strong>' . tx_em_Tools
::rfw($inst_curVer) . '</strong>';
600 $cells[] = '<td nowrap="nowrap">' . t3lib_befunc
::date($extInfo['EM_CONF']['lastuploaddate']) . '</td>';
601 $cells[] = '<td nowrap="nowrap">' . htmlspecialchars(t3lib_div
::fixed_lgd_cs($extInfo['EM_CONF']['author'], $GLOBALS['BE_USER']->uc
[titleLen
])) . '</td>';
602 $cells[] = '<td nowrap="nowrap">' . $inst_curVer . '</td>';
603 $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>';
604 $cells[] = '<td nowrap="nowrap">' . ($extInfo['downloadcounter_all'] ?
$extInfo['downloadcounter_all'] : ' ') . '/' . ($extInfo['downloadcounter'] ?
$extInfo['downloadcounter'] : ' ') . '</td>';
606 $cells[] = '<td nowrap="nowrap" class="extstate" style="background-color:' . $this->parentObject
->stateColors
[$extInfo['EM_CONF']['state']] . ';">' . $this->parentObject
->states
[$extInfo['EM_CONF']['state']] . '</td>';
609 // show a different background through a different class for insecure (-1) extensions,
610 // for unreviewed (0) and reviewed extensions (1), just use the regular class
611 if ($this->parentObject
->xmlhandler
->getReviewState($extKey, $extInfo['EM_CONF']['version']) < 0) {
612 $bgclass = ' class="unsupported-ext"';
614 $bgclass = ' class="' . ($bgColorClass ?
$bgColorClass : 'em-listbg1') . '"';
626 * Displays a list of extensions where a newer version is available
627 * in the TER than the one that is installed right now
628 * integrated from the extension "ter_update_check" for TYPO3 4.2 by Christian Welzel
632 function showExtensionsToUpdate() {
634 $extList = $this->getInstalledExtensions();
636 $content = '<table border="0" cellpadding="2" cellspacing="1">' .
637 '<tr class="t3-row-header">' .
639 '<td>' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:tab_mod_name') . '</td>' .
640 '<td>' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:tab_mod_key') . '</td>' .
641 '<td>' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:tab_mod_loc_ver') . '</td>' .
642 '<td>' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:tab_mod_rem_ver') . '</td>' .
643 '<td>' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:tab_mod_location') . '</td>' .
644 '<td>' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:tab_mod_comment') . '</td>' .
647 foreach ($extList[0] as $name => $data) {
648 $this->parentObject
->xmlhandler
->searchExtensionsXMLExact($name, '', '', TRUE, TRUE);
649 if (!is_array($this->parentObject
->xmlhandler
->extensionsXML
[$name])) {
653 $v = $this->parentObject
->xmlhandler
->extensionsXML
[$name]['versions'];
654 $versions = array_keys($v);
656 $lastversion = end($versions);
658 if ((t3lib_extMgm
::isLoaded($name) ||
$this->parentObject
->MOD_SETTINGS
['display_installed']) &&
659 ($data['EM_CONF']['shy'] == 0 ||
$this->parentObject
->MOD_SETTINGS
['display_shy']) &&
660 tx_em_Tools
::versionDifference($lastversion, $data['EM_CONF']['version'], 1)) {
662 $imgInfo = @getImageSize
(tx_em_Tools
::getExtPath($name, $data['type']) . '/ext_icon.gif');
663 if (is_array($imgInfo)) {
664 $icon = '<img src="' . $GLOBALS['BACK_PATH'] . tx_em_Tools
::typeRelPath($data['type']) . $name . '/ext_icon.gif' . '" ' . $imgInfo[3] . ' alt="" />';
665 } elseif ($data['_ICON']) { //TODO: see if this can be removed, seems to be wrong in this context
666 $icon = $data['_ICON'];
668 $icon = '<img src="clear.gif" width="1" height="1" alt="" />';
670 $comment = '<table cellpadding="0" cellspacing="0" width="100%">';
671 foreach ($versions as $vk) {
673 if (t3lib_div
::int_from_ver($vk) <= t3lib_div
::int_from_ver($data['EM_CONF']['version'])) {
676 $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>';
678 $comment .= '</table>';
680 $serverMD5Array = $this->parentObject
->extensionDetails
->serverExtensionMD5array($name, $data);
681 if (is_array($serverMD5Array)) {
682 ksort($serverMD5Array);
684 $currentMD5Array = unserialize($data['EM_CONF']['_md5_values_when_last_written']);
685 if (is_array($currentMD5Array)) {
686 @ksort
($currentMD5Array);
689 if (strcmp(serialize($currentMD5Array), serialize($serverMD5Array))) {
690 $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
;
691 if ($this->parentObject
->MOD_SETTINGS
['display_files'] == 1) {
692 $affectedFiles = tx_em_Tools
::findMD5ArrayDiff($serverMD5Array, $currentMD5Array);
693 if (count($affectedFiles)) {
694 $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
;
698 //TODO: $extInfo is unknown in this context
699 $content .= '<tr class="bgColor4"><td valign="top">' . $icon . '</td>' .
700 '<td valign="top">' . ($data['EM_CONF']['state'] == 'excludeFromUpdates'
701 ?
'<span style="color:#cf7307">' . $data['EM_CONF']['title'] . ' ' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:write_protected') . '</span>'
702 : '<a href="' . t3lib_div
::linkThisScript(array(
703 'CMD[importExtInfo]' => $name
704 )) . '">' . $data[EM_CONF
][title
] . '</a>') . '</td>' .
705 '<td valign="top">' . $name . '</td>' .
706 '<td valign="top" align="right">' . $data[EM_CONF
][version
] . '</td>' .
707 '<td valign="top" align="right">' . $lastversion . '</td>' .
708 '<td valign="top" nowrap="nowrap">' . $this->api
->typeLabels
[$data['type']] . (strlen($data['doubleInstall']) > 1 ?
'<strong> ' . tx_em_Tools
::rfw($extInfo['doubleInstall']) . '</strong>' : '') . '</td>' .
709 '<td valign="top">' . $comment . '</td></tr>' . LF
.
711 '<tr class="bgColor4"><td colspan="7"><hr style="margin:0px" /></td></tr>' . LF
;
715 return $content . '</table><br />';
719 * Maps remote extensions information into $cat/$list arrays for listing
721 * @param boolean If set the info in the internal extensionsXML array will be unset before returning the result.
722 * @return array List array and category index as key 0 / 1 in an array.
724 function prepareImportExtList($unsetProc = false) {
726 $cat = $this->parentObject
->defaultCategories
;
727 $filepath = $this->parentObject
->getMirrorURL();
729 foreach ($this->parentObject
->xmlhandler
->extensionsXML
as $extKey => $data) {
730 $GLOBALS['LANG']->csConvObj
->convarray($data, 'utf-8', $GLOBALS['LANG']->charSet
); // is there a better place for conversion?
731 $list[$extKey]['type'] = '_';
732 $version = array_keys($data['versions']);
733 $extPath = t3lib_div
::strtolower($extKey);
734 $list[$extKey]['_ICON'] = '<img alt="" src="' . $filepath . $extPath{0} . '/' . $extPath{1} . '/' . $extPath . '_' . end($version) . '.gif" />';
735 $list[$extKey]['downloadcounter'] = $data['downloadcounter'];
737 foreach (array_keys($data['versions']) as $version) {
738 $list[$extKey]['versions'][$version]['downloadcounter'] = $data['versions'][$version]['downloadcounter'];
740 $list[$extKey]['versions'][$version]['EM_CONF'] = array(
741 'version' => $version,
742 'title' => $data['versions'][$version]['title'],
743 'description' => $data['versions'][$version]['description'],
744 'category' => $data['versions'][$version]['category'],
745 'constraints' => $data['versions'][$version]['dependencies'],
746 'state' => $data['versions'][$version]['state'],
747 'reviewstate' => $data['versions'][$version]['reviewstate'],
748 'lastuploaddate' => $data['versions'][$version]['lastuploaddate'],
749 'author' => $data['versions'][$version]['authorname'],
750 'author_email' => $data['versions'][$version]['authoremail'],
751 'author_company' => $data['versions'][$version]['authorcompany'],
754 tx_em_Tools
::setCat($cat, $list[$extKey]['versions'][$version], $extKey);
756 unset($this->parentObject
->xmlhandler
->extensionsXML
[$extKey]);
760 return array($list, $cat);
765 * Adds extension to extension list and returns new list. If -1 is returned, an error happend.
766 * Checks dependencies etc.
768 * @param string Extension key
769 * @param array Extension information array - information about installed extensions
770 * @return string New list of installed extensions or -1 if error
771 * @see showExtDetails()
773 function addExtToList($extKey, $instExtInfo) {
774 global $TYPO3_LOADED_EXT;
776 // ext_emconf.php information:
777 $conf = $instExtInfo[$extKey]['EM_CONF'];
779 // Get list of installed extensions and add this one.
780 $listArr = array_keys($TYPO3_LOADED_EXT);
781 if ($conf['priority'] == 'top') {
782 array_unshift($listArr, $extKey);
784 $listArr[] = $extKey;
787 // Manage other circumstances:
788 $listArr = tx_em_Tools
::managesPriorities($listArr, $instExtInfo);
789 $listArr = $this->removeRequiredExtFromListArr($listArr);
791 // Implode unique list of extensions to load and return:
792 $list = implode(',', array_unique($listArr));
798 * Remove extension key from the list of currently installed extensions and return list. If -1 is returned, an error happend.
799 * Checks dependencies etc.
801 * @param string Extension key
802 * @param array Extension information array - information about installed extensions
803 * @return string New list of installed extensions or -1 if error
804 * @see showExtDetails()
806 function removeExtFromList($extKey, $instExtInfo) {
807 global $TYPO3_LOADED_EXT;
811 $listArr = array_keys($TYPO3_LOADED_EXT);
813 // 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!
814 foreach ($listArr as $k => $ext) {
815 if ($instExtInfo[$ext]['EM_CONF']['dependencies']) {
816 $dep = t3lib_div
::trimExplode(',', $instExtInfo[$ext]['EM_CONF']['dependencies'], 1);
817 if (in_array($extKey, $dep)) {
821 if (!strcmp($ext, $extKey)) {
826 // Returns either error or the new list
827 if (count($depList)) {
828 $msg = sprintf($GLOBALS['LANG']->getLL('removeExtFromList_dependency'),
829 implode(', ', $depList)
831 $this->parentObject
->content
.= $this->parentObject
->doc
->section($GLOBALS['LANG']->getLL('removeExtFromList_dependency_error'), $msg, 0, 1, 2);
834 $listArr = $this->removeRequiredExtFromListArr($listArr);
835 $list = implode(',', array_unique($listArr));
841 * 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
843 * @param array Array of extension keys as values
844 * @return array Modified array
845 * @see removeExtFromList(), addExtToList()
847 function removeRequiredExtFromListArr($listArr) {
848 $requiredExtensions = t3lib_div
::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['EXT']['requiredExt'], 1);
849 foreach ($listArr as $k => $ext) {
850 if (in_array($ext, $requiredExtensions) ||
!strcmp($ext, '_CACHEFILE')) {