‪TYPO3CMS  ‪main
LinkBrowserController.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\ResponseInterface;
21 use Psr\Http\Message\ServerRequestInterface;
23 use TYPO3\CMS\Backend\Utility\BackendUtility;
27 use TYPO3\CMS\Core\LinkHandling\TypoLinkCodecService;
33 
37 #[AsController]
38 class ‪LinkBrowserController extends AbstractLinkBrowserController
39 {
40  public function ‪__construct(
41  protected readonly ‪LinkService $linkService,
42  protected readonly TypoLinkCodecService $typoLinkCodecService,
43  protected readonly ‪FlashMessageService $flashMessageService,
44  ) {}
45 
46  public function ‪getConfiguration(): array
47  {
48  $tsConfig = BackendUtility::getPagesTSconfig($this->‪getCurrentPageId());
49  return $tsConfig['TCEMAIN.']['linkHandler.']['page.']['configuration.'] ?? [];
50  }
51 
56  public function ‪encodeTypoLink(ServerRequestInterface $request): ResponseInterface
57  {
58  $typoLinkParts = $request->getQueryParams();
59  if (isset($typoLinkParts['params'])) {
60  $typoLinkParts['additionalParams'] = $typoLinkParts['params'];
61  unset($typoLinkParts['params']);
62  }
63  $typoLink = $this->typoLinkCodecService->encode($typoLinkParts);
64  return new ‪JsonResponse(['typoLink' => $typoLink]);
65  }
66 
67  protected function ‪initDocumentTemplate(): void
68  {
70  $this->parameters['fieldChangeFunc'] = [];
71  }
72  $this->pageRenderer->getJavaScriptRenderer()->addJavaScriptModuleInstruction(
73  ‪JavaScriptModuleInstruction::create('@typo3/backend/form-engine-link-browser-adapter.js')
74  // @todo use a proper constructor when migrating to TypeScript
75  ->invoke('setOnFieldChangeItems', $this->parameters['fieldChangeFunc'])
76  );
77  }
78 
79  protected function ‪getCurrentPageId(): int
80  {
81  $pageId = 0;
82  $browserParameters = $this->parameters;
83  if (isset($browserParameters['pid'])) {
84  $pageId = $browserParameters['pid'];
85  } elseif (isset($browserParameters['itemName'])) {
86  // parse data[<table>][<uid>]
87  if (preg_match('~data\[([^]]*)\]\[([^]]*)\]~', $browserParameters['itemName'], $matches)) {
88  $recordArray = BackendUtility::getRecord($matches['1'], $matches['2']);
89  if (is_array($recordArray)) {
90  $pageId = $recordArray['pid'];
91  }
92  }
93  }
94  return (int)BackendUtility::getTSCpidCached($browserParameters['table'], $browserParameters['uid'], $pageId)[0];
95  }
96 
97  protected function ‪initCurrentUrl(): void
98  {
99  $currentLink = isset($this->parameters['currentValue']) ? trim($this->parameters['currentValue']) : '';
101  $currentLinkParts = $this->typoLinkCodecService->decode($currentLink);
102  $currentLinkParts['params'] = $currentLinkParts['additionalParams'];
103  unset($currentLinkParts['additionalParams']);
104 
105  if (!empty($currentLinkParts['url'])) {
106  try {
107  $data = $this->linkService->resolve($currentLinkParts['url']);
108  $currentLinkParts['type'] = $data['type'];
109  unset($data['type']);
110  $currentLinkParts['url'] = $data;
111  } catch (‪UnknownLinkHandlerException $e) {
112  $this->flashMessageService->getMessageQueueByIdentifier()->enqueue(
113  new ‪FlashMessage(message: $e->getMessage(), severity: ContextualFeedbackSeverity::ERROR)
114  );
115  }
116  }
117 
118  $this->currentLinkParts = $currentLinkParts;
119 
120  parent::initCurrentUrl();
121  }
122 
130  protected function ‪areFieldChangeFunctionsValid(bool $handleFlexformSections = false): bool
131  {
132  $result = false;
133  if (isset($this->parameters['fieldChangeFunc']) && is_array($this->parameters['fieldChangeFunc']) && isset($this->parameters['fieldChangeFuncHash'])) {
134  $matches = [];
135  $pattern = '#\\[el\\]\\[(([^]-]+-[^]-]+-)(idx\\d+-)([^]]+))\\]#i';
136  $fieldChangeFunctions = $this->parameters['fieldChangeFunc'];
137  // Special handling of flexform sections:
138  // Field change functions are modified in JavaScript, thus the hash is always invalid
139  if ($handleFlexformSections && preg_match($pattern, $this->parameters['itemName'], $matches)) {
140  $originalName = $matches[1];
141  $cleanedName = $matches[2] . $matches[4];
142  $fieldChangeFunctions = $this->‪strReplaceRecursively(
143  $originalName,
144  $cleanedName,
145  $fieldChangeFunctions
146  );
147  }
148  $result = hash_equals(‪GeneralUtility::hmac(serialize($fieldChangeFunctions), 'backend-link-browser'), $this->parameters['fieldChangeFuncHash']);
149  }
150  return $result;
151  }
152 
153  protected function ‪strReplaceRecursively(string $search, string $replace, array $array): array
154  {
155  foreach ($array as &$item) {
156  if (is_array($item)) {
157  $item = $this->‪strReplaceRecursively($search, $replace, $item);
158  } else {
159  $item = str_replace($search, $replace, $item);
160  }
161  }
162  return $array;
163  }
164 }
‪TYPO3\CMS\Core\Page\JavaScriptModuleInstruction\create
‪static create(string $name, string $exportName=null)
Definition: JavaScriptModuleInstruction.php:47
‪TYPO3\CMS\Core\Page\JavaScriptModuleInstruction
Definition: JavaScriptModuleInstruction.php:23
‪TYPO3\CMS\Core\Type\ContextualFeedbackSeverity
‪ContextualFeedbackSeverity
Definition: ContextualFeedbackSeverity.php:25
‪TYPO3\CMS\Core\Utility\GeneralUtility\hmac
‪static string hmac($input, $additionalSecret='')
Definition: GeneralUtility.php:474
‪TYPO3\CMS\Core\Messaging\FlashMessage
Definition: FlashMessage.php:27
‪TYPO3\CMS\Core\Http\JsonResponse
Definition: JsonResponse.php:28
‪TYPO3\CMS\Backend\Attribute\AsController
Definition: AsController.php:25
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Backend\Controller
Definition: AboutController.php:18
‪TYPO3\CMS\Core\Messaging\FlashMessageService
Definition: FlashMessageService.php:27