getCurrentPageId());
return $tsConfig['TCEMAIN.']['linkHandler.']['page.']['configuration.'] ?? [];
}
/**
* Encode a typolink via ajax.
* This avoids implementing the encoding functionality again in JS for the browser.
*/
public function encodeTypoLink(ServerRequestInterface $request): ResponseInterface
{
$typoLinkParts = $request->getQueryParams();
if (isset($typoLinkParts['params'])) {
$typoLinkParts['additionalParams'] = $typoLinkParts['params'];
unset($typoLinkParts['params']);
}
$typoLink = $this->typoLinkCodecService->encode($typoLinkParts);
return new JsonResponse(['typoLink' => $typoLink]);
}
protected function initDocumentTemplate(): void
{
if (!$this->areFieldChangeFunctionsValid() && !$this->areFieldChangeFunctionsValid(true)) {
$this->parameters['fieldChangeFunc'] = [];
}
$this->pageRenderer->getJavaScriptRenderer()->addJavaScriptModuleInstruction(
JavaScriptModuleInstruction::create('@typo3/backend/form-engine-link-browser-adapter.js')
// @todo use a proper constructor when migrating to TypeScript
->invoke('setOnFieldChangeItems', $this->parameters['fieldChangeFunc'])
);
}
protected function getCurrentPageId(): int
{
$pageId = 0;
$browserParameters = $this->parameters;
if (isset($browserParameters['pid'])) {
$pageId = $browserParameters['pid'];
} elseif (isset($browserParameters['itemName'])) {
// parse data[
][]
if (preg_match('~data\[([^]]*)\]\[([^]]*)\]~', $browserParameters['itemName'], $matches)) {
$recordArray = BackendUtility::getRecord($matches['1'], $matches['2']);
if (is_array($recordArray)) {
$pageId = $recordArray['pid'];
}
}
}
return (int)BackendUtility::getRealPageId((string)$browserParameters['table'], (int)$browserParameters['uid'], (int)$pageId);
}
protected function initCurrentUrl(): void
{
$currentLink = isset($this->parameters['currentValue']) ? trim($this->parameters['currentValue']) : '';
/** @var array $currentLinkParts */
$currentLinkParts = $this->typoLinkCodecService->decode($currentLink);
$currentLinkParts['params'] = $currentLinkParts['additionalParams'];
unset($currentLinkParts['additionalParams']);
if (!empty($currentLinkParts['url'])) {
try {
$data = $this->linkService->resolve($currentLinkParts['url']);
$currentLinkParts['type'] = $data['type'];
unset($data['type']);
$currentLinkParts['url'] = $data;
} catch (UnknownLinkHandlerException $e) {
$this->flashMessageService->getMessageQueueByIdentifier()->enqueue(
new FlashMessage(message: $e->getMessage(), severity: ContextualFeedbackSeverity::ERROR)
);
}
}
$this->currentLinkParts = $currentLinkParts;
parent::initCurrentUrl();
}
/**
* Determines whether submitted field change functions are valid
* and are coming from the system and not from an external abuse.
*
* @param bool $handleFlexformSections Whether to handle flexform sections differently
* @return bool Whether the submitted field change functions are valid
*/
protected function areFieldChangeFunctionsValid(bool $handleFlexformSections = false): bool
{
$result = false;
if (isset($this->parameters['fieldChangeFunc']) && is_array($this->parameters['fieldChangeFunc']) && isset($this->parameters['fieldChangeFuncHash'])) {
$matches = [];
$pattern = '#\\[el\\]\\[(([^]-]+-[^]-]+-)(idx\\d+-)([^]]+))\\]#i';
$fieldChangeFunctions = $this->parameters['fieldChangeFunc'];
// Special handling of flexform sections:
// Field change functions are modified in JavaScript, thus the hash is always invalid
if ($handleFlexformSections && preg_match($pattern, $this->parameters['itemName'], $matches)) {
$originalName = $matches[1];
$cleanedName = $matches[2] . $matches[4];
$fieldChangeFunctions = $this->strReplaceRecursively(
$originalName,
$cleanedName,
$fieldChangeFunctions
);
}
$result = hash_equals($this->hashService->hmac(serialize($fieldChangeFunctions), 'backend-link-browser'), $this->parameters['fieldChangeFuncHash']);
}
return $result;
}
protected function strReplaceRecursively(string $search, string $replace, array $array): array
{
foreach ($array as &$item) {
if (is_array($item)) {
$item = $this->strReplaceRecursively($search, $replace, $item);
} else {
$item = str_replace($search, $replace, $item);
}
}
return $array;
}
}