[TASK] Deprecate PageRenderer->loadJQuery()
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Controller / LinkBrowserController.php
1 <?php
2 namespace TYPO3\CMS\Backend\Controller;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use Psr\Http\Message\ResponseInterface;
18 use Psr\Http\Message\ServerRequestInterface;
19 use TYPO3\CMS\Backend\Utility\BackendUtility;
20 use TYPO3\CMS\Core\Http\JsonResponse;
21 use TYPO3\CMS\Core\LinkHandling\LinkService;
22 use TYPO3\CMS\Core\Page\PageRenderer;
23 use TYPO3\CMS\Core\Utility\GeneralUtility;
24 use TYPO3\CMS\Frontend\Service\TypoLinkCodecService;
25 use TYPO3\CMS\Recordlist\Controller\AbstractLinkBrowserController;
26
27 /**
28 * Extended controller for link browser
29 */
30 class LinkBrowserController extends AbstractLinkBrowserController
31 {
32 /**
33 * Initialize $this->currentLinkParts
34 */
35 protected function initCurrentUrl()
36 {
37 $currentLink = isset($this->parameters['currentValue']) ? trim($this->parameters['currentValue']) : '';
38 $currentLinkParts = GeneralUtility::makeInstance(TypoLinkCodecService::class)->decode($currentLink);
39 $currentLinkParts['params'] = $currentLinkParts['additionalParams'];
40 unset($currentLinkParts['additionalParams']);
41
42 if (!empty($currentLinkParts['url'])) {
43 $linkService = GeneralUtility::makeInstance(LinkService::class);
44 $data = $linkService->resolve($currentLinkParts['url']);
45 $currentLinkParts['type'] = $data['type'];
46 unset($data['type']);
47 $currentLinkParts['url'] = $data;
48 }
49
50 $this->currentLinkParts = $currentLinkParts;
51
52 parent::initCurrentUrl();
53 }
54
55 /**
56 * Initialize document template object
57 */
58 protected function initDocumentTemplate()
59 {
60 parent::initDocumentTemplate();
61
62 if (!$this->areFieldChangeFunctionsValid() && !$this->areFieldChangeFunctionsValid(true)) {
63 $this->parameters['fieldChangeFunc'] = [];
64 }
65 unset($this->parameters['fieldChangeFunc']['alert']);
66 $update = [];
67 foreach ($this->parameters['fieldChangeFunc'] as $v) {
68 $update[] = 'parent.opener.' . $v;
69 }
70 $inlineJS = implode(LF, $update);
71
72 $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
73 $pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/FormEngineLinkBrowserAdapter', 'function(FormEngineLinkBrowserAdapter) {
74 FormEngineLinkBrowserAdapter.updateFunctions = function() {' . $inlineJS . '};
75 }');
76 }
77
78 /**
79 * Encode a typolink via ajax
80 *
81 * This avoids to implement the encoding functionality again in JS for the browser.
82 *
83 * @param ServerRequestInterface $request
84 * @return ResponseInterface
85 */
86 public function encodeTypoLink(ServerRequestInterface $request): ResponseInterface
87 {
88 $typoLinkParts = $request->getQueryParams();
89 if (isset($typoLinkParts['params'])) {
90 $typoLinkParts['additionalParams'] = $typoLinkParts['params'];
91 unset($typoLinkParts['params']);
92 }
93
94 $typoLink = GeneralUtility::makeInstance(TypoLinkCodecService::class)->encode($typoLinkParts);
95 return new JsonResponse(['typoLink' => $typoLink]);
96 }
97
98 /**
99 * Determines whether submitted field change functions are valid
100 * and are coming from the system and not from an external abuse.
101 *
102 * @param bool $handleFlexformSections Whether to handle flexform sections differently
103 * @return bool Whether the submitted field change functions are valid
104 */
105 protected function areFieldChangeFunctionsValid($handleFlexformSections = false)
106 {
107 $result = false;
108 if (isset($this->parameters['fieldChangeFunc']) && is_array($this->parameters['fieldChangeFunc']) && isset($this->parameters['fieldChangeFuncHash'])) {
109 $matches = [];
110 $pattern = '#\\[el\\]\\[(([^]-]+-[^]-]+-)(idx\\d+-)([^]]+))\\]#i';
111 $fieldChangeFunctions = $this->parameters['fieldChangeFunc'];
112 // Special handling of flexform sections:
113 // Field change functions are modified in JavaScript, thus the hash is always invalid
114 if ($handleFlexformSections && preg_match($pattern, $this->parameters['itemName'], $matches)) {
115 $originalName = $matches[1];
116 $cleanedName = $matches[2] . $matches[4];
117 foreach ($fieldChangeFunctions as &$value) {
118 $value = str_replace($originalName, $cleanedName, $value);
119 }
120 unset($value);
121 }
122 $result = hash_equals(GeneralUtility::hmac(serialize($fieldChangeFunctions)), $this->parameters['fieldChangeFuncHash']);
123 }
124 return $result;
125 }
126
127 /**
128 * Get attributes for the body tag
129 *
130 * @return string[] Array of body-tag attributes
131 */
132 protected function getBodyTagAttributes()
133 {
134 $parameters = parent::getBodyTagAttributes();
135
136 $formEngineParameters['fieldChangeFunc'] = $this->parameters['fieldChangeFunc'];
137 $formEngineParameters['fieldChangeFuncHash'] = GeneralUtility::hmac(serialize($this->parameters['fieldChangeFunc']));
138
139 $parameters['data-add-on-params'] .= GeneralUtility::implodeArrayForUrl('P', $formEngineParameters);
140
141 return $parameters;
142 }
143
144 /**
145 * Return the ID of current page
146 *
147 * @return int
148 */
149 protected function getCurrentPageId()
150 {
151 $pageId = 0;
152 $browserParameters = $this->parameters;
153 if (isset($browserParameters['pid'])) {
154 $pageId = $browserParameters['pid'];
155 } elseif (isset($browserParameters['itemName'])) {
156 // parse data[<table>][<uid>]
157 if (preg_match('~data\[([^]]*)\]\[([^]]*)\]~', $browserParameters['itemName'], $matches)) {
158 $recordArray = BackendUtility::getRecord($matches['1'], $matches['2']);
159 if (is_array($recordArray)) {
160 $pageId = $recordArray['pid'];
161 }
162 }
163 }
164 return (int)BackendUtility::getTSCpidCached($browserParameters['table'], $browserParameters['uid'], $pageId)[0];
165 }
166 }