[BUGFIX] Prematurely end data array processing on invalid item
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Classes / Typolink / FileOrFolderLinkBuilder.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\Resource\FileInterface;
21 use TYPO3\CMS\Core\Resource\Folder;
22 use TYPO3\CMS\Frontend\Http\UrlProcessorInterface;
23
24 /**
25 * Builds a TypoLink to a folder or file
26 */
27 class FileOrFolderLinkBuilder extends AbstractTypolinkBuilder
28 {
29 /**
30 * @inheritdoc
31 */
32 public function build(array &$linkDetails, string $linkText, string $target, array $conf): array
33 {
34 $fileOrFolderObject = $linkDetails['file'] ?: $linkDetails['folder'];
35 // check if the file exists or if a / is contained (same check as in detectLinkType)
36 if (!($fileOrFolderObject instanceof FileInterface) && !($fileOrFolderObject instanceof Folder)) {
37 throw new UnableToLinkException(
38 'File "' . $linkDetails['typoLinkParameter'] . '" did not exist, so "' . $linkText . '" was not linked.',
39 1490989449,
40 null,
41 $linkText
42 );
43 }
44
45 $tsfe = $this->getTypoScriptFrontendController();
46 $linkLocation = $fileOrFolderObject->getPublicUrl();
47 if ($linkLocation === null) {
48 // set the linkLocation to an empty string if null,
49 // so it does not collide with the various string functions
50 $linkLocation = '';
51 }
52 // Setting title if blank value to link
53 $linkText = $this->encodeFallbackLinkTextIfLinkTextIsEmpty($linkText, rawurldecode($linkLocation));
54 if (strpos($linkLocation, '/') !== 0
55 && parse_url($linkLocation, PHP_URL_SCHEME) === null
56 ) {
57 $linkLocation = $tsfe->absRefPrefix . $linkLocation;
58 }
59 $url = $this->processUrl(UrlProcessorInterface::CONTEXT_FILE, $linkLocation, $conf) ?? '';
60 if (!empty($linkDetails['fragment'])) {
61 $url .= '#' . $linkDetails['fragment'];
62 }
63 return [
64 $this->forceAbsoluteUrl($url, $conf),
65 $linkText,
66 $target ?: $this->resolveTargetAttribute($conf, 'fileTarget', false, $tsfe->fileTarget)
67 ];
68 }
69 }