currentLinkParts */ protected function initCurrentUrl() { $currentLink = isset($this->parameters['currentValue']) ? trim($this->parameters['currentValue']) : ''; $currentLinkParts = GeneralUtility::makeInstance(TypoLinkCodecService::class)->decode($currentLink); $currentLinkParts['params'] = $currentLinkParts['additionalParams']; unset($currentLinkParts['additionalParams']); if (!empty($currentLinkParts['url'])) { $linkService = GeneralUtility::makeInstance(LinkService::class); $data = $linkService->resolve($currentLinkParts['url']); $currentLinkParts['type'] = $data['type']; unset($data['type']); $currentLinkParts['url'] = $data; } $this->currentLinkParts = $currentLinkParts; parent::initCurrentUrl(); } /** * Initialize document template object */ protected function initDocumentTemplate() { parent::initDocumentTemplate(); if (!$this->areFieldChangeFunctionsValid() && !$this->areFieldChangeFunctionsValid(true)) { $this->parameters['fieldChangeFunc'] = []; } unset($this->parameters['fieldChangeFunc']['alert']); $update = []; foreach ($this->parameters['fieldChangeFunc'] as $v) { $update[] = 'parent.opener.' . $v; } $inlineJS = implode(LF, $update); $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class); $pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/FormEngineLinkBrowserAdapter', 'function(FormEngineLinkBrowserAdapter) { FormEngineLinkBrowserAdapter.updateFunctions = function() {' . $inlineJS . '}; }'); } /** * Encode a typolink via ajax * * This avoids to implement the encoding functionality again in JS for the browser. * * @param ServerRequestInterface $request * @return ResponseInterface */ public function encodeTypoLink(ServerRequestInterface $request): ResponseInterface { $typoLinkParts = $request->getQueryParams(); if (isset($typoLinkParts['params'])) { $typoLinkParts['additionalParams'] = $typoLinkParts['params']; unset($typoLinkParts['params']); } $typoLink = GeneralUtility::makeInstance(TypoLinkCodecService::class)->encode($typoLinkParts); return new JsonResponse(['typoLink' => $typoLink]); } /** * 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($handleFlexformSections = false) { $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]; foreach ($fieldChangeFunctions as &$value) { $value = str_replace($originalName, $cleanedName, $value); } unset($value); } $result = hash_equals(GeneralUtility::hmac(serialize($fieldChangeFunctions), 'backend-link-browser'), $this->parameters['fieldChangeFuncHash']); } return $result; } /** * Get attributes for the body tag * * @return string[] Array of body-tag attributes */ protected function getBodyTagAttributes() { $parameters = parent::getBodyTagAttributes(); $formEngineParameters['fieldChangeFunc'] = $this->parameters['fieldChangeFunc']; $formEngineParameters['fieldChangeFuncHash'] = GeneralUtility::hmac(serialize($this->parameters['fieldChangeFunc']), 'backend-link-browser'); $parameters['data-add-on-params'] .= HttpUtility::buildQueryString(['P' => $formEngineParameters], '&'); return $parameters; } /** * Return the ID of current page * * @return int */ protected function getCurrentPageId() { $pageId = 0; $browserParameters = $this->parameters; if (isset($browserParameters['pid'])) { $pageId = $browserParameters['pid']; } elseif (isset($browserParameters['itemName'])) { // parse data[