[TASK] Use trait for public method access deprecation
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Controller / File / CreateFolderController.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Backend\Controller\File;
4
5 /*
6 * This file is part of the TYPO3 CMS project.
7 *
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.
11 *
12 * For the full copyright and license information, please read the
13 * LICENSE.txt file that was distributed with this source code.
14 *
15 * The TYPO3 project - inspiring people to share!
16 */
17
18 use Psr\Http\Message\ResponseInterface;
19 use Psr\Http\Message\ServerRequestInterface;
20 use TYPO3\CMS\Backend\Routing\UriBuilder;
21 use TYPO3\CMS\Backend\Template\ModuleTemplate;
22 use TYPO3\CMS\Backend\Utility\BackendUtility;
23 use TYPO3\CMS\Core\Compatibility\PublicMethodDeprecationTrait;
24 use TYPO3\CMS\Core\Compatibility\PublicPropertyDeprecationTrait;
25 use TYPO3\CMS\Core\Http\HtmlResponse;
26 use TYPO3\CMS\Core\Imaging\Icon;
27 use TYPO3\CMS\Core\Localization\LanguageService;
28 use TYPO3\CMS\Core\Resource\Exception\InsufficientFolderAccessPermissionsException;
29 use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperRegistry;
30 use TYPO3\CMS\Core\Resource\ResourceFactory;
31 use TYPO3\CMS\Core\Utility\GeneralUtility;
32 use TYPO3\CMS\Core\Utility\MathUtility;
33 use TYPO3\CMS\Fluid\View\StandaloneView;
34
35 /**
36 * Script class for the create-new script
37 *
38 * Displays forms for creating folders (1 to 10), a media asset or a new file.
39 */
40 class CreateFolderController
41 {
42 use PublicMethodDeprecationTrait;
43 use PublicPropertyDeprecationTrait;
44
45 /**
46 * @var array
47 */
48 private $deprecatedPublicMethods = [
49 'main' => 'Using CreateFolderController::main() is deprecated and will not be possible anymore in TYPO3 v10.',
50 ];
51
52 /**
53 * @var array
54 */
55 private $deprecatedPublicProperties = [
56 'number' => 'Using $number of class CreateFolderController from outside is discouraged, as this variable is only used for internal storage.',
57 'folderNumber' => 'Using $folderNumber of class CreateFolderController from outside is discouraged, as this variable is only used for internal storage.',
58 'target' => 'Using $target of class CreateFolderController from outside is discouraged, as this variable is only used for internal storage.',
59 'content' => 'Using $content of class CreateFolderController from outside is discouraged, as this variable is only used for internal storage.',
60 'returnUrl' => 'Using $content of class CreateFolderController from outside is discouraged, as this variable is only used for internal storage.',
61 'title' => 'Using $content of class CreateFolderController from outside is discouraged, as this variable is only used for internal storage.',
62 ];
63
64 /**
65 * @var int
66 */
67 protected $folderNumber = 10;
68
69 /**
70 * Name of the filemount
71 *
72 * @var string
73 * @deprecated since v9, will be removed in v10, unused
74 */
75 protected $title;
76
77 /**
78 * @var int
79 */
80 protected $number;
81
82 /**
83 * Set with the target path inputted in &target
84 *
85 * @var string
86 */
87 protected $target;
88
89 /**
90 * The folder object which is the target directory
91 *
92 * @var \TYPO3\CMS\Core\Resource\Folder $folderObject
93 */
94 protected $folderObject;
95
96 /**
97 * Return URL of list module.
98 *
99 * @var string
100 */
101 protected $returnUrl;
102
103 /**
104 * @var array
105 */
106 protected $pathInfo;
107
108 /**
109 * Accumulating content
110 *
111 * @var string
112 * @deprecated since v9, will be removed in v10, unused
113 */
114 protected $content;
115
116 /**
117 * ModuleTemplate object
118 *
119 * @var ModuleTemplate
120 */
121 protected $moduleTemplate;
122
123 /**
124 * Constructor
125 */
126 public function __construct()
127 {
128 $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
129 $GLOBALS['SOBE'] = $this;
130 // @deprecated since v9, will be moved out of __construct() in v10
131 $this->init($GLOBALS['TYPO3_REQUEST']);
132 }
133
134 /**
135 * Processes the request, currently everything is handled and put together via "main()"
136 *
137 * @param ServerRequestInterface $request the current request
138 * @return ResponseInterface the response with the content
139 */
140 public function mainAction(ServerRequestInterface $request): ResponseInterface
141 {
142 $this->main();
143 return new HtmlResponse($this->moduleTemplate->renderContent());
144 }
145
146 /**
147 * @param ServerRequestInterface|null $request
148 *
149 * @throws InsufficientFolderAccessPermissionsException
150 * @throws \RuntimeException
151 */
152 protected function init(ServerRequestInterface $request): void
153 {
154 $parsedBody = $request->getParsedBody();
155 $queryParams = $request->getQueryParams();
156
157 $this->number = $parsedBody['number'] ?? $queryParams['number'] ?? 0;
158 $this->target = ($combinedIdentifier = $parsedBody['target'] ?? $queryParams['target'] ?? '');
159 $this->returnUrl = GeneralUtility::sanitizeLocalUrl($parsedBody['returnUrl'] ?? $queryParams['returnUrl'] ?? '');
160 // create the folder object
161 if ($combinedIdentifier) {
162 $this->folderObject = ResourceFactory::getInstance()
163 ->getFolderObjectFromCombinedIdentifier($combinedIdentifier);
164 }
165 // Cleaning and checking target directory
166 if (!$this->folderObject) {
167 $title = $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:paramError');
168 $message = $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:targetNoDir');
169 throw new \RuntimeException($title . ': ' . $message, 1294586845);
170 }
171 if ($this->folderObject->getStorage()->getUid() === 0) {
172 throw new InsufficientFolderAccessPermissionsException(
173 'You are not allowed to access folders outside your storages',
174 1375889838
175 );
176 }
177
178 $pathInfo = [
179 'combined_identifier' => $this->folderObject->getCombinedIdentifier(),
180 ];
181 $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
182
183 $this->moduleTemplate->getDocHeaderComponent()->setMetaInformation($pathInfo);
184 $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
185 $this->moduleTemplate->addJavaScriptCode(
186 'CreateFolderInlineJavaScript',
187 'var path = "' . $this->target . '";
188 var confirmTitle = '
189 . GeneralUtility::quoteJSvalue(
190 $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:pleaseConfirm')
191 )
192 . ';
193 var confirmText = '
194 . GeneralUtility::quoteJSvalue(
195 $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:mess.redraw')
196 )
197 . ';
198 function reload(a) {
199 var params = "&target="+encodeURIComponent(path)+"&number="+a+"&returnUrl=' . rawurlencode($this->returnUrl) . '";
200 var url = \'' . (string)$uriBuilder->buildUriFromRoute('file_newfolder') . '\';
201 if (!changed) {
202 window.location.href = url + params;
203 } else {
204 var modal = top.TYPO3.Modal.confirm(confirmTitle, confirmText);
205 modal.on(\'confirm.button.cancel\', function(e) {
206 top.TYPO3.Modal.currentModal.trigger(\'modal-dismiss\');
207 });
208 modal.on(\'confirm.button.ok\', function(e) {
209 top.TYPO3.Modal.currentModal.trigger(\'modal-dismiss\');
210 window.location.href = url + params;
211 });
212 }
213 }
214 function backToList() {
215 top.goToModule("file_FilelistList");
216 }
217 var changed = 0;'
218 );
219 }
220
221 /**
222 * Main function, rendering the main module content
223 */
224 protected function main()
225 {
226 $lang = $this->getLanguageService();
227 $assigns = [];
228 $assigns['target'] = $this->target;
229 if ($this->folderObject->checkActionPermission('add')) {
230 $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
231 $assigns['moduleUrlTceFile'] = (string)$uriBuilder->buildUriFromRoute('tce_file');
232 $assigns['cshFileNewFolder'] = BackendUtility::cshItem('xMOD_csh_corebe', 'file_newfolder');
233 // Making the selector box for the number of concurrent folder-creations
234 $this->number = MathUtility::forceIntegerInRange($this->number, 1, 10);
235 for ($a = 1; $a <= $this->folderNumber; $a++) {
236 $options = [];
237 $options['value'] = $a;
238 $options['selected'] = ($this->number == $a ? ' selected="selected"' : '');
239 $assigns['options'][] = $options;
240 }
241 // Making the number of new-folder boxes needed:
242 for ($a = 0; $a < $this->number; $a++) {
243 $folder = [];
244 $folder['this'] = $a;
245 $folder['next'] = $a + 1;
246 $assigns['folders'][] = $folder;
247 }
248 // Making submit button for folder creation:
249 $assigns['returnUrl'] = $this->returnUrl;
250 }
251
252 if ($this->folderObject->getStorage()->checkUserActionPermission('add', 'File')) {
253 $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
254 $assigns['moduleUrlOnlineMedia'] = (string)$uriBuilder->buildUriFromRoute('online_media');
255 $assigns['cshFileNewMedia'] = BackendUtility::cshItem('xMOD_csh_corebe', 'file_newMedia');
256 // Create a list of allowed file extensions with the readable format "youtube, vimeo" etc.
257 $fileExtList = [];
258 $onlineMediaFileExt = OnlineMediaHelperRegistry::getInstance()->getSupportedFileExtensions();
259 foreach ($onlineMediaFileExt as $fileExt) {
260 if (GeneralUtility::verifyFilenameAgainstDenyPattern('.' . $fileExt)) {
261 $fileExtList[] = strtoupper(htmlspecialchars($fileExt));
262 }
263 }
264 $assigns['fileExtList'] = $fileExtList;
265
266 $assigns['moduleUrlTceFile'] = (string)$uriBuilder->buildUriFromRoute('tce_file');
267 $assigns['cshFileNewFile'] = BackendUtility::cshItem('xMOD_csh_corebe', 'file_newfile');
268 // Create a list of allowed file extensions with a text format "*.txt, *.css" etc.
269 $fileExtList = [];
270 $textFileExt = GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['SYS']['textfile_ext'], true);
271 foreach ($textFileExt as $fileExt) {
272 if (GeneralUtility::verifyFilenameAgainstDenyPattern('.' . $fileExt)) {
273 $fileExtList[] = strtoupper(htmlspecialchars($fileExt));
274 }
275 }
276 $assigns['txtFileExtList'] = $fileExtList;
277 }
278
279 $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
280 // CSH button
281 $helpButton = $buttonBar->makeHelpButton()
282 ->setFieldName('file_new')
283 ->setModuleName('xMOD_csh_corebe');
284 $buttonBar->addButton($helpButton);
285
286 // Back
287 if ($this->returnUrl) {
288 $backButton = $buttonBar->makeLinkButton()
289 ->setHref($this->returnUrl)
290 ->setTitle($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.goBack'))
291 ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-view-go-back', Icon::SIZE_SMALL));
292 $buttonBar->addButton($backButton);
293 }
294
295 // Rendering of the output via fluid
296 $view = GeneralUtility::makeInstance(StandaloneView::class);
297 $view->setTemplateRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates')]);
298 $view->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Partials')]);
299 $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName(
300 'EXT:backend/Resources/Private/Templates/File/CreateFolder.html'
301 ));
302 $view->assignMultiple($assigns);
303 $this->moduleTemplate->setContent($view->render());
304 }
305
306 /**
307 * Returns LanguageService
308 *
309 * @return LanguageService
310 */
311 protected function getLanguageService(): LanguageService
312 {
313 return $GLOBALS['LANG'];
314 }
315 }