TYPO3  7.6
SoftReferenceIndex.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Core\Database;
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
19 
71 {
75  public $fileAdminDir = '';
76 
80  public $tokenID_basePrefix = '';
81 
85  public function __construct()
86  {
87  $this->fileAdminDir = !empty($GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir']) ? rtrim($GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'], '/') : 'fileadmin';
88  }
89 
102  public function findRef($table, $field, $uid, $content, $spKey, $spParams, $structurePath = '')
103  {
104  $retVal = false;
105  $this->tokenID_basePrefix = $table . ':' . $uid . ':' . $field . ':' . $structurePath . ':' . $spKey;
106  switch ($spKey) {
107  case 'notify':
108  // Simple notification
109  $resultArray = array(
110  'elements' => array(
111  array(
112  'matchString' => $content
113  )
114  )
115  );
116  $retVal = $resultArray;
117  break;
118  case 'substitute':
119  $tokenID = $this->makeTokenID();
120  $resultArray = array(
121  'content' => '{softref:' . $tokenID . '}',
122  'elements' => array(
123  array(
124  'matchString' => $content,
125  'subst' => array(
126  'type' => 'string',
127  'tokenID' => $tokenID,
128  'tokenValue' => $content
129  )
130  )
131  )
132  );
133  $retVal = $resultArray;
134  break;
135  case 'images':
136  $retVal = $this->findRef_images($content, $spParams);
137  break;
138  case 'typolink':
139  $retVal = $this->findRef_typolink($content, $spParams);
140  break;
141  case 'typolink_tag':
142  $retVal = $this->findRef_typolink_tag($content, $spParams);
143  break;
144  case 'ext_fileref':
145  $retVal = $this->findRef_extension_fileref($content, $spParams);
146  break;
147  case 'TStemplate':
148  $retVal = $this->findRef_TStemplate($content, $spParams);
149  break;
150  case 'TSconfig':
151  $retVal = $this->findRef_TSconfig($content, $spParams);
152  break;
153  case 'email':
154  $retVal = $this->findRef_email($content, $spParams);
155  break;
156  case 'url':
157  $retVal = $this->findRef_url($content, $spParams);
158  break;
159  default:
160  $retVal = false;
161  }
162  return $retVal;
163  }
164 
175  public function findRef_images($content, $spParams)
176  {
177  // Start HTML parser and split content by image tag:
178  $htmlParser = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Html\HtmlParser::class);
179  $splitContent = $htmlParser->splitTags('img', $content);
180  $elements = array();
181  // Traverse splitted parts:
182  foreach ($splitContent as $k => $v) {
183  if ($k % 2) {
184  // Get file reference:
185  $attribs = $htmlParser->get_tag_attributes($v);
186  $srcRef = htmlspecialchars_decode($attribs[0]['src']);
187  $pI = pathinfo($srcRef);
188  // If it looks like a local image, continue. Otherwise ignore it.
189  $absPath = GeneralUtility::getFileAbsFileName(PATH_site . $srcRef);
190  if (!$pI['scheme'] && !$pI['query'] && $absPath && $srcRef !== 'clear.gif') {
191  // Initialize the element entry with info text here:
192  $tokenID = $this->makeTokenID($k);
193  $elements[$k] = array();
194  $elements[$k]['matchString'] = $v;
195  // If the image seems to be from fileadmin/ folder or an RTE image, then proceed to set up substitution token:
196  if (GeneralUtility::isFirstPartOfStr($srcRef, $this->fileAdminDir . '/') || GeneralUtility::isFirstPartOfStr($srcRef, 'uploads/') && preg_match('/^RTEmagicC_/', basename($srcRef))) {
197  // Token and substitute value:
198  // Make sure the value we work on is found and will get substituted in the content (Very important that the src-value is not DeHSC'ed)
199  if (strstr($splitContent[$k], $attribs[0]['src'])) {
200  // Substitute value with token (this is not be an exact method if the value is in there twice, but we assume it will not)
201  $splitContent[$k] = str_replace($attribs[0]['src'], '{softref:' . $tokenID . '}', $splitContent[$k]);
202  $elements[$k]['subst'] = array(
203  'type' => 'file',
204  'relFileName' => $srcRef,
205  'tokenID' => $tokenID,
206  'tokenValue' => $attribs[0]['src']
207  );
208  // Finally, notice if the file does not exist.
209  if (!@is_file($absPath)) {
210  $elements[$k]['error'] = 'File does not exist!';
211  }
212  } else {
213  $elements[$k]['error'] = 'Could not substitute image source with token!';
214  }
215  }
216  }
217  }
218  }
219  // Return result:
220  if (!empty($elements)) {
221  $resultArray = array(
222  'content' => implode('', $splitContent),
223  'elements' => $elements
224  );
225  return $resultArray;
226  }
227  }
228 
238  public function findRef_typolink($content, $spParams)
239  {
240  // First, split the input string by a comma if the "linkList" parameter is set.
241  // An example: the link field for images in content elements of type "textpic" or "image". This field CAN be configured to define a link per image, separated by comma.
242  if (is_array($spParams) && in_array('linkList', $spParams)) {
243  // Preserving whitespace on purpose.
244  $linkElement = explode(',', $content);
245  } else {
246  // If only one element, just set in this array to make it easy below.
247  $linkElement = array($content);
248  }
249  // Traverse the links now:
250  $elements = array();
251  foreach ($linkElement as $k => $typolinkValue) {
252  $tLP = $this->getTypoLinkParts($typolinkValue);
253  $linkElement[$k] = $this->setTypoLinkPartsElement($tLP, $elements, $typolinkValue, $k);
254  }
255  // Return output:
256  if (!empty($elements)) {
257  $resultArray = array(
258  'content' => implode(',', $linkElement),
259  'elements' => $elements
260  );
261  return $resultArray;
262  }
263  }
264 
274  public function findRef_typolink_tag($content, $spParams)
275  {
276  // Parse string for special TYPO3 <link> tag:
277  $htmlParser = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Html\HtmlParser::class);
278  $linkTags = $htmlParser->splitTags('link', $content);
279  // Traverse result:
280  $elements = array();
281  foreach ($linkTags as $k => $foundValue) {
282  if ($k % 2) {
283  $typolinkValue = preg_replace('/<LINK[[:space:]]+/i', '', substr($foundValue, 0, -1));
284  $tLP = $this->getTypoLinkParts($typolinkValue);
285  $linkTags[$k] = '<LINK ' . $this->setTypoLinkPartsElement($tLP, $elements, $typolinkValue, $k) . '>';
286  }
287  }
288  // Return output:
289  if (!empty($elements)) {
290  $resultArray = array(
291  'content' => implode('', $linkTags),
292  'elements' => $elements
293  );
294  return $resultArray;
295  }
296  }
297 
306  public function findRef_TStemplate($content, $spParams)
307  {
308  $elements = array();
309  // First, try to find images and links:
310  $htmlParser = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Html\HtmlParser::class);
311  $splitContent = $htmlParser->splitTags('img,a,form', $content);
312  // Traverse splitted parts:
313  foreach ($splitContent as $k => $v) {
314  if ($k % 2) {
315  $attribs = $htmlParser->get_tag_attributes($v);
316  $attributeName = '';
317  switch ($htmlParser->getFirstTagName($v)) {
318  case 'img':
319  $attributeName = 'src';
320  break;
321  case 'a':
322  $attributeName = 'href';
323  break;
324  case 'form':
325  $attributeName = 'action';
326  break;
327  }
328  // Get file reference:
329  if (isset($attribs[0][$attributeName])) {
330  $srcRef = htmlspecialchars_decode($attribs[0][$attributeName]);
331  // Set entry:
332  $tokenID = $this->makeTokenID($k);
333  $elements[$k] = array();
334  $elements[$k]['matchString'] = $v;
335  // OK, if it looks like a local file from fileadmin/, include it:
336  $pI = pathinfo($srcRef);
337  $absPath = GeneralUtility::getFileAbsFileName(PATH_site . $srcRef);
338  if (GeneralUtility::isFirstPartOfStr($srcRef, $this->fileAdminDir . '/') && !$pI['query'] && $absPath) {
339  // Token and substitute value:
340  // Very important that the src-value is not DeHSC'ed
341  if (strstr($splitContent[$k], $attribs[0][$attributeName])) {
342  $splitContent[$k] = str_replace($attribs[0][$attributeName], '{softref:' . $tokenID . '}', $splitContent[$k]);
343  $elements[$k]['subst'] = array(
344  'type' => 'file',
345  'relFileName' => $srcRef,
346  'tokenID' => $tokenID,
347  'tokenValue' => $attribs[0][$attributeName]
348  );
349  if (!@is_file($absPath)) {
350  $elements[$k]['error'] = 'File does not exist!';
351  }
352  } else {
353  $elements[$k]['error'] = 'Could not substitute attribute (' . $attributeName . ') value with token!';
354  }
355  }
356  }
357  }
358  }
359  $content = implode('', $splitContent);
360  // Process free fileadmin/ references as well:
361  $content = $this->fileadminReferences($content, $elements);
362  // Return output:
363  if (!empty($elements)) {
364  $resultArray = array(
365  'content' => $content,
366  'elements' => $elements
367  );
368  return $resultArray;
369  }
370  }
371 
380  public function findRef_TSconfig($content, $spParams)
381  {
382  $elements = array();
383  // Process free fileadmin/ references from TSconfig
384  $content = $this->fileadminReferences($content, $elements);
385  // Return output:
386  if (!empty($elements)) {
387  $resultArray = array(
388  'content' => $content,
389  'elements' => $elements
390  );
391  return $resultArray;
392  }
393  }
394 
402  public function findRef_email($content, $spParams)
403  {
404  $resultArray = array();
405  // Email:
406  $parts = preg_split('/([^[:alnum:]]+)([A-Za-z0-9\\._-]+[@][A-Za-z0-9\\._-]+[\\.].[A-Za-z0-9]+)/', ' ' . $content . ' ', 10000, PREG_SPLIT_DELIM_CAPTURE);
407  foreach ($parts as $idx => $value) {
408  if ($idx % 3 == 2) {
409  $tokenID = $this->makeTokenID($idx);
410  $elements[$idx] = array();
411  $elements[$idx]['matchString'] = $value;
412  if (is_array($spParams) && in_array('subst', $spParams)) {
413  $parts[$idx] = '{softref:' . $tokenID . '}';
414  $elements[$idx]['subst'] = array(
415  'type' => 'string',
416  'tokenID' => $tokenID,
417  'tokenValue' => $value
418  );
419  }
420  }
421  }
422  // Return output:
423  if (!empty($elements)) {
424  $resultArray = array(
425  'content' => substr(implode('', $parts), 1, -1),
426  'elements' => $elements
427  );
428  return $resultArray;
429  }
430  }
431 
439  public function findRef_url($content, $spParams)
440  {
441  $resultArray = array();
442  // Fileadmin files:
443  $parts = preg_split('/([^[:alnum:]"\']+)((http|ftp):\\/\\/[^[:space:]"\'<>]*)([[:space:]])/', ' ' . $content . ' ', 10000, PREG_SPLIT_DELIM_CAPTURE);
444  foreach ($parts as $idx => $value) {
445  if ($idx % 5 == 3) {
446  unset($parts[$idx]);
447  }
448  if ($idx % 5 == 2) {
449  $tokenID = $this->makeTokenID($idx);
450  $elements[$idx] = array();
451  $elements[$idx]['matchString'] = $value;
452  if (is_array($spParams) && in_array('subst', $spParams)) {
453  $parts[$idx] = '{softref:' . $tokenID . '}';
454  $elements[$idx]['subst'] = array(
455  'type' => 'string',
456  'tokenID' => $tokenID,
457  'tokenValue' => $value
458  );
459  }
460  }
461  }
462  // Return output:
463  if (!empty($elements)) {
464  $resultArray = array(
465  'content' => substr(implode('', $parts), 1, -1),
466  'elements' => $elements
467  );
468  return $resultArray;
469  }
470  }
471 
479  public function findRef_extension_fileref($content, $spParams)
480  {
481  $resultArray = array();
482  // Fileadmin files:
483  $parts = preg_split('/([^[:alnum:]"\']+)(EXT:[[:alnum:]_]+\\/[^[:space:]"\',]*)/', ' ' . $content . ' ', 10000, PREG_SPLIT_DELIM_CAPTURE);
484  foreach ($parts as $idx => $value) {
485  if ($idx % 3 == 2) {
486  $tokenID = $this->makeTokenID($idx);
487  $elements[$idx] = array();
488  $elements[$idx]['matchString'] = $value;
489  }
490  }
491  // Return output:
492  if (!empty($elements)) {
493  $resultArray = array(
494  'content' => substr(implode('', $parts), 1, -1),
495  'elements' => $elements
496  );
497  return $resultArray;
498  }
499  }
500 
501  /*************************
502  *
503  * Helper functions
504  *
505  *************************/
514  public function fileadminReferences($content, &$elements)
515  {
516  // Fileadmin files are found
517  $parts = preg_split('/([^[:alnum:]]+)(' . preg_quote($this->fileAdminDir, '/') . '\\/[^[:space:]"\'<>]*)/', ' ' . $content . ' ', 10000, PREG_SPLIT_DELIM_CAPTURE);
518  // Traverse files:
519  foreach ($parts as $idx => $value) {
520  if ($idx % 3 == 2) {
521  // when file is found, set up an entry for the element:
522  $tokenID = $this->makeTokenID('fileadminReferences:' . $idx);
523  $elements['fileadminReferences.' . $idx] = array();
524  $elements['fileadminReferences.' . $idx]['matchString'] = $value;
525  $elements['fileadminReferences.' . $idx]['subst'] = array(
526  'type' => 'file',
527  'relFileName' => $value,
528  'tokenID' => $tokenID,
529  'tokenValue' => $value
530  );
531  $parts[$idx] = '{softref:' . $tokenID . '}';
532  // Check if the file actually exists:
533  $absPath = GeneralUtility::getFileAbsFileName(PATH_site . $value);
534  if (!@is_file($absPath)) {
535  $elements['fileadminReferences.' . $idx]['error'] = 'File does not exist!';
536  }
537  }
538  }
539  // Implode the content again, removing prefixed and trailing white space:
540  return substr(implode('', $parts), 1, -1);
541  }
542 
554  public function getTypoLinkParts($typolinkValue)
555  {
556  $finalTagParts = GeneralUtility::makeInstance(TypoLinkCodecService::class)->decode($typolinkValue);
557 
558  $link_param = $finalTagParts['url'];
559  // we define various keys below, "url" might be misleading
560  unset($finalTagParts['url']);
561 
562  // Parse URL:
563  $pU = @parse_url($link_param);
564 
565  // If it's a mail address:
566  if (strstr($link_param, '@') && !$pU['scheme']) {
567  $link_param = preg_replace('/^mailto:/i', '', $link_param);
568  $finalTagParts['LINK_TYPE'] = 'mailto';
569  $finalTagParts['url'] = trim($link_param);
570  return $finalTagParts;
571  }
572 
573  list($linkHandlerKeyword, $linkHandlerValue) = explode(':', trim($link_param), 2);
574 
575  // Dispatch available signal slots.
576  $linkHandlerFound = false;
577  list($linkHandlerFound, $finalTagParts) = $this->emitGetTypoLinkParts($linkHandlerFound, $finalTagParts, $linkHandlerKeyword, $linkHandlerValue);
578  if ($linkHandlerFound) {
579  return $finalTagParts;
580  }
581 
582  // Check for FAL link-handler keyword
583  if ($linkHandlerKeyword === 'file') {
584  $finalTagParts['LINK_TYPE'] = 'file';
585  $finalTagParts['identifier'] = trim($link_param);
586  return $finalTagParts;
587  }
588 
589  $isLocalFile = 0;
590  $fileChar = (int)strpos($link_param, '/');
591  $urlChar = (int)strpos($link_param, '.');
592 
593  // Detects if a file is found in site-root and if so it will be treated like a normal file.
594  list($rootFileDat) = explode('?', rawurldecode($link_param));
595  $containsSlash = strstr($rootFileDat, '/');
596  $rFD_fI = pathinfo($rootFileDat);
597  if (trim($rootFileDat) && !$containsSlash && (@is_file(PATH_site . $rootFileDat) || GeneralUtility::inList('php,html,htm', strtolower($rFD_fI['extension'])))) {
598  $isLocalFile = 1;
599  } elseif ($containsSlash) {
600  // Adding this so realurl directories are linked right (non-existing).
601  $isLocalFile = 2;
602  }
603  if ($pU['scheme'] || ($isLocalFile != 1 && $urlChar && (!$containsSlash || $urlChar < $fileChar))) { // url (external): If doubleSlash or if a '.' comes before a '/'.
604  $finalTagParts['LINK_TYPE'] = 'url';
605  $finalTagParts['url'] = $link_param;
606  } elseif ($containsSlash || $isLocalFile) { // file (internal)
607  $splitLinkParam = explode('?', $link_param);
608  if (file_exists(rawurldecode($splitLinkParam[0])) || $isLocalFile) {
609  $finalTagParts['LINK_TYPE'] = 'file';
610  $finalTagParts['filepath'] = rawurldecode($splitLinkParam[0]);
611  $finalTagParts['query'] = $splitLinkParam[1];
612  }
613  } else {
614  // integer or alias (alias is without slashes or periods or commas, that is
615  // 'nospace,alphanum_x,lower,unique' according to definition in $GLOBALS['TCA']!)
616  $finalTagParts['LINK_TYPE'] = 'page';
617 
618  $link_params_parts = explode('#', $link_param);
619  // Link-data del
620  $link_param = trim($link_params_parts[0]);
621 
622  if ((string)$link_params_parts[1] !== '') {
623  $finalTagParts['anchor'] = trim($link_params_parts[1]);
624  }
625 
626  // Splitting the parameter by ',' and if the array counts more than 1 element it's a id/type/? pair
627  $pairParts = GeneralUtility::trimExplode(',', $link_param);
628  if (count($pairParts) > 1) {
629  $link_param = $pairParts[0];
630  $finalTagParts['type'] = $pairParts[1]; // Overruling 'type'
631  }
632 
633  // Checking if the id-parameter is an alias.
634  if ((string)$link_param !== '') {
635  if (!\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($link_param)) {
636  $finalTagParts['alias'] = $link_param;
637  $link_param = $this->getPageIdFromAlias($link_param);
638  }
639 
640  $finalTagParts['page_id'] = (int)$link_param;
641  }
642  }
643 
644  return $finalTagParts;
645  }
646 
657  public function setTypoLinkPartsElement($tLP, &$elements, $content, $idx)
658  {
659  // Initialize, set basic values. In any case a link will be shown
660  $tokenID = $this->makeTokenID('setTypoLinkPartsElement:' . $idx);
661  $elements[$tokenID . ':' . $idx] = array();
662  $elements[$tokenID . ':' . $idx]['matchString'] = $content;
663  // Based on link type, maybe do more:
664  switch ((string)$tLP['LINK_TYPE']) {
665  case 'mailto':
666 
667  case 'url':
668  // Mail addresses and URLs can be substituted manually:
669  $elements[$tokenID . ':' . $idx]['subst'] = array(
670  'type' => 'string',
671  'tokenID' => $tokenID,
672  'tokenValue' => $tLP['url']
673  );
674  // Output content will be the token instead:
675  $content = '{softref:' . $tokenID . '}';
676  break;
677  case 'file':
678  // Process files referenced by their FAL uid
679  if ($tLP['identifier']) {
680  list($linkHandlerKeyword, $linkHandlerValue) = explode(':', trim($tLP['identifier']), 2);
681  if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($linkHandlerValue)) {
682  // Token and substitute value
683  $elements[$tokenID . ':' . $idx]['subst'] = array(
684  'type' => 'db',
685  'recordRef' => 'sys_file:' . $linkHandlerValue,
686  'tokenID' => $tokenID,
687  'tokenValue' => $tLP['identifier'],
688  );
689  // Output content will be the token instead:
690  $content = '{softref:' . $tokenID . '}';
691  } else {
692  // This is a link to a folder...
693  return $content;
694  }
695 
696  // Process files found in fileadmin directory:
697  } elseif (!$tLP['query']) {
698  // We will not process files which has a query added to it. That will look like a script we don't want to move.
699  // File must be inside fileadmin/
700  if (GeneralUtility::isFirstPartOfStr($tLP['filepath'], $this->fileAdminDir . '/')) {
701  // Set up the basic token and token value for the relative file:
702  $elements[$tokenID . ':' . $idx]['subst'] = array(
703  'type' => 'file',
704  'relFileName' => $tLP['filepath'],
705  'tokenID' => $tokenID,
706  'tokenValue' => $tLP['filepath']
707  );
708  // Depending on whether the file exists or not we will set the
709  $absPath = GeneralUtility::getFileAbsFileName(PATH_site . $tLP['filepath']);
710  if (!@is_file($absPath)) {
711  $elements[$tokenID . ':' . $idx]['error'] = 'File does not exist!';
712  }
713  // Output content will be the token instead
714  $content = '{softref:' . $tokenID . '}';
715  } else {
716  return $content;
717  }
718  } else {
719  return $content;
720  }
721  break;
722  case 'page':
723  // Rebuild page reference typolink part:
724  $content = '';
725  // Set page id:
726  if ($tLP['page_id']) {
727  $content .= '{softref:' . $tokenID . '}';
728  $elements[$tokenID . ':' . $idx]['subst'] = array(
729  'type' => 'db',
730  'recordRef' => 'pages:' . $tLP['page_id'],
731  'tokenID' => $tokenID,
732  'tokenValue' => $tLP['alias'] ? $tLP['alias'] : $tLP['page_id']
733  );
734  }
735  // Add type if applicable
736  if ((string)$tLP['type'] !== '') {
737  $content .= ',' . $tLP['type'];
738  }
739  // Add anchor if applicable
740  if ((string)$tLP['anchor'] !== '') {
741  // Anchor is assumed to point to a content elements:
742  if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($tLP['anchor'])) {
743  // Initialize a new entry because we have a new relation:
744  $newTokenID = $this->makeTokenID('setTypoLinkPartsElement:anchor:' . $idx);
745  $elements[$newTokenID . ':' . $idx] = array();
746  $elements[$newTokenID . ':' . $idx]['matchString'] = 'Anchor Content Element: ' . $tLP['anchor'];
747  $content .= '#{softref:' . $newTokenID . '}';
748  $elements[$newTokenID . ':' . $idx]['subst'] = array(
749  'type' => 'db',
750  'recordRef' => 'tt_content:' . $tLP['anchor'],
751  'tokenID' => $newTokenID,
752  'tokenValue' => $tLP['anchor']
753  );
754  } else {
755  // Anchor is a hardcoded string
756  $content .= '#' . $tLP['type'];
757  }
758  }
759  break;
760  default:
761  $linkHandlerFound = false;
762  list($linkHandlerFound, $tLP, $content, $newElements) = $this->emitSetTypoLinkPartsElement($linkHandlerFound, $tLP, $content, $elements, $idx, $tokenID);
763  // We need to merge the array, otherwise we would loose the reference.
764  \TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($elements, $newElements);
765 
766  if (!$linkHandlerFound) {
767  $elements[$tokenID . ':' . $idx]['error'] = 'Couldn\'t decide typolink mode.';
768  return $content;
769  }
770  }
771  // Finally, for all entries that was rebuild with tokens, add target, class, title and additionalParams in the end:
772  $tLP['url'] = $content;
773  $content = GeneralUtility::makeInstance(TypoLinkCodecService::class)->encode($tLP);
774 
775  // Return rebuilt typolink value:
776  return $content;
777  }
778 
785  public function getPageIdFromAlias($link_param)
786  {
787  $pRec = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordsByField('pages', 'alias', $link_param);
788  return $pRec[0]['uid'];
789  }
790 
797  public function makeTokenID($index = '')
798  {
799  return md5($this->tokenID_basePrefix . ':' . $index);
800  }
801 
805  protected function getSignalSlotDispatcher()
806  {
807  return GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher::class);
808  }
809 
817  protected function emitGetTypoLinkParts($linkHandlerFound, $finalTagParts, $linkHandlerKeyword, $linkHandlerValue)
818  {
819  return $this->getSignalSlotDispatcher()->dispatch(get_class($this), 'getTypoLinkParts', array($linkHandlerFound, $finalTagParts, $linkHandlerKeyword, $linkHandlerValue));
820  }
821 
831  protected function emitSetTypoLinkPartsElement($linkHandlerFound, $tLP, $content, $elements, $idx, $tokenID)
832  {
833  return $this->getSignalSlotDispatcher()->dispatch(get_class($this), 'setTypoLinkPartsElement', array($linkHandlerFound, $tLP, $content, $elements, $idx, $tokenID, $this));
834  }
835 }