2 declare(strict_types
= 1);
3 namespace TYPO3\CMS\Backend\Controller\File
;
6 * This file is part of the TYPO3 CMS project.
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.
12 * For the full copyright and license information, please read the
13 * LICENSE.txt file that was distributed with this source code.
15 * The TYPO3 project - inspiring people to share!
18 use Psr\Http\Message\ResponseInterface
;
19 use Psr\Http\Message\ServerRequestInterface
;
20 use TYPO3\CMS\Backend\Template\ModuleTemplate
;
21 use TYPO3\CMS\Core\Compatibility\PublicPropertyDeprecationTrait
;
22 use TYPO3\CMS\Core\Http\HtmlResponse
;
23 use TYPO3\CMS\Core\Imaging\Icon
;
24 use TYPO3\CMS\Core\Localization\LanguageService
;
25 use TYPO3\CMS\Core\
Resource\Exception\InsufficientFolderAccessPermissionsException
;
26 use TYPO3\CMS\Core\
Resource\ResourceFactory
;
27 use TYPO3\CMS\Core\Utility\GeneralUtility
;
30 * Script Class for display up to 10 upload fields
31 * @internal This class is a specific Backend controller implementation and is not considered part of the Public TYPO3 API.
33 class FileUploadController
35 use PublicPropertyDeprecationTrait
;
40 protected $deprecatedPublicProperties = [
41 'title' => 'Using $title of class FileUploadController from outside is discouraged as this variable is only used for internal storage.',
42 'target' => 'Using $target of class FileUploadController from outside is discouraged as this variable is only used for internal storage.',
43 'returnUrl' => 'Using $returnUrl of class FileUploadController from outside is discouraged as this variable is only used for internal storage.',
44 'content' => 'Using $content of class FileUploadController from outside is discouraged as this variable is only used for internal storage.',
48 * Name of the filemount
55 * Set with the target path inputted in &target
62 * Return URL of list module.
69 * Accumulating content
76 * The folder object which is the target directory for the upload
78 * @var \TYPO3\CMS\Core\Resource\Folder $folderObject
80 protected $folderObject;
83 * ModuleTemplate object
87 protected $moduleTemplate;
92 public function __construct()
94 $this->moduleTemplate
= GeneralUtility
::makeInstance(ModuleTemplate
::class);
95 $this->getLanguageService()->includeLLFile('EXT:core/Resources/Private/Language/locallang_misc.xlf');
97 // @deprecated since TYPO3 v9, will be moved out of __construct() in TYPO3 v10.0
98 $this->init($GLOBALS['TYPO3_REQUEST']);
102 * Processes the request, currently everything is handled and put together via "renderContent()"
104 * @param ServerRequestInterface $request the current request
105 * @return ResponseInterface the response with the content
107 public function mainAction(ServerRequestInterface
$request): ResponseInterface
109 $this->renderContent();
110 return new HtmlResponse($this->moduleTemplate
->renderContent());
114 * Main function, rendering the upload file form fields
116 * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0
118 public function main()
120 trigger_error('FileUploadController->main() will be replaced by protected method renderContent() in TYPO3 v10.0. Do not call from other extension.', E_USER_DEPRECATED
);
121 $this->renderContent();
125 * This function renders the upload form
127 * @return string The HTML form as a string, ready for outputting
128 * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0
130 public function renderUploadForm()
132 trigger_error('FileUploadController->renderUploadForm() will be replaced by protected method renderUploadFormInternal() in TYPO3 v10.0. Do not call from other extension.', E_USER_DEPRECATED
);
133 return $this->renderUploadFormInternal();
139 * @param ServerRequestInterface $request
140 * @throws InsufficientFolderAccessPermissionsException
142 protected function init(ServerRequestInterface
$request): void
144 $parsedBody = $request->getParsedBody();
145 $queryParams = $request->getQueryParams();
147 /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
148 $uriBuilder = GeneralUtility
::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder
::class);
149 // Initialize GPvars:
150 $this->target
= $parsedBody['target'] ??
$queryParams['target'] ??
null;
151 $this->returnUrl
= GeneralUtility
::sanitizeLocalUrl($parsedBody['returnUrl'] ??
$queryParams['returnUrl'] ??
'');
152 if (!$this->returnUrl
) {
153 $this->returnUrl
= (string)$uriBuilder->buildUriFromRoute('file_list', [
154 'id' => rawurlencode($this->target
)
157 // Create the folder object
159 $this->folderObject
= ResourceFactory
::getInstance()
160 ->retrieveFileOrFolderObject($this->target
);
162 if ($this->folderObject
->getStorage()->getUid() === 0) {
163 throw new InsufficientFolderAccessPermissionsException(
164 'You are not allowed to access folders outside your storages',
169 // Cleaning and checking target directory
170 if (!$this->folderObject
) {
171 $title = $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:paramError');
172 $message = $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:targetNoDir');
173 throw new \
RuntimeException($title . ': ' . $message, 1294586843);
176 // Setting up the context sensitive menu
177 $this->moduleTemplate
->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
179 // building pathInfo for metaInformation
181 'combined_identifier' => $this->folderObject
->getCombinedIdentifier(),
183 $this->moduleTemplate
->getDocHeaderComponent()->setMetaInformation($pathInfo);
187 * Render module content
189 protected function renderContent(): void
191 $lang = $this->getLanguageService();
192 /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
193 $uriBuilder = GeneralUtility
::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder
::class);
196 $this->moduleTemplate
->setTitle($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_upload.php.pagetitle'));
198 $pageContent = '<form action="'
199 . htmlspecialchars((string)$uriBuilder->buildUriFromRoute('tce_file'))
200 . '" method="post" id="FileUploadController" name="editform" enctype="multipart/form-data">';
202 $pageContent .= '<h1>' . $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_upload.php.pagetitle') . '</h1>';
203 $pageContent .= $this->renderUploadFormInternal();
206 $buttonBar = $this->moduleTemplate
->getDocHeaderComponent()->getButtonBar();
209 $cshButton = $buttonBar->makeHelpButton()
210 ->setModuleName('xMOD_csh_corebe')
211 ->setFieldName('file_upload');
212 $buttonBar->addButton($cshButton);
215 if ($this->returnUrl
) {
216 $backButton = $buttonBar->makeLinkButton()
217 ->setHref($this->returnUrl
)
218 ->setTitle($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.goBack'))
219 ->setIcon($this->moduleTemplate
->getIconFactory()->getIcon('actions-view-go-back', Icon
::SIZE_SMALL
));
220 $buttonBar->addButton($backButton);
223 $pageContent .= '</form>';
224 $this->content
.= '<div>' . $pageContent . '</div>';
225 $this->moduleTemplate
->setContent($this->content
);
229 * This function renders the upload form
231 * @return string The HTML form as a string, ready for outputting
233 protected function renderUploadFormInternal(): string
235 // Make checkbox for "overwrite"
237 <div id="c-override">
238 <p class="checkbox"><label for="overwriteExistingFiles"><input type="checkbox" name="overwriteExistingFiles" id="overwriteExistingFiles" value="replace" /> ' . htmlspecialchars($this->getLanguageService()->getLL('overwriteExistingFiles')) . '</label></p>
239 <p>' . htmlspecialchars($this->getLanguageService()->getLL('uploadMultipleFilesInfo')) . '</p>
242 // Produce the number of upload-fields needed:
246 // Adding 'size="50" ' for the sake of Mozilla!
248 <input type="file" multiple="multiple" name="upload_1[]" />
249 <input type="hidden" name="data[upload][1][target]" value="' . htmlspecialchars($this->folderObject
->getCombinedIdentifier()) . '" />
250 <input type="hidden" name="data[upload][1][data]" value="1" /><br />
258 <input type="hidden" name="data[upload][1][redirect]" value="' . $this->returnUrl
. '" /><br />
259 <input class="btn btn-default" type="submit" value="' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_upload.php.submit')) . '" />
267 * @return LanguageService
269 protected function getLanguageService(): LanguageService
271 return $GLOBALS['LANG'];