[TASK] Create own response instance in controller actions
[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->loadJquery();
74 $pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/FormEngineLinkBrowserAdapter', 'function(FormEngineLinkBrowserAdapter) {
75 FormEngineLinkBrowserAdapter.updateFunctions = function() {' . $inlineJS . '};
76 }');
77 }
78
79 /**
80 * Encode a typolink via ajax
81 *
82 * This avoids to implement the encoding functionality again in JS for the browser.
83 *
84 * @param ServerRequestInterface $request
85 * @return ResponseInterface
86 */
87 public function encodeTypoLink(ServerRequestInterface $request): ResponseInterface
88 {
89 $typoLinkParts = $request->getQueryParams();
90 if (isset($typoLinkParts['params'])) {
91 $typoLinkParts['additionalParams'] = $typoLinkParts['params'];
92 unset($typoLinkParts['params']);
93 }
94
95 $typoLink = GeneralUtility::makeInstance(TypoLinkCodecService::class)->encode($typoLinkParts);
96 return new JsonResponse(['typoLink' => $typoLink]);
97 }
98
99 /**
100 * Determines whether submitted field change functions are valid
101 * and are coming from the system and not from an external abuse.
102 *
103 * @param bool $handleFlexformSections Whether to handle flexform sections differently
104 * @return bool Whether the submitted field change functions are valid
105 */
106 protected function areFieldChangeFunctionsValid($handleFlexformSections = false)
107 {
108 $result = false;
109 if (isset($this->parameters['fieldChangeFunc']) && is_array($this->parameters['fieldChangeFunc']) && isset($this->parameters['fieldChangeFuncHash'])) {
110 $matches = [];
111 $pattern = '#\\[el\\]\\[(([^]-]+-[^]-]+-)(idx\\d+-)([^]]+))\\]#i';
112 $fieldChangeFunctions = $this->parameters['fieldChangeFunc'];
113 // Special handling of flexform sections:
114 // Field change functions are modified in JavaScript, thus the hash is always invalid
115 if ($handleFlexformSections && preg_match($pattern, $this->parameters['itemName'], $matches)) {
116 $originalName = $matches[1];
117 $cleanedName = $matches[2] . $matches[4];
118 foreach ($fieldChangeFunctions as &$value) {
119 $value = str_replace($originalName, $cleanedName, $value);
120 }
121 unset($value);
122 }
123 $result = hash_equals(GeneralUtility::hmac(serialize($fieldChangeFunctions)), $this->parameters['fieldChangeFuncHash']);
124 }
125 return $result;
126 }
127
128 /**
129 * Get attributes for the body tag
130 *
131 * @return string[] Array of body-tag attributes
132 */
133 protected function getBodyTagAttributes()
134 {
135 $parameters = parent::getBodyTagAttributes();
136
137 $formEngineParameters['fieldChangeFunc'] = $this->parameters['fieldChangeFunc'];
138 $formEngineParameters['fieldChangeFuncHash'] = GeneralUtility::hmac(serialize($this->parameters['fieldChangeFunc']));
139
140 $parameters['data-add-on-params'] .= GeneralUtility::implodeArrayForUrl('P', $formEngineParameters);
141
142 return $parameters;
143 }
144
145 /**
146 * Return the ID of current page
147 *
148 * @return int
149 */
150 protected function getCurrentPageId()
151 {
152 $pageId = 0;
153 $browserParameters = $this->parameters;
154 if (isset($browserParameters['pid'])) {
155 $pageId = $browserParameters['pid'];
156 } elseif (isset($browserParameters['itemName'])) {
157 // parse data[<table>][<uid>]
158 if (preg_match('~data\[([^]]*)\]\[([^]]*)\]~', $browserParameters['itemName'], $matches)) {
159 $recordArray = BackendUtility::getRecord($matches['1'], $matches['2']);
160 if (is_array($recordArray)) {
161 $pageId = $recordArray['pid'];
162 }
163 }
164 }
165 return (int)BackendUtility::getTSCpidCached($browserParameters['table'], $browserParameters['uid'], $pageId)[0];
166 }
167 }