/**
  *  Displays a list of extensions where a newer version is available
  *  in the TER than the one that is installed right now
  *  integrated from the extension "ter_update_check" for TYPO3 4.2 by Christian Welzel
  *
  * @return string
  */
 function showExtensionsToUpdate()
 {
     global $LANG;
     $extList = $this->getInstalledExtensions();
     $content = '<table cellspacing="1" class="t3-em-extension-list t3-em-extension-list-to-update">' . '<tr class="t3-row-header">' . '<td></td>' . '<td>' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:tab_mod_name') . '</td>' . '<td>' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:tab_mod_key') . '</td>' . '<td>' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:tab_mod_loc_ver') . '</td>' . '<td>' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:tab_mod_rem_ver') . '</td>' . '<td>' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:tab_mod_location') . '</td>' . '<td>' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:tab_mod_comment') . '</td>' . '</tr>';
     foreach ($extList[0] as $name => $data) {
         $this->xmlHandler->searchExtensionsXMLExact($name, '', '', TRUE, TRUE);
         if (!is_array($this->xmlHandler->extensionsXML[$name])) {
             continue;
         }
         $v = $this->xmlHandler->extensionsXML[$name]['versions'];
         $versions = array_keys($v);
         natsort($versions);
         $lastversion = end($versions);
         if ((t3lib_extMgm::isLoaded($name) || $this->parentObject->MOD_SETTINGS['display_installed']) && ($data['EM_CONF']['shy'] == 0 || $this->parentObject->MOD_SETTINGS['display_shy']) && tx_em_Tools::versionDifference($lastversion, $data['EM_CONF']['version'], 1)) {
             $imgInfo = @getImageSize(tx_em_Tools::getExtPath($name, $data['type']) . '/ext_icon.gif');
             if (is_array($imgInfo)) {
                 $icon = '<img src="' . $GLOBALS['BACK_PATH'] . tx_em_Tools::typeRelPath($data['type']) . $name . '/ext_icon.gif' . '" ' . $imgInfo[3] . ' alt="" />';
             } elseif ($data['_ICON']) {
                 //TODO: see if this can be removed, seems to be wrong in this context
                 $icon = $data['_ICON'];
             } else {
                 $icon = '<img src="clear.gif" width="1" height="1" alt="" />';
             }
             $comment = '<table cellpadding="0" cellspacing="0" width="100%">';
             foreach ($versions as $vk) {
                 $va =& $v[$vk];
                 if (t3lib_div::int_from_ver($vk) <= t3lib_div::int_from_ver($data['EM_CONF']['version'])) {
                     continue;
                 }
                 $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>';
             }
             $comment .= '</table>';
             $serverMD5Array = $this->parentObject->extensionDetails->serverExtensionMD5array($name, $data);
             if (is_array($serverMD5Array)) {
                 ksort($serverMD5Array);
             }
             $currentMD5Array = unserialize($data['EM_CONF']['_md5_values_when_last_written']);
             if (is_array($currentMD5Array)) {
                 @ksort($currentMD5Array);
             }
             $warn = '';
             if (strcmp(serialize($currentMD5Array), serialize($serverMD5Array))) {
                 $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;
                 if ($this->parentObject->MOD_SETTINGS['display_files'] == 1) {
                     $affectedFiles = tx_em_Tools::findMD5ArrayDiff($serverMD5Array, $currentMD5Array);
                     if (count($affectedFiles)) {
                         $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;
                     }
                 }
             }
             $content .= '<tr class="bgColor4"><td valign="top">' . $icon . '</td>' . '<td valign="top">' . ($data['EM_CONF']['state'] == 'excludeFromUpdates' ? '<span style="color:#cf7307">' . $data['EM_CONF']['title'] . ' ' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:write_protected') . '</span>' : '<a href="' . t3lib_div::linkThisScript(array('CMD[importExtInfo]' => $name)) . '">' . $data[EM_CONF][title] . '</a>') . '</td>' . '<td valign="top">' . $name . '</td>' . '<td valign="top" align="right">' . $data[EM_CONF][version] . '</td>' . '<td valign="top" align="right">' . $lastversion . '</td>' . '<td valign="top" nowrap="nowrap">' . $this->api->typeLabels[$data['type']] . (strlen($data['doubleInstall']) > 1 ? '<strong> ' . tx_em_Tools::rfw($data['doubleInstall']) . '</strong>' : '') . '</td>' . '<td valign="top">' . $comment . '</td></tr>' . LF . $warn . '<tr class="bgColor4"><td colspan="7"><hr style="margin:0px" /></td></tr>' . LF;
         }
     }
     return $content . '</table><br />';
 }
    /**
     * Prints a table with extension information in it.
     *
     * @param	string		Extension key
     * @param	array		Extension information array
     * @param	boolean		If set, the information array shows information for a remote extension in TER, not a local one.
     * @return	string		HTML content.
     */
    function extInformationarray($extKey, $extInfo, $remote = 0)
    {
        $emConf = $extInfo['EM_CONF'];
        $lines = array();
        $lines[] = '
			<tr class="t3-row-header"><td colspan="2"><strong>' . $GLOBALS['LANG']->getLL('extInfoArray_general_info') . '</strong></td></tr>';
        // row for the extension title
        $key = 'title';
        $dataCol = $emConf['_icon'] . $emConf[$key];
        $lines[] = array($this->headerCol($key), $dataCol);
        // row for the extension description
        $key = 'description';
        $dataCol = nl2br(htmlspecialchars($emConf[$key]));
        $lines[] = array($this->headerCol($key), $dataCol);
        // row for the extension author
        $key = 'author';
        $dataCol = tx_em_Tools::wrapEmail($emConf['author'] . ($emConf['author_email'] ? ' <' . $emConf['author_email'] . '>' : ''), $emConf['author_email']);
        if ($emConf['author_company']) {
            $dataCol .= ', ' . $emConf['author_company'];
        }
        $lines[] = array($this->headerCol($key), $dataCol);
        // row for the version
        $key = 'version';
        $dataCol = $emConf[$key];
        $lines[] = array($this->headerCol($key), $dataCol);
        // row for the category
        $key = 'category';
        $dataCol = $this->categories[$emConf[$key]];
        $lines[] = array($this->headerCol($key), $dataCol);
        // row for the state
        $key = 'state';
        $dataCol = $this->states[$emConf[$key]];
        $lines[] = array($this->headerCol($key), $dataCol);
        // row for the shy state
        $key = 'shy';
        if ($emConf[$key]) {
            $dataCol = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:yes');
        } else {
            $dataCol = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:no');
        }
        $lines[] = array($this->headerCol($key), $dataCol);
        // row for the internal state
        $key = 'internal';
        if ($emConf[$key]) {
            $dataCol = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:yes');
        } else {
            $dataCol = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:no');
        }
        $lines[] = array($this->headerCol($key), $dataCol);
        // row for the dependencies
        $headerCol = $GLOBALS['LANG']->getLL('extInfoArray_depends_on');
        $headerCol = t3lib_BEfunc::wrapInHelp($this->descrTable, 'emconf_dependencies', $headerCol);
        $dataCol = tx_em_Tools::depToString($emConf['constraints']);
        $lines[] = array($headerCol, $dataCol);
        // row for the conflicts
        $headerCol = $GLOBALS['LANG']->getLL('extInfoArray_conflicts_with');
        $headerCol = t3lib_BEfunc::wrapInHelp($this->descrTable, 'emconf_conflicts', $headerCol);
        $dataCol = tx_em_Tools::depToString($emConf['constraints'], 'conflicts');
        $lines[] = array($headerCol, $dataCol);
        // row for the suggestions
        $headerCol = $GLOBALS['LANG']->getLL('extInfoArray_suggests');
        $headerCol = t3lib_BEfunc::wrapInHelp($this->descrTable, 'emconf_conflicts', $headerCol);
        $dataCol = tx_em_Tools::depToString($emConf['constraints'], 'suggests');
        $lines[] = array($this->headerCol('suggests'), $dataCol);
        if (!$remote) {
            $key = 'priority';
            $lines[] = array($this->headerCol($key), $emConf[$key]);
            $headerCol = $GLOBALS['LANG']->getLL('extInfoArray_clear_cache');
            $headerCol = t3lib_BEfunc::wrapInHelp($this->descrTable, 'emconf_clearCacheOnLoad', $headerCol);
            if ($emConf['clearCacheOnLoad']) {
                $dataCol = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:yes');
            } else {
                $dataCol = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:no');
            }
            $lines[] = array($headerCol, $dataCol);
            $key = 'module';
            $headerCol = $GLOBALS['LANG']->getLL('extInfoArray_incl_modules');
            $headerCol = t3lib_BEfunc::wrapInHelp($this->descrTable, 'emconf_module', $headerCol);
            $lines[] = array($headerCol, $emConf[$key]);
            $key = 'lockType';
            $headerCol = $GLOBALS['LANG']->getLL('extInfoArray_lock_type');
            $headerCol = t3lib_BEfunc::wrapInHelp($this->descrTable, 'emconf_lockType', $headerCol);
            $lines[] = array($headerCol, $emConf[$key] ? $emConf[$key] : '');
            $key = 'doNotLoadInFE';
            $headerCol = $GLOBALS['LANG']->getLL('extInfoArray_load_in_frontend');
            $headerCol = t3lib_BEfunc::wrapInHelp($this->descrTable, 'emconf_doNotLoadInFE', $headerCol);
            if (!$emConf['doNotLoadInFE']) {
                $dataCol = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:yes');
            } else {
                $dataCol = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:no');
            }
            $lines[] = array($headerCol, $dataCol);
            $key = 'modify_tables';
            $headerCol = $GLOBALS['LANG']->getLL('extInfoArray_modifies_tables');
            $headerCol = t3lib_BEfunc::wrapInHelp($this->descrTable, 'emconf_modify_tables', $headerCol);
            $lines[] = array($headerCol, $emConf[$key]);
            // Installation status:
            $techInfo = $this->install->makeDetailedExtensionAnalysis($extKey, $extInfo, 1);
            $lines[] = array('<tr><td colspan="2">&nbsp;</td></tr>');
            $lines[] = array('<tr class="t3-row-header"><td colspan="2"><strong>' . $GLOBALS['LANG']->getLL('extInfoArray_inst_status') . '</strong></td></tr>');
            $headerCol = $GLOBALS['LANG']->getLL('extInfoArray_inst_type');
            $headerCol = t3lib_BEfunc::wrapInHelp($this->descrTable, 'emconf_type', $headerCol);
            $dataCol = $this->api->typeLabels[$extInfo['type']] . ' - <em>' . $this->api->typeDescr[$extInfo['type']] . '</em>';
            $lines[] = array($headerCol, $dataCol);
            $headerCol = $GLOBALS['LANG']->getLL('extInfoArray_inst_twice');
            $headerCol = t3lib_BEfunc::wrapInHelp($this->descrTable, 'emconf_doubleInstall', $headerCol);
            $dataCol = $this->extInformationArray_dbInst($extInfo['doubleInstall'], $extInfo['type']);
            $lines[] = array($headerCol, $dataCol);
            if (is_array($extInfo['files'])) {
                sort($extInfo['files']);
                $headerCol = $GLOBALS['LANG']->getLL('extInfoArray_root_files');
                $headerCol = t3lib_BEfunc::wrapInHelp($this->descrTable, 'emconf_rootfiles', $headerCol);
                $dataCol = implode('<br />', $extInfo['files']);
                $lines[] = array($headerCol, $dataCol);
            }
            if ($techInfo['tables'] || $techInfo['static'] || $techInfo['fields']) {
                if (!$remote && t3lib_extMgm::isLoaded($extKey)) {
                    $tableStatus = tx_em_Tools::rfw(($techInfo['tables_error'] ? '<strong>' . $GLOBALS['LANG']->getLL('extInfoArray_table_error') . '</strong><br />' . $GLOBALS['LANG']->getLL('extInfoArray_missing_fields') : '') . ($techInfo['static_error'] ? '<strong>' . $GLOBALS['LANG']->getLL('extInfoArray_static_table_error') . '</strong><br />' . $GLOBALS['LANG']->getLL('extInfoArray_static_tables_missing_empty') : ''));
                } else {
                    $tableStatus = $techInfo['tables_error'] || $techInfo['static_error'] ? $GLOBALS['LANG']->getLL('extInfoArray_db_update_needed') : $GLOBALS['LANG']->getLL('extInfoArray_tables_ok');
                }
            }
            $headerCol = $GLOBALS['LANG']->getLL('extInfoArray_db_requirements');
            $headerCol = t3lib_BEfunc::wrapInHelp($this->descrTable, 'emconf_dbReq', $headerCol);
            $dataCol = $this->extInformationArray_dbReq($techInfo, 1);
            $lines[] = array($headerCol, $dataCol);
            $headerCol = $GLOBALS['LANG']->getLL('extInfoArray_db_status');
            $headerCol = t3lib_BEfunc::wrapInHelp($this->descrTable, 'emconf_dbStatus', $headerCol);
            $lines[] = array($headerCol, $tableStatus);
            $headerCol = $GLOBALS['LANG']->getLL('extInfoArray_flags');
            $headerCol = t3lib_BEfunc::wrapInHelp($this->descrTable, 'emconf_flags', $headerCol);
            $dataCol = is_array($techInfo['flags']) ? implode('<br />', $techInfo['flags']) : '';
            $lines[] = array($headerCol, $dataCol);
            $headerCol = $GLOBALS['LANG']->getLL('extInfoArray_config_template');
            $headerCol = t3lib_BEfunc::wrapInHelp($this->descrTable, 'emconf_conf', $headerCol);
            $dataCol = $techInfo['conf'] ? $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:yes') : '';
            $lines[] = array($headerCol, $dataCol);
            $headerCol = $GLOBALS['LANG']->getLL('extInfoArray_typoscript_files');
            $headerCol = t3lib_BEfunc::wrapInHelp($this->descrTable, 'emconf_TSfiles', $headerCol);
            $dataCol = is_array($techInfo['TSfiles']) ? implode('<br />', $techInfo['TSfiles']) : '';
            $lines[] = array($headerCol, $dataCol);
            $headerCol = $GLOBALS['LANG']->getLL('extInfoArray_language_files');
            $headerCol = t3lib_BEfunc::wrapInHelp($this->descrTable, 'emconf_locallang', $headerCol);
            $dataCol = is_array($techInfo['locallang']) ? implode('<br />', $techInfo['locallang']) : '';
            $lines[] = array($headerCol, $dataCol);
            $headerCol = $GLOBALS['LANG']->getLL('extInfoArray_upload_folder');
            $headerCol = t3lib_BEfunc::wrapInHelp($this->descrTable, 'emconf_uploadfolder', $headerCol);
            $dataCol = $techInfo['uploadfolder'] ? $techInfo['uploadfolder'] : '';
            $lines[] = array($headerCol, $dataCol);
            $headerCol = $GLOBALS['LANG']->getLL('extInfoArray_create_directories');
            $headerCol = t3lib_BEfunc::wrapInHelp($this->descrTable, 'emconf_createDirs', $headerCol);
            $dataCol = is_array($techInfo['createDirs']) ? implode('<br />', $techInfo['createDirs']) : '';
            $lines[] = array($headerCol, $dataCol);
            $headerCol = $GLOBALS['LANG']->getLL('extInfoArray_module_names');
            $headerCol = t3lib_BEfunc::wrapInHelp($this->descrTable, 'emconf_moduleNames', $headerCol);
            $dataCol = is_array($techInfo['moduleNames']) ? implode('<br />', $techInfo['moduleNames']) : '';
            $lines[] = array($headerCol, $dataCol);
            $headerCol = $GLOBALS['LANG']->getLL('extInfoArray_class_names');
            $headerCol = t3lib_BEfunc::wrapInHelp($this->descrTable, 'emconf_classNames', $headerCol);
            $dataCol = is_array($techInfo['classes']) ? implode('<br />', $techInfo['classes']) : '';
            $lines[] = array($headerCol, $dataCol);
            $currentMd5Array = $this->serverExtensionMD5array($extKey, $extInfo);
            $msgLines = array();
            if (strcmp($extInfo['EM_CONF']['_md5_values_when_last_written'], serialize($currentMd5Array))) {
                $msgLines[] = tx_em_Tools::rfw('<br /><strong>' . $GLOBALS['LANG']->getLL('extInfoArray_difference_detected') . '</strong>');
                $affectedFiles = tx_em_Tools::findMD5ArrayDiff($currentMd5Array, unserialize($extInfo['EM_CONF']['_md5_values_when_last_written']));
                if (count($affectedFiles)) {
                    $msgLines[] = '<br /><strong>' . $GLOBALS['LANG']->getLL('extInfoArray_modified_files') . '</strong><br />' . tx_em_Tools::rfw(implode('<br />', $affectedFiles));
                }
            }
            $headerCol = $GLOBALS['LANG']->getLL('extInfoArray_files_changed');
            $headerCol = t3lib_BEfunc::wrapInHelp($this->descrTable, 'emconf_filesChanged', $headerCol);
            $dataCol = implode('<br />', $msgLines);
            $lines[] = array($headerCol, $dataCol);
        }
        $output = '';
        foreach ($lines as $cols) {
            // if it's just one line, we assume it's a headline,
            // thus no need to wrap it in HTML table tags
            if (count($cols) == 1) {
                $output .= $cols[0];
            } else {
                $output .= '
					<tr class="bgColor4">
						<td>' . $cols[0] . '</td>
						<td>' . $cols[1] . '</td>
					</tr>';
            }
        }
        return '<table border="0" cellpadding="1" cellspacing="2">
					' . $output . '
				</table>';
    }