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