Fixed bug 529 (TSconfig_help)
authorSebastian Kurfürst <sebastian.kurfuerst@typo3.org>
Wed, 14 Nov 2007 07:33:22 +0000 (07:33 +0000)
committerSebastian Kurfürst <sebastian.kurfuerst@typo3.org>
Wed, 14 Nov 2007 07:33:22 +0000 (07:33 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@2697 709f56b5-9817-0410-a4d7-c38de5d9e867

ChangeLog
typo3/sysext/tsconfig_help/ext_emconf.php
typo3/sysext/tsconfig_help/ext_tables.php [new file with mode: 0644]
typo3/sysext/tsconfig_help/ext_tables.sql
typo3/sysext/tsconfig_help/mod1/conf.php [new file with mode: 0644]
typo3/sysext/tsconfig_help/mod1/index.php [new file with mode: 0644]
typo3/sysext/tsconfig_help/mod1/locallang.xml [new file with mode: 0644]
typo3/sysext/tsconfig_help/mod1/locallang_mod.xml [new file with mode: 0644]

index af44b12..caad36b 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2007-11-14  Sebastian Kurfuerst  <sebastian@typo3.org>
+
+       * Fixed feature #529: update inline TypoScript help (Thanks to Francois Suter)
+
 2007-11-14  Benjamin Mack  <mack@xnos.org>
 
        * (feature) Fixed #6625: Cleaner Backend / HCI: Make "alt_doc" header fixed
index 9419243..be4be74 100755 (executable)
@@ -3,40 +3,44 @@
 ########################################################################
 # Extension Manager/Repository config file for ext: "tsconfig_help"
 #
-# Auto generated 16-11-2004 17:18
+# Auto generated 08-11-2007 21:34
 #
 # Manual updates:
-# Only the data in the array - anything else is removed by next write
+# Only the data in the array - anything else is removed by next write.
+# "version" and "dependencies" must not be touched!
 ########################################################################
 
-$EM_CONF[$_EXTKEY] = Array (
+$EM_CONF[$_EXTKEY] = array(
        'title' => 'TSConfig / TypoScript Object Reference',
        'description' => 'Object reference for TSref, Page TSconfig and User TSconfig which is enabled by the TS icon close to the TSconfig field.',
        'category' => 'be',
+       'author' => 'Stephane Schitter',
+       'author_email' => 'stephane.schitter@free.fr',
        'shy' => 1,
-       'dependencies' => '',
+       'dependencies' => 'cms',
        'conflicts' => '',
        'priority' => '',
-       'loadOrder' => '',
-       'TYPO3_version' => '3.7.0-',
-       'PHP_version' => '-',
-       'module' => '',
-       'state' => 'stable',
+       'module' => 'mod1',
+       'state' => 'beta',
        'internal' => 1,
        'uploadfolder' => 0,
        'createDirs' => '',
        'modify_tables' => '',
        'clearCacheOnLoad' => 0,
-       'lockType' => '',
-       'author' => 'Kasper Skårhøj',
-       'author_email' => 'kasperYYYY@typo3.com',
-       'author_company' => 'Curby Soft Multimedia',
-       'CGLcompliance' => '',
-       'CGLcompliance_note' => '',
-       'private' => 0,
-       'download_password' => '',
-       'version' => '1.2.0',   // Don't modify this! Managed automatically during upload to repository.
-       '_md5_values_when_last_written' => 'a:10:{s:12:"ext_icon.gif";s:4:"bdd9";s:14:"ext_tables.sql";s:4:"70f9";s:25:"ext_tables_static+adt.sql";s:4:"436b";s:11:"CVS/Entries";s:4:"253d";s:14:"CVS/Repository";s:4:"a058";s:8:"CVS/Root";s:4:"0ea2";s:12:"doc/TODO.txt";s:4:"cfc6";s:15:"doc/CVS/Entries";s:4:"fb2f";s:18:"doc/CVS/Repository";s:4:"135d";s:12:"doc/CVS/Root";s:4:"0ea2";}',
-);
+       'author_company' => '',
+       'version' => '1.0.0',
+       'constraints' => array(
+               'depends' => array(
+                       'cms' => '',
+               ),
+               'conflicts' => array(
+               ),
+               'suggests' => array(
+               ),
+       ),
+       '_md5_values_when_last_written' => 'a:14:{s:9:"ChangeLog";s:4:"c251";s:10:"README.txt";s:4:"ee2d";s:12:"ext_icon.gif";s:4:"bdd9";s:14:"ext_tables.php";s:4:"1592";s:14:"ext_tables.sql";s:4:"fbdf";s:19:"doc/wizard_form.dat";s:4:"af41";s:20:"doc/wizard_form.html";s:4:"8a54";s:14:"mod1/clear.gif";s:4:"cc11";s:13:"mod1/conf.php";s:4:"9d75";s:14:"mod1/index.php";s:4:"8dbb";s:18:"mod1/locallang.xml";s:4:"247f";s:22:"mod1/locallang_mod.xml";s:4:"1b64";s:19:"mod1/moduleicon.gif";s:4:"8074";s:13:"mod1/test.php";s:4:"c35a";}',
+       'suggests' => array(
+       ),
+  );
 
 ?>
\ No newline at end of file
diff --git a/typo3/sysext/tsconfig_help/ext_tables.php b/typo3/sysext/tsconfig_help/ext_tables.php
new file mode 100644 (file)
index 0000000..c0859f0
--- /dev/null
@@ -0,0 +1,16 @@
+<?php
+if (!defined ('TYPO3_MODE'))   die ('Access denied.');
+
+if (TYPO3_MODE == 'BE')        {
+               
+       t3lib_extMgm::addModule('help','txtsconfighelpM1','',t3lib_extMgm::extPath($_EXTKEY).'mod1/');
+}
+?>
+<?php
+if (!defined ('TYPO3_MODE'))   die ('Access denied.');
+
+if (TYPO3_MODE == 'BE')        {
+               
+       t3lib_extMgm::addModule('help','txtsconfighelpM1','',t3lib_extMgm::extPath($_EXTKEY).'mod1/');
+}
+?>
\ No newline at end of file
index 9c3070c..a795e9e 100755 (executable)
@@ -6,10 +6,9 @@ CREATE TABLE static_tsconfig_help (
   guide int(11) DEFAULT '0' NOT NULL,
   md5hash varchar(32) DEFAULT '' NOT NULL,
   description text NOT NULL,
-  obj_string varchar(255) DEFAULT '' NOT NULL,
-  appdata blob NOT NULL,
-  title varchar(255) DEFAULT '' NOT NULL,
-
+  obj_string tinytext NOT NULL,
+  appdata mediumblob NOT NULL,
+  title tinytext NOT NULL,
   PRIMARY KEY (uid),
   KEY guide (guide,md5hash)
 );
diff --git a/typo3/sysext/tsconfig_help/mod1/conf.php b/typo3/sysext/tsconfig_help/mod1/conf.php
new file mode 100644 (file)
index 0000000..39998c1
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+define('TYPO3_MOD_PATH', 'sysext/tsconfig_help/mod1/');
+$BACK_PATH='../../../';
+$MCONF['name']='help_txtsconfighelpM1';
+
+       
+$MCONF['access']='user,group';
+$MCONF['script']='index.php';
+
+$MLANG['default']['tabs_images']['tab'] = 'moduleicon.gif';
+$MLANG['default']['ll_ref']='LLL:EXT:tsconfig_help/mod1/locallang_mod.xml';
+?>
+<?php
+define('TYPO3_MOD_PATH', 'sysext/tsconfig_help/mod1/');
+$BACK_PATH='../../../';
+$MCONF['name']='help_txtsconfighelpM1';
+
+       
+$MCONF['access']='user,group';
+$MCONF['script']='index.php';
+
+$MLANG['default']['tabs_images']['tab'] = 'moduleicon.gif';
+$MLANG['default']['ll_ref']='LLL:EXT:tsconfig_help/mod1/locallang_mod.xml';
+?>
\ No newline at end of file
diff --git a/typo3/sysext/tsconfig_help/mod1/index.php b/typo3/sysext/tsconfig_help/mod1/index.php
new file mode 100644 (file)
index 0000000..08c8053
--- /dev/null
@@ -0,0 +1,1558 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2007 Stephane Schitter <stephane.schitter@free.fr>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+
+// DEFAULT initialization of a module [BEGIN]
+unset($MCONF);
+require_once('conf.php');
+require_once($BACK_PATH.'init.php');
+require_once($BACK_PATH.'template.php');
+require_once($BACK_PATH.'mod/tools/em/class.em_unzip.php');
+
+$LANG->includeLLFile('EXT:tsconfig_help/mod1/locallang.xml');
+require_once(PATH_t3lib.'class.t3lib_scbase.php');
+$BE_USER->modAccess($MCONF,1); // This checks permissions and exits if the users has no permission for entry.
+// DEFAULT initialization of a module [END]
+
+
+/**
+ * Module 'TypoScript Help' for the 'tsconfig_help' extension.
+ *
+ * @author     Stephane Schitter <stephane.schitter@free.fr>
+ * @package    TYPO3
+ * @subpackage tx_tsconfighelp
+ */
+class  tx_tsconfighelp_module1 extends t3lib_SCbase {
+       var $pageinfo;
+       var $objStringsPerExtension = array(); // This is used to count how many times the same obj_string appears in each extension manual
+       var $allObjStrings = array(); // This is used to count how many times the same obj_string appears across all extensions
+
+       /**
+        * Initializes the Module
+        * @return      void
+        */
+       function init() {
+               global $BE_USER,$LANG,$BACK_PATH,$TCA_DESCR,$TCA,$CLIENT,$TYPO3_CONF_VARS;
+               parent::init();
+       }
+
+       /**
+        * Adds items to the ->MOD_MENU array. Used for the function menu selector.
+        *
+        * @return      void
+        */
+       function menuConfig()   {
+               global $LANG;
+               $this->MOD_MENU = array(
+                       'function' => array(
+                               '1' => $LANG->getLL('display')
+                       )
+               );
+
+               if($GLOBALS['BE_USER']->user['admin'])  {
+                       $this->MOD_MENU['function']['2'] = $LANG->getLL('rebuild');
+               }
+               
+               parent::menuConfig();
+       }
+
+       /**
+        * Main function of the module. Write the content to $this->content
+        *
+        * @return      void
+        */
+       function main() {
+               global $BE_USER,$LANG,$BACK_PATH,$TCA_DESCR,$TCA,$CLIENT,$TYPO3_CONF_VARS;
+
+               // Access check!
+               // The page will show only if there is a valid page and if this page may be viewed by the user
+               $this->pageinfo = t3lib_BEfunc::readPageAccess($this->id,$this->perms_clause);
+               $access = is_array($this->pageinfo) ? 1 : 0;
+
+               if (($this->id && $access) || ($BE_USER->user['admin'] && !$this->id))  {
+
+                               // Draw the header.
+                       $this->doc = t3lib_div::makeInstance('mediumDoc');
+                       $this->doc->backPath = $BACK_PATH;
+                       $this->doc->docType = 'xhtml_trans';
+                       $this->doc->form = '<form action="" method="POST">';
+
+                               // JavaScript
+                       $this->doc->JScode = '
+                               <script language="javascript" type="text/javascript">
+                                       script_ended = 0;
+                                       function jumpToUrl(URL) {
+                                               document.location = URL;
+                                       }
+                               </script>
+                       ';
+                       $this->doc->postCode = '
+                               <script language="javascript" type="text/javascript">
+                                       script_ended = 1;
+                                       if (top.fsMod) top.fsMod.recentIds["web"] = 0;
+                               </script>
+                       ';
+
+                       $headerSection = $this->doc->getHeader('pages',$this->pageinfo,$this->pageinfo['_thePath']).'<br />'.$LANG->sL('LLL:EXT:lang/locallang_core.xml:labels.path').': '.t3lib_div::fixed_lgd_pre($this->pageinfo['_thePath'],50);
+
+                       $this->content .= $this->doc->startPage($LANG->getLL('title'));
+                       $this->content .= $this->doc->header($LANG->getLL('title'));
+                       $this->content .= $this->doc->spacer(5);
+                       $this->content .= $this->doc->section('',$this->doc->funcMenu($headerSection,t3lib_BEfunc::getFuncMenu($this->id,'SET[function]',$this->MOD_SETTINGS['function'],$this->MOD_MENU['function'])));
+                       $this->content .= $this->doc->divider(5);
+
+                       // Render content:
+                       $this->moduleContent();
+
+                       // ShortCut
+                       if ($BE_USER->mayMakeShortcut())        {
+                               $this->content .= $this->doc->spacer(20).$this->doc->section('',$this->doc->makeShortcutIcon('id',implode(',',array_keys($this->MOD_MENU)),$this->MCONF['name']));
+                       }
+
+                       $this->content .= $this->doc->spacer(10);
+               } else {
+                               // If no access or if ID == zero
+                       $this->doc = t3lib_div::makeInstance('mediumDoc');
+                       $this->doc->backPath = $BACK_PATH;
+
+                       $this->content .= $this->doc->startPage($LANG->getLL('title'));
+                       $this->content .= $this->doc->header($LANG->getLL('title'));
+                       $this->content .= $this->doc->spacer(5);
+                       $this->content .= $this->doc->spacer(10);
+               }
+       }
+
+       /**
+        * Prints out the module HTML
+        *
+        * @return      void
+        */
+       function printContent() {
+               $this->content .= $this->doc->endPage();
+               echo $this->content;
+       }
+
+       /**
+        * Generates the module content
+        *
+        * @return      void
+        */
+       function moduleContent()        {
+               global $BACK_PATH, $TYPO3_LOADED_EXT, $LANG;
+
+               switch ((string)$this->MOD_SETTINGS['function'])        {
+                       case 1:
+                               $content = '<div align="left"><strong>'.$LANG->getLL('referenceExplanation').'</strong></div>';
+                               $content .= '<p>'.$LANG->getLL('referenceExplanationDetailed').'</p><br />';
+                               $this->content .= $this->doc->section($LANG->getLL('displayReferences'),$content,0,1);
+                               $this->content .= '<a href="#" onClick="vHWin=window.open(\''.$BACK_PATH.'wizard_tsconfig.php?mode=tsref&P[formName]=editForm\',\'popUp\',\'height=500,width=780,status=0,menubar=0,scrollbars=1\');vHWin.focus();return false;"><img  src="'.$BACK_PATH.'sysext/t3skin/icons/gfx/wizard_tsconfig.gif" width="22" height="27" width="22" height="27" border="0" title="TSref reference"> TSREF</a><br />';
+                               $this->content .= '<a href="#" onClick="vHWin=window.open(\''.$BACK_PATH.'wizard_tsconfig.php?mode=beuser&P[formName]=editForm\',\'popUp\',\'height=500,width=780,status=0,menubar=0,scrollbars=1\');vHWin.focus();return false;"><img  src="'.$BACK_PATH.'sysext/t3skin/icons/gfx/wizard_tsconfig.gif" width="22" height="27" width="22" height="27" border="0" title="TSref reference"> USER TSCONFIG</a><br />';
+                               $this->content .= '<a href="#" onClick="vHWin=window.open(\''.$BACK_PATH.'wizard_tsconfig.php?mode=page&P[formName]=editForm\',\'popUp\',\'height=500,width=780,status=0,menubar=0,scrollbars=1\');vHWin.focus();return false;"><img  src="'.$BACK_PATH.'sysext/t3skin/icons/gfx/wizard_tsconfig.gif" width="22" height="27" width="22" height="27" border="0" title="TSref reference"> PAGE TSCONFIG</a><br />';
+                       break;
+
+                       case 2:
+                               if ($GLOBALS['BE_USER']->user['admin']) {
+                                       if (t3lib_div::_GP('_rebuild')) {
+                                                       // remove all data from the database
+                                               $this->purgeSQLContents();
+       
+                                                       // get all loaded extension keys
+                                               $extArray = $TYPO3_LOADED_EXT;
+       
+                                               $content = '<div align="left"><strong>'.$LANG->getLL('loadedTSfrom').'</strong></div><br />';
+       
+                                                       // parse the extension names only (no need for all details from the TYPO3_LOADED_EXT table
+                                               foreach ($extArray as $extName => $dummy)       {
+                                                               // check that the extension is really loaded (which should always be the case)
+                                                       if (t3lib_extMgm::isLoaded($extName))   {
+                                                                       // extract the content.xml from the manual.sxw ZIP file
+                                                               $manual = $this->getZIPFileContents(t3lib_extMgm::extPath($extName).'doc/manual.sxw', 'content.xml');
+       
+                                                                       // check if the manual file actually exists and if the content.xml could be loaded
+                                                               if ($manual != '')      {
+                                                                               // if the manual file exists, proceed with the load into the SQL database
+                                                                       $content .= '<p>Extension '.$extName.'...';
+       
+                                                                               // run the extraction processing and import the data into SQL. Return the number of TS tables found in the open office doucment
+                                                                       $number = $this->loadExtensionManual($extName, $manual);
+       
+                                                                               // print a status message with a link to the openoffice manual
+                                                                       $content .= $number.' '.$LANG->getLL('sections').' (<a href="'.t3lib_div::getIndpEnv('TYPO3_SITE_URL').TYPO3_mainDir.t3lib_extMgm::extRelPath($extName).'doc/manual.sxw">manual</a>)</p>';
+                                                               }
+                                                       } else  {
+                                                                       // this should never happen!
+                                                               die ("Fatal error : loaded extension not actually loaded? Please file a bug report at http://bugs.typo3.org!");
+                                                       }
+                                               }
+                                               
+                                               $this->content .= $this->doc->section($LANG->getLL('rebuildTS'),$content.'<br />',0,1);
+
+                                                       // Issue warnings about duplicate or empty obj_strings, if any
+                                                       // An obj_string should be unique. It should appear in only one extension manual and then only once
+                                                       // If the sum of all occurrences of a given obj_string is more than one, issue a list of duplicate entries as a warning
+                                               $duplicateWarnings = '';
+                                               $emptyWarnings = '';
+                                               foreach ($this->objStringsPerExtension as $obj_string => $extensions)   {
+                                                       if (empty($obj_string)) {
+                                                               $emptyWarnings = '<p class="typo3-red">'.$LANG->getLL('warning_manualsWithoutMarkers');
+                                                               foreach ($extensions as $extensionKey => $counter)      {
+                                                                       $emptyWarnings .= ' '.$extensionKey.' ('.$counter.')<br />';
+                                                               }
+                                                               $emptyWarnings .= '</p><br />';
+                                                       } else {
+                                                               if (array_sum($extensions) > 1) {
+                                                                       $duplicateWarnings .= $obj_string.':';
+                                                                       foreach ($extensions as $extensionKey => $counter)      {
+                                                                               $duplicateWarnings .= ' '.$extensionKey.' ('.$counter.')';
+                                                                       }
+                                                                       $duplicateWarnings .= '<br />';
+                                                               }
+                                                       }
+                                               }
+                                               $warnings = $emptyWarnings;
+                                               if (!empty($duplicateWarnings)) {
+                                                       $warnings .= '<p class="typo3-red">'.$LANG->getLL('warning_duplicateMarkers').'<br />'.$duplicateWarnings.'</p>';
+                                               }
+                                               if (!empty($warnings))  {
+                                                       $this->content .= $this->doc->section($LANG->getLL('updateWarnings'),'<div>'.$warnings.'</div>',0,1);
+                                               }
+                                       }
+       
+                                       $content = '<p>'.$LANG->getLL('rebuildExplanation').'</p><br />';
+                                       $content .= $LANG->getLL('rebuild').' <input type="submit" name="_rebuild" value="Rebuild" /><br />';
+                                       $this->content .= $this->doc->section($LANG->getLL('rebuildTS'),$content,0,1);
+                               } else {
+                                               $this->content .= 'Access to this function of the module is restricted to admins.';                     
+                               }
+
+
+                       break;
+               }
+       }
+
+       /**
+        * Returns the contents of a specific file within the ZIP
+        *
+        * @return      string  contents
+        */
+       function getZIPFileContents($ZIPfile, $filename)        {
+               if (@file_exists($ZIPfile))     {
+                               // Unzipping SXW file, getting filelist:
+                       $tempPath = PATH_site.'typo3temp/tx_tsconfighelp_ziptemp/';
+                       t3lib_div::mkdir($tempPath);
+
+                       $this->unzip($ZIPfile, $tempPath);
+                       $output = t3lib_div::getURL($tempPath.$filename);
+
+                       $cmd = 'rm -r "'.$tempPath.'"';
+                       exec($cmd);
+
+                       return $output;
+               }
+       }
+
+       /**
+        * Unzips a zip file in the given path.
+        * Uses the Extension Manager unzip functions.
+        *
+        *
+        * @param string $file          Full path to zip file
+        * @param string $path          Path to change to before extracting
+        * @return boolean      True on success, false in failure
+        */
+       function unzip($file, $path)    {
+                       // we use the unzip class of the Extension Manager here
+               $className = t3lib_div::makeInstanceClassName('em_unzip');
+               $unzip = new $className($file);
+               $ret = $unzip->extract(array('add_path'=>$path));
+               return (is_array($ret));
+       }
+
+       /**
+        * Parses the whole XML file in order to understand the Styles structure. This function is mostly looking at the styles
+        * that create bold or italic characters in the document, as these will later on need to be translated to <i> and <b> tags
+        * This function takes into account the hierarchy of the styles, as created by OpenOffice. This means that if a style has
+        * a parant, this function will make it inherit the styles of the parent. Therefore bold and italic styles are propagated
+        * to children as well.
+        *
+        * This function assumes the STYLE definitions are not nested. If they are then, then "close" type will need to be used
+        * more carefully, and a depth counter will need to be implemented.
+        *
+        * @param       array           The XML values array. The XML index is not necessary in this function.
+        * @return      array           Array that contains the different styles with their parent (required to recognise "Table Contents"-type styles), and their style (bold/italic)
+        */
+       function parseStyles($vals)     {
+               $currentStyleName = '';
+               $style = array ();
+
+               foreach ($vals as $node)        {
+                       switch ($node['type'])  {
+                               case 'open':
+                                       switch ($node['tag'])   {
+                                               case 'STYLE:STYLE':
+                                                       $currentStyleName = $node['attributes']['STYLE:NAME'];
+
+                                                       if (array_key_exists('STYLE:PARENT-STYLE-NAME',$node['attributes']))    {
+                                                               $parentStyleName = $node['attributes']['STYLE:PARENT-STYLE-NAME'];
+                                                               $style[$currentStyleName]['parents'][] = $parentStyleName; // keep trace of parents in the style array
+                                                       } else {
+                                                               $parentStyleName = ''; // this style has no parent, therefore clean the variable to avoid side effects with next use of that variable
+                                                       }
+
+                                                       if (array_key_exists($parentStyleName, $style)) { // the style parent is already documented in the array
+                                                               $style[$currentStyleName] = $style[$parentStyleName]; // inherit parent style
+                                                       }
+                                               break;
+                                       }
+                               break;
+
+                               case 'complete':
+                                       switch ($node['tag'])   {
+                                               case 'STYLE:PROPERTIES':
+                                                       if (is_array($node['attributes']) && array_key_exists('FO:FONT-WEIGHT',$node['attributes']))    {
+                                                               $style[$currentStyleName]['font-weight'] = $node['attributes']['FO:FONT-WEIGHT'];       // bold for example
+                                                       }
+                                                       if (is_array($node['attributes']) && array_key_exists('FO:FONT-STYLE',$node['attributes']))     {
+                                                               $style[$currentStyleName]['font-style'] = $node['attributes']['FO:FONT-STYLE']; // italic for example
+                                                       }
+                                               break;
+                                       }
+                               break;
+
+                               case 'close':
+                                       switch ($node['tag'])   {
+                                               case 'STYLE:STYLE':
+                                                       $currentStyleName = '';
+                                               break;
+                                               case 'STYLE:PROPERTIES':
+                                               break;
+                                       }
+                               break;
+                       }
+               }
+
+               return $style;
+       }
+
+
+       /**
+        * Checks if the style is a child of a specified parent. This is useful for example to check if a specific style that has
+        * a generic name ("P8" for example) is a child of the "Table Contents" style. It would not only inherit its style (bold/
+        * italic) but also its properties like being part of a Table.
+        *
+        * This function references the global $Styles variables which must have been created previously with parseStyles()
+        *
+        * @param       string          Name of the child style that we want to get properties for
+        * @param       string          Name of the parent style that we want to compare the child against
+        * @return      boolean         true if the child and parent are linked together. false otherwise.
+        */
+       function isStyleChildOf($child, $parent) {
+               global $Styles;
+
+               if (!strcmp($child, $parent))   { // the child is actually the same as the parent. They are obviously linked together
+                       return TRUE;
+               }
+
+               if (is_array($Styles[$child])  // the child is a documented style
+                && array_key_exists('parents',$Styles[$child])  // it has some parents
+                && (array_search($parent, $Styles[$child]['parents']) !== FALSE))      { // and the parent appears amongst its ancestors
+                       return TRUE;
+               }
+               return FALSE;
+       }
+
+       /**
+        * Find the table description that we want, then find a TABLE:TABLE close, immediately followed by a TEXT:P which has a
+        * style which is a child of a "Table Contents", then look up the index to find where the TABLE begins, and start browsing
+        * from there (returns these start and end indexes).
+        *
+        * This function only finds the next TS definition table. In order to find all TS definition tables from the document, the
+        * function needs to be called several times, starting where it left off last time. The third parameter is the index that
+        * is used to indicate where to start, and which is modified when the function returns to indicate where we left off.
+        *
+        * This function uses the unusual index XML array in addition to the values, this is necessary to find where in the XML
+        * tree a TABLE starts once we found where it ends.
+        *
+        * @param       array           The XML values array
+        * @param       array           The XML index array
+        * @param       integer         This is a reference to the index in the array where we should be starting the search
+        * @return      array           Array of the table start index and table end index where TS is defined. table start is FALSE if there are no more TS entries in the document (consider it similar to an EOF reached status).
+        */
+       function nextTSDefinitionTable($vals, $index, &$id)     {
+                       // browse the table where we left off last time
+               while ($id < count ($vals))     {
+                       $node = $vals[$id];
+                       if (!strcmp($node['type'], 'close') && !strcmp($node['tag'], 'TABLE:TABLE'))    { // check if next entry is a candidate
+                               $nextNode = $vals[$id+1];
+                               if (!strcmp($nextNode['tag'], 'TEXT:P') && $this->isStyleChildOf($nextNode['attributes']['TEXT:STYLE-NAME'], 'Table Contents')) {
+                                               // we found a good entry
+                                       $closeIndex = array_search($id, $index['TABLE:TABLE']); // find the ID in the list of table items
+
+                                       $tableStart = $index['TABLE:TABLE'][$closeIndex-1]; // find the matching start of the table in the $vals array
+
+                                       return array($tableStart, $id++);
+                               }
+                       }
+                       $id = $id+1;
+               }
+               return array(FALSE, 0); // marks the end of the input, no more table to find. WARNING: needs to be tested with === FALSE
+       }
+
+       /**
+        * Converts an Open Office like style (font-weight:bold for example) into an HTML style (b is for bold). This function uses the global
+        * $Styles defined through the parseStyles function
+        *
+        * @param       array           an array containing the [attributes][style] items in the OO format
+        * @return      array           an array where the items are all the HTML styles to apply to closely match the input OO-like styles
+        */
+       function styleTags($node)       {
+               global $Styles;
+
+               $styleName = $node['attributes']['TEXT:STYLE-NAME'];
+               switch ($Styles[$styleName]['font-weight'])     {
+                       case 'bold':
+                               $styleTags[] = 'b';
+                       break;
+               }
+               switch ($Styles[$styleName]['font-style'])      {
+                       case 'italic':
+                               $styleTags[] = 'i';
+                       break;
+               }
+               if (!strcmp($styleName,'Table Contents/PRE'))   {
+                       //$styleTags[]='pre'; // unused yet, but could be <pre> in the future - this is for inline code in the manuals
+               }
+               return $styleTags;
+       }
+
+       /**
+        * Converts an array containing style strings (for example ['b','i']) into their HTML equivalents
+        *
+        * @param       array           an array containing all the style tags
+        * @param       string          either '' or '/' depending on whether the style definition is to open or close the style
+        * @return      string          the sequence of tags to open or close the style, for example <b><i>
+        */
+       function styleHTML($style, $char)       {
+               $string = '';
+               if (count ($style) > 0) {
+                       foreach ($style as $tag)        {
+                               $string .= '<'.$char.$tag.'>';
+                       }
+               }
+               return $string;
+       }
+
+       /**
+        * This function does a little more than just HSC'ing the text passed to it. It does a general cleaning of the input:
+        * htmlspecialchars() : general cleaning for the HTML display, including single quotes transformation
+        * stripslashes() : otherwise the backslashes will cause an issue with a future unserialize of the data
+        * &nbsp if empty : if the input is empty, we return a &nbsp; string so that in the HTML output something will be       displayed
+        * utf8 to entities cleaning : in some SXW docs we can find UTF8 characters that need to be converted to be displayed on screen
+        *
+        * @param       string          Text that will need to be transformed according to the HSC and other rules
+        * @return      string          Transformed text that can now be freely serialized or exported to HTML
+        */
+       function HSCtext($text) {
+               global $LANG;
+
+               if (strcmp($text,''))   { // there is some content in the text field
+                       $cleantext = stripslashes(htmlspecialchars($text, ENT_QUOTES)); // stripslashes required as it could confuse unserialize
+                       return $LANG->csConvObj->utf8_to_entities($cleantext, $LANG->charSet);
+               } else { // there is no text, it's empty
+                       return '&nbsp;';
+               }
+       }
+
+       /**
+        * This function parses a Table from an Open Office document, in an XML format, and extracts the information. It will therefore crawl the
+        * XML tree and aggregate all the accepted contents into an array with the table contents.
+        *
+        * This function needs to extract the following information from the TABLE:
+        *   property => (column 1)
+        *   datatype => (column 2)
+        *   description => (column 3)
+        *   default => (column 4)
+        *   column_count => number of columns found in table. Usually 4, but for spanned columns, it would be less (1 for example)
+        *   is_propertyTable => ??? (almost always equal to 1)
+        *
+        * @param       array           This is the input XML data that is to be parsed
+        * @param       integer         The starting ID in the XML array to parse the data from
+        * @param       integer         The ending ID in the XML array to stop parsing data
+        * @return      array           An array with the contents of the different columns extracted from the input data
+        */
+       function parseTable($vals, $start, $end) {
+               $sectionHeader = 0;
+               $sectionRow = 0;
+               $sectionCell = 0;
+               $sectionP = 0;
+
+               $newLineRequired = ''; // this variable will either be empty (no newline required) or '\n' (newline required)
+               $textStyle = array (); // this will be the list of tag styles to apply to the text
+
+               $currentRow = 0;
+               $currentCell = 0;
+
+               $rowID = 0;
+               $cellID = 0;  // also gets reset at every top-level row
+
+               $table = array(); // will contain the results of the function
+
+               $id = $start;
+               while ($id < $end)      {
+                       $node = $vals[$id];
+
+                       // sanity check
+                       if ($sectionHeader < 0) die ('Malformed XML (header-rows)'."\n");
+                       if ($sectionRow < 0)    die ('Malformed XML (row)'."\n");
+                       if ($sectionCell < 0)   die ('Malformed XML (cell)'."\n");
+                       if ($sectionP < 0)              die ('Malformed XML (P)'."\n");
+
+                       switch ($node['type'])  {
+                               case 'open':
+                                       switch ($node['tag'])   {
+                                               case 'TABLE:TABLE-HEADER-ROWS':
+                                                       $sectionHeader++;
+                                               break;
+                                               
+                                               case 'TABLE:TABLE-ROW':
+                                                       if (!$sectionHeader)    { // skip section header, we only look at the *contents* of the table
+                                                               $sectionRow++;
+                                                               if ($sectionRow == 1)   { // make sure we are within a top-level row
+                                                                       $rowID++;
+                                                                       $cellID = 0;
+                                                               }
+                                                       }
+                                               break;
+                                               
+                                               case 'TABLE:TABLE-CELL':
+                                                       if (!$sectionHeader)    { // skip section header, we only look at the *contents* of the table
+                                                               $sectionCell++;
+                                                               if ($sectionCell == 1)  { // make sure we are within a top-level cell
+                                                                       $cellID++;
+                                                                       $newLineRequired = ''; // no newline required after this
+                                                               }
+                                                       }
+                                               break;
+                                               
+                                               case 'TEXT:P':
+                                                       if ($sectionCell)       { // make sure we are in a cell
+                                                               $sectionP++;
+                                                               $table[$rowID-1][$cellID-1] .= $this->styleHTML($this->styleTags($node),'') . $newLineRequired.$this->HSCtext($node['value']);
+                                                               $newLineRequired = ''; // no newline required after this
+                                                               $latestTEXTPopen = $node;
+                                                       }
+                                               break;
+                                       }
+                               break;
+
+                               case 'complete':
+                                       switch ($node['tag'])   {
+                                               case 'TEXT:P':
+                                                       if ($sectionCell)       { // make sure we are in a cell
+                                                               $table[$rowID-1][$cellID-1] .= $this->styleHTML($this->styleTags($node),'') . $newLineRequired.$this->HSCtext($node['value']).$this->styleHTML($this->styleTags($node),'/');
+                                                               $newLineRequired = '<br>'; // after a paragraph, require a new-line
+                                                       }
+                                               break;
+                                               
+                                               case 'TEXT:SPAN':
+                                                       if ($sectionCell)       { // make sure we are in a cell
+                                                               $table[$rowID-1][$cellID-1] .= $this->styleHTML($this->styleTags($node),'').$newLineRequired.$this->HSCtext($node['value']).$this->styleHTML($this->styleTags($node),'/');
+                                                               $newLineRequired = ''; // no newline required after this
+                                                       }
+                                               break;
+                                               
+                                               case 'TEXT:S':
+                                                       if ($sectionCell)       { // make sure we are in a cell
+                                                               for ($i=0; $i<$node['attributes']['TEXT:C']; $i++)      {
+                                                                       $table[$rowID-1][$cellID-1] .= '&nbsp;';
+                                                               }
+                                                               $newLineRequired = ''; // no newline required after this
+                                                       }
+                                               break;
+                                       }
+                               break;
+
+                               case 'cdata':
+                                       switch ($node['tag'])   {
+                                               case 'TEXT:P':
+                                                       if ($sectionCell)       { // make sure we are in a cell
+                                                               $table[$rowID-1][$cellID-1] .= $this->styleHTML($this->styleTags($node),'') . $newLineRequired.$this->HSCtext($node['value']).$this->styleHTML($this->styleTags($node),'/');
+                                                               $newLineRequired = ''; // no newline required after this
+                                                       }
+                                               break;
+                                       }
+                               break;
+
+                               case 'close':
+                                       switch ($node['tag'])   {
+                                               case 'TABLE:TABLE-HEADER-ROWS':
+                                                       $sectionHeader--;
+                                               break;
+                                               
+                                               case 'TABLE:TABLE-ROW':
+                                                       if (!$sectionHeader)    { // skip section header, we only look at the *contents* of the table
+                                                               $sectionRow--;
+                                                       }
+                                               break;
+                                               
+                                               case 'TABLE:TABLE-CELL':
+                                                       if (!$sectionHeader)    { // skip section header, we only look at the *contents* of the table
+                                                               $sectionCell--;
+                                                       }
+                                               break;
+                                               
+                                               case 'TEXT:P':
+                                                       $sectionP--;
+                                                       $newLineRequired = '<br>'; // after a paragraph, require a new-line
+                                                       $table[$rowID-1][$cellID-1] .= $this->styleHTML($this->styleTags($latestTEXTPopen),'/');
+                                               break;
+                                       }
+                               break;
+                       }
+                       $id = $id+1;
+               }
+               return $table;
+       }
+
+       /**
+        * Load the contents of the table into the SQL database
+        *
+        * @param       string          Name of the extension to load the documentation for. This is used to make the unique hash in the database
+        * @param       array           Contents of the documentation table
+        * @param       string          Name of the table from the source document (name at the bottom of the table in OpenOffice)
+        * @return      boolean         TRUE on success and FALSE on failure from the INSERT database query
+        */
+       function dumpIntoSQL($extension, $table, $tableName)    {
+               global $uid;
+
+               foreach ($table as $row)        {
+                       $tempArray = array();
+                       $tempArray['property'] = $row[0];
+
+                       $tempArray['datatype'] = count($row)==2 ? '&nbsp;':$row[1];     // in the case there are only 2 columns, the second one is the description !
+                       $tempArray['description'] = count($row)==2 ? $row[1]:$row[2];  // in the case there are only 2 columns, the second one is the description !
+                       $tempArray['default'] = $row[3];
+                       $tempArray['column_count'] = count($row);
+                       $tempArray['is_propertyTable'] = 1;
+                       $tsHelpArray['rows'][] = $tempArray;
+               }
+               $appdata = serialize($tsHelpArray);
+               $obj_string = trim($tableName, '[]');
+
+               if (isset($this->objStringsPerExtension[$obj_string]))  {
+                       if (isset($this->objStringsPerExtension[$obj_string][$extension]))      {
+                               $this->objStringsPerExtension[$obj_string][$extension]++;
+                       } else {
+                               $this->objStringsPerExtension[$obj_string][$extension] = 1;
+                       }
+               } else {
+                       $this->objStringsPerExtension[$obj_string] = array();
+                       $this->objStringsPerExtension[$obj_string][$extension] = 1;
+               }
+
+                       // If the obj_string was already encountered increase its counter. If not initialise it as 0
+                       // The counter (when bigger than 0) is appended to the obj_string to make it unique
+                       // This way the tables do not overwrite each other in the online help
+               if (isset($this->allObjStrings[$obj_string]))   {
+                       $this->allObjStrings[$obj_string]++;
+                       $obj_string .= ' ('.$this->allObjStrings[$obj_string].')';
+               } else {
+                       $this->allObjStrings[$obj_string] = 0;
+               }
+               $md5hash = md5($obj_string);
+               $description = ''; // unused
+               $guide = hexdec(substr(md5($extension),6,6));  // try to find a way to uniquely identify the source extension and place the identified into the "guide" column
+               $title = ''; // unused
+
+               $insertFields = array(
+                       'guide' => $guide,
+                       'md5hash' => $md5hash,
+                       'description' => $description,
+                       'obj_string' => $obj_string,
+                       'appdata' => $appdata,
+                       'title' => $title
+               );
+
+               return $GLOBALS['TYPO3_DB']->exec_INSERTquery('static_tsconfig_help', $insertFields);
+       }
+
+       /**
+        * Purges the existing contents for TypoScript help in the database. This ensures that several runs of the import process will not push
+        * duplicate information in the database, but that we clean it first before adding new contents.
+        *
+        * @param       string          Name of the extension for which to delete all the data in the database. If empty, all database will be cleaned
+        * @return      void
+        */
+       function purgeSQLContents($extension='')        {
+               $guide = hexdec(substr(md5($extension), 6, 6));
+               if ($extension != '')   {
+                       $GLOBALS['TYPO3_DB']->exec_DELETEquery('static_tsconfig_help', 'guide='.$guide);
+               } else {
+                       $GLOBALS['TYPO3_DB']->exec_DELETEquery('static_tsconfig_help', '');
+               }
+       }
+
+       /**
+        * This is the main function of the loading process. It will first parse the input data and load it into an XML array. It will then find all
+        * the styles associated with the contents so that later on we can distinguish bold and italic characters for example. It then parses the XML
+        * array to find all the TS-like description tables and parses them before loading them into the SQL database.
+        *
+        * @param       string          Name of the extension to load manual from
+        * @param       string          Input data from the manual.sxw in a string form. One large string with the whole OO manual document.
+        * @return      integer         Number of individual tables found in the document and loaded into the SQL database
+        */
+       function loadExtensionManual($extension, $contents)     {
+               global $Styles;
+
+                       // read the contents into an XML array
+               $parser = xml_parser_create();
+               xml_parse_into_struct($parser, $contents, $vals, $index);
+
+               xml_parser_free($parser);
+
+                       // parse styles from the manual for future rendering
+               $Styles = $this->parseStyles($vals);
+
+               $id = 0;
+               $tableNumber = 0;
+               do {
+                       list($tableStart, $tableEnd) = $this->nextTSDefinitionTable($vals, $index, $id);
+                       if ($tableStart !== FALSE)      {
+                                       // The title of the table can either be self-contained in a single complete entry
+                               if (!strcmp($vals[$id]['type'], 'complete'))    {
+                                       $title = $vals[$id]['value'];
+                               } else { // or it can be spread across a number of spans or similar
+                                       $watchTag = $vals[$id]['tag'];
+                                       $title = '';
+                                       while (strcmp($vals[$id]['tag'], $watchTag) || strcmp($vals[$id]['type'], 'close'))     {
+                                               $title .= $vals[$id++]['value'];
+                                       }
+                               }
+                               $tableContents = $this->parseTable($vals, $tableStart, $tableEnd);
+                               $this->dumpIntoSQL($extension, $tableContents, $title);
+                               $tableNumber++;
+                       }
+               } while ($tableStart !== FALSE);
+               return $tableNumber;
+       }
+}
+
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/tsconfig_help/mod1/index.php'])       {
+       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/tsconfig_help/mod1/index.php']);
+}
+
+
+
+
+// Make instance:
+$SOBE = t3lib_div::makeInstance('tx_tsconfighelp_module1');
+$SOBE->init();
+
+// Include files?
+foreach ($SOBE->include_once as $INC_FILE) include_once($INC_FILE);
+
+$SOBE->main();
+$SOBE->printContent();
+
+?>
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2007 Stephane Schitter <stephane.schitter@free.fr>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+
+// DEFAULT initialization of a module [BEGIN]
+unset($MCONF);
+require_once('conf.php');
+require_once($BACK_PATH.'init.php');
+require_once($BACK_PATH.'template.php');
+require_once($BACK_PATH.'mod/tools/em/class.em_unzip.php');
+
+$LANG->includeLLFile('EXT:tsconfig_help/mod1/locallang.xml');
+require_once(PATH_t3lib.'class.t3lib_scbase.php');
+$BE_USER->modAccess($MCONF,1); // This checks permissions and exits if the users has no permission for entry.
+// DEFAULT initialization of a module [END]
+
+
+/**
+ * Module 'TypoScript Help' for the 'tsconfig_help' extension.
+ *
+ * @author     Stephane Schitter <stephane.schitter@free.fr>
+ * @package    TYPO3
+ * @subpackage tx_tsconfighelp
+ */
+class  tx_tsconfighelp_module1 extends t3lib_SCbase {
+       var $pageinfo;
+       var $objStringsPerExtension = array(); // This is used to count how many times the same obj_string appears in each extension manual
+       var $allObjStrings = array(); // This is used to count how many times the same obj_string appears across all extensions
+
+       /**
+        * Initializes the Module
+        * @return      void
+        */
+       function init() {
+               global $BE_USER,$LANG,$BACK_PATH,$TCA_DESCR,$TCA,$CLIENT,$TYPO3_CONF_VARS;
+               parent::init();
+       }
+
+       /**
+        * Adds items to the ->MOD_MENU array. Used for the function menu selector.
+        *
+        * @return      void
+        */
+       function menuConfig()   {
+               global $LANG;
+               $this->MOD_MENU = array(
+                       'function' => array(
+                               '1' => $LANG->getLL('display')
+                       )
+               );
+
+               if($GLOBALS['BE_USER']->user['admin'])  {
+                       $this->MOD_MENU['function']['2'] = $LANG->getLL('rebuild');
+               }
+               
+               parent::menuConfig();
+       }
+
+       /**
+        * Main function of the module. Write the content to $this->content
+        *
+        * @return      void
+        */
+       function main() {
+               global $BE_USER,$LANG,$BACK_PATH,$TCA_DESCR,$TCA,$CLIENT,$TYPO3_CONF_VARS;
+
+               // Access check!
+               // The page will show only if there is a valid page and if this page may be viewed by the user
+               $this->pageinfo = t3lib_BEfunc::readPageAccess($this->id,$this->perms_clause);
+               $access = is_array($this->pageinfo) ? 1 : 0;
+
+               if (($this->id && $access) || ($BE_USER->user['admin'] && !$this->id))  {
+
+                               // Draw the header.
+                       $this->doc = t3lib_div::makeInstance('mediumDoc');
+                       $this->doc->backPath = $BACK_PATH;
+                       $this->doc->docType = 'xhtml_trans';
+                       $this->doc->form = '<form action="" method="POST">';
+
+                               // JavaScript
+                       $this->doc->JScode = '
+                               <script language="javascript" type="text/javascript">
+                                       script_ended = 0;
+                                       function jumpToUrl(URL) {
+                                               document.location = URL;
+                                       }
+                               </script>
+                       ';
+                       $this->doc->postCode = '
+                               <script language="javascript" type="text/javascript">
+                                       script_ended = 1;
+                                       if (top.fsMod) top.fsMod.recentIds["web"] = 0;
+                               </script>
+                       ';
+
+                       $headerSection = $this->doc->getHeader('pages',$this->pageinfo,$this->pageinfo['_thePath']).'<br />'.$LANG->sL('LLL:EXT:lang/locallang_core.xml:labels.path').': '.t3lib_div::fixed_lgd_pre($this->pageinfo['_thePath'],50);
+
+                       $this->content .= $this->doc->startPage($LANG->getLL('title'));
+                       $this->content .= $this->doc->header($LANG->getLL('title'));
+                       $this->content .= $this->doc->spacer(5);
+                       $this->content .= $this->doc->section('',$this->doc->funcMenu($headerSection,t3lib_BEfunc::getFuncMenu($this->id,'SET[function]',$this->MOD_SETTINGS['function'],$this->MOD_MENU['function'])));
+                       $this->content .= $this->doc->divider(5);
+
+                       // Render content:
+                       $this->moduleContent();
+
+                       // ShortCut
+                       if ($BE_USER->mayMakeShortcut())        {
+                               $this->content .= $this->doc->spacer(20).$this->doc->section('',$this->doc->makeShortcutIcon('id',implode(',',array_keys($this->MOD_MENU)),$this->MCONF['name']));
+                       }
+
+                       $this->content .= $this->doc->spacer(10);
+               } else {
+                               // If no access or if ID == zero
+                       $this->doc = t3lib_div::makeInstance('mediumDoc');
+                       $this->doc->backPath = $BACK_PATH;
+
+                       $this->content .= $this->doc->startPage($LANG->getLL('title'));
+                       $this->content .= $this->doc->header($LANG->getLL('title'));
+                       $this->content .= $this->doc->spacer(5);
+                       $this->content .= $this->doc->spacer(10);
+               }
+       }
+
+       /**
+        * Prints out the module HTML
+        *
+        * @return      void
+        */
+       function printContent() {
+               $this->content .= $this->doc->endPage();
+               echo $this->content;
+       }
+
+       /**
+        * Generates the module content
+        *
+        * @return      void
+        */
+       function moduleContent()        {
+               global $BACK_PATH, $TYPO3_LOADED_EXT, $LANG;
+
+               switch ((string)$this->MOD_SETTINGS['function'])        {
+                       case 1:
+                               $content = '<div align="left"><strong>'.$LANG->getLL('referenceExplanation').'</strong></div>';
+                               $content .= '<p>'.$LANG->getLL('referenceExplanationDetailed').'</p><br />';
+                               $this->content .= $this->doc->section($LANG->getLL('displayReferences'),$content,0,1);
+                               $this->content .= '<a href="#" onClick="vHWin=window.open(\''.$BACK_PATH.'wizard_tsconfig.php?mode=tsref&P[formName]=editForm\',\'popUp\',\'height=500,width=780,status=0,menubar=0,scrollbars=1\');vHWin.focus();return false;"><img  src="'.$BACK_PATH.'sysext/t3skin/icons/gfx/wizard_tsconfig.gif" width="22" height="27" width="22" height="27" border="0" title="TSref reference"> TSREF</a><br />';
+                               $this->content .= '<a href="#" onClick="vHWin=window.open(\''.$BACK_PATH.'wizard_tsconfig.php?mode=beuser&P[formName]=editForm\',\'popUp\',\'height=500,width=780,status=0,menubar=0,scrollbars=1\');vHWin.focus();return false;"><img  src="'.$BACK_PATH.'sysext/t3skin/icons/gfx/wizard_tsconfig.gif" width="22" height="27" width="22" height="27" border="0" title="TSref reference"> USER TSCONFIG</a><br />';
+                               $this->content .= '<a href="#" onClick="vHWin=window.open(\''.$BACK_PATH.'wizard_tsconfig.php?mode=page&P[formName]=editForm\',\'popUp\',\'height=500,width=780,status=0,menubar=0,scrollbars=1\');vHWin.focus();return false;"><img  src="'.$BACK_PATH.'sysext/t3skin/icons/gfx/wizard_tsconfig.gif" width="22" height="27" width="22" height="27" border="0" title="TSref reference"> PAGE TSCONFIG</a><br />';
+                       break;
+
+                       case 2:
+                               if ($GLOBALS['BE_USER']->user['admin']) {
+                                       if (t3lib_div::_GP('_rebuild')) {
+                                                       // remove all data from the database
+                                               $this->purgeSQLContents();
+       
+                                                       // get all loaded extension keys
+                                               $extArray = $TYPO3_LOADED_EXT;
+       
+                                               $content = '<div align="left"><strong>'.$LANG->getLL('loadedTSfrom').'</strong></div><br />';
+       
+                                                       // parse the extension names only (no need for all details from the TYPO3_LOADED_EXT table
+                                               foreach ($extArray as $extName => $dummy)       {
+                                                               // check that the extension is really loaded (which should always be the case)
+                                                       if (t3lib_extMgm::isLoaded($extName))   {
+                                                                       // extract the content.xml from the manual.sxw ZIP file
+                                                               $manual = $this->getZIPFileContents(t3lib_extMgm::extPath($extName).'doc/manual.sxw', 'content.xml');
+       
+                                                                       // check if the manual file actually exists and if the content.xml could be loaded
+                                                               if ($manual != '')      {
+                                                                               // if the manual file exists, proceed with the load into the SQL database
+                                                                       $content .= '<p>Extension '.$extName.'...';
+       
+                                                                               // run the extraction processing and import the data into SQL. Return the number of TS tables found in the open office doucment
+                                                                       $number = $this->loadExtensionManual($extName, $manual);
+       
+                                                                               // print a status message with a link to the openoffice manual
+                                                                       $content .= $number.' '.$LANG->getLL('sections').' (<a href="/typo3/'.t3lib_extMgm::extRelPath($extName).'doc/manual.sxw">manual</a>)</p>';
+                                                               }
+                                                       } else  {
+                                                                       // this should never happen!
+                                                               die ("Fatal error : loaded extension not actually loaded? Please file a bug report at http://bugs.typo3.org!");
+                                                       }
+                                               }
+                                               
+                                               $this->content .= $this->doc->section($LANG->getLL('rebuildTS'),$content.'<br />',0,1);
+
+                                                       // Issue warnings about duplicate or empty obj_strings, if any
+                                                       // An obj_string should be unique. It should appear in only one extension manual and then only once
+                                                       // If the sum of all occurrences of a given obj_string is more than one, issue a list of duplicate entries as a warning
+                                               $duplicateWarnings = '';
+                                               $emptyWarnings = '';
+                                               foreach ($this->objStringsPerExtension as $obj_string => $extensions)   {
+                                                       if (empty($obj_string)) {
+                                                               $emptyWarnings = '<p class="typo3-red">'.$LANG->getLL('warning_manualsWithoutMarkers');
+                                                               foreach ($extensions as $extensionKey => $counter)      {
+                                                                       $emptyWarnings .= ' '.$extensionKey.' ('.$counter.')<br />';
+                                                               }
+                                                               $emptyWarnings .= '</p><br />';
+                                                       } else {
+                                                               if (array_sum($extensions) > 1) {
+                                                                       $duplicateWarnings .= $obj_string.':';
+                                                                       foreach ($extensions as $extensionKey => $counter)      {
+                                                                               $duplicateWarnings .= ' '.$extensionKey.' ('.$counter.')';
+                                                                       }
+                                                                       $duplicateWarnings .= '<br />';
+                                                               }
+                                                       }
+                                               }
+                                               $warnings = $emptyWarnings;
+                                               if (!empty($duplicateWarnings)) {
+                                                       $warnings .= '<p class="typo3-red">'.$LANG->getLL('warning_duplicateMarkers').'<br />'.$duplicateWarnings.'</p>';
+                                               }
+                                               if (!empty($warnings))  {
+                                                       $this->content .= $this->doc->section($LANG->getLL('updateWarnings'),'<div>'.$warnings.'</div>',0,1);
+                                               }
+                                       }
+       
+                                       $content = '<p>'.$LANG->getLL('rebuildExplanation').'</p><br />';
+                                       $content .= $LANG->getLL('rebuild').' <input type="submit" name="_rebuild" value="Rebuild" /><br />';
+                                       $this->content .= $this->doc->section($LANG->getLL('rebuildTS'),$content,0,1);
+                               } else {
+                                               $this->content .= 'Access to this function of the module is restricted to admins.';                     
+                               }
+
+
+                       break;
+               }
+       }
+
+       /**
+        * Returns the contents of a specific file within the ZIP
+        *
+        * @return      string  contents
+        */
+       function getZIPFileContents($ZIPfile, $filename)        {
+               if (@file_exists($ZIPfile))     {
+                               // Unzipping SXW file, getting filelist:
+                       $tempPath = PATH_site.'typo3temp/tx_tsconfighelp_ziptemp/';
+                       t3lib_div::mkdir($tempPath);
+
+                       $this->unzip($ZIPfile, $tempPath);
+                       $output = t3lib_div::getURL($tempPath.$filename);
+
+                       $cmd = 'rm -r "'.$tempPath.'"';
+                       exec($cmd);
+
+                       return $output;
+               }
+       }
+
+       /**
+        * Unzips a zip file in the given path.
+        * Uses the Extension Manager unzip functions.
+        *
+        *
+        * @param string $file          Full path to zip file
+        * @param string $path          Path to change to before extracting
+        * @return boolean      True on success, false in failure
+        */
+       function unzip($file, $path)    {
+                       // we use the unzip class of the Extension Manager here
+               $className = t3lib_div::makeInstanceClassName('em_unzip');
+               $unzip = new $className($file);
+               $ret = $unzip->extract(array('add_path'=>$path));
+               return (is_array($ret));
+       }
+
+       /**
+        * Parses the whole XML file in order to understand the Styles structure. This function is mostly looking at the styles
+        * that create bold or italic characters in the document, as these will later on need to be translated to <i> and <b> tags
+        * This function takes into account the hierarchy of the styles, as created by OpenOffice. This means that if a style has
+        * a parant, this function will make it inherit the styles of the parent. Therefore bold and italic styles are propagated
+        * to children as well.
+        *
+        * This function assumes the STYLE definitions are not nested. If they are then, then "close" type will need to be used
+        * more carefully, and a depth counter will need to be implemented.
+        *
+        * @param       array           The XML values array. The XML index is not necessary in this function.
+        * @return      array           Array that contains the different styles with their parent (required to recognise "Table Contents"-type styles), and their style (bold/italic)
+        */
+       function parseStyles($vals)     {
+               $currentStyleName = '';
+               $style = array ();
+
+               foreach ($vals as $node)        {
+                       switch ($node['type'])  {
+                               case 'open':
+                                       switch ($node['tag'])   {
+                                               case 'STYLE:STYLE':
+                                                       $currentStyleName = $node['attributes']['STYLE:NAME'];
+
+                                                       if (array_key_exists('STYLE:PARENT-STYLE-NAME',$node['attributes']))    {
+                                                               $parentStyleName = $node['attributes']['STYLE:PARENT-STYLE-NAME'];
+                                                               $style[$currentStyleName]['parents'][] = $parentStyleName; // keep trace of parents in the style array
+                                                       } else {
+                                                               $parentStyleName = ''; // this style has no parent, therefore clean the variable to avoid side effects with next use of that variable
+                                                       }
+
+                                                       if (array_key_exists($parentStyleName, $style)) { // the style parent is already documented in the array
+                                                               $style[$currentStyleName] = $style[$parentStyleName]; // inherit parent style
+                                                       }
+                                               break;
+                                       }
+                               break;
+
+                               case 'complete':
+                                       switch ($node['tag'])   {
+                                               case 'STYLE:PROPERTIES':
+                                                       if (is_array($node['attributes']) && array_key_exists('FO:FONT-WEIGHT',$node['attributes']))    {
+                                                               $style[$currentStyleName]['font-weight'] = $node['attributes']['FO:FONT-WEIGHT'];       // bold for example
+                                                       }
+                                                       if (is_array($node['attributes']) && array_key_exists('FO:FONT-STYLE',$node['attributes']))     {
+                                                               $style[$currentStyleName]['font-style'] = $node['attributes']['FO:FONT-STYLE']; // italic for example
+                                                       }
+                                               break;
+                                       }
+                               break;
+
+                               case 'close':
+                                       switch ($node['tag'])   {
+                                               case 'STYLE:STYLE':
+                                                       $currentStyleName = '';
+                                               break;
+                                               case 'STYLE:PROPERTIES':
+                                               break;
+                                       }
+                               break;
+                       }
+               }
+
+               return $style;
+       }
+
+
+       /**
+        * Checks if the style is a child of a specified parent. This is useful for example to check if a specific style that has
+        * a generic name ("P8" for example) is a child of the "Table Contents" style. It would not only inherit its style (bold/
+        * italic) but also its properties like being part of a Table.
+        *
+        * This function references the global $Styles variables which must have been created previously with parseStyles()
+        *
+        * @param       string          Name of the child style that we want to get properties for
+        * @param       string          Name of the parent style that we want to compare the child against
+        * @return      boolean         true if the child and parent are linked together. false otherwise.
+        */
+       function isStyleChildOf($child, $parent) {
+               global $Styles;
+
+               if (!strcmp($child, $parent))   { // the child is actually the same as the parent. They are obviously linked together
+                       return TRUE;
+               }
+
+               if (is_array($Styles[$child])  // the child is a documented style
+                && array_key_exists('parents',$Styles[$child])  // it has some parents
+                && (array_search($parent, $Styles[$child]['parents']) !== FALSE))      { // and the parent appears amongst its ancestors
+                       return TRUE;
+               }
+               return FALSE;
+       }
+
+       /**
+        * Find the table description that we want, then find a TABLE:TABLE close, immediately followed by a TEXT:P which has a
+        * style which is a child of a "Table Contents", then look up the index to find where the TABLE begins, and start browsing
+        * from there (returns these start and end indexes).
+        *
+        * This function only finds the next TS definition table. In order to find all TS definition tables from the document, the
+        * function needs to be called several times, starting where it left off last time. The third parameter is the index that
+        * is used to indicate where to start, and which is modified when the function returns to indicate where we left off.
+        *
+        * This function uses the unusual index XML array in addition to the values, this is necessary to find where in the XML
+        * tree a TABLE starts once we found where it ends.
+        *
+        * @param       array           The XML values array
+        * @param       array           The XML index array
+        * @param       integer         This is a reference to the index in the array where we should be starting the search
+        * @return      array           Array of the table start index and table end index where TS is defined. table start is FALSE if there are no more TS entries in the document (consider it similar to an EOF reached status).
+        */
+       function nextTSDefinitionTable($vals, $index, &$id)     {
+                       // browse the table where we left off last time
+               while ($id < count ($vals))     {
+                       $node = $vals[$id];
+                       if (!strcmp($node['type'], 'close') && !strcmp($node['tag'], 'TABLE:TABLE'))    { // check if next entry is a candidate
+                               $nextNode = $vals[$id+1];
+                               if (!strcmp($nextNode['tag'], 'TEXT:P') && $this->isStyleChildOf($nextNode['attributes']['TEXT:STYLE-NAME'], 'Table Contents')) {
+                                               // we found a good entry
+                                       $closeIndex = array_search($id, $index['TABLE:TABLE']); // find the ID in the list of table items
+
+                                       $tableStart = $index['TABLE:TABLE'][$closeIndex-1]; // find the matching start of the table in the $vals array
+
+                                       return array($tableStart, $id++);
+                               }
+                       }
+                       $id = $id+1;
+               }
+               return array(FALSE, 0); // marks the end of the input, no more table to find. WARNING: needs to be tested with === FALSE
+       }
+
+       /**
+        * Converts an Open Office like style (font-weight:bold for example) into an HTML style (b is for bold). This function uses the global
+        * $Styles defined through the parseStyles function
+        *
+        * @param       array           an array containing the [attributes][style] items in the OO format
+        * @return      array           an array where the items are all the HTML styles to apply to closely match the input OO-like styles
+        */
+       function styleTags($node)       {
+               global $Styles;
+
+               $styleName = $node['attributes']['TEXT:STYLE-NAME'];
+               switch ($Styles[$styleName]['font-weight'])     {
+                       case 'bold':
+                               $styleTags[] = 'b';
+                       break;
+               }
+               switch ($Styles[$styleName]['font-style'])      {
+                       case 'italic':
+                               $styleTags[] = 'i';
+                       break;
+               }
+               if (!strcmp($styleName,'Table Contents/PRE'))   {
+                       //$styleTags[]='pre'; // unused yet, but could be <pre> in the future - this is for inline code in the manuals
+               }
+               return $styleTags;
+       }
+
+       /**
+        * Converts an array containing style strings (for example ['b','i']) into their HTML equivalents
+        *
+        * @param       array           an array containing all the style tags
+        * @param       string          either '' or '/' depending on whether the style definition is to open or close the style
+        * @return      string          the sequence of tags to open or close the style, for example <b><i>
+        */
+       function styleHTML($style, $char)       {
+               $string = '';
+               if (count ($style) > 0) {
+                       foreach ($style as $tag)        {
+                               $string .= '<'.$char.$tag.'>';
+                       }
+               }
+               return $string;
+       }
+
+       /**
+        * This function does a little more than just HSC'ing the text passed to it. It does a general cleaning of the input:
+        * htmlspecialchars() : general cleaning for the HTML display, including single quotes transformation
+        * stripslashes() : otherwise the backslashes will cause an issue with a future unserialize of the data
+        * &nbsp if empty : if the input is empty, we return a &nbsp; string so that in the HTML output something will be       displayed
+        * utf8 to entities cleaning : in some SXW docs we can find UTF8 characters that need to be converted to be displayed on screen
+        *
+        * @param       string          Text that will need to be transformed according to the HSC and other rules
+        * @return      string          Transformed text that can now be freely serialized or exported to HTML
+        */
+       function HSCtext($text) {
+               global $LANG;
+
+               if (strcmp($text,''))   { // there is some content in the text field
+                       $cleantext = stripslashes(htmlspecialchars($text, ENT_QUOTES)); // stripslashes required as it could confuse unserialize
+                       return $LANG->csConvObj->utf8_to_entities($cleantext, $LANG->charSet);
+               } else { // there is no text, it's empty
+                       return '&nbsp;';
+               }
+       }
+
+       /**
+        * This function parses a Table from an Open Office document, in an XML format, and extracts the information. It will therefore crawl the
+        * XML tree and aggregate all the accepted contents into an array with the table contents.
+        *
+        * This function needs to extract the following information from the TABLE:
+        *   property => (column 1)
+        *   datatype => (column 2)
+        *   description => (column 3)
+        *   default => (column 4)
+        *   column_count => number of columns found in table. Usually 4, but for spanned columns, it would be less (1 for example)
+        *   is_propertyTable => ??? (almost always equal to 1)
+        *
+        * @param       array           This is the input XML data that is to be parsed
+        * @param       integer         The starting ID in the XML array to parse the data from
+        * @param       integer         The ending ID in the XML array to stop parsing data
+        * @return      array           An array with the contents of the different columns extracted from the input data
+        */
+       function parseTable($vals, $start, $end) {
+               $sectionHeader = 0;
+               $sectionRow = 0;
+               $sectionCell = 0;
+               $sectionP = 0;
+
+               $newLineRequired = ''; // this variable will either be empty (no newline required) or '\n' (newline required)
+               $textStyle = array (); // this will be the list of tag styles to apply to the text
+
+               $currentRow = 0;
+               $currentCell = 0;
+
+               $rowID = 0;
+               $cellID = 0;  // also gets reset at every top-level row
+
+               $table = array(); // will contain the results of the function
+
+               $id = $start;
+               while ($id < $end)      {
+                       $node = $vals[$id];
+
+                       // sanity check
+                       if ($sectionHeader < 0) die ('Malformed XML (header-rows)'."\n");
+                       if ($sectionRow < 0)    die ('Malformed XML (row)'."\n");
+                       if ($sectionCell < 0)   die ('Malformed XML (cell)'."\n");
+                       if ($sectionP < 0)              die ('Malformed XML (P)'."\n");
+
+                       switch ($node['type'])  {
+                               case 'open':
+                                       switch ($node['tag'])   {
+                                               case 'TABLE:TABLE-HEADER-ROWS':
+                                                       $sectionHeader++;
+                                               break;
+                                               
+                                               case 'TABLE:TABLE-ROW':
+                                                       if (!$sectionHeader)    { // skip section header, we only look at the *contents* of the table
+                                                               $sectionRow++;
+                                                               if ($sectionRow == 1)   { // make sure we are within a top-level row
+                                                                       $rowID++;
+                                                                       $cellID = 0;
+                                                               }
+                                                       }
+                                               break;
+                                               
+                                               case 'TABLE:TABLE-CELL':
+                                                       if (!$sectionHeader)    { // skip section header, we only look at the *contents* of the table
+                                                               $sectionCell++;
+                                                               if ($sectionCell == 1)  { // make sure we are within a top-level cell
+                                                                       $cellID++;
+                                                                       $newLineRequired = ''; // no newline required after this
+                                                               }
+                                                       }
+                                               break;
+                                               
+                                               case 'TEXT:P':
+                                                       if ($sectionCell)       { // make sure we are in a cell
+                                                               $sectionP++;
+                                                               $table[$rowID-1][$cellID-1] .= $this->styleHTML($this->styleTags($node),'') . $newLineRequired.$this->HSCtext($node['value']);
+                                                               $newLineRequired = ''; // no newline required after this
+                                                               $latestTEXTPopen = $node;
+                                                       }
+                                               break;
+                                       }
+                               break;
+
+                               case 'complete':
+                                       switch ($node['tag'])   {
+                                               case 'TEXT:P':
+                                                       if ($sectionCell)       { // make sure we are in a cell
+                                                               $table[$rowID-1][$cellID-1] .= $this->styleHTML($this->styleTags($node),'') . $newLineRequired.$this->HSCtext($node['value']).$this->styleHTML($this->styleTags($node),'/');
+                                                               $newLineRequired = '<br>'; // after a paragraph, require a new-line
+                                                       }
+                                               break;
+                                               
+                                               case 'TEXT:SPAN':
+                                                       if ($sectionCell)       { // make sure we are in a cell
+                                                               $table[$rowID-1][$cellID-1] .= $this->styleHTML($this->styleTags($node),'').$newLineRequired.$this->HSCtext($node['value']).$this->styleHTML($this->styleTags($node),'/');
+                                                               $newLineRequired = ''; // no newline required after this
+                                                       }
+                                               break;
+                                               
+                                               case 'TEXT:S':
+                                                       if ($sectionCell)       { // make sure we are in a cell
+                                                               for ($i=0; $i<$node['attributes']['TEXT:C']; $i++)      {
+                                                                       $table[$rowID-1][$cellID-1] .= '&nbsp;';
+                                                               }
+                                                               $newLineRequired = ''; // no newline required after this
+                                                       }
+                                               break;
+                                       }
+                               break;
+
+                               case 'cdata':
+                                       switch ($node['tag'])   {
+                                               case 'TEXT:P':
+                                                       if ($sectionCell)       { // make sure we are in a cell
+                                                               $table[$rowID-1][$cellID-1] .= $this->styleHTML($this->styleTags($node),'') . $newLineRequired.$this->HSCtext($node['value']).$this->styleHTML($this->styleTags($node),'/');
+                                                               $newLineRequired = ''; // no newline required after this
+                                                       }
+                                               break;
+                                       }
+                               break;
+
+                               case 'close':
+                                       switch ($node['tag'])   {
+                                               case 'TABLE:TABLE-HEADER-ROWS':
+                                                       $sectionHeader--;
+                                               break;
+                                               
+                                               case 'TABLE:TABLE-ROW':
+                                                       if (!$sectionHeader)    { // skip section header, we only look at the *contents* of the table
+                                                               $sectionRow--;
+                                                       }
+                                               break;
+                                               
+                                               case 'TABLE:TABLE-CELL':
+                                                       if (!$sectionHeader)    { // skip section header, we only look at the *contents* of the table
+                                                               $sectionCell--;
+                                                       }
+                                               break;
+                                               
+                                               case 'TEXT:P':
+                                                       $sectionP--;
+                                                       $newLineRequired = '<br>'; // after a paragraph, require a new-line
+                                                       $table[$rowID-1][$cellID-1] .= $this->styleHTML($this->styleTags($latestTEXTPopen),'/');
+                                               break;
+                                       }
+                               break;
+                       }
+                       $id = $id+1;
+               }
+               return $table;
+       }
+
+       /**
+        * Load the contents of the table into the SQL database
+        *
+        * @param       string          Name of the extension to load the documentation for. This is used to make the unique hash in the database
+        * @param       array           Contents of the documentation table
+        * @param       string          Name of the table from the source document (name at the bottom of the table in OpenOffice)
+        * @return      boolean         TRUE on success and FALSE on failure from the INSERT database query
+        */
+       function dumpIntoSQL($extension, $table, $tableName)    {
+               global $uid;
+
+               foreach ($table as $row)        {
+                       $tempArray = array();
+                       $tempArray['property'] = $row[0];
+
+                       $tempArray['datatype'] = count($row)==2 ? '&nbsp;':$row[1];     // in the case there are only 2 columns, the second one is the description !
+                       $tempArray['description'] = count($row)==2 ? $row[1]:$row[2];  // in the case there are only 2 columns, the second one is the description !
+                       $tempArray['default'] = $row[3];
+                       $tempArray['column_count'] = count($row);
+                       $tempArray['is_propertyTable'] = 1;
+                       $tsHelpArray['rows'][] = $tempArray;
+               }
+               $appdata = serialize($tsHelpArray);
+               $obj_string = trim($tableName, '[]');
+
+               if (isset($this->objStringsPerExtension[$obj_string]))  {
+                       if (isset($this->objStringsPerExtension[$obj_string][$extension]))      {
+                               $this->objStringsPerExtension[$obj_string][$extension]++;
+                       } else {
+                               $this->objStringsPerExtension[$obj_string][$extension] = 1;
+                       }
+               } else {
+                       $this->objStringsPerExtension[$obj_string] = array();
+                       $this->objStringsPerExtension[$obj_string][$extension] = 1;
+               }
+
+                       // If the obj_string was already encountered increase its counter. If not initialise it as 0
+                       // The counter (when bigger than 0) is appended to the obj_string to make it unique
+                       // This way the tables do not overwrite each other in the online help
+               if (isset($this->allObjStrings[$obj_string]))   {
+                       $this->allObjStrings[$obj_string]++;
+                       $obj_string .= ' ('.$this->allObjStrings[$obj_string].')';
+               } else {
+                       $this->allObjStrings[$obj_string] = 0;
+               }
+               $md5hash = md5($obj_string);
+               $description = ''; // unused
+               $guide = hexdec(substr(md5($extension),6,6));  // try to find a way to uniquely identify the source extension and place the identified into the "guide" column
+               $title = ''; // unused
+
+               $insertFields = array(
+                       'guide' => $guide,
+                       'md5hash' => $md5hash,
+                       'description' => $description,
+                       'obj_string' => $obj_string,
+                       'appdata' => $appdata,
+                       'title' => $title
+               );
+
+               return $GLOBALS['TYPO3_DB']->exec_INSERTquery('static_tsconfig_help', $insertFields);
+       }
+
+       /**
+        * Purges the existing contents for TypoScript help in the database. This ensures that several runs of the import process will not push
+        * duplicate information in the database, but that we clean it first before adding new contents.
+        *
+        * @param       string          Name of the extension for which to delete all the data in the database. If empty, all database will be cleaned
+        * @return      void
+        */
+       function purgeSQLContents($extension='')        {
+               $guide = hexdec(substr(md5($extension), 6, 6));
+               if ($extension != '')   {
+                       $GLOBALS['TYPO3_DB']->exec_DELETEquery('static_tsconfig_help', 'guide='.$guide);
+               } else {
+                       $GLOBALS['TYPO3_DB']->exec_DELETEquery('static_tsconfig_help', '');
+               }
+       }
+
+       /**
+        * This is the main function of the loading process. It will first parse the input data and load it into an XML array. It will then find all
+        * the styles associated with the contents so that later on we can distinguish bold and italic characters for example. It then parses the XML
+        * array to find all the TS-like description tables and parses them before loading them into the SQL database.
+        *
+        * @param       string          Name of the extension to load manual from
+        * @param       string          Input data from the manual.sxw in a string form. One large string with the whole OO manual document.
+        * @return      integer         Number of individual tables found in the document and loaded into the SQL database
+        */
+       function loadExtensionManual($extension, $contents)     {
+               global $Styles;
+
+                       // read the contents into an XML array
+               $parser = xml_parser_create();
+               xml_parse_into_struct($parser, $contents, $vals, $index);
+
+               xml_parser_free($parser);
+
+                       // parse styles from the manual for future rendering
+               $Styles = $this->parseStyles($vals);
+
+               $id = 0;
+               $tableNumber = 0;
+               do {
+                       list($tableStart, $tableEnd) = $this->nextTSDefinitionTable($vals, $index, $id);
+                       if ($tableStart !== FALSE)      {
+                                       // The title of the table can either be self-contained in a single complete entry
+                               if (!strcmp($vals[$id]['type'], 'complete'))    {
+                                       $title = $vals[$id]['value'];
+                               } else { // or it can be spread across a number of spans or similar
+                                       $watchTag = $vals[$id]['tag'];
+                                       $title = '';
+                                       while (strcmp($vals[$id]['tag'], $watchTag) || strcmp($vals[$id]['type'], 'close'))     {
+                                               $title .= $vals[$id++]['value'];
+                                       }
+                               }
+                               $tableContents = $this->parseTable($vals, $tableStart, $tableEnd);
+                               $this->dumpIntoSQL($extension, $tableContents, $title);
+                               $tableNumber++;
+                       }
+               } while ($tableStart !== FALSE);
+               return $tableNumber;
+       }
+}
+
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/tsconfig_help/mod1/index.php'])       {
+       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/tsconfig_help/mod1/index.php']);
+}
+
+
+
+
+// Make instance:
+$SOBE = t3lib_div::makeInstance('tx_tsconfighelp_module1');
+$SOBE->init();
+
+// Include files?
+foreach ($SOBE->include_once as $INC_FILE) include_once($INC_FILE);
+
+$SOBE->main();
+$SOBE->printContent();
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/tsconfig_help/mod1/locallang.xml b/typo3/sysext/tsconfig_help/mod1/locallang.xml
new file mode 100644 (file)
index 0000000..162634c
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<T3locallang>
+       <meta type="array">
+               <type>module</type>
+               <description>Language labels for module &quot;help_txtsconfighelpM1&quot;</description>
+       </meta>
+       <data type="array">
+               <languageKey index="default" type="array">
+                       <label index="title">TypoScript Help</label>
+                       <label index="display">Display TypoScript Help</label>
+                       <label index="rebuild">Rebuild TypoScript Help</label>
+                       <label index="referenceExplanation">Choose from the following reference data</label>
+                       <label index="referenceExplanationDetailed">In order to view the different TypoScript help popup windows, select from the following reference icons. This online help is built automatically from the manuals available in the installed extensions on your TYPO3 server. To rebuild the help files when you add or remove an extension, you will need to select the "Rebuild TypoScript Help" function of this module.</label>
+                       <label index="displayReferences">Display TypoScript Online Help</label>
+                       <label index="loadedTSfrom">Loaded TypoScript from:</label>
+                       <label index="sections">sections</label>
+                       <label index="rebuildTS">Rebuild TypoScript online help</label>
+                       <label index="warning_manualsWithoutMarkers">The following manuals contain one or more tables without markers: </label>
+                       <label index="warning_duplicateMarkers">The following markers appear in several manuals or several times in the same manual:</label>
+                       <label index="updateWarnings">Update warnings</label>
+                       <label index="rebuildExplanation">Rebuilding the online help will totally wipe the online help database before parsing the TypoScript help for loaded extensions. We suggest you to have doc_core_tsref and doc_core_tsconfig installed to have them parsed as well.</label>
+               </languageKey>
+       </data>
+</T3locallang>
\ No newline at end of file
diff --git a/typo3/sysext/tsconfig_help/mod1/locallang_mod.xml b/typo3/sysext/tsconfig_help/mod1/locallang_mod.xml
new file mode 100644 (file)
index 0000000..ce86907
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<T3locallang>
+       <meta type="array">
+               <type>module</type>
+               <description>Language labels for module &quot;help_txtsconfighelpM1&quot; - header, description</description>
+       </meta>
+       <data type="array">
+               <languageKey index="default" type="array">
+                       <label index="mlang_tabs_tab">TypoScript Help</label>
+                       <label index="mlang_labels_tabdescr">Object reference for TSref, Page TSconfig and User TSconfig. Also enables the admin to rebuild the whole TypoScript online reference with the manuals of all installed extensions (including core documentation, if installed).</label>
+                       <label index="mlang_labels_tablabel">TypoScript Help</label>
+               </languageKey>
+       </data>
+</T3locallang>
\ No newline at end of file