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