[BUGFIX] Prematurely end data array processing on invalid item
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Classes / Typolink / DatabaseRecordLinkBuilder.php
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
18 namespace TYPO3\CMS\Frontend\Typolink;
19
20 use TYPO3\CMS\Core\Utility\GeneralUtility;
21 use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
22 use TYPO3\CMS\Frontend\Service\TypoLinkCodecService;
23
24 /**
25 * Builds a TypoLink to a database record
26 */
27 class DatabaseRecordLinkBuilder extends AbstractTypolinkBuilder
28 {
29 /**
30 * @inheritdoc
31 */
32 public function build(array &$linkDetails, string $linkText, string $target, array $conf): array
33 {
34 $tsfe = $this->getTypoScriptFrontendController();
35 $pageTsConfig = $tsfe->getPagesTSconfig();
36 $configurationKey = $linkDetails['identifier'] . '.';
37 $configuration = $tsfe->tmpl->setup['config.']['recordLinks.'];
38 $linkHandlerConfiguration = $pageTsConfig['TCEMAIN.']['linkHandler.'];
39
40 if (!isset($configuration[$configurationKey], $linkHandlerConfiguration[$configurationKey])) {
41 throw new UnableToLinkException(
42 'Configuration how to link "' . $linkDetails['typoLinkParameter'] . '" was not found, so "' . $linkText . '" was not linked.',
43 1490989149,
44 null,
45 $linkText
46 );
47 }
48 $typoScriptConfiguration = $configuration[$configurationKey]['typolink.'];
49 $linkHandlerConfiguration = $linkHandlerConfiguration[$configurationKey]['configuration.'];
50
51 if ($configuration[$configurationKey]['forceLink']) {
52 $record = $tsfe->sys_page->getRawRecord($linkHandlerConfiguration['table'], $linkDetails['uid']);
53 } else {
54 $record = $tsfe->sys_page->checkRecord($linkHandlerConfiguration['table'], $linkDetails['uid']);
55 }
56 if ($record === 0) {
57 throw new UnableToLinkException(
58 'Record not found for "' . $linkDetails['typoLinkParameter'] . '" was not found, so "' . $linkText . '" was not linked.',
59 1490989659,
60 null,
61 $linkText
62 );
63 }
64
65 // Unset the parameter part of the given TypoScript configuration while keeping
66 // config that has been set in addition.
67 unset($conf['parameter.']);
68
69 $typoLinkCodecService = GeneralUtility::makeInstance(TypoLinkCodecService::class);
70 $parameterFromDb = $typoLinkCodecService->decode($conf['parameter']);
71 unset($parameterFromDb['url']);
72 $parameterFromTypoScript = $typoLinkCodecService->decode($typoScriptConfiguration['parameter']);
73 $parameter = array_replace_recursive($parameterFromTypoScript, array_filter($parameterFromDb));
74 $typoScriptConfiguration['parameter'] = $typoLinkCodecService->encode($parameter);
75
76 $typoScriptConfiguration = array_replace_recursive($conf, $typoScriptConfiguration);
77
78 if (!empty($linkDetails['fragment'])) {
79 $typoScriptConfiguration['section'] = $linkDetails['fragment'];
80 }
81 // Build the full link to the record
82 $request = $this->contentObjectRenderer->getRequest();
83 $localContentObjectRenderer = GeneralUtility::makeInstance(ContentObjectRenderer::class);
84 $localContentObjectRenderer->start($record, $linkHandlerConfiguration['table'], $request);
85 $localContentObjectRenderer->parameters = $this->contentObjectRenderer->parameters;
86 $link = $localContentObjectRenderer->typoLink($linkText, $typoScriptConfiguration);
87
88 $this->contentObjectRenderer->lastTypoLinkLD = $localContentObjectRenderer->lastTypoLinkLD;
89 $this->contentObjectRenderer->lastTypoLinkUrl = $localContentObjectRenderer->lastTypoLinkUrl;
90 $this->contentObjectRenderer->lastTypoLinkTarget = $localContentObjectRenderer->lastTypoLinkTarget;
91
92 // nasty workaround so typolink stops putting a link together, there is a link already built
93 throw new UnableToLinkException(
94 '',
95 1491130170,
96 null,
97 $link
98 );
99 }
100 }