[BUGFIX] Warning in list module
[Packages/TYPO3.CMS.git] / typo3 / view_help.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Document for viewing the online help texts, also known as TCA_DESCR.
29 * See Inside TYPO3 for details.
30 *
31 * $Id$
32 * Revised for TYPO3 3.7 5/2004 by Kasper Skårhøj
33 * XHTML-trans compliant
34 *
35 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
36 */
37 /**
38 * [CLASS/FUNCTION INDEX of SCRIPT]
39 *
40 *
41 *
42 * 91: class local_t3lib_parsehtml extends t3lib_parsehtml
43 * 102: function processContent($value,$dir,$conf)
44 *
45 *
46 * 122: class SC_view_help
47 * 146: function init()
48 * 167: function main()
49 * 198: function printContent()
50 *
51 * SECTION: Rendering main modes
52 * 221: function render_TOC()
53 * 338: function render_TOC_el($table, $tocCat, &$outputSections, &$tocArray, &$CSHkeys)
54 * 370: function render_TOC_makeTocList($tocArray)
55 * 409: function render_Table($table)
56 * 469: function render_Single($table,$field)
57 *
58 * SECTION: Rendering CSH items
59 * 515: function make_seeAlso($value,$anchorTable='')
60 * 564: function printImage($images,$descr)
61 * 599: function headerLine($str,$type=0)
62 * 620: function prepareContent($str)
63 * 635: function printItem($table,$field,$anchors=0)
64 * 668: function getTableFieldNames($table,$field)
65 * 691: function getTableFieldLabel($table,$field='',$mergeToken=': ')
66 *
67 * SECTION: Glossary related
68 * 726: function createGlossaryIndex()
69 * 785: function substituteGlossaryWords($code)
70 * 801: function substituteGlossaryWords_htmlcleaner_callback($code)
71 *
72 * TOTAL FUNCTIONS: 19
73 * (This index is automatically created/updated by the extension "extdeveval")
74 *
75 */
76
77 require('init.php');
78 require('template.php');
79 $LANG->includeLLFile('EXT:lang/locallang_view_help.xml');
80
81
82 /**
83 * Extension of the parse_html class.
84 *
85 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
86 * @package TYPO3
87 * @subpackage core
88 */
89 class local_t3lib_parsehtml extends t3lib_parsehtml {
90
91 /**
92 * Processing content between tags for HTML_cleaner
93 *
94 * @param string The value
95 * @param integer Direction, either -1 or +1. 0 (zero) means no change to input value.
96 * @param mixed Not used, ignore.
97 * @return string The processed value.
98 * @access private
99 */
100 function processContent($value,$dir,$conf) {
101 $value = $this->pObj->substituteGlossaryWords_htmlcleaner_callback($value);
102
103 return $value;
104 }
105 }
106
107
108
109
110
111
112
113 /**
114 * Script Class for rendering the Context Sensitive Help documents, either the single display in the small pop-up window or the full-table view in the larger window.
115 *
116 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
117 * @package TYPO3
118 * @subpackage core
119 */
120 class SC_view_help {
121 var $allowedHTML = '<strong><em><b><i>';
122
123 // For these vars, see init()
124 var $limitAccess; // If set access to fields and tables is checked. Should be done for true database tables.
125 var $table; // The "table" key
126 var $field; // The "field" key
127 /**
128 * Key used to point to the right CSH resource
129 * In simple cases, is equal to $table
130 *
131 * @var string
132 */
133 protected $mainKey;
134
135 // Internal, static: GPvar:
136 var $tfID; // Table/FIeld id.
137 var $ffID; // Flexform file/field information
138 var $back; // Back (previous tfID)
139 var $renderALL; // If set, then in TOC mode the FULL manual will be printed as well!
140
141 // Internal, dynamic:
142 var $content; // Content accumulation.
143 var $glossaryWords; // Glossary words
144
145
146
147 /**
148 * Initialize the class for various input etc.
149 *
150 * @return void
151 */
152 function init() {
153 global $LANG, $TCA;
154
155 // Setting GPvars:
156 $this->tfID = t3lib_div::_GP('tfID');
157 // Sanitizes the tfID using whitelisting.
158 if (!preg_match('/^[a-zA-Z0-9_\-\.\*]*$/', $this->tfID)) {
159 $this->tfID = '';
160 }
161 if (!$this->tfID) {
162 $ffID = t3lib_div::_GP('ffID');
163 if (!empty($ffID)) {
164 $this->ffID = unserialize(base64_decode($this->validateAndStripHmac($ffID)));
165 }
166 }
167 $this->back = t3lib_div::_GP('back');
168 $this->renderALL = t3lib_div::_GP('renderALL');
169
170 // Set internal table/field to the parts of "tfID" incoming var.
171 $identifierParts = explode('.', $this->tfID);
172 // The table is the first item
173 $this->table = array_shift($identifierParts);
174 $this->mainKey = $this->table;
175 // The field is the second one
176 $this->field = array_shift($identifierParts);
177 // There may be extra parts for FlexForms
178 if (count($identifierParts) > 0) {
179 // There's at least one extra part
180 $extraIdentifierInformation = array();
181 $extraIdentifierInformation[] = array_shift($identifierParts);
182 // Load the TCA details of the table
183 t3lib_div::loadTCA($this->table);
184 // If the ds_pointerField contains a comma, it means the choice of FlexForm DS
185 // is determined by 2 parameters. In this case we have an extra identifier part
186 if (strpos($TCA[$this->table]['columns'][$this->field]['config']['ds_pointerField'], ',') !== FALSE) {
187 $extraIdentifierInformation[] = array_shift($identifierParts);
188 }
189 // The remaining parts make up the FlexForm field name itself
190 // (reassembled with dots)
191 $flexFormField = implode('.', $identifierParts);
192 // Assemble a different main key and switch field to use FlexForm field name
193 $this->mainKey .= '.' . $this->field;
194 foreach ($extraIdentifierInformation as $extraKey) {
195 $this->mainKey .= '.' . $extraKey;
196 }
197 $this->field = $flexFormField;
198 }
199
200 // limitAccess is checked if the $this->table really IS a table (and if the user is NOT a translator who should see all!)
201 $showAllToUser = t3lib_BEfunc::isModuleSetInTBE_MODULES('txllxmltranslateM1') && $GLOBALS['BE_USER']->check('modules','txllxmltranslateM1');
202 $this->limitAccess = isset($TCA[$this->table]) ? !$showAllToUser : FALSE;
203 }
204
205 /**
206 * @param $string
207 * @return string
208 * @throws InvalidArgumentException
209 */
210 protected function validateAndStripHmac($string) {
211 if (!is_string($string)) {
212 throw new InvalidArgumentException('A hash can only be validated for a string, but "' . gettype($string) . '" was given.', 1320829762);
213 }
214 if (strlen($string) < 40) {
215 throw new InvalidArgumentException('A hashed string must contain at least 40 characters, the given string was only ' . strlen($string) . ' characters long.', 1320830276);
216 }
217 $stringWithoutHmac = substr($string, 0, -40);
218 if (t3lib_div::hmac($stringWithoutHmac) !== substr($string, -40)) {
219 throw new InvalidArgumentException('The given string was not appended with a valid HMAC.', 1320830018);
220 }
221 return $stringWithoutHmac;
222
223 }
224
225 /**
226 * Main function, rendering the display
227 *
228 * @return void
229 */
230 function main() {
231 global $BE_USER,$LANG,$TCA_DESCR,$TCA,$TBE_TEMPLATE;
232
233 // Start HTML output accumulation:
234 $TBE_TEMPLATE->divClass = 'typo3-view-help';
235 $this->content .= $TBE_TEMPLATE->startPage($LANG->getLL('title'));
236
237 if ($this->field == '*') {
238 // If ALL fields is supposed to be shown:
239 $this->createGlossaryIndex();
240 $this->content .= $this->render_Table($this->mainKey);
241
242 } elseif ($this->tfID) {
243 // ... otherwise show only single field:
244 $this->createGlossaryIndex();
245 $this->content .= $this->render_Single($this->mainKey, $this->field);
246
247 } elseif (is_array($this->ffID)) {
248 $this->content .= $this->render_SingleFlex();
249
250 } else {
251 // Render Table Of Contents if nothing else:
252 $this->content.= $this->render_TOC();
253 }
254
255 // Print close-button:
256 # $this->content.='<br /><form action=""><input type="submit" value="'.htmlspecialchars($LANG->getLL('close')).'" onclick="self.close(); return false;" /></form><br/>';
257
258 // End page:
259 $this->content.= '<br/>';
260 $this->content.= $TBE_TEMPLATE->endPage();
261 }
262
263 /**
264 * Outputting the accumulated content to screen
265 *
266 * @return void
267 */
268 function printContent() {
269 echo $this->content;
270 }
271
272
273
274
275
276
277
278
279
280 /************************************
281 *
282 * Rendering main modes
283 *
284 ************************************/
285
286 /**
287 * Creates Table Of Contents and possibly "Full Manual" mode if selected.
288 *
289 * @return string HTML content
290 */
291 function render_TOC() {
292 global $TCA_DESCR,$TCA,$LANG,$BE_USER,$TBE_MODULES;
293
294 // Initialize:
295 $CSHkeys = array_flip(array_keys($TCA_DESCR));
296 $TCAkeys = array_keys($TCA);
297
298 $outputSections = array();
299 $tocArray = array();
300
301
302 // TYPO3 Core Features:
303 $LANG->loadSingleTableDescription('xMOD_csh_corebe');
304 $this->render_TOC_el('xMOD_csh_corebe', 'core', $outputSections, $tocArray, $CSHkeys);
305
306 // Backend Modules:
307 $loadModules = t3lib_div::makeInstance('t3lib_loadModules');
308 $loadModules->load($TBE_MODULES);
309 foreach($loadModules->modules as $mainMod => $info) {
310 $cshKey = '_MOD_'.$mainMod;
311 if ($CSHkeys[$cshKey]) {
312 $LANG->loadSingleTableDescription($cshKey);
313 $this->render_TOC_el($cshKey, 'modules', $outputSections, $tocArray, $CSHkeys);
314 }
315
316 if (is_array($info['sub'])) {
317 foreach($info['sub'] as $subMod => $subInfo) {
318 $cshKey = '_MOD_'.$mainMod.'_'.$subMod;
319 if ($CSHkeys[$cshKey]) {
320 $LANG->loadSingleTableDescription($cshKey);
321 $this->render_TOC_el($cshKey, 'modules', $outputSections, $tocArray, $CSHkeys);
322 }
323 }
324 }
325 }
326
327 // Database Tables:
328 foreach($TCAkeys as $table) {
329 // Load descriptions for table $table
330 $LANG->loadSingleTableDescription($table);
331 if (is_array($TCA_DESCR[$table]['columns']) && $BE_USER->check('tables_select',$table)) {
332 $this->render_TOC_el($table, 'tables', $outputSections, $tocArray, $CSHkeys);
333 }
334 }
335
336 // Extensions
337 foreach($CSHkeys as $cshKey => $value) {
338 if (t3lib_div::isFirstPartOfStr($cshKey, 'xEXT_') && !isset($TCA[$cshKey])) {
339 $LANG->loadSingleTableDescription($cshKey);
340 $this->render_TOC_el($cshKey, 'extensions', $outputSections, $tocArray, $CSHkeys);
341 }
342 }
343
344 // Glossary
345 foreach($CSHkeys as $cshKey => $value) {
346 if (t3lib_div::isFirstPartOfStr($cshKey, 'xGLOSSARY_') && !isset($TCA[$cshKey])) {
347 $LANG->loadSingleTableDescription($cshKey);
348 $this->render_TOC_el($cshKey, 'glossary', $outputSections, $tocArray, $CSHkeys);
349 }
350 }
351
352 // Other:
353 foreach($CSHkeys as $cshKey => $value) {
354 if (!t3lib_div::isFirstPartOfStr($cshKey, '_MOD_') && !isset($TCA[$cshKey])) {
355 $LANG->loadSingleTableDescription($cshKey);
356 $this->render_TOC_el($cshKey, 'other', $outputSections, $tocArray, $CSHkeys);
357 }
358 }
359
360
361 // COMPILE output:
362 $output = '';
363 $output.= '
364
365 <h1>'.$LANG->getLL('manual_title',1).'</h1>';
366
367 $output.= '
368
369 <h2>'.$LANG->getLL('introduction',1).'</h2>
370 <p>'.$LANG->getLL('description',1).'</p>';
371
372 $output.= '
373
374 <h2>'.$LANG->getLL('TOC',1).'</h2>'.
375 $this->render_TOC_makeTocList($tocArray);
376
377 if (!$this->renderALL) {
378 $output.= '
379 <br/>
380 <p class="c-nav"><a href="view_help.php?renderALL=1">'.$LANG->getLL('full_manual',1).'</a></p>';
381 }
382
383 if ($this->renderALL) {
384 $output.= '
385
386 <h2>'.$LANG->getLL('full_manual_chapters',1).'</h2>'.
387 implode('
388
389
390 <!-- NEW SECTION: -->
391 ',$outputSections);
392 }
393
394 $output .= '<hr /><p class="manual-title">'.t3lib_BEfunc::TYPO3_copyRightNotice().'</p>';
395
396 return $output;
397 }
398
399 /**
400 * Creates a TOC list element and renders corresponding HELP content if "renderALL" mode is set.
401 *
402 * @param string CSH key / Table name
403 * @param string TOC category keyword: "core", "modules", "tables", "other"
404 * @param array Array for accumulation of rendered HELP Content (in "renderALL" mode). Passed by reference!
405 * @param array TOC array; Here TOC index elements are created. Passed by reference!
406 * @param array CSH keys array. Every item rendered will be unset in this array so finally we can see what CSH keys are not processed yet. Passed by reference!
407 * @return void
408 */
409 function render_TOC_el($table, $tocCat, &$outputSections, &$tocArray, &$CSHkeys) {
410 global $LANG;
411
412 if ($this->renderALL) { // Render full manual right here!
413 $outputSections[$table] = $this->render_Table($table);
414
415 if ($outputSections[$table]) {
416 $outputSections[$table] = '
417
418 <!-- New CSHkey/Table: '.$table.' -->
419 <p class="c-nav"><a name="ANCHOR_'.$table.'" href="#">'.$LANG->getLL('to_top',1).'</a></p>
420 <h2>'.$this->getTableFieldLabel($table).'</h2>
421
422 '.$outputSections[$table];
423 $tocArray[$tocCat][$table] = '<a href="#ANCHOR_'.$table.'">'.$this->getTableFieldLabel($table).'</a>';
424 } else {
425 unset($outputSections[$table]);
426 }
427 } else { // Only TOC:
428 $tocArray[$tocCat][$table] = '<p><a href="view_help.php?tfID='.rawurlencode($table.'.*').'">'.$this->getTableFieldLabel($table).'</a></p>';
429 }
430
431 // Unset CSH key:
432 unset($CSHkeys[$table]);
433 }
434
435 /**
436 * Renders the TOC index as a HTML bullet list from TOC array
437 *
438 * @param array ToC Array.
439 * @return string HTML bullet list for index.
440 */
441 function render_TOC_makeTocList($tocArray) {
442 global $LANG;
443
444 // The Various manual sections:
445 $keys = explode(',', 'core,modules,tables,extensions,glossary,other');
446
447 // Create TOC bullet list:
448 $output = '';
449 foreach($keys as $tocKey) {
450 if (is_array($tocArray[$tocKey])) {
451 $output.='
452 <li>'.$LANG->getLL('TOC_'.$tocKey,1).'
453 <ul>
454 <li>'.implode('</li>
455 <li>',$tocArray[$tocKey]).'</li>
456 </ul>
457 </li>';
458 }
459 }
460
461 // Compile TOC:
462 $output = '
463
464 <!-- TOC: -->
465 <div class="c-toc">
466 <ul>
467 '.$output.'
468 </ul>
469 </div>';
470
471 return $output;
472 }
473
474 /**
475 * Render CSH for a full cshKey/table
476 *
477 * @param string $key Full CSH key (may be different from table name)
478 * @param string $table CSH key / table name
479 * @return string HTML output
480 */
481 function render_Table($key, $table = NULL) {
482 global $BE_USER,$TCA_DESCR,$TCA,$LANG;
483
484 $output = '';
485
486 // take default key if not explicitly specified
487 if ($table === NULL) {
488 $table = $key;
489 }
490
491 // Load table TCA
492 t3lib_div::loadTCA($key);
493
494 // Load descriptions for table $table
495 $LANG->loadSingleTableDescription($key);
496
497 if (is_array($TCA_DESCR[$key]['columns']) && (!$this->limitAccess || $BE_USER->check('tables_select', $table))) {
498 // Initialize variables:
499 $parts = array();
500 $parts[0] = ''; // Reserved for header of table
501
502 // Traverse table columns as listed in TCA_DESCR
503 foreach ($TCA_DESCR[$key]['columns'] as $field => $_) {
504
505 $fieldValue = isset($TCA[$key]) && strcmp($field, '') ? $TCA[$key]['columns'][$field] : array();
506
507 if (is_array($fieldValue) && (!$this->limitAccess || !$fieldValue['exclude'] || $BE_USER->check('non_exclude_fields', $table . ':' . $field))) {
508 if (!$field) {
509 $parts[0] = $this->printItem($key, '', 1); // Header
510 } else {
511 $parts[] = $this->printItem($key, $field, 1); // Field
512 }
513 }
514 }
515
516 if (!$parts[0]) {
517 unset($parts[0]);
518 }
519 $output .= implode('<br />', $parts);
520 }
521
522 // Substitute glossary words:
523 $output = $this->substituteGlossaryWords($output);
524
525 // TOC link:
526 if (!$this->renderALL) {
527 $tocLink = '<p class="c-nav"><a href="view_help.php">' . $LANG->getLL('goToToc', 1) . '</a></p>';
528
529 $output =
530 $tocLink.'
531 <br/>'.
532 $output.'
533 <br />'.
534 $tocLink;
535 }
536
537 return $output;
538 }
539
540 /**
541 * Renders CSH for a single field.
542 *
543 * @param string $key CSH key / table name
544 * @param string $field Sub key / field name
545 * @return string HTML output
546 */
547 function render_Single($key, $field) {
548 global $LANG, $TCA;
549
550 $output = '';
551
552 // Load the description field
553 $LANG->loadSingleTableDescription($key);
554
555 // Render single item
556 $output.= $this->printItem($key, $field);
557
558 // Substitute glossary words:
559 $output = $this->substituteGlossaryWords($output);
560
561 // Link to Full table description and TOC:
562 $getLLKey = $this->limitAccess ? 'fullDescription' : 'fullDescription_module';
563 $output.= '<br />
564 <p class="c-nav"><a href="view_help.php?tfID=' . rawurlencode($key . '.*') . '">' . $LANG->getLL($getLLKey, 1) . '</a></p>
565 <p class="c-nav"><a href="view_help.php">' . $LANG->getLL('goToToc', 1) . '</a></p>';
566
567 return $output;
568 }
569
570
571 /**
572 * Renders CSH for a single field.
573 *
574 * @param string CSH key / table name
575 * @param string Sub key / field name
576 * @return string HTML output
577 * @deprecated since TYPO3 4.5, this function will be removed in TYPO3 4.7. Use render_Single() instead.
578 */
579 function render_SingleFlex() {
580 t3lib_div::logDeprecatedFunction();
581 $output = '';
582
583 // Render
584 $output.= $this->printItemFlex();
585
586 // Substitute glossary words:
587 return $this->substituteGlossaryWords($output);
588 }
589
590
591 /************************************
592 *
593 * Rendering CSH items
594 *
595 ************************************/
596
597 /**
598 * Make seeAlso links from $value
599 *
600 * @param string See-also input codes
601 * @param string If $anchorTable is set to a tablename, then references to this table will be made as anchors, not URLs.
602 * @return string See-also links HTML
603 */
604 function make_seeAlso($value,$anchorTable='') {
605 global $TCA,$BE_USER,$TCA_DESCR;
606
607 // Split references by comma or linebreak
608 $items = preg_split('/[,' . LF . ']/', $value);
609 $lines = array();
610
611 foreach($items as $val) {
612 $val = trim($val);
613 if ($val) {
614 $iP = explode(':',$val);
615 $iPUrl = t3lib_div::trimExplode('|',$val);
616 // URL reference:
617 if (substr($iPUrl[1],0,4)=='http') {
618 $lines[] = '<a href="'.htmlspecialchars($iPUrl[1]).'" target="_blank"><em>'.htmlspecialchars($iPUrl[0]).'</em></a>';
619 } elseif (substr($iPUrl[1],0,5)=='FILE:') {
620 $fileName = t3lib_div::getFileAbsFileName(substr($iPUrl[1],5),1,1);
621 if ($fileName && @is_file($fileName)) {
622 $fileName = '../'.substr($fileName,strlen(PATH_site));
623 $lines[] = '<a href="'.htmlspecialchars($fileName).'" target="_blank"><em>'.htmlspecialchars($iPUrl[0]).'</em></a>';
624 }
625 } else {
626 // "table" reference
627 t3lib_div::loadTCA($iP[0]);
628
629 if (!isset($TCA[$iP[0]]) || ((!$iP[1] || is_array($TCA[$iP[0]]['columns'][$iP[1]])) && (!$this->limitAccess || ($BE_USER->check('tables_select',$iP[0]) && (!$iP[1] || !$TCA[$iP[0]]['columns'][$iP[1]]['exclude'] || $BE_USER->check('non_exclude_fields',$iP[0].':'.$iP[1])))))) { // Checking read access:
630
631 // Load table descriptions:
632 #$LANG->loadSingleTableDescription($iP[0]);
633 if (isset($TCA_DESCR[$iP[0]])) {
634 // Make see-also link:
635 $href = ($this->renderALL || ($anchorTable && $iP[0]==$anchorTable) ? '#'.implode('.',$iP) : 'view_help.php?tfID='.rawurlencode(implode('.',$iP)).'&back='.$this->tfID);
636 $label = $this->getTableFieldLabel($iP[0],$iP[1],' / ');
637 $lines[] = '<a href="'.htmlspecialchars($href).'">'.htmlspecialchars($label).'</a>';
638 }
639 }
640 }
641 }
642 }
643 return implode('<br />',$lines);
644 }
645
646 /**
647 * Will return an image tag with description in italics.
648 *
649 * @param string Image file reference (list of)
650 * @param string Description string (divided for each image by line break)
651 * @return string Image HTML codes
652 */
653 function printImage($images,$descr) {
654 $code = '';
655 // Splitting:
656 $imgArray = t3lib_div::trimExplode(',', $images, 1);
657 if (count($imgArray)) {
658 $descrArray = explode(LF,$descr,count($imgArray));
659
660 foreach($imgArray as $k => $image) {
661 $descr = $descrArray[$k];
662
663 $absImagePath = t3lib_div::getFileAbsFileName($image,1,1);
664 if ($absImagePath && @is_file($absImagePath)) {
665 $imgFile = substr($absImagePath,strlen(PATH_site));
666 $imgInfo = @getimagesize($absImagePath);
667 if (is_array($imgInfo)) {
668 $imgFile = '../'.$imgFile;
669 $code.= '<br /><img src="'.$imgFile.'" '.$imgInfo[3].' class="c-inlineimg" alt="" /><br />
670 ';
671 $code.= '<p><em>'.$GLOBALS['LANG']->hscAndCharConv($descr,1).'</em></p>
672 ';
673 } else $code.= '<div style="background-color: red; border: 1px solid black; color: white;">NOT AN IMAGE: '.$imgFile.'</div>';
674 } else $code.= '<div style="background-color: red; border: 1px solid black; color: white;">IMAGE FILE NOT FOUND: '.$image.'</div>';
675 }
676 }
677
678 return $code;
679 }
680
681 /**
682 * Returns header HTML content
683 *
684 * @param string Header text
685 * @param string Header type (1, 0)
686 * @return string The HTML for the header.
687 */
688 function headerLine($str,$type=0) {
689 switch($type) {
690 case 1:
691 $str = '<h2 class="t3-row-header">' . htmlspecialchars($str) . '</h2>
692 ';
693 break;
694 case 0:
695 $str = '<h3 class="divider">' . htmlspecialchars($str) . '</h3>
696 ';
697 break;
698 }
699
700 return $str;
701 }
702
703 /**
704 * Returns prepared content
705 *
706 * @param string Content to format.
707 * @return string Formatted content.
708 */
709 function prepareContent($str) {
710 $str = $GLOBALS['LANG']->hscAndCharConv($str,0);
711 return '<p>'.nl2br(trim(strip_tags($str,$this->allowedHTML))).'</p>
712 ';
713 }
714
715 /**
716 * Prints a single $table/$field information piece
717 * If $anchors is set, then seeAlso references to the same table will be page-anchors, not links.
718 *
719 * @param string $key CSH key / table name
720 * @param string $field Sub key / field name
721 * @param boolean $anchors If anchors is to be shown.
722 * @return string HTML content
723 */
724 function printItem($key, $field, $anchors = FALSE) {
725 global $TCA_DESCR, $LANG, $TCA, $BE_USER;
726 $out = '';
727
728 // Load full table definition in $TCA
729 t3lib_div::loadTCA($key);
730
731 if ($key && (!$field || is_array($TCA_DESCR[$key]['columns'][$field]))) {
732 // Make seeAlso references.
733 $seeAlsoRes = $this->make_seeAlso($TCA_DESCR[$key]['columns'][$field]['seeAlso'], $anchors ? $key : '');
734
735 // Making item:
736 $out = '<a name="' . $key . '.' . $field . '"></a>' .
737 $this->headerLine($this->getTableFieldLabel($key, $field), 1) .
738 $this->prepareContent($TCA_DESCR[$key]['columns'][$field]['description']) .
739 ($TCA_DESCR[$key]['columns'][$field]['details'] ? $this->headerLine($LANG->getLL('details').':').$this->prepareContent($TCA_DESCR[$key]['columns'][$field]['details']) : '') .
740 ($TCA_DESCR[$key]['columns'][$field]['syntax'] ? $this->headerLine($LANG->getLL('syntax').':').$this->prepareContent($TCA_DESCR[$key]['columns'][$field]['syntax']) : '') .
741 ($TCA_DESCR[$key]['columns'][$field]['image'] ? $this->printImage($TCA_DESCR[$key]['columns'][$field]['image'],$TCA_DESCR[$key]['columns'][$field]['image_descr']) : '') .
742 ($TCA_DESCR[$key]['columns'][$field]['seeAlso'] && $seeAlsoRes ? $this->headerLine($LANG->getLL('seeAlso').':').'<p>'.$seeAlsoRes.'</p>' : '') .
743 ($this->back ? '<br /><p><a href="' . htmlspecialchars('view_help.php?tfID=' . rawurlencode($this->back)) . '" class="typo3-goBack">' . htmlspecialchars($LANG->getLL('goBack')) . '</a></p>' : '') .
744 '<br />';
745 }
746 return $out;
747 }
748
749 /**
750 * Prints a single $table/$field information piece
751 * If $anchors is set, then seeAlso references to the same table will be page-anchors, not links.
752 *
753 * @param string Table name
754 * @param string Field name
755 * @param boolean If anchors is to be shown.
756 * @return string HTML content
757 * @deprecated since TYPO3 4.5, this function will be removed in TYPO3 4.7. Use printItem() instead.
758 */
759 function printItemFlex() {
760 t3lib_div::logDeprecatedFunction();
761 // Get all texts
762 foreach (explode(',', 'description,details,syntax,image,image_descr,seeAlso') as $var) {
763 // Double $ below is not a error!
764 $$var = $GLOBALS['LANG']->sL($this->ffID['cshFile'] . ':' . $this->ffID['field'] . '.' . $var);
765 }
766 // Make seeAlso references.
767 $seeAlsoRes = $this->make_seeAlso($seeAlso);
768
769 // Making item:
770 $out= $this->headerLine($this->ffID['title'], 1) .
771 $this->prepareContent($description) .
772 ($details ? $this->headerLine($GLOBALS['LANG']->getLL('details').':') . $this->prepareContent($details) : '') .
773 ($syntax ? $this->headerLine($GLOBALS['LANG']->getLL('syntax').':') . $this->prepareContent($syntax) : '') .
774 ($image ? $this->printImage($image, $image_descr) : '') .
775 ($seeAlso && $seeAlsoRes ? $this->headerLine($GLOBALS['LANG']->getLL('seeAlso').':').'<p>'.$seeAlsoRes.'</p>' : '') .
776 '<br />';
777 return $out;
778 }
779
780 /**
781 * Returns labels for a given field in a given structure
782 *
783 * @param string $key CSH key / table name
784 * @param string $field Sub key / field name
785 * @return array Table and field labels in a numeric array
786 */
787 function getTableFieldNames($key, $field) {
788 global $TCA, $TCA_DESCR, $LANG;
789
790 $LANG->loadSingleTableDescription($key);
791
792 // Define the label for the key
793 $keyName = $key;
794 if (is_array($TCA_DESCR[$key]['columns']['']) && isset($TCA_DESCR[$key]['columns']['']['alttitle'])) {
795 // If there's an alternative title, use it
796 $keyName = $TCA_DESCR[$key]['columns']['']['alttitle'];
797 } elseif (isset($TCA[$key])) {
798 // Otherwise, if it's a table, use its title
799 $keyName = $TCA[$key]['ctrl']['title'];
800 } else {
801 // If no title was found, make sure to remove any "_MOD_"
802 $keyName = preg_replace('/^_MOD_/', '', $key);
803 }
804 // Define the label for the field
805 $fieldName = $field;
806 if (is_array($TCA_DESCR[$key]['columns'][$field]) && isset($TCA_DESCR[$key]['columns'][$field]['alttitle'])) {
807 // If there's an alternative title, use it
808 $fieldName = $TCA_DESCR[$key]['columns'][$field]['alttitle'];
809 } elseif (isset($TCA[$key])&&isset($TCA[$key]['columns'][$field])) {
810 // Otherwise, if it's a table, use its title
811 $fieldName = $TCA[$key]['columns'][$field]['label'];
812 }
813 return array($keyName, $fieldName);
814 }
815
816 /**
817 * Returns composite label for table/field
818 *
819 * @param string $key CSH key / table name
820 * @param string $field Sub key / field name
821 * @param string $mergeToken Token to merge the two strings with
822 * @return string Labels joined with merge token
823 * @see getTableFieldNames()
824 */
825 function getTableFieldLabel($key, $field = '', $mergeToken = ': ') {
826 global $LANG;
827 $tableName = '';
828 $fieldName = '';
829
830 // Get table / field parts:
831 list($tableName, $fieldName) = $this->getTableFieldNames($key, $field);
832
833 // Create label:
834 $labelString = $LANG->sL($tableName) .
835 ($field ? $mergeToken . rtrim(trim($LANG->sL($fieldName)), ':') : '');
836
837 return $labelString;
838 }
839
840
841
842
843
844
845
846
847
848
849
850 /******************************
851 *
852 * Glossary related
853 *
854 ******************************/
855
856 /**
857 * Creates glossary index in $this->glossaryWords
858 * Glossary is cached in cache_hash cache and so will be updated only when cache is cleared.
859 *
860 * @return void
861 */
862 function createGlossaryIndex() {
863 global $TCA_DESCR,$TCA,$LANG;
864
865 // Create hash string and try to retrieve glossary array:
866 $hash = md5('typo3/view_help.php:glossary');
867 list($this->glossaryWords,$this->substWords) = unserialize(t3lib_BEfunc::getHash($hash));
868
869 // Generate glossary words if not found:
870 if (!is_array($this->glossaryWords)) {
871
872 // Initialize:
873 $this->glossaryWords = array();
874 $this->substWords = array();
875 $CSHkeys = array_flip(array_keys($TCA_DESCR));
876
877 // Glossary
878 foreach($CSHkeys as $cshKey => $value) {
879 if (t3lib_div::isFirstPartOfStr($cshKey, 'xGLOSSARY_') && !isset($TCA[$cshKey])) {
880 $LANG->loadSingleTableDescription($cshKey);
881
882 if (is_array($TCA_DESCR[$cshKey]['columns'])) {
883
884 // Traverse table columns as listed in TCA_DESCR
885 foreach ($TCA_DESCR[$cshKey]['columns'] as $field => $data) {
886 if ($field) {
887 $this->glossaryWords[$cshKey.'.'.$field] = array(
888 'title' => trim($data['alttitle'] ? $data['alttitle'] : $cshKey),
889 'description' => str_replace('%22','%23%23%23', rawurlencode($data['description'])),
890 );
891 }
892 }
893 }
894 }
895 }
896
897 // First, create unique list of words:
898 foreach($this->glossaryWords as $key => $value) {
899 $word = strtolower($value['title']); // Making word lowercase in order to filter out same words in different cases.
900
901 if ($word!=='') {
902 $this->substWords[$word] = $value;
903 $this->substWords[$word]['key'] = $key;
904 }
905 }
906
907 krsort($this->substWords);
908
909 t3lib_BEfunc::storeHash($hash,serialize(array($this->glossaryWords,$this->substWords)),'Glossary');
910 }
911 }
912
913 /**
914 * Processing of all non-HTML content in the output
915 * Will be done by a call-back to ->substituteGlossaryWords_htmlcleaner_callback()
916 *
917 * @param string Input HTML code
918 * @return string Output HTML code
919 */
920 function substituteGlossaryWords($code) {
921 $htmlParser = t3lib_div::makeInstance('local_t3lib_parsehtml');
922 $htmlParser->pObj = $this;
923 $code = $htmlParser->HTMLcleaner($code, array(), 1);
924
925 return $code;
926 }
927
928 /**
929 * Substituting glossary words in the CSH
930 * (This is a call-back function from "class local_t3lib_parsehtml extends t3lib_parsehtml", see top of this script)
931 *
932 * @param string Input HTML string
933 * @return string HTML with substituted words in.
934 * @coauthor alex widschwendter, media.res kommunikationsloesungen
935 */
936 function substituteGlossaryWords_htmlcleaner_callback($code) {
937 if (is_array($this->substWords) && count($this->substWords) && strlen(trim($code))) {
938
939 // Substitute words:
940 foreach($this->substWords as $wordKey => $wordSet) {
941 // quoteMeta used so special chars (which should not occur though) in words will not break the regex. Seemed to work (- kasper)
942 $parts = preg_split('/( |[\(])('.quoteMeta($wordSet['title']).')([\.\!\)\?\:\,]+| )/i', ' '.$code.' ', 2, PREG_SPLIT_DELIM_CAPTURE);
943 if (count($parts) == 5) {
944 $parts[2] = '<a class="glossary-term" href="'.htmlspecialchars('view_help.php?tfID='.rawurlencode($wordSet['key']).'&back='.$this->tfID).'" title="'.rawurlencode(htmlspecialchars(t3lib_div::fixed_lgd_cs(rawurldecode($wordSet['description']),80))).'">'.
945 htmlspecialchars($parts[2]).
946 '</a>';
947 $code = substr(implode('',$parts),1,-1);
948
949 // Disable entry so it doesn't get used next time:
950 unset($this->substWords[$wordKey]);
951 }
952 }
953 $code = str_replace('###', '&quot;',rawurldecode($code));
954 }
955
956 return $code;
957 }
958
959 }
960
961
962
963 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/view_help.php'])) {
964 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/view_help.php']);
965 }
966
967
968
969 // Make instance:
970 $SOBE = t3lib_div::makeInstance('SC_view_help');
971 $SOBE->init();
972 $SOBE->main();
973 $SOBE->printContent();
974
975 ?>