PageRenderTime 62ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/typo3/sysext/em/classes/extensions/class.tx_em_extensions_list.php

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