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