TYPO3 CMS  TYPO3_6-2
HelpModuleController.php
Go to the documentation of this file.
1 <?php
3 
19 
27 
31  public $allowedHTML = '<strong><em><b><i>';
32 
39  public $limitAccess;
40 
46  public $table;
47 
53  public $field;
54 
61  protected $mainKey;
62 
69  public $tfID;
70 
76  public $back;
77 
83  public $renderALL;
84 
90  public $content;
91 
98 
104  protected $moduleUrl;
105 
112  public function init() {
113  $this->moduleUrl = BackendUtility::getModuleUrl('help_cshmanual');
114  // Setting GPvars:
115  $this->tfID = GeneralUtility::_GP('tfID');
116  // Sanitizes the tfID using whitelisting.
117  if (!preg_match('/^[a-zA-Z0-9_\\-\\.\\*]*$/', $this->tfID)) {
118  $this->tfID = '';
119  }
120  $this->back = GeneralUtility::_GP('back');
121  $this->renderALL = GeneralUtility::_GP('renderALL');
122  // Set internal table/field to the parts of "tfID" incoming var.
123  $identifierParts = explode('.', $this->tfID);
124  // The table is the first item
125  $this->table = array_shift($identifierParts);
126  $this->mainKey = $this->table;
127  // The field is the second one
128  $this->field = array_shift($identifierParts);
129  // There may be extra parts for FlexForms
130  if (count($identifierParts) > 0) {
131  // There's at least one extra part
132  $extraIdentifierInformation = array();
133  $extraIdentifierInformation[] = array_shift($identifierParts);
134  // If the ds_pointerField contains a comma, it means the choice of FlexForm DS
135  // is determined by 2 parameters. In this case we have an extra identifier part
136  if (strpos($GLOBALS['TCA'][$this->table]['columns'][$this->field]['config']['ds_pointerField'], ',') !== FALSE) {
137  $extraIdentifierInformation[] = array_shift($identifierParts);
138  }
139  // The remaining parts make up the FlexForm field name itself
140  // (reassembled with dots)
141  $flexFormField = implode('.', $identifierParts);
142  // Assemble a different main key and switch field to use FlexForm field name
143  $this->mainKey .= '.' . $this->field;
144  foreach ($extraIdentifierInformation as $extraKey) {
145  $this->mainKey .= '.' . $extraKey;
146  }
147  $this->field = $flexFormField;
148  }
149  // limitAccess is checked if the $this->table really IS a table (and if the user is NOT a translator who should see all!)
150  $showAllToUser = BackendUtility::isModuleSetInTBE_MODULES('txllxmltranslateM1') && $GLOBALS['BE_USER']->check('modules', 'txllxmltranslateM1');
151  $this->limitAccess = isset($GLOBALS['TCA'][$this->table]) ? !$showAllToUser : FALSE;
152  $GLOBALS['LANG']->includeLLFile('EXT:lang/locallang_view_help.xlf', 1);
153  }
154 
161  public function main() {
162  if ($this->field == '*') {
163  // If ALL fields is supposed to be shown:
164  $this->createGlossaryIndex();
165  $this->content .= $this->render_Table($this->mainKey);
166  } elseif ($this->tfID) {
167  // ... otherwise show only single field:
168  $this->createGlossaryIndex();
169  $this->content .= $this->render_Single($this->mainKey, $this->field);
170  } else {
171  // Render Table Of Contents if nothing else:
172  $this->content .= $this->render_TOC();
173  }
174 
175  $this->doc = GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Template\\DocumentTemplate');
176  $this->doc->backPath = $GLOBALS['BACK_PATH'];
177  $this->doc->setModuleTemplate('EXT:cshmanual/Resources/Private/Templates/cshmanual.html');
178 
179  $markers = array('CONTENT' => $this->content);
180 
181  $this->content = $this->doc->moduleBody(array(), array(), $markers);
182  $this->content = $this->doc->render($GLOBALS['LANG']->getLL('title'), $this->content);
183  }
184 
191  public function printContent() {
192  echo $this->content;
193  }
194 
195  /************************************
196  * Rendering main modes
197  ************************************/
198 
205  public function render_TOC() {
206  // Initialize:
207  $CSHkeys = array_flip(array_keys($GLOBALS['TCA_DESCR']));
208  $TCAkeys = array_keys($GLOBALS['TCA']);
209  $outputSections = array();
210  $tocArray = array();
211  // TYPO3 Core Features:
212  $GLOBALS['LANG']->loadSingleTableDescription('xMOD_csh_corebe');
213  $this->render_TOC_el('xMOD_csh_corebe', 'core', $outputSections, $tocArray, $CSHkeys);
214  // Backend Modules:
215  $loadModules = GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Module\\ModuleLoader');
216  $loadModules->load($GLOBALS['TBE_MODULES']);
217  foreach ($loadModules->modules as $mainMod => $info) {
218  $cshKey = '_MOD_' . $mainMod;
219  if ($CSHkeys[$cshKey]) {
220  $GLOBALS['LANG']->loadSingleTableDescription($cshKey);
221  $this->render_TOC_el($cshKey, 'modules', $outputSections, $tocArray, $CSHkeys);
222  }
223  if (is_array($info['sub'])) {
224  foreach ($info['sub'] as $subMod => $subInfo) {
225  $cshKey = '_MOD_' . $mainMod . '_' . $subMod;
226  if ($CSHkeys[$cshKey]) {
227  $GLOBALS['LANG']->loadSingleTableDescription($cshKey);
228  $this->render_TOC_el($cshKey, 'modules', $outputSections, $tocArray, $CSHkeys);
229  }
230  }
231  }
232  }
233  // Database Tables:
234  foreach ($TCAkeys as $table) {
235  // Load descriptions for table $table
236  $GLOBALS['LANG']->loadSingleTableDescription($table);
237  if (is_array($GLOBALS['TCA_DESCR'][$table]['columns']) && $GLOBALS['BE_USER']->check('tables_select', $table)) {
238  $this->render_TOC_el($table, 'tables', $outputSections, $tocArray, $CSHkeys);
239  }
240  }
241  // Extensions
242  foreach ($CSHkeys as $cshKey => $value) {
243  if (GeneralUtility::isFirstPartOfStr($cshKey, 'xEXT_') && !isset($GLOBALS['TCA'][$cshKey])) {
244  $GLOBALS['LANG']->loadSingleTableDescription($cshKey);
245  $this->render_TOC_el($cshKey, 'extensions', $outputSections, $tocArray, $CSHkeys);
246  }
247  }
248  // Glossary
249  foreach ($CSHkeys as $cshKey => $value) {
250  if (GeneralUtility::isFirstPartOfStr($cshKey, 'xGLOSSARY_') && !isset($GLOBALS['TCA'][$cshKey])) {
251  $GLOBALS['LANG']->loadSingleTableDescription($cshKey);
252  $this->render_TOC_el($cshKey, 'glossary', $outputSections, $tocArray, $CSHkeys);
253  }
254  }
255  // Other:
256  foreach ($CSHkeys as $cshKey => $value) {
257  if (!GeneralUtility::isFirstPartOfStr($cshKey, '_MOD_') && !isset($GLOBALS['TCA'][$cshKey])) {
258  $GLOBALS['LANG']->loadSingleTableDescription($cshKey);
259  $this->render_TOC_el($cshKey, 'other', $outputSections, $tocArray, $CSHkeys);
260  }
261  }
262 
263  // COMPILE output:
264  $output = '';
265  $output .= '<h1>' . $GLOBALS['LANG']->getLL('manual_title', TRUE) . '</h1>';
266  $output .= '<p class="lead">' . $GLOBALS['LANG']->getLL('description', TRUE) . '</p>';
267 
268  $output .= '<h2>' . $GLOBALS['LANG']->getLL('TOC', TRUE) . '</h2>' . $this->render_TOC_makeTocList($tocArray);
269  if (!$this->renderALL) {
270  $output .= '
271  <br/>
272  <p class="c-nav"><a href="' . htmlspecialchars($this->moduleUrl) . '&amp;renderALL=1">' . $GLOBALS['LANG']->getLL('full_manual', TRUE) . '</a></p>';
273  }
274  if ($this->renderALL) {
275  $output .= '
276 
277  <h2>' . $GLOBALS['LANG']->getLL('full_manual_chapters', TRUE) . '</h2>' . implode('
278 
279 
280  <!-- NEW SECTION: -->
281  ', $outputSections);
282  }
283  $output .= '<hr /><p class="manual-title">' . BackendUtility::TYPO3_copyRightNotice() . '</p>';
284  return $output;
285  }
286 
298  public function render_TOC_el($table, $tocCat, &$outputSections, &$tocArray, &$CSHkeys) {
299  // Render full manual right here!
300  if ($this->renderALL) {
301  $outputSections[$table] = $this->render_Table($table);
302  if ($outputSections[$table]) {
303  $outputSections[$table] = '
304 
305  <!-- New CSHkey/Table: ' . $table . ' -->
306  <p class="c-nav"><a name="ANCHOR_' . $table . '" href="#">' . $GLOBALS['LANG']->getLL('to_top', TRUE) . '</a></p>
307  <h2>' . $this->getTableFieldLabel($table) . '</h2>
308 
309  ' . $outputSections[$table];
310  $tocArray[$tocCat][$table] = '<a href="#ANCHOR_' . $table . '">' . $this->getTableFieldLabel($table) . '</a>';
311  } else {
312  unset($outputSections[$table]);
313  }
314  } else {
315  // Only TOC:
316  $tocArray[$tocCat][$table] = '<p><a href="' . htmlspecialchars($this->moduleUrl) . '&amp;tfID=' . rawurlencode(($table . '.*')) . '">' . $this->getTableFieldLabel($table) . '</a></p>';
317  }
318  // Unset CSH key:
319  unset($CSHkeys[$table]);
320  }
321 
329  public function render_TOC_makeTocList($tocArray) {
330  // The Various manual sections:
331  $keys = explode(',', 'core,modules,tables,extensions,glossary,other');
332  // Create TOC bullet list:
333  $output = '';
334  foreach ($keys as $tocKey) {
335  if (is_array($tocArray[$tocKey])) {
336  $output .= '
337  <li>' . $GLOBALS['LANG']->getLL(('TOC_' . $tocKey), TRUE) . '
338  <ul>
339  <li>' . implode('</li>
340  <li>', $tocArray[$tocKey]) . '</li>
341  </ul>
342  </li>';
343  }
344  }
345  // Compile TOC:
346  $output = '
347 
348  <!-- TOC: -->
349  <div class="c-toc">
350  <ul>
351  ' . $output . '
352  </ul>
353  </div>';
354  return $output;
355  }
356 
365  public function render_Table($key, $table = NULL) {
366  $output = '';
367  // Take default key if not explicitly specified
368  if ($table === NULL) {
369  $table = $key;
370  }
371  // Load descriptions for table $table
372  $GLOBALS['LANG']->loadSingleTableDescription($key);
373  if (is_array($GLOBALS['TCA_DESCR'][$key]['columns']) && (!$this->limitAccess || $GLOBALS['BE_USER']->check('tables_select', $table))) {
374  // Initialize variables:
375  $parts = array();
376  // Reserved for header of table
377  $parts[0] = '';
378  // Traverse table columns as listed in TCA_DESCR
379  foreach ($GLOBALS['TCA_DESCR'][$key]['columns'] as $field => $_) {
380  $fieldValue = isset($GLOBALS['TCA'][$key]) && (string)$field !== '' ? $GLOBALS['TCA'][$key]['columns'][$field] : array();
381  if (is_array($fieldValue) && (!$this->limitAccess || !$fieldValue['exclude'] || $GLOBALS['BE_USER']->check('non_exclude_fields', $table . ':' . $field))) {
382  if (!$field) {
383  // Header
384  $parts[0] = $this->printItem($key, '', 1);
385  } else {
386  // Field
387  $parts[] = $this->printItem($key, $field, 1);
388  }
389  }
390  }
391  if (!$parts[0]) {
392  unset($parts[0]);
393  }
394  $output .= implode('<br />', $parts);
395  }
396  // Substitute glossary words:
397  $output = $this->substituteGlossaryWords($output);
398  // TOC link:
399  if (!$this->renderALL) {
400  $tocLink = '<p class="c-nav"><a href="' . htmlspecialchars($this->moduleUrl) . '">' . $GLOBALS['LANG']->getLL('goToToc', TRUE) . '</a></p>';
401  $output = $tocLink . '
402  <br/>' . $output . '
403  <br />' . $tocLink;
404  }
405  return $output;
406  }
407 
416  public function render_Single($key, $field) {
417  $output = '';
418  // Load the description field
419  $GLOBALS['LANG']->loadSingleTableDescription($key);
420  // Render single item
421  $output .= $this->printItem($key, $field);
422  // Substitute glossary words:
423  $output = $this->substituteGlossaryWords($output);
424  // Link to Full table description and TOC:
425  $getLLKey = $this->limitAccess ? 'fullDescription' : 'fullDescription_module';
426  $output .= '<br />
427  <p class="c-nav"><a href="' . htmlspecialchars($this->moduleUrl) . '&amp;tfID=' . rawurlencode(($key . '.*')) . '">' . $GLOBALS['LANG']->getLL($getLLKey, TRUE) . '</a></p>
428  <p class="c-nav"><a href="' . htmlspecialchars($this->moduleUrl) . '">' . $GLOBALS['LANG']->getLL('goToToc', TRUE) . '</a></p>';
429  return $output;
430  }
431 
432  /************************************
433  * Rendering CSH items
434  ************************************/
435 
444  public function make_seeAlso($value, $anchorTable = '') {
445  // Split references by comma or linebreak
446  $items = preg_split('/[,' . LF . ']/', $value);
447  $lines = array();
448  foreach ($items as $val) {
449  $val = trim($val);
450  if ($val) {
451  $iP = explode(':', $val);
452  $iPUrl = GeneralUtility::trimExplode('|', $val);
453  // URL reference:
454  if (substr($iPUrl[1], 0, 4) == 'http') {
455  $lines[] = '<a href="' . htmlspecialchars($iPUrl[1]) . '" target="_blank"><em>' . htmlspecialchars($iPUrl[0]) . '</em></a>';
456  } elseif (substr($iPUrl[1], 0, 5) == 'FILE:') {
457  $fileName = GeneralUtility::getFileAbsFileName(substr($iPUrl[1], 5), 1, 1);
458  if ($fileName && @is_file($fileName)) {
459  $fileName = '../' . \TYPO3\CMS\Core\Utility\PathUtility::stripPathSitePrefix($fileName);
460  $lines[] = '<a href="' . htmlspecialchars($fileName) . '" target="_blank"><em>' . htmlspecialchars($iPUrl[0]) . '</em></a>';
461  }
462  } else {
463  // "table" reference
464  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])))) {
465  // Checking read access:
466  if (isset($GLOBALS['TCA_DESCR'][$iP[0]])) {
467  // Make see-also link:
468  $href = $this->renderALL || $anchorTable && $iP[0] == $anchorTable ? '#' . rawurlencode(implode('.', $iP)) : $this->moduleUrl . '&tfID=' . rawurlencode(implode('.', $iP)) . '&back=' . $this->tfID;
469  $label = $this->getTableFieldLabel($iP[0], $iP[1], ' / ');
470  $lines[] = '<a href="' . htmlspecialchars($href) . '">' . htmlspecialchars($label) . '</a>';
471  }
472  }
473  }
474  }
475  }
476  return implode('<br />', $lines);
477  }
478 
487  public function printImage($images, $descr) {
488  $code = '';
489  // Splitting:
490  $imgArray = GeneralUtility::trimExplode(',', $images, TRUE);
491  if (count($imgArray)) {
492  $descrArray = explode(LF, $descr, count($imgArray));
493  foreach ($imgArray as $k => $image) {
494  $descr = $descrArray[$k];
495  $absImagePath = GeneralUtility::getFileAbsFileName($image, 1, 1);
496  if ($absImagePath && @is_file($absImagePath)) {
498  $imgInfo = @getimagesize($absImagePath);
499  if (is_array($imgInfo)) {
500  $imgFile = '../' . $imgFile;
501  $code .= '<br /><img src="' . $imgFile . '" ' . $imgInfo[3] . ' class="c-inlineimg" alt="" /><br />
502  ';
503  $code .= '<p><em>' . htmlspecialchars($descr) . '</em></p>
504  ';
505  } else {
506  $code .= '<div style="background-color: red; border: 1px solid black; color: white;">NOT AN IMAGE: ' . $imgFile . '</div>';
507  }
508  } else {
509  $code .= '<div style="background-color: red; border: 1px solid black; color: white;">IMAGE FILE NOT FOUND: ' . $image . '</div>';
510  }
511  }
512  }
513  return $code;
514  }
515 
524  public function headerLine($str, $type = 0) {
525  switch ($type) {
526  case 1:
527  $str = '<h2 class="t3-row-header">' . htmlspecialchars($str) . '</h2>
528  ';
529  break;
530  case 0:
531  $str = '<h3 class="divider">' . htmlspecialchars($str) . '</h3>
532  ';
533  break;
534  }
535  return $str;
536  }
537 
545  public function prepareContent($str) {
546  return '<p>' . nl2br(trim(strip_tags($str, $this->allowedHTML))) . '</p>
547  ';
548  }
549 
560  public function printItem($key, $field, $anchors = FALSE) {
561  $out = '';
562  if ($key && (!$field || is_array($GLOBALS['TCA_DESCR'][$key]['columns'][$field]))) {
563  // Make seeAlso references.
564  $seeAlsoRes = $this->make_seeAlso($GLOBALS['TCA_DESCR'][$key]['columns'][$field]['seeAlso'], $anchors ? $key : '');
565  // Making item:
566  $out = '<a name="' . $key . '.' . $field . '"></a>' . $this->headerLine($this->getTableFieldLabel($key, $field), 1) . $this->prepareContent($GLOBALS['TCA_DESCR'][$key]['columns'][$field]['description']) . ($GLOBALS['TCA_DESCR'][$key]['columns'][$field]['details'] ? $this->headerLine(($GLOBALS['LANG']->getLL('details') . ':')) . $this->prepareContent($GLOBALS['TCA_DESCR'][$key]['columns'][$field]['details']) : '') . ($GLOBALS['TCA_DESCR'][$key]['columns'][$field]['syntax'] ? $this->headerLine(($GLOBALS['LANG']->getLL('syntax') . ':')) . $this->prepareContent($GLOBALS['TCA_DESCR'][$key]['columns'][$field]['syntax']) : '') . ($GLOBALS['TCA_DESCR'][$key]['columns'][$field]['image'] ? $this->printImage($GLOBALS['TCA_DESCR'][$key]['columns'][$field]['image'], $GLOBALS['TCA_DESCR'][$key]['columns'][$field]['image_descr']) : '') . ($GLOBALS['TCA_DESCR'][$key]['columns'][$field]['seeAlso'] && $seeAlsoRes ? $this->headerLine(($GLOBALS['LANG']->getLL('seeAlso') . ':')) . '<p>' . $seeAlsoRes . '</p>' : '') . ($this->back ? '<br /><p><a href="' . htmlspecialchars($this->moduleUrl . '&amp;tfID=' . rawurlencode($this->back)) . '" class="typo3-goBack">' . htmlspecialchars($GLOBALS['LANG']->getLL('goBack')) . '</a></p>' : '') . '<br />';
567  }
568  return $out;
569  }
570 
579  public function getTableFieldNames($key, $field) {
580  $GLOBALS['LANG']->loadSingleTableDescription($key);
581  // Define the label for the key
582  $keyName = $key;
583  if (is_array($GLOBALS['TCA_DESCR'][$key]['columns']['']) && isset($GLOBALS['TCA_DESCR'][$key]['columns']['']['alttitle'])) {
584  // If there's an alternative title, use it
585  $keyName = $GLOBALS['TCA_DESCR'][$key]['columns']['']['alttitle'];
586  } elseif (isset($GLOBALS['TCA'][$key])) {
587  // Otherwise, if it's a table, use its title
588  $keyName = $GLOBALS['TCA'][$key]['ctrl']['title'];
589  } else {
590  // If no title was found, make sure to remove any "_MOD_"
591  $keyName = preg_replace('/^_MOD_/', '', $key);
592  }
593  // Define the label for the field
594  $fieldName = $field;
595  if (is_array($GLOBALS['TCA_DESCR'][$key]['columns'][$field]) && isset($GLOBALS['TCA_DESCR'][$key]['columns'][$field]['alttitle'])) {
596  // If there's an alternative title, use it
597  $fieldName = $GLOBALS['TCA_DESCR'][$key]['columns'][$field]['alttitle'];
598  } elseif (isset($GLOBALS['TCA'][$key]) && isset($GLOBALS['TCA'][$key]['columns'][$field])) {
599  // Otherwise, if it's a table, use its title
600  $fieldName = $GLOBALS['TCA'][$key]['columns'][$field]['label'];
601  }
602  return array($keyName, $fieldName);
603  }
604 
615  public function getTableFieldLabel($key, $field = '', $mergeToken = ': ') {
616  // Get table / field parts:
617  list($tableName, $fieldName) = $this->getTableFieldNames($key, $field);
618  // Create label:
619  $labelString = $GLOBALS['LANG']->sL($tableName) . ($field ? $mergeToken . rtrim(trim($GLOBALS['LANG']->sL($fieldName)), ':') : '');
620  return $labelString;
621  }
622 
623  /******************************
624  * Glossary related
625  ******************************/
626 
634  public function createGlossaryIndex() {
635  // Create hash string and try to retrieve glossary array:
636  $hash = md5('help_cshmanual:glossary');
637  $cachedData = BackendUtility::getHash($hash);
638  // Generate glossary words if not found:
639  if (is_array($cachedData)) {
640  list($this->glossaryWords, $this->substWords) = $cachedData;
641  } else {
642  // Initialize:
643  $this->glossaryWords = array();
644  $this->substWords = array();
645  $CSHkeys = array_flip(array_keys($GLOBALS['TCA_DESCR']));
646  // Glossary
647  foreach ($CSHkeys as $cshKey => $value) {
648  if (GeneralUtility::isFirstPartOfStr($cshKey, 'xGLOSSARY_') && !isset($GLOBALS['TCA'][$cshKey])) {
649  $GLOBALS['LANG']->loadSingleTableDescription($cshKey);
650  if (is_array($GLOBALS['TCA_DESCR'][$cshKey]['columns'])) {
651  // Traverse table columns as listed in TCA_DESCR
652  foreach ($GLOBALS['TCA_DESCR'][$cshKey]['columns'] as $field => $data) {
653  if ($field) {
654  $this->glossaryWords[$cshKey . '.' . $field] = array(
655  'title' => trim($data['alttitle'] ?: $cshKey),
656  'description' => str_replace('%22', '%23%23%23', rawurlencode($data['description']))
657  );
658  }
659  }
660  }
661  }
662  }
663  // First, create unique list of words:
664  foreach ($this->glossaryWords as $key => $value) {
665  // Making word lowercase in order to filter out same words in different cases.
666  $word = strtolower($value['title']);
667  if ($word !== '') {
668  $this->substWords[$word] = $value;
669  $this->substWords[$word]['key'] = $key;
670  }
671  }
672  krsort($this->substWords);
673  BackendUtility::storeHash($hash, array($this->glossaryWords, $this->substWords), 'Glossary');
674  }
675  }
676 
685  public function substituteGlossaryWords($code) {
686  $htmlParser = GeneralUtility::makeInstance('TYPO3\CMS\Core\Html\HtmlParser');
687  $htmlParser->pObj = $this;
688  $code = $htmlParser->HTMLcleaner($code, array(), 1);
689  return $code;
690  }
691 
702  if (is_array($this->substWords) && count($this->substWords) && strlen(trim($code))) {
703  // Substitute words:
704  foreach ($this->substWords as $wordKey => $wordSet) {
705  // quoteMeta used so special chars (which should not occur though) in words will not break the regex. Seemed to work (- kasper)
706  $parts = preg_split('/( |[\\(])(' . quoteMeta($wordSet['title']) . ')([\\.\\!\\)\\?\\:\\,]+| )/i', ' ' . $code . ' ', 2, PREG_SPLIT_DELIM_CAPTURE);
707  if (count($parts) == 5) {
708  $parts[2] = '<a class="glossary-term" href="' . htmlspecialchars($this->moduleUrl . '&amp;tfID=' . rawurlencode($wordSet['key']) . '&amp;back=' . $this->tfID) . '" title="' . rawurlencode(htmlspecialchars(GeneralUtility::fixed_lgd_cs(rawurldecode($wordSet['description']), 80))) . '">' . htmlspecialchars($parts[2]) . '</a>';
709  $code = substr(implode('', $parts), 1, -1);
710  // Disable entry so it doesn't get used next time:
711  unset($this->substWords[$wordKey]);
712  }
713  }
714  $code = str_replace('###', '&quot;', rawurldecode($code));
715  }
716  return $code;
717  }
718 
719 }
static isFirstPartOfStr($str, $partStr)
static storeHash($hash, $data, $ident)
static trimExplode($delim, $string, $removeEmptyValues=FALSE, $limit=0)
static getModuleUrl($moduleName, $urlParameters=array(), $backPathOverride=FALSE, $returnAbsoluteUrl=FALSE)
static fixed_lgd_cs($string, $chars, $appendString='...')
if(!defined('TYPO3_MODE')) $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_pre_processing'][]
render_TOC_el($table, $tocCat, &$outputSections, &$tocArray, &$CSHkeys)
static getFileAbsFileName($filename, $onlyRelative=TRUE, $relToTYPO3_mainDir=FALSE)
static TYPO3_copyRightNotice($showVersionNumber=TRUE)