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