[BUGFIX] Fix file upload and directory creation in file browser
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Controller / File / FileUploadController.php
1 <?php
2 namespace TYPO3\CMS\Backend\Controller\File;
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\Module\AbstractModule;
20 use TYPO3\CMS\Backend\Utility\BackendUtility;
21 use TYPO3\CMS\Core\Imaging\Icon;
22 use TYPO3\CMS\Core\Resource\Exception\InsufficientFolderAccessPermissionsException;
23 use TYPO3\CMS\Core\Resource\ResourceFactory;
24 use TYPO3\CMS\Core\Utility\GeneralUtility;
25
26 /**
27 * Script Class for display up to 10 upload fields
28 */
29 class FileUploadController extends AbstractModule
30 {
31 /**
32 * Name of the filemount
33 *
34 * @var string
35 */
36 public $title;
37
38 /**
39 * Set with the target path inputted in &target
40 *
41 * @var string
42 */
43 public $target;
44
45 /**
46 * Return URL of list module.
47 *
48 * @var string
49 */
50 public $returnUrl;
51
52 /**
53 * Accumulating content
54 *
55 * @var string
56 */
57 public $content;
58
59 /**
60 * The folder object which is the target directory for the upload
61 *
62 * @var \TYPO3\CMS\Core\Resource\Folder $folderObject
63 */
64 protected $folderObject;
65
66 /**
67 * Constructor
68 */
69 public function __construct()
70 {
71 parent::__construct();
72 $GLOBALS['SOBE'] = $this;
73 $this->getLanguageService()->includeLLFile('EXT:lang/Resources/Private/Language/locallang_misc.xlf');
74 $this->init();
75 }
76
77 /**
78 * Initialize
79 *
80 * @throws InsufficientFolderAccessPermissionsException
81 */
82 protected function init()
83 {
84 // Initialize GPvars:
85 $this->target = GeneralUtility::_GP('target');
86 $this->returnUrl = GeneralUtility::sanitizeLocalUrl(GeneralUtility::_GP('returnUrl'));
87 if (!$this->returnUrl) {
88 $this->returnUrl = BackendUtility::getModuleUrl('file_list', [
89 'id' => rawurlencode($this->target)
90 ]);
91 }
92 // Create the folder object
93 if ($this->target) {
94 $this->folderObject = ResourceFactory::getInstance()
95 ->retrieveFileOrFolderObject($this->target);
96 }
97 if ($this->folderObject->getStorage()->getUid() === 0) {
98 throw new InsufficientFolderAccessPermissionsException(
99 'You are not allowed to access folders outside your storages',
100 1375889834
101 );
102 }
103
104 // Cleaning and checking target directory
105 if (!$this->folderObject) {
106 $title = $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:paramError');
107 $message = $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:targetNoDir');
108 throw new \RuntimeException($title . ': ' . $message, 1294586843);
109 }
110
111 // Setting up the context sensitive menu
112 $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
113
114 // building pathInfo for metaInformation
115 $pathInfo = [
116 'combined_identifier' => $this->folderObject->getCombinedIdentifier(),
117 ];
118 $this->moduleTemplate->getDocHeaderComponent()->setMetaInformation($pathInfo);
119 }
120
121 /**
122 * Main function, rendering the upload file form fields
123 */
124 public function main()
125 {
126 $lang = $this->getLanguageService();
127
128 // set page title
129 $this->moduleTemplate->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:file_upload.php.pagetitle'));
130
131 $pageContent = '<form action="'
132 . htmlspecialchars(BackendUtility::getModuleUrl('tce_file'))
133 . '" method="post" id="FileUploadController" name="editform" enctype="multipart/form-data">';
134 // Make page header:
135 $pageContent .= '<h1>' . $lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:file_upload.php.pagetitle') . '</h1>';
136 $pageContent .= $this->renderUploadForm();
137
138 // Header Buttons
139 $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
140
141 // csh button
142 $cshButton = $buttonBar->makeHelpButton()
143 ->setModuleName('xMOD_csh_corebe')
144 ->setFieldName('file_upload');
145 $buttonBar->addButton($cshButton);
146
147 // back button
148 if ($this->returnUrl) {
149 $backButton = $buttonBar->makeLinkButton()
150 ->setHref($this->returnUrl)
151 ->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.goBack'))
152 ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-view-go-back', Icon::SIZE_SMALL));
153 $buttonBar->addButton($backButton);
154 }
155
156 $pageContent .= '</form>';
157 $this->content .= '<div>' . $pageContent . '</div>';
158 $this->moduleTemplate->setContent($this->content);
159 }
160
161 /**
162 * This function renders the upload form
163 *
164 * @return string The HTML form as a string, ready for outputting
165 */
166 public function renderUploadForm()
167 {
168 // Make checkbox for "overwrite"
169 $content = '
170 <div id="c-override">
171 <p><label for="overwriteExistingFiles"><input type="checkbox" class="checkbox" name="overwriteExistingFiles" id="overwriteExistingFiles" value="replace" /> ' . htmlspecialchars($this->getLanguageService()->getLL('overwriteExistingFiles')) . '</label></p>
172 <p>&nbsp;</p>
173 <p>' . htmlspecialchars($this->getLanguageService()->getLL('uploadMultipleFilesInfo')) . '</p>
174 </div>
175 ';
176 // Produce the number of upload-fields needed:
177 $content .= '
178 <div id="c-upload">
179 ';
180 // Adding 'size="50" ' for the sake of Mozilla!
181 $content .= '
182 <input type="file" multiple="multiple" name="upload_1[]" />
183 <input type="hidden" name="data[upload][1][target]" value="' . htmlspecialchars($this->folderObject->getCombinedIdentifier()) . '" />
184 <input type="hidden" name="data[upload][1][data]" value="1" /><br />
185 ';
186 $content .= '
187 </div>
188 ';
189 // Submit button:
190 $content .= '
191 <div id="c-submit">
192 <input type="hidden" name="data[upload][1][redirect]" value="' . $this->returnUrl . '" /><br />
193 <input class="btn btn-default" type="submit" value="' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:file_upload.php.submit')) . '" />
194 </div>
195 ';
196 return $content;
197 }
198
199 /**
200 * Processes the request, currently everything is handled and put together via "main()"
201 *
202 * @param ServerRequestInterface $request the current request
203 * @param ResponseInterface $response
204 * @return ResponseInterface the response with the content
205 */
206 public function mainAction(ServerRequestInterface $request, ResponseInterface $response)
207 {
208 $this->main();
209 $response->getBody()->write($this->moduleTemplate->renderContent());
210
211 return $response;
212 }
213
214 /**
215 * Returns LanguageService
216 *
217 * @return \TYPO3\CMS\Core\Localization\LanguageService
218 */
219 protected function getLanguageService()
220 {
221 return $GLOBALS['LANG'];
222 }
223 }