62a47fafe5f9f059482ae8b4617579b83b2ac2b4
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Controller / File / CreateFolderController.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 TYPO3\CMS\Backend\Utility\BackendUtility;
18 use TYPO3\CMS\Core\Imaging\Icon;
19 use TYPO3\CMS\Core\Imaging\IconFactory;
20 use TYPO3\CMS\Core\Utility\GeneralUtility;
21 use Psr\Http\Message\ResponseInterface;
22 use Psr\Http\Message\ServerRequestInterface;
23 use TYPO3\CMS\Core\Http\Response;
24
25 /**
26 * Script Class for the create-new script; Displays a form for creating up to 10 folders or one new text file
27 */
28 class CreateFolderController implements \TYPO3\CMS\Core\Http\ControllerInterface {
29
30 /**
31 * @var int
32 */
33 public $folderNumber = 10;
34
35 /**
36 * document template object
37 *
38 * @var \TYPO3\CMS\Backend\Template\DocumentTemplate
39 */
40 public $doc;
41
42 /**
43 * Name of the filemount
44 *
45 * @var string
46 */
47 public $title;
48
49 /**
50 * @var int
51 */
52 public $number;
53
54 /**
55 * Set with the target path inputted in &target
56 *
57 * @var string
58 */
59 public $target;
60
61 /**
62 * The folder object which is the target directory
63 *
64 * @var \TYPO3\CMS\Core\Resource\Folder $folderObject
65 */
66 protected $folderObject;
67
68 /**
69 * Return URL of list module.
70 *
71 * @var string
72 */
73 public $returnUrl;
74
75 /**
76 * Accumulating content
77 *
78 * @var string
79 */
80 public $content;
81
82 /**
83 * Constructor
84 */
85 public function __construct() {
86 $GLOBALS['SOBE'] = $this;
87 $this->init();
88 }
89
90 /**
91 * Initialize
92 *
93 * @return void
94 */
95 protected function init() {
96 // Initialize GPvars:
97 $this->number = GeneralUtility::_GP('number');
98 $this->target = ($combinedIdentifier = GeneralUtility::_GP('target'));
99 $this->returnUrl = GeneralUtility::sanitizeLocalUrl(GeneralUtility::_GP('returnUrl'));
100 // create the folder object
101 if ($combinedIdentifier) {
102 $this->folderObject = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->getFolderObjectFromCombinedIdentifier($combinedIdentifier);
103 }
104 // Cleaning and checking target directory
105 if (!$this->folderObject) {
106 $title = $this->getLanguageService()->sL('LLL:EXT:lang/locallang_mod_file_list.xlf:paramError', TRUE);
107 $message = $this->getLanguageService()->sL('LLL:EXT:lang/locallang_mod_file_list.xlf:targetNoDir', TRUE);
108 throw new \RuntimeException($title . ': ' . $message, 1294586845);
109 }
110 if ($this->folderObject->getStorage()->getUid() === 0) {
111 throw new \TYPO3\CMS\Core\Resource\Exception\InsufficientFolderAccessPermissionsException('You are not allowed to access folders outside your storages', 1375889838);
112 }
113
114 // Setting the title and the icon
115 $icon = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('apps-filetree-root');
116 $this->title = $icon . htmlspecialchars($this->folderObject->getStorage()->getName()) . ': ' . htmlspecialchars($this->folderObject->getIdentifier());
117 // Setting template object
118 $this->doc = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Template\DocumentTemplate::class);
119 $this->doc->setModuleTemplate('EXT:backend/Resources/Private/Templates/file_newfolder.html');
120 $this->doc->JScode = $this->doc->wrapScriptTags('
121 var path = "' . $this->target . '";
122
123 function reload(a) {
124 if (!changed || (changed && confirm(' . GeneralUtility::quoteJSvalue($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:mess.redraw')) . '))) {
125 var params = "&target="+encodeURIComponent(path)+"&number="+a+"&returnUrl=' . rawurlencode($this->returnUrl) . '";
126 window.location.href = ' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('file_newfolder')) . '+params;
127 }
128 }
129 function backToList() {
130 top.goToModule("file_FilelistList");
131 }
132
133 var changed = 0;
134 ');
135 }
136
137 /**
138 * Main function, rendering the main module content
139 *
140 * @return void
141 */
142 public function main() {
143 $lang = $this->getLanguageService();
144 // Start content compilation
145 $this->content .= $this->doc->startPage($lang->sL('LLL:EXT:lang/locallang_core.xlf:file_newfolder.php.pagetitle'));
146 // Make page header:
147 $pageContent = $this->doc->header($lang->sL('LLL:EXT:lang/locallang_core.xlf:file_newfolder.php.pagetitle'));
148 if ($this->folderObject->checkActionPermission('add')) {
149 $code = '<form role="form" action="' . htmlspecialchars(BackendUtility::getModuleUrl('tce_file')) . '" method="post" name="editform">';
150 // Making the selector box for the number of concurrent folder-creations
151 $this->number = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($this->number, 1, 10);
152 $code .= '
153 <div class="form-group">
154 <div class="form-section">
155 <div class="form-group">
156 <label for="number-of-new-folders">' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:file_newfolder.php.number_of_folders') . ' ' . BackendUtility::cshItem('xMOD_csh_corebe', 'file_newfolder') . '</label>
157 <div class="form-control-wrap">
158 <div class="input-group">
159 <select class="form-control form-control-adapt" name="number" id="number-of-new-folders" onchange="reload(this.options[this.selectedIndex].value);">';
160 for ($a = 1; $a <= $this->folderNumber; $a++) {
161 $code .= '<option value="' . $a . '"' . ($this->number == $a ? ' selected="selected"' : '') . '>' . $a . '</option>';
162 }
163 $code .= '
164 </select>
165 </div>
166 </div>
167 </div>
168 </div>
169 ';
170 // Making the number of new-folder boxes needed:
171 for ($a = 0; $a < $this->number; $a++) {
172 $code .= '
173 <div class="form-section">
174 <div class="form-group">
175 <label for="folder_new_' . $a . '">' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:file_newfolder.php.label_newfolder') . ' ' . ($a + 1) . ':</label>
176 <div class="form-control-wrap">
177 <input type="text" class="form-control" id="folder_new_' . $a . '" name="file[newfolder][' . $a . '][data]" onchange="changed=true;" />
178 <input type="hidden" name="file[newfolder][' . $a . '][target]" value="' . htmlspecialchars($this->target) . '" />
179 </div>
180 </div>
181 </div>';
182 }
183 // Making submit button for folder creation:
184 $code .= '
185 </div><div class="form-group">
186 <input class="btn btn-default" type="submit" value="' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:file_newfolder.php.submit', TRUE) . '" />
187 <input type="hidden" name="redirect" value="' . htmlspecialchars($this->returnUrl) . '" />
188 </div>
189 ';
190 // Switching form tags:
191 $pageContent .= $this->doc->section($lang->sL('LLL:EXT:lang/locallang_core.xlf:file_newfolder.php.newfolders'), $code);
192 $pageContent .= $this->doc->sectionEnd() . '</form>';
193 }
194
195 if ($this->folderObject->getStorage()->checkUserActionPermission('add', 'File')) {
196 $pageContent .= '<form action="' . BackendUtility::getModuleUrl('tce_file') . '" method="post" name="editform2">';
197 // Create a list of allowed file extensions with the nice format "*.jpg, *.gif" etc.
198 $fileExtList = array();
199 $textFileExt = GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['SYS']['textfile_ext'], TRUE);
200 foreach ($textFileExt as $fileExt) {
201 if (!preg_match(('/' . $GLOBALS['TYPO3_CONF_VARS']['BE']['fileDenyPattern'] . '/i'), ('.' . $fileExt))) {
202 $fileExtList[] = '<span class="label label-success">' . strtoupper(htmlspecialchars($fileExt)) . '</span>';
203 }
204 }
205 // Add form fields for creation of a new, blank text file:
206 $code = '
207 <div class="form-group">
208 <div class="form-section">
209 <div class="form-group">
210 <label for="newfile">' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:file_newfolder.php.label_newfile') . ' ' . BackendUtility::cshItem('xMOD_csh_corebe', 'file_newfile') . '</label>
211 <div class="form-control-wrap">
212 <input class="form-control" type="text" id="newfile" name="file[newfile][0][data]" onchange="changed=true;" />
213 <input type="hidden" name="file[newfile][0][target]" value="' . htmlspecialchars($this->target) . '" />
214 </div>
215 <div class="help-block">
216 ' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:cm.allowedFileExtensions') . '<br>
217 ' . implode(' ', $fileExtList) . '
218 </div>
219 </div>
220 </div>
221 </div>
222 ';
223 // Submit button for creation of a new file:
224 $code .= '
225 <div class="form-group">
226 <input class="btn btn-default" type="submit" value="' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:file_newfolder.php.newfile_submit', TRUE) . '" />
227 <input type="hidden" name="redirect" value="' . htmlspecialchars($this->returnUrl) . '" />
228 </div>
229 ';
230 $pageContent .= $this->doc->section($lang->sL('LLL:EXT:lang/locallang_core.xlf:file_newfolder.php.newfile'), $code);
231 $pageContent .= $this->doc->sectionEnd();
232 $pageContent .= '</form>';
233 }
234
235 $docHeaderButtons = array(
236 'back' => ''
237 );
238 $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
239 // Back
240 if ($this->returnUrl) {
241 $docHeaderButtons['back'] = '<a href="' . htmlspecialchars(GeneralUtility::linkThisUrl($this->returnUrl)) . '" class="typo3-goBack" title="' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.goBack', TRUE) . '">' . $iconFactory->getIcon('actions-view-go-back', Icon::SIZE_SMALL) . '</a>';
242 }
243 // Add the HTML as a section:
244 $markerArray = array(
245 'CSH' => $docHeaderButtons['csh'],
246 'FUNC_MENU' => '',
247 'CONTENT' => $pageContent,
248 'PATH' => $this->title
249 );
250 $this->content .= $this->doc->moduleBody(array(), $docHeaderButtons, $markerArray);
251 $this->content .= $this->doc->endPage();
252 $this->content = $this->doc->insertStylesAndJS($this->content);
253 }
254
255 /**
256 * Processes the request, currently everything is handled and put together via "main()"
257 *
258 * @param ServerRequestInterface $request The request object
259 * @return ResponseInterface $response The response, created by the controller
260 */
261 public function processRequest(ServerRequestInterface $request) {
262 $this->main();
263 /** @var Response $response */
264 $response = GeneralUtility::makeInstance(Response::class);
265 $response->getBody()->write($this->content);
266 return $response;
267 }
268
269 /**
270 * Outputting the accumulated content to screen
271 *
272 * @return void
273 * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8, use the processRequest() method instead
274 */
275 public function printContent() {
276 GeneralUtility::logDeprecatedFunction();
277 echo $this->content;
278 }
279
280 /**
281 * Returns LanguageService
282 *
283 * @return \TYPO3\CMS\Lang\LanguageService
284 */
285 protected function getLanguageService() {
286 return $GLOBALS['LANG'];
287 }
288
289 }