index.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 2007-2010 Stephane Schitter <stephane.schitter@free.fr>
00006 *  All rights reserved
00007 *
00008 *  This script is part of the TYPO3 project. The TYPO3 project is
00009 *  free software; you can redistribute it and/or modify
00010 *  it under the terms of the GNU General Public License as published by
00011 *  the Free Software Foundation; either version 2 of the License, or
00012 *  (at your option) any later version.
00013 *
00014 *  The GNU General Public License can be found at
00015 *  http://www.gnu.org/copyleft/gpl.html.
00016 *
00017 *  This script is distributed in the hope that it will be useful,
00018 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 *  GNU General Public License for more details.
00021 *
00022 *  This copyright notice MUST APPEAR in all copies of the script!
00023 ***************************************************************/
00024 
00025 
00026 // DEFAULT initialization of a module [BEGIN]
00027 unset($MCONF);
00028 require_once('conf.php');
00029 require_once($BACK_PATH.'init.php');
00030 require_once($BACK_PATH.'template.php');
00031 require_once($BACK_PATH . 'sysext/em/mod1/class.em_unzip.php');
00032 
00033 $LANG->includeLLFile('EXT:tsconfig_help/mod1/locallang.xml');
00034 $BE_USER->modAccess($MCONF,1);  // This checks permissions and exits if the users has no permission for entry.
00035 // DEFAULT initialization of a module [END]
00036 
00037 
00038 /**
00039  * Module 'TypoScript Help' for the 'tsconfig_help' extension.
00040  *
00041  * @author  Stephane Schitter <stephane.schitter@free.fr>
00042  * @package TYPO3
00043  * @subpackage  tx_tsconfighelp
00044  */
00045 class tx_tsconfighelp_module1 extends t3lib_SCbase {
00046     var $pageinfo;
00047     var $objStringsPerExtension = array(); // This is used to count how many times the same obj_string appears in each extension manual
00048     var $allObjStrings = array(); // This is used to count how many times the same obj_string appears across all extensions
00049 
00050     /**
00051      * Initializes the Module
00052      * @return  void
00053      */
00054     function init() {
00055         global $BE_USER,$LANG,$BACK_PATH,$TCA_DESCR,$TCA,$CLIENT,$TYPO3_CONF_VARS;
00056         parent::init();
00057     }
00058 
00059     /**
00060      * Adds items to the ->MOD_MENU array. Used for the function menu selector.
00061      *
00062      * @return  void
00063      */
00064     function menuConfig()   {
00065         global $LANG;
00066         $this->MOD_MENU = array(
00067             'function' => array(
00068                 '1' => $LANG->getLL('display')
00069             )
00070         );
00071 
00072         if($GLOBALS['BE_USER']->user['admin'])  {
00073             $this->MOD_MENU['function']['2'] = $LANG->getLL('rebuild');
00074         }
00075 
00076         parent::menuConfig();
00077     }
00078 
00079     /**
00080      * Main function of the module. Write the content to $this->content
00081      *
00082      * @return  void
00083      */
00084     function main() {
00085         global $BE_USER,$LANG,$BACK_PATH,$TCA_DESCR,$TCA,$CLIENT,$TYPO3_CONF_VARS;
00086 
00087         // Access check!
00088         $access = $BE_USER->check('modules', 'help_txtsconfighelpM1');
00089 
00090             // Draw the header.
00091         $this->doc = t3lib_div::makeInstance('template');
00092         $this->doc->backPath = $BACK_PATH;
00093         $this->doc->setModuleTemplate('templates/tsconfig_help.html');
00094 
00095         if ($access || $BE_USER->user['admin']) {
00096 
00097             $this->doc->form = '<form action="" method="post">';
00098 
00099                 // JavaScript
00100             $this->doc->JScode = '
00101                 <script language="javascript" type="text/javascript">
00102                     script_ended = 0;
00103                     function jumpToUrl(URL) {
00104                         document.location = URL;
00105                     }
00106                 </script>
00107             ';
00108             $this->doc->postCode = '
00109                 <script language="javascript" type="text/javascript">
00110                     script_ended = 1;
00111                     if (top.fsMod) top.fsMod.recentIds["web"] = 0;
00112                 </script>
00113             ';
00114 
00115             $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_cs($this->pageinfo['_thePath'],-50);
00116 
00117             $this->content .= $this->doc->header($LANG->getLL('title'));
00118             $this->content .= $this->doc->spacer(5);
00119 
00120             // Render content:
00121             $this->moduleContent();
00122 
00123             $this->content .= $this->doc->spacer(10);
00124 
00125             $markers['FUNC_MENU'] = t3lib_BEfunc::getFuncMenu($this->id,'SET[function]',$this->MOD_SETTINGS['function'],$this->MOD_MENU['function']);
00126         } else {
00127             $this->content .= $this->doc->header($LANG->getLL('title'));
00128             $markers['FUNC_MENU'] = '';
00129         }
00130             // Setting up the buttons and markers for docheader
00131         $docHeaderButtons = $this->getButtons();
00132         $markers['CSH'] = $docHeaderButtons['csh'];
00133         $markers['CONTENT'] = $this->content;
00134 
00135             // Build the <body> for the module
00136         $this->content = $this->doc->startPage($LANG->getLL('title'));
00137         $this->content.= $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $markers);
00138         $this->content.= $this->doc->endPage();
00139         $this->content = $this->doc->insertStylesAndJS($this->content);
00140     }
00141 
00142     /**
00143      * Prints out the module HTML
00144      *
00145      * @return  void
00146      */
00147     function printContent() {
00148         echo $this->content;
00149     }
00150 
00151     /**
00152      * Create the panel of buttons for submitting the form or otherwise perform operations.
00153      *
00154      * @return  array   all available buttons as an assoc. array
00155      */
00156     protected function getButtons() {
00157         global $TCA, $LANG, $BACK_PATH, $BE_USER;
00158 
00159         $buttons = array(
00160             'csh' => '',
00161             'shortcut' => '',
00162         );
00163             // CSH
00164         //$buttons['csh'] = t3lib_BEfunc::cshItem('_MOD_web_func', '', $GLOBALS['BACK_PATH']);
00165 
00166         if (($this->id && is_array($this->pageinfo)) || ($BE_USER->user['admin'] && !$this->id)) {
00167                 // Shortcut
00168             if ($BE_USER->mayMakeShortcut()) {
00169                 $buttons['shortcut'] = $this->doc->makeShortcutIcon('id', implode(',', array_keys($this->MOD_MENU)), $this->MCONF['name']);
00170             }
00171         }
00172         return $buttons;
00173     }
00174 
00175     /**
00176      * Generates the module content
00177      *
00178      * @return  void
00179      */
00180     function moduleContent()    {
00181         global $BACK_PATH, $TYPO3_LOADED_EXT, $LANG;
00182 
00183         switch ((string)$this->MOD_SETTINGS['function'])    {
00184             case 1:
00185                 $content = '<div align="left"><strong>'.$LANG->getLL('referenceExplanation').'</strong></div>';
00186                 $content .= '<p>'.$LANG->getLL('referenceExplanationDetailed').'</p><br />';
00187                 $this->content .= $this->doc->section($LANG->getLL('displayReferences'),$content,0,1);
00188                 $this->content .= '<a href="#" onclick="vHWin=window.open(\''.$BACK_PATH.'wizard_tsconfig.php?mode=tsref&amp;P[formName]=editForm\',\'popUp\',\'height=500,width=780,status=0,menubar=0,scrollbars=1\');vHWin.focus();return false;" title="TSref reference">'.t3lib_iconWorks::getSpriteIcon('actions-system-typoscript-documentation-open').'TSREF</a><br />';
00189                 $this->content .= '<a href="#" onclick="vHWin=window.open(\''.$BACK_PATH.'wizard_tsconfig.php?mode=beuser&amp;P[formName]=editForm\',\'popUp\',\'height=500,width=780,status=0,menubar=0,scrollbars=1\');vHWin.focus();return false;" title="TSref reference">'.t3lib_iconWorks::getSpriteIcon('actions-system-typoscript-documentation-open').'USER TSCONFIG</a><br />';
00190                 $this->content .= '<a href="#" onclick="vHWin=window.open(\''.$BACK_PATH.'wizard_tsconfig.php?mode=page&amp;P[formName]=editForm\',\'popUp\',\'height=500,width=780,status=0,menubar=0,scrollbars=1\');vHWin.focus();return false;" title="TSref reference">'.t3lib_iconWorks::getSpriteIcon('actions-system-typoscript-documentation-open').'PAGE TSCONFIG</a><br />';
00191             break;
00192 
00193             case 2:
00194                 if ($GLOBALS['BE_USER']->user['admin']) {
00195                     if (t3lib_div::_GP('_rebuild')) {
00196                             // remove all data from the database
00197                         $this->purgeSQLContents();
00198 
00199                             // get all loaded extension keys
00200                         $extArray = $TYPO3_LOADED_EXT;
00201 
00202                         $content = '<div align="left"><strong>'.$LANG->getLL('loadedTSfrom').'</strong></div><br />';
00203 
00204                             // parse the extension names only (no need for all details from the TYPO3_LOADED_EXT table
00205                         foreach ($extArray as $extName => $dummy)   {
00206                                 // check that the extension is really loaded (which should always be the case)
00207                             if (t3lib_extMgm::isLoaded($extName))   {
00208                                     // extract the content.xml from the manual.sxw ZIP file
00209                                 $manual = $this->getZIPFileContents(t3lib_extMgm::extPath($extName).'doc/manual.sxw', 'content.xml');
00210 
00211                                     // check if the manual file actually exists and if the content.xml could be loaded
00212                                 if ($manual != '')  {
00213                                         // if the manual file exists, proceed with the load into the SQL database
00214                                     $content .= '<p>Extension '.$extName.'...';
00215 
00216                                         // run the extraction processing and import the data into SQL. Return the number of TS tables found in the open office document
00217                                     $number = $this->loadExtensionManual($extName, $manual);
00218 
00219                                         // print a status message with a link to the openoffice manual
00220                                     $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>';
00221                                 }
00222                             } else  {
00223                                     // this should never happen!
00224                                 die ("Fatal error : loaded extension not actually loaded? Please file a bug report at http://bugs.typo3.org!");
00225                             }
00226                         }
00227 
00228                         $this->content .= $this->doc->section($LANG->getLL('rebuildTS'),$content.'<br />',0,1);
00229 
00230                             // Issue warnings about duplicate or empty obj_strings, if any
00231                             // An obj_string should be unique. It should appear in only one extension manual and then only once
00232                             // If the sum of all occurrences of a given obj_string is more than one, issue a list of duplicate entries as a warning
00233                         $duplicateWarnings = '';
00234                         $emptyWarnings = '';
00235                         foreach ($this->objStringsPerExtension as $obj_string => $extensions)   {
00236                             if (empty($obj_string)) {
00237                                 $emptyWarnings = '<p class="typo3-red">'.$LANG->getLL('warning_manualsWithoutMarkers');
00238                                 foreach ($extensions as $extensionKey => $counter)  {
00239                                     $emptyWarnings .= ' '.$extensionKey.' ('.$counter.')<br />';
00240                                 }
00241                                 $emptyWarnings .= '</p><br />';
00242                             } else {
00243                                 if (array_sum($extensions) > 1) {
00244                                     $duplicateWarnings .= $obj_string.':';
00245                                     foreach ($extensions as $extensionKey => $counter)  {
00246                                         $duplicateWarnings .= ' '.$extensionKey.' ('.$counter.')';
00247                                     }
00248                                     $duplicateWarnings .= '<br />';
00249                                 }
00250                             }
00251                         }
00252                         $warnings = $emptyWarnings;
00253                         if (!empty($duplicateWarnings)) {
00254                             $warnings .= '<p class="typo3-red">'.$LANG->getLL('warning_duplicateMarkers').'<br />'.$duplicateWarnings.'</p>';
00255                         }
00256                         if (!empty($warnings))  {
00257                             $this->content .= $this->doc->section($LANG->getLL('updateWarnings'),'<div>'.$warnings.'</div>',0,1);
00258                         }
00259                     }
00260 
00261                     $content = '<p>'.$LANG->getLL('rebuildExplanation').'</p><br />';
00262                     $content .= $LANG->getLL('rebuild').' <input type="submit" name="_rebuild" value="Rebuild" /><br />';
00263                     $this->content .= $this->doc->section($LANG->getLL('rebuildTS'),$content,0,1);
00264                 } else {
00265                     $this->content .= '<p>'.$LANG->getLL('adminAccessOnly').'</p><br />';
00266                 }
00267 
00268 
00269             break;
00270         }
00271     }
00272 
00273     /**
00274      * Returns the contents of a specific file within the ZIP
00275      *
00276      * @return  string  contents
00277      */
00278     function getZIPFileContents($ZIPfile, $filename)    {
00279         if (file_exists($ZIPfile))  {
00280                 // Unzipping SXW file, getting filelist:
00281             $tempPath = PATH_site.'typo3temp/tx_tsconfighelp_ziptemp/';
00282             t3lib_div::mkdir($tempPath);
00283 
00284             $this->unzip($ZIPfile, $tempPath);
00285             $output = t3lib_div::getURL($tempPath.$filename);
00286 
00287             $cmd = 'rm -r "'.$tempPath.'"';
00288             exec($cmd);
00289 
00290             return $output;
00291         }
00292     }
00293 
00294     /**
00295      * Unzips a zip file in the given path.
00296      * Uses the Extension Manager unzip functions.
00297      *
00298      *
00299      * @param string $file      Full path to zip file
00300      * @param string $path      Path to change to before extracting
00301      * @return boolean  True on success, false in failure
00302      */
00303     function unzip($file, $path)    {
00304             // we use the unzip class of the Extension Manager here
00305             // TODO: move unzip class to core
00306         $unzip = t3lib_div::makeInstance('em_unzip', $file);
00307         $ret = $unzip->extract(array('add_path'=>$path));
00308         return (is_array($ret));
00309     }
00310 
00311     /**
00312      * Parses the whole XML file in order to understand the Styles structure. This function is mostly looking at the styles
00313      * that create bold or italic characters in the document, as these will later on need to be translated to <i> and <strong> tags
00314      * This function takes into account the hierarchy of the styles, as created by OpenOffice. This means that if a style has
00315      * a parant, this function will make it inherit the styles of the parent. Therefore bold and italic styles are propagated
00316      * to children as well.
00317      *
00318      * This function assumes the STYLE definitions are not nested. If they are then, then "close" type will need to be used
00319      * more carefully, and a depth counter will need to be implemented.
00320      *
00321      * @param   array       The XML values array. The XML index is not necessary in this function.
00322      * @return  array       Array that contains the different styles with their parent (required to recognise "Table Contents"-type styles), and their style (bold/italic)
00323      */
00324     function parseStyles($vals) {
00325         $currentStyleName = '';
00326         $style = array ();
00327 
00328         foreach ($vals as $node)    {
00329             switch ($node['type'])  {
00330                 case 'open':
00331                     switch ($node['tag'])   {
00332                         case 'STYLE:STYLE':
00333                             $currentStyleName = $node['attributes']['STYLE:NAME'];
00334 
00335                             if (array_key_exists('STYLE:PARENT-STYLE-NAME',$node['attributes']))    {
00336                                 $parentStyleName = $node['attributes']['STYLE:PARENT-STYLE-NAME'];
00337                                 $style[$currentStyleName]['parents'][] = $parentStyleName; // keep trace of parents in the style array
00338                             } else {
00339                                 $parentStyleName = ''; // this style has no parent, therefore clean the variable to avoid side effects with next use of that variable
00340                             }
00341 
00342                             if (array_key_exists($parentStyleName, $style)) { // the style parent is already documented in the array
00343                                 $style[$currentStyleName] = $style[$parentStyleName]; // inherit parent style
00344                             }
00345                         break;
00346                     }
00347                 break;
00348 
00349                 case 'complete':
00350                     switch ($node['tag'])   {
00351                         case 'STYLE:PROPERTIES':
00352                             if (is_array($node['attributes']) && array_key_exists('FO:FONT-WEIGHT',$node['attributes']))    {
00353                                 $style[$currentStyleName]['font-weight'] = $node['attributes']['FO:FONT-WEIGHT'];   // bold for example
00354                             }
00355                             if (is_array($node['attributes']) && array_key_exists('FO:FONT-STYLE',$node['attributes'])) {
00356                                 $style[$currentStyleName]['font-style'] = $node['attributes']['FO:FONT-STYLE']; // italic for example
00357                             }
00358                         break;
00359                     }
00360                 break;
00361 
00362                 case 'close':
00363                     switch ($node['tag'])   {
00364                         case 'STYLE:STYLE':
00365                             $currentStyleName = '';
00366                         break;
00367                         case 'STYLE:PROPERTIES':
00368                         break;
00369                     }
00370                 break;
00371             }
00372         }
00373 
00374         return $style;
00375     }
00376 
00377 
00378     /**
00379      * Checks if the style is a child of a specified parent. This is useful for example to check if a specific style that has
00380      * a generic name ("P8" for example) is a child of the "Table Contents" style. It would not only inherit its style (bold/
00381      * italic) but also its properties like being part of a Table.
00382      *
00383      * This function references the global $Styles variables which must have been created previously with parseStyles()
00384      *
00385      * @param   string      Name of the child style that we want to get properties for
00386      * @param   string      Name of the parent style that we want to compare the child against
00387      * @return  boolean     true if the child and parent are linked together. false otherwise.
00388      */
00389     function isStyleChildOf($child, $parent) {
00390         global $Styles;
00391 
00392         if (!strcmp($child, $parent))   { // the child is actually the same as the parent. They are obviously linked together
00393             return TRUE;
00394         }
00395 
00396         if (is_array($Styles[$child])  // the child is a documented style
00397          && array_key_exists('parents',$Styles[$child])  // it has some parents
00398          && (array_search($parent, $Styles[$child]['parents']) !== FALSE))  { // and the parent appears amongst its ancestors
00399             return TRUE;
00400         }
00401         return FALSE;
00402     }
00403 
00404     /**
00405      * Find the table description that we want, then find a TABLE:TABLE close, immediately followed by a TEXT:P which has a
00406      * style which is a child of a "Table Contents", then look up the index to find where the TABLE begins, and start browsing
00407      * from there (returns these start and end indexes).
00408      *
00409      * This function only finds the next TS definition table. In order to find all TS definition tables from the document, the
00410      * function needs to be called several times, starting where it left off last time. The third parameter is the index that
00411      * is used to indicate where to start, and which is modified when the function returns to indicate where we left off.
00412      *
00413      * This function uses the unusual index XML array in addition to the values, this is necessary to find where in the XML
00414      * tree a TABLE starts once we found where it ends.
00415      *
00416      * @param   array       The XML values array
00417      * @param   array       The XML index array
00418      * @param   integer     This is a reference to the index in the array where we should be starting the search
00419      * @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).
00420      */
00421     function nextTSDefinitionTable($vals, $index, &$id) {
00422             // browse the table where we left off last time
00423         while ($id < count ($vals)) {
00424             $node = $vals[$id];
00425             if (!strcmp($node['type'], 'close') && !strcmp($node['tag'], 'TABLE:TABLE'))    { // check if next entry is a candidate
00426                 $nextNode = $vals[$id+1];
00427                 if (!strcmp($nextNode['tag'], 'TEXT:P') && $this->isStyleChildOf($nextNode['attributes']['TEXT:STYLE-NAME'], 'Table Contents')) {
00428                         // we found a good entry
00429                     $closeIndex = array_search($id, $index['TABLE:TABLE']); // find the ID in the list of table items
00430 
00431                     $tableStart = $index['TABLE:TABLE'][$closeIndex-1]; // find the matching start of the table in the $vals array
00432 
00433                     return array($tableStart, $id++);
00434                 }
00435             }
00436             $id = $id+1;
00437         }
00438         return array(FALSE, 0); // marks the end of the input, no more table to find. WARNING: needs to be tested with === FALSE
00439     }
00440 
00441     /**
00442      * Converts an Open Office like style (font-weight:bold for example) into an HTML style (b is for bold). This function uses the global
00443      * $Styles defined through the parseStyles function
00444      *
00445      * @param   array       an array containing the [attributes][style] items in the OO format
00446      * @return  array       an array where the items are all the HTML styles to apply to closely match the input OO-like styles
00447      */
00448     function styleTags($node)   {
00449         global $Styles;
00450 
00451         $styleName = $node['attributes']['TEXT:STYLE-NAME'];
00452         switch ($Styles[$styleName]['font-weight']) {
00453             case 'bold':
00454                 $styleTags[] = 'b';
00455             break;
00456         }
00457         switch ($Styles[$styleName]['font-style'])  {
00458             case 'italic':
00459                 $styleTags[] = 'i';
00460             break;
00461         }
00462         if (!strcmp($styleName,'Table Contents/PRE'))   {
00463             //$styleTags[]='pre'; // unused yet, but could be <pre> in the future - this is for inline code in the manuals
00464         }
00465         return $styleTags;
00466     }
00467 
00468     /**
00469      * Converts an array containing style strings (for example ['b','i']) into their HTML equivalents
00470      *
00471      * @param   array       an array containing all the style tags
00472      * @param   string      either '' or '/' depending on whether the style definition is to open or close the style
00473      * @return  string      the sequence of tags to open or close the style, for example <strong><i>
00474      */
00475     function styleHTML($style, $char)   {
00476         $string = '';
00477         if (count ($style) > 0) {
00478             foreach ($style as $tag)    {
00479                 $string .= '<'.$char.$tag.'>';
00480             }
00481         }
00482         return $string;
00483     }
00484 
00485     /**
00486      * This function does a little more than just HSC'ing the text passed to it. It does a general cleaning of the input:
00487      * htmlspecialchars() : general cleaning for the HTML display, including single quotes transformation
00488      * stripslashes() : otherwise the backslashes will cause an issue with a future unserialize of the data
00489      * &nbsp if empty : if the input is empty, we return a &nbsp; string so that in the HTML output something will be   displayed
00490      * utf8 to entities cleaning : in some SXW docs we can find UTF8 characters that need to be converted to be displayed on screen
00491      *
00492      * @param   string      Text that will need to be transformed according to the HSC and other rules
00493      * @return  string      Transformed text that can now be freely serialized or exported to HTML
00494      */
00495     function HSCtext($text) {
00496         global $LANG;
00497 
00498         if (strcmp($text,''))   { // there is some content in the text field
00499             $cleantext = stripslashes(htmlspecialchars($text, ENT_QUOTES)); // stripslashes required as it could confuse unserialize
00500             return $LANG->csConvObj->utf8_to_entities($cleantext, $LANG->charSet);
00501         } else { // there is no text, it's empty
00502             return '&nbsp;';
00503         }
00504     }
00505 
00506     /**
00507      * This function parses a Table from an Open Office document, in an XML format, and extracts the information. It will therefore crawl the
00508      * XML tree and aggregate all the accepted contents into an array with the table contents.
00509      *
00510      * This function needs to extract the following information from the TABLE:
00511      *   property => (column 1)
00512      *   datatype => (column 2)
00513      *   description => (column 3)
00514      *   default => (column 4)
00515      *   column_count => number of columns found in table. Usually 4, but for spanned columns, it would be less (1 for example)
00516      *   is_propertyTable => ??? (almost always equal to 1)
00517      *
00518      * @param   array       This is the input XML data that is to be parsed
00519      * @param   integer     The starting ID in the XML array to parse the data from
00520      * @param   integer     The ending ID in the XML array to stop parsing data
00521      * @return  array       An array with the contents of the different columns extracted from the input data
00522      */
00523     function parseTable($vals, $start, $end) {
00524         $sectionHeader = 0;
00525         $sectionRow = 0;
00526         $sectionCell = 0;
00527         $sectionP = 0;
00528 
00529         $newLineRequired = ''; // this variable will either be empty (no newline required) or '\n' (newline required)
00530         $textStyle = array (); // this will be the list of tag styles to apply to the text
00531 
00532         $currentRow = 0;
00533         $currentCell = 0;
00534 
00535         $rowID = 0;
00536         $cellID = 0;  // also gets reset at every top-level row
00537 
00538         $table = array(); // will contain the results of the function
00539 
00540         $id = $start;
00541         while ($id < $end)  {
00542             $node = $vals[$id];
00543 
00544             // sanity check
00545             if ($sectionHeader < 0) die ('Malformed XML (header-rows)'.LF);
00546             if ($sectionRow < 0)    die ('Malformed XML (row)'.LF);
00547             if ($sectionCell < 0)   die ('Malformed XML (cell)'.LF);
00548             if ($sectionP < 0)      die ('Malformed XML (P)'.LF);
00549 
00550             switch ($node['type'])  {
00551                 case 'open':
00552                     switch ($node['tag'])   {
00553                         case 'TABLE:TABLE-HEADER-ROWS':
00554                             $sectionHeader++;
00555                         break;
00556 
00557                         case 'TABLE:TABLE-ROW':
00558                             if (!$sectionHeader)    { // skip section header, we only look at the *contents* of the table
00559                                 $sectionRow++;
00560                                 if ($sectionRow == 1)   { // make sure we are within a top-level row
00561                                     $rowID++;
00562                                     $cellID = 0;
00563                                 }
00564                             }
00565                         break;
00566 
00567                         case 'TABLE:TABLE-CELL':
00568                             if (!$sectionHeader)    { // skip section header, we only look at the *contents* of the table
00569                                 $sectionCell++;
00570                                 if ($sectionCell == 1)  { // make sure we are within a top-level cell
00571                                     $cellID++;
00572                                     $newLineRequired = ''; // no newline required after this
00573                                 }
00574                             }
00575                         break;
00576 
00577                         case 'TEXT:P':
00578                             if ($sectionCell)   { // make sure we are in a cell
00579                                 $sectionP++;
00580                                 $table[$rowID-1][$cellID-1] .= $this->styleHTML($this->styleTags($node),'') . $newLineRequired.$this->HSCtext($node['value']);
00581                                 $newLineRequired = ''; // no newline required after this
00582                                 $latestTEXTPopen = $node;
00583                             }
00584                         break;
00585                     }
00586                 break;
00587 
00588                 case 'complete':
00589                     switch ($node['tag'])   {
00590                         case 'TEXT:P':
00591                             if ($sectionCell)   { // make sure we are in a cell
00592                                 $table[$rowID-1][$cellID-1] .= $this->styleHTML($this->styleTags($node),'') . $newLineRequired.$this->HSCtext($node['value']).$this->styleHTML($this->styleTags($node),'/');
00593                                 $newLineRequired = '<br>'; // after a paragraph, require a new-line
00594                             }
00595                         break;
00596 
00597                         case 'TEXT:SPAN':
00598                             if ($sectionCell)   { // make sure we are in a cell
00599                                 $table[$rowID-1][$cellID-1] .= $this->styleHTML($this->styleTags($node),'').$newLineRequired.$this->HSCtext($node['value']).$this->styleHTML($this->styleTags($node),'/');
00600                                 $newLineRequired = ''; // no newline required after this
00601                             }
00602                         break;
00603 
00604                         case 'TEXT:S':
00605                             if ($sectionCell)   { // make sure we are in a cell
00606                                 for ($i=0; $i<$node['attributes']['TEXT:C']; $i++)  {
00607                                     $table[$rowID-1][$cellID-1] .= '&nbsp;';
00608                                 }
00609                                 $newLineRequired = ''; // no newline required after this
00610                             }
00611                         break;
00612                     }
00613                 break;
00614 
00615                 case 'cdata':
00616                     switch ($node['tag'])   {
00617                         case 'TEXT:P':
00618                             if ($sectionCell)   { // make sure we are in a cell
00619                                 $table[$rowID-1][$cellID-1] .= $this->styleHTML($this->styleTags($node),'') . $newLineRequired.$this->HSCtext($node['value']).$this->styleHTML($this->styleTags($node),'/');
00620                                 $newLineRequired = ''; // no newline required after this
00621                             }
00622                         break;
00623                     }
00624                 break;
00625 
00626                 case 'close':
00627                     switch ($node['tag'])   {
00628                         case 'TABLE:TABLE-HEADER-ROWS':
00629                             $sectionHeader--;
00630                         break;
00631 
00632                         case 'TABLE:TABLE-ROW':
00633                             if (!$sectionHeader)    { // skip section header, we only look at the *contents* of the table
00634                                 $sectionRow--;
00635                             }
00636                         break;
00637 
00638                         case 'TABLE:TABLE-CELL':
00639                             if (!$sectionHeader)    { // skip section header, we only look at the *contents* of the table
00640                                 $sectionCell--;
00641                             }
00642                         break;
00643 
00644                         case 'TEXT:P':
00645                             $sectionP--;
00646                             $newLineRequired = '<br>'; // after a paragraph, require a new-line
00647                             $table[$rowID-1][$cellID-1] .= $this->styleHTML($this->styleTags($latestTEXTPopen),'/');
00648                         break;
00649                     }
00650                 break;
00651             }
00652             $id = $id+1;
00653         }
00654         return $table;
00655     }
00656 
00657     /**
00658      * Load the contents of the table into the SQL database
00659      *
00660      * @param   string      Name of the extension to load the documentation for. This is used to make the unique hash in the database
00661      * @param   array       Contents of the documentation table
00662      * @param   string      Name of the table from the source document (name at the bottom of the table in OpenOffice)
00663      * @return  boolean     TRUE on success and FALSE on failure from the INSERT database query
00664      */
00665     function dumpIntoSQL($extension, $table, $tableName)    {
00666         global $uid;
00667 
00668         foreach ($table as $row)    {
00669             $tempArray = array();
00670             $tempArray['property'] = $row[0];
00671 
00672             $tempArray['datatype'] = count($row)==2 ? '&nbsp;':$row[1]; // in the case there are only 2 columns, the second one is the description !
00673             $tempArray['description'] = count($row)==2 ? $row[1]:$row[2];  // in the case there are only 2 columns, the second one is the description !
00674             $tempArray['default'] = $row[3];
00675             $tempArray['column_count'] = count($row);
00676             $tempArray['is_propertyTable'] = 1;
00677             $tsHelpArray['rows'][] = $tempArray;
00678         }
00679         $appdata = serialize($tsHelpArray);
00680         $obj_string = trim($tableName, '[]');
00681 
00682         if (isset($this->objStringsPerExtension[$obj_string]))  {
00683             if (isset($this->objStringsPerExtension[$obj_string][$extension]))  {
00684                 $this->objStringsPerExtension[$obj_string][$extension]++;
00685             } else {
00686                 $this->objStringsPerExtension[$obj_string][$extension] = 1;
00687             }
00688         } else {
00689             $this->objStringsPerExtension[$obj_string] = array();
00690             $this->objStringsPerExtension[$obj_string][$extension] = 1;
00691         }
00692 
00693             // If the obj_string was already encountered increase its counter. If not initialise it as 0
00694             // The counter (when bigger than 0) is appended to the obj_string to make it unique
00695             // This way the tables do not overwrite each other in the online help
00696         if (isset($this->allObjStrings[$obj_string]))   {
00697             $this->allObjStrings[$obj_string]++;
00698             $obj_string .= ' ('.$this->allObjStrings[$obj_string].')';
00699         } else {
00700             $this->allObjStrings[$obj_string] = 0;
00701         }
00702         $md5hash = md5($obj_string);
00703         $description = ''; // unused
00704         $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
00705         $title = ''; // unused
00706 
00707         $insertFields = array(
00708             'guide' => $guide,
00709             'md5hash' => $md5hash,
00710             'description' => $description,
00711             'obj_string' => $obj_string,
00712             'appdata' => $appdata,
00713             'title' => $title
00714         );
00715 
00716         return $GLOBALS['TYPO3_DB']->exec_INSERTquery('static_tsconfig_help', $insertFields);
00717     }
00718 
00719     /**
00720      * Purges the existing contents for TypoScript help in the database. This ensures that several runs of the import process will not push
00721      * duplicate information in the database, but that we clean it first before adding new contents.
00722      *
00723      * @param   string      Name of the extension for which to delete all the data in the database. If empty, all database will be cleaned
00724      * @return  void
00725      */
00726     function purgeSQLContents($extension='')    {
00727         $guide = hexdec(substr(md5($extension), 6, 6));
00728         if ($extension != '')   {
00729             $GLOBALS['TYPO3_DB']->exec_DELETEquery('static_tsconfig_help', 'guide='.$guide);
00730         } else {
00731             $GLOBALS['TYPO3_DB']->exec_TRUNCATEquery('static_tsconfig_help');
00732         }
00733     }
00734 
00735     /**
00736      * 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
00737      * the styles associated with the contents so that later on we can distinguish bold and italic characters for example. It then parses the XML
00738      * array to find all the TS-like description tables and parses them before loading them into the SQL database.
00739      *
00740      * @param   string      Name of the extension to load manual from
00741      * @param   string      Input data from the manual.sxw in a string form. One large string with the whole OO manual document.
00742      * @return  integer     Number of individual tables found in the document and loaded into the SQL database
00743      */
00744     function loadExtensionManual($extension, $contents) {
00745         global $Styles;
00746 
00747             // read the contents into an XML array
00748         $parser = xml_parser_create();
00749         xml_parse_into_struct($parser, $contents, $vals, $index);
00750 
00751         xml_parser_free($parser);
00752 
00753             // parse styles from the manual for future rendering
00754         $Styles = $this->parseStyles($vals);
00755 
00756         $id = 0;
00757         $tableNumber = 0;
00758         do {
00759             list($tableStart, $tableEnd) = $this->nextTSDefinitionTable($vals, $index, $id);
00760             if ($tableStart !== FALSE)  {
00761                     // The title of the table can either be self-contained in a single complete entry
00762                 if (!strcmp($vals[$id]['type'], 'complete'))    {
00763                     $title = $vals[$id]['value'];
00764                 } else { // or it can be spread across a number of spans or similar
00765                     $watchTag = $vals[$id]['tag'];
00766                     $title = '';
00767                     while (strcmp($vals[$id]['tag'], $watchTag) || strcmp($vals[$id]['type'], 'close')) {
00768                         $title .= $vals[$id++]['value'];
00769                     }
00770                 }
00771                 $tableContents = $this->parseTable($vals, $tableStart, $tableEnd);
00772                 $this->dumpIntoSQL($extension, $tableContents, $title);
00773                 $tableNumber++;
00774             }
00775         } while ($tableStart !== FALSE);
00776         return $tableNumber;
00777     }
00778 }
00779 
00780 
00781 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/tsconfig_help/mod1/index.php'])    {
00782     include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/tsconfig_help/mod1/index.php']);
00783 }
00784 
00785 
00786 
00787 
00788 // Make instance:
00789 $SOBE = t3lib_div::makeInstance('tx_tsconfighelp_module1');
00790 $SOBE->init();
00791 
00792 // Include files?
00793 foreach ($SOBE->include_once as $INC_FILE) include_once($INC_FILE);
00794 
00795 $SOBE->main();
00796 $SOBE->printContent();
00797 
00798 ?>

Generated on Sat Jul 24 04:17:16 2010 for TYPO3 API by  doxygen 1.4.7