‪TYPO3CMS  ‪main
DatabaseRecordLinkBuilder.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Psr\Http\Message\ServerRequestInterface;
24 use TYPO3\CMS\Core\LinkHandling\TypoLinkCodecService;
30 
35 {
36  public function ‪build(array &$linkDetails, string $linkText, string $target, array $conf): ‪LinkResultInterface
37  {
38  $request = $this->contentObjectRenderer->getRequest();
39  $pageTsConfig = $this->‪getPageTsConfig($request);
40  $configurationKey = $linkDetails['identifier'] . '.';
41  $typoScriptArray = $request->getAttribute('frontend.typoscript')?->getSetupArray() ?? [];
42  $configuration = $typoScriptArray['config.']['recordLinks.'] ?? [];
43  $linkHandlerConfiguration = $pageTsConfig['TCEMAIN.']['linkHandler.'] ?? [];
44 
45  if (!isset($configuration[$configurationKey], $linkHandlerConfiguration[$configurationKey])) {
46  throw new ‪UnableToLinkException(
47  'Configuration how to link "' . $linkDetails['typoLinkParameter'] . '" was not found, so "' . $linkText . '" was not linked.',
48  1490989149,
49  null,
50  $linkText
51  );
52  }
53  $typoScriptConfiguration = $configuration[$configurationKey]['typolink.'];
54  $linkHandlerConfiguration = $linkHandlerConfiguration[$configurationKey]['configuration.'];
55  $databaseTable = (string)($linkHandlerConfiguration['table'] ?? '');
56 
57  $pageRepository = GeneralUtility::makeInstance(PageRepository::class);
58  if ($configuration[$configurationKey]['forceLink'] ?? false) {
59  ‪$record = $pageRepository->getRawRecord($databaseTable, (int)$linkDetails['uid']);
60  } else {
61  ‪$record = $pageRepository->checkRecord($databaseTable, (int)$linkDetails['uid']);
62  $languageAspect = GeneralUtility::makeInstance(Context::class)->getAspect('language');
63  $languageField = (string)(‪$GLOBALS['TCA'][$databaseTable]['ctrl']['languageField'] ?? '');
64 
65  if (is_array(‪$record) && $languageField !== '') {
66  $languageIdOfRecord = ‪$record[$languageField];
67  // If a record is already in a localized version OR if the record is set to "All Languages"
68  // we allow the generation of the link
69  if ($languageIdOfRecord === 0 && $languageAspect->doOverlays()) {
70  $overlay = $pageRepository->getLanguageOverlay(
71  $databaseTable,
72  ‪$record,
73  $languageAspect
74  );
75  // If the record is not translated (overlays enabled), even though it should have been done
76  // We avoid linking to it
77  if (!isset($overlay['_LOCALIZED_UID'])) {
78  ‪$record = 0;
79  }
80  }
81  }
82  }
83  if (‪$record === null) {
84  throw new ‪UnableToLinkException(
85  'Record not found for "' . $linkDetails['typoLinkParameter'] . '" was not found, so "' . $linkText . '" was not linked.',
86  1490989659,
87  null,
88  $linkText
89  );
90  }
91 
92  // Unset the parameter part of the given TypoScript configuration while keeping
93  // config that has been set in addition.
94  unset($conf['parameter.']);
95 
96  $typoLinkCodecService = GeneralUtility::makeInstance(TypoLinkCodecService::class);
97  $parameterFromDb = $typoLinkCodecService->decode((string)($conf['parameter'] ?? ''));
98  unset($parameterFromDb['url']);
99  $parameterFromTypoScript = $typoLinkCodecService->decode((string)($typoScriptConfiguration['parameter'] ?? ''));
100  $parameter = array_replace_recursive($parameterFromTypoScript, array_filter($parameterFromDb));
101  $typoScriptConfiguration['parameter'] = $typoLinkCodecService->encode($parameter);
102 
103  $typoScriptConfiguration = array_replace_recursive($conf, $typoScriptConfiguration);
104 
105  if (!empty($linkDetails['fragment'])) {
106  $typoScriptConfiguration['section'] = $linkDetails['fragment'];
107  }
108  // Build the full link to the record by calling LinkFactory again ("inception")
109  $localContentObjectRenderer = GeneralUtility::makeInstance(ContentObjectRenderer::class);
110  $localContentObjectRenderer->setRequest($request);
111  $localContentObjectRenderer->start(‪$record, $databaseTable);
112  $localContentObjectRenderer->parameters = $this->contentObjectRenderer->parameters;
113  return $localContentObjectRenderer->createLink($linkText, $typoScriptConfiguration);
114  }
115 
119  protected function ‪getPageTsConfig(ServerRequestInterface $request): array
120  {
121  $pageInformation = $request->getAttribute('frontend.page.information');
122  $id = $pageInformation->getId();
123  $runtimeCache = GeneralUtility::makeInstance(CacheManager::class)->getCache('runtime');
124  $pageTsConfig = $runtimeCache->get('pageTsConfig-' . $id);
125  if ($pageTsConfig instanceof ‪PageTsConfig) {
126  return $pageTsConfig->getPageTsConfigArray();
127  }
128  $fullRootLine = $pageInformation->getRootLine();
129  ksort($fullRootLine);
130  $site = $request->getAttribute('site') ?? new ‪NullSite();
131  $pageTsConfigFactory = GeneralUtility::makeInstance(PageTsConfigFactory::class);
132  $pageTsConfig = $pageTsConfigFactory->create($fullRootLine, $site);
133  $runtimeCache->set('pageTsConfig-' . $id, $pageTsConfig);
134  return $pageTsConfig->getPageTsConfigArray();
135  }
136 }
‪TYPO3\CMS\Core\Site\Entity\NullSite
Definition: NullSite.php:32
‪TYPO3\CMS\Core\Context\Context
Definition: Context.php:54
‪TYPO3\CMS\Core\TypoScript\PageTsConfig
Definition: PageTsConfig.php:28
‪TYPO3\CMS\Webhooks\Message\$record
‪identifier readonly int readonly array $record
Definition: PageModificationMessage.php:36
‪TYPO3\CMS\Core\Cache\CacheManager
Definition: CacheManager.php:36
‪TYPO3\CMS\Core\TypoScript\PageTsConfigFactory
Definition: PageTsConfigFactory.php:44
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
Definition: ContentObjectRenderer.php:102
‪TYPO3\CMS\Core\Domain\Repository\PageRepository
Definition: PageRepository.php:69
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52