[TASK] Move filelist related controllers to filelist 53/60153/9
authorSusanne Moog <susanne.moog@typo3.com>
Mon, 11 Mar 2019 15:29:09 +0000 (16:29 +0100)
committerAndreas Fernandez <a.fernandez@scripting-base.de>
Fri, 15 Mar 2019 12:30:16 +0000 (13:30 +0100)
The following controllers have been moved to filelist as they are
part of filelist functionality and not called anywhere else:

- `CreateFolderController`
- `EditFileController`
- `FileUploadController`
- `RenameFileController`
- `ReplaceFileController`

In addition the TypeScript module `RenameFile` has also been moved to
EXT:filelist.

The base file function route `tce_file` has not been changed.

Related: #87878
Resolves: #87882
Releases: master
Change-Id: I160d13dc6ac20de23aa89543c0f6975ad403075e
Reviewed-on: https://review.typo3.org/c/60153
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de>
34 files changed:
typo3/sysext/backend/Classes/Controller/BackendController.php
typo3/sysext/backend/Classes/Controller/File/CreateFolderController.php
typo3/sysext/backend/Classes/Controller/File/EditFileController.php
typo3/sysext/backend/Classes/Controller/File/FileController.php
typo3/sysext/backend/Classes/Controller/File/FileUploadController.php
typo3/sysext/backend/Classes/Controller/File/RenameFileController.php
typo3/sysext/backend/Classes/Controller/File/ReplaceFileController.php
typo3/sysext/backend/Configuration/Backend/Routes.php
typo3/sysext/backend/Resources/Private/Templates/File/CreateFolder.html [deleted file]
typo3/sysext/backend/Resources/Private/Templates/File/EditFile.html [deleted file]
typo3/sysext/backend/Resources/Private/Templates/File/RenameFile.html [deleted file]
typo3/sysext/backend/Resources/Private/Templates/File/ReplaceFile.html [deleted file]
typo3/sysext/backend/Resources/Private/TypeScript/RenameFile.ts [deleted file]
typo3/sysext/backend/Resources/Public/JavaScript/RenameFile.js [deleted file]
typo3/sysext/backend/Tests/Unit/Controller/File/FileControllerTest.php
typo3/sysext/backend/Tests/Unit/Controller/File/ThumbnailControllerTest.php
typo3/sysext/core/Documentation/Changelog/master/Deprecation-87882-FileRelatedControllersMovedToEXTfilelist.rst [new file with mode: 0644]
typo3/sysext/core/Resources/Private/Language/locallang_core.xlf
typo3/sysext/filelist/Classes/Controller/File/CreateFolderController.php [new file with mode: 0644]
typo3/sysext/filelist/Classes/Controller/File/EditFileController.php [new file with mode: 0644]
typo3/sysext/filelist/Classes/Controller/File/FileUploadController.php [new file with mode: 0644]
typo3/sysext/filelist/Classes/Controller/File/RenameFileController.php [new file with mode: 0644]
typo3/sysext/filelist/Classes/Controller/File/ReplaceFileController.php [new file with mode: 0644]
typo3/sysext/filelist/Classes/Hook/BackendControllerHook.php
typo3/sysext/filelist/Configuration/Backend/Routes.php [new file with mode: 0644]
typo3/sysext/filelist/Resources/Private/Language/locallang.xlf
typo3/sysext/filelist/Resources/Private/Templates/File/CreateFolder.html [new file with mode: 0644]
typo3/sysext/filelist/Resources/Private/Templates/File/EditFile.html [new file with mode: 0644]
typo3/sysext/filelist/Resources/Private/Templates/File/RenameFile.html [new file with mode: 0644]
typo3/sysext/filelist/Resources/Private/Templates/File/ReplaceFile.html [new file with mode: 0644]
typo3/sysext/filelist/Resources/Private/TypeScript/RenameFile.ts [new file with mode: 0644]
typo3/sysext/filelist/Resources/Public/JavaScript/RenameFile.js [new file with mode: 0644]
typo3/sysext/install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php
typo3/sysext/t3editor/Classes/Hook/FileEditHook.php

index 093174f..94f5dc7 100644 (file)
@@ -154,6 +154,7 @@ class BackendController
         $this->pageRenderer->addInlineSetting('NewRecord', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('db_new'));
         $this->pageRenderer->addInlineSetting('FormEngine', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('record_edit'));
         $this->pageRenderer->addInlineSetting('RecordCommit', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('tce_db'));
+        $this->pageRenderer->addInlineSetting('FileCommit', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('tce_file'));
         $this->pageRenderer->addInlineSetting('WebLayout', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('web_layout'));
 
         $this->initializeToolbarItems();
index 8a66ef7..3707f40 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 declare(strict_types = 1);
+
 namespace TYPO3\CMS\Backend\Controller\File;
 
 /*
@@ -15,253 +16,18 @@ namespace TYPO3\CMS\Backend\Controller\File;
  * The TYPO3 project - inspiring people to share!
  */
 
-use Psr\Http\Message\ResponseInterface;
-use Psr\Http\Message\ServerRequestInterface;
-use TYPO3\CMS\Backend\Routing\UriBuilder;
-use TYPO3\CMS\Backend\Template\ModuleTemplate;
-use TYPO3\CMS\Backend\Utility\BackendUtility;
-use TYPO3\CMS\Core\Http\HtmlResponse;
-use TYPO3\CMS\Core\Imaging\Icon;
-use TYPO3\CMS\Core\Localization\LanguageService;
-use TYPO3\CMS\Core\Resource\Exception\InsufficientFolderAccessPermissionsException;
-use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperRegistry;
-use TYPO3\CMS\Core\Resource\ResourceFactory;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Core\Utility\MathUtility;
-use TYPO3\CMS\Fluid\View\StandaloneView;
-
 /**
- * Script class for the create-new script
+ * Class CreateFolderController
  *
- * Displays forms for creating folders (1 to 10), a media asset or a new file.
- * @internal This class is a specific Backend controller implementation and is not considered part of the Public TYPO3 API.
+ * @deprecated see \TYPO3\CMS\Filelist\Controller\File\CreateFolderController
  */
-class CreateFolderController
+class CreateFolderController extends \TYPO3\CMS\Filelist\Controller\File\CreateFolderController
 {
-    /**
-     * @var int
-     */
-    protected $folderNumber = 10;
-
-    /**
-     * @var int
-     */
-    protected $number;
-
-    /**
-     * Set with the target path inputted in &target
-     *
-     * @var string
-     */
-    protected $target;
-
-    /**
-     * The folder object which is  the target directory
-     *
-     * @var \TYPO3\CMS\Core\Resource\Folder $folderObject
-     */
-    protected $folderObject;
-
-    /**
-     * Return URL of list module.
-     *
-     * @var string
-     */
-    protected $returnUrl;
-
-    /**
-     * @var array
-     */
-    protected $pathInfo;
-
-    /**
-     * ModuleTemplate object
-     *
-     * @var ModuleTemplate
-     */
-    protected $moduleTemplate;
-
-    /**
-     * Processes the request, currently everything is handled and put together via "main()"
-     *
-     * @param ServerRequestInterface $request the current request
-     * @return ResponseInterface the response with the content
-     */
-    public function mainAction(ServerRequestInterface $request): ResponseInterface
-    {
-        $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
-        $this->init($request);
-        $this->main();
-        return new HtmlResponse($this->moduleTemplate->renderContent());
-    }
-
-    /**
-     * @param ServerRequestInterface|null $request
-     *
-     * @throws InsufficientFolderAccessPermissionsException
-     * @throws \RuntimeException
-     */
-    protected function init(ServerRequestInterface $request): void
+    public function __construct()
     {
-        $parsedBody = $request->getParsedBody();
-        $queryParams = $request->getQueryParams();
-
-        $this->number = $parsedBody['number'] ?? $queryParams['number'] ?? 0;
-        $this->target = ($combinedIdentifier = $parsedBody['target'] ?? $queryParams['target'] ?? '');
-        $this->returnUrl = GeneralUtility::sanitizeLocalUrl($parsedBody['returnUrl'] ?? $queryParams['returnUrl'] ?? '');
-        // create the folder object
-        if ($combinedIdentifier) {
-            $this->folderObject = ResourceFactory::getInstance()
-                ->getFolderObjectFromCombinedIdentifier($combinedIdentifier);
-        }
-        // Cleaning and checking target directory
-        if (!$this->folderObject) {
-            $title = $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:paramError');
-            $message = $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:targetNoDir');
-            throw new \RuntimeException($title . ': ' . $message, 1294586845);
-        }
-        if ($this->folderObject->getStorage()->getUid() === 0) {
-            throw new InsufficientFolderAccessPermissionsException(
-                'You are not allowed to access folders outside your storages',
-                1375889838
-            );
-        }
-
-        $pathInfo = [
-            'combined_identifier' => $this->folderObject->getCombinedIdentifier(),
-        ];
-        $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
-
-        $this->moduleTemplate->getDocHeaderComponent()->setMetaInformation($pathInfo);
-        $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
-        $this->moduleTemplate->addJavaScriptCode(
-            'CreateFolderInlineJavaScript',
-            'var path = "' . $this->target . '";
-            var confirmTitle = '
-            . GeneralUtility::quoteJSvalue(
-                $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:pleaseConfirm')
-            )
-            . ';
-            var confirmText = '
-            . GeneralUtility::quoteJSvalue(
-                $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:mess.redraw')
-            )
-            . ';
-            function reload(a) {
-                var params = "&target="+encodeURIComponent(path)+"&number="+a+"&returnUrl=' . rawurlencode($this->returnUrl) . '";
-                var url = \'' . (string)$uriBuilder->buildUriFromRoute('file_newfolder') . '\';
-                if (!changed) {
-                    window.location.href = url + params;
-                } else {
-                    var modal = top.TYPO3.Modal.confirm(confirmTitle, confirmText);
-                    modal.on(\'confirm.button.cancel\', function(e) {
-                        top.TYPO3.Modal.currentModal.trigger(\'modal-dismiss\');
-                    });
-                    modal.on(\'confirm.button.ok\', function(e) {
-                        top.TYPO3.Modal.currentModal.trigger(\'modal-dismiss\');
-                        window.location.href = url + params;
-                    });
-                }
-            }
-            function backToList() {
-                top.goToModule("file_FilelistList");
-            }
-            var changed = 0;'
+        trigger_error(
+            'Using \TYPO3\CMS\Backend\Controller\File\CreateFolderController is deprecated and internal, please use an own controller.',
+            E_USER_DEPRECATED
         );
     }
-
-    /**
-     * Main function, rendering the main module content
-     */
-    protected function main()
-    {
-        $lang = $this->getLanguageService();
-        $assigns = [];
-        $assigns['target'] = $this->target;
-        if ($this->folderObject->checkActionPermission('add')) {
-            $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
-            $assigns['moduleUrlTceFile'] = (string)$uriBuilder->buildUriFromRoute('tce_file');
-            $assigns['cshFileNewFolder'] = BackendUtility::cshItem('xMOD_csh_corebe', 'file_newfolder');
-            // Making the selector box for the number of concurrent folder-creations
-            $this->number = MathUtility::forceIntegerInRange($this->number, 1, 10);
-            for ($a = 1; $a <= $this->folderNumber; $a++) {
-                $options = [];
-                $options['value'] = $a;
-                $options['selected'] = ($this->number == $a ? ' selected="selected"' : '');
-                $assigns['options'][] = $options;
-            }
-            // Making the number of new-folder boxes needed:
-            for ($a = 0; $a < $this->number; $a++) {
-                $folder = [];
-                $folder['this'] = $a;
-                $folder['next'] = $a + 1;
-                $assigns['folders'][] = $folder;
-            }
-            // Making submit button for folder creation:
-            $assigns['returnUrl'] = $this->returnUrl;
-        }
-
-        if ($this->folderObject->getStorage()->checkUserActionPermission('add', 'File')) {
-            $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
-            $assigns['moduleUrlOnlineMedia'] = (string)$uriBuilder->buildUriFromRoute('online_media');
-            $assigns['cshFileNewMedia'] = BackendUtility::cshItem('xMOD_csh_corebe', 'file_newMedia');
-            // Create a list of allowed file extensions with the readable format "youtube, vimeo" etc.
-            $fileExtList = [];
-            $onlineMediaFileExt = OnlineMediaHelperRegistry::getInstance()->getSupportedFileExtensions();
-            foreach ($onlineMediaFileExt as $fileExt) {
-                if (GeneralUtility::verifyFilenameAgainstDenyPattern('.' . $fileExt)) {
-                    $fileExtList[] = strtoupper(htmlspecialchars($fileExt));
-                }
-            }
-            $assigns['fileExtList'] = $fileExtList;
-
-            $assigns['moduleUrlTceFile'] = (string)$uriBuilder->buildUriFromRoute('tce_file');
-            $assigns['cshFileNewFile'] = BackendUtility::cshItem('xMOD_csh_corebe', 'file_newfile');
-            // Create a list of allowed file extensions with a text format "*.txt, *.css" etc.
-            $fileExtList = [];
-            $textFileExt = GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['SYS']['textfile_ext'], true);
-            foreach ($textFileExt as $fileExt) {
-                if (GeneralUtility::verifyFilenameAgainstDenyPattern('.' . $fileExt)) {
-                    $fileExtList[] = strtoupper(htmlspecialchars($fileExt));
-                }
-            }
-            $assigns['txtFileExtList'] = $fileExtList;
-        }
-
-        $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
-        // CSH button
-        $helpButton = $buttonBar->makeHelpButton()
-            ->setFieldName('file_new')
-            ->setModuleName('xMOD_csh_corebe');
-        $buttonBar->addButton($helpButton);
-
-        // Back
-        if ($this->returnUrl) {
-            $backButton = $buttonBar->makeLinkButton()
-                ->setHref($this->returnUrl)
-                ->setTitle($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.goBack'))
-                ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-view-go-back', Icon::SIZE_SMALL));
-            $buttonBar->addButton($backButton);
-        }
-
-        // Rendering of the output via fluid
-        $view = GeneralUtility::makeInstance(StandaloneView::class);
-        $view->setTemplateRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates')]);
-        $view->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Partials')]);
-        $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName(
-            'EXT:backend/Resources/Private/Templates/File/CreateFolder.html'
-        ));
-        $view->assignMultiple($assigns);
-        $this->moduleTemplate->setContent($view->render());
-    }
-
-    /**
-     * Returns LanguageService
-     *
-     * @return LanguageService
-     */
-    protected function getLanguageService(): LanguageService
-    {
-        return $GLOBALS['LANG'];
-    }
 }
index f698a70..f0f9756 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 declare(strict_types = 1);
+
 namespace TYPO3\CMS\Backend\Controller\File;
 
 /*
@@ -15,340 +16,19 @@ namespace TYPO3\CMS\Backend\Controller\File;
  * The TYPO3 project - inspiring people to share!
  */
 
-use Psr\Http\Message\ResponseInterface;
-use Psr\Http\Message\ServerRequestInterface;
-use TYPO3\CMS\Backend\Form\FormResultCompiler;
-use TYPO3\CMS\Backend\Form\NodeFactory;
-use TYPO3\CMS\Backend\Routing\UriBuilder;
-use TYPO3\CMS\Backend\Template\Components\ButtonBar;
-use TYPO3\CMS\Backend\Template\ModuleTemplate;
-use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
-use TYPO3\CMS\Core\Http\HtmlResponse;
-use TYPO3\CMS\Core\Http\RedirectResponse;
-use TYPO3\CMS\Core\Imaging\Icon;
-use TYPO3\CMS\Core\Localization\LanguageService;
-use TYPO3\CMS\Core\Messaging\FlashMessage;
-use TYPO3\CMS\Core\Messaging\FlashMessageService;
-use TYPO3\CMS\Core\Resource\Exception\InsufficientFileAccessPermissionsException;
-use TYPO3\CMS\Core\Resource\ResourceFactory;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Fluid\View\StandaloneView;
-
 /**
- * Script Class for rendering the file editing screen
- * @internal This class is a specific Backend controller implementation and is not considered part of the Public TYPO3 API.
+ * Class EditFileController
+ *
+ * @deprecated see \TYPO3\CMS\Filelist\Controller\File\EditFileController
  */
-class EditFileController
+class EditFileController extends \TYPO3\CMS\Filelist\Controller\File\EditFileController
 {
-    /**
-     * Module content accumulated.
-     *
-     * @var string
-     */
-    protected $content;
-
-    /**
-     * Original input target
-     *
-     * @var string
-     */
-    protected $origTarget;
-
-    /**
-     * The original target, but validated.
-     *
-     * @var string
-     */
-    protected $target;
-
-    /**
-     * Return URL of list module.
-     *
-     * @var string
-     */
-    protected $returnUrl;
-
-    /**
-     * the file that is being edited on
-     *
-     * @var \TYPO3\CMS\Core\Resource\AbstractFile
-     */
-    protected $fileObject;
-
-    /**
-     * ModuleTemplate object
-     *
-     * @var ModuleTemplate
-     */
-    protected $moduleTemplate;
-
-    /**
-     * Constructor
-     */
     public function __construct()
     {
-        $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
-    }
-
-    /**
-     * Processes the request, currently everything is handled and put together via "process()"
-     *
-     * @param ServerRequestInterface $request the current request
-     * @return ResponseInterface the response with the content
-     */
-    public function mainAction(ServerRequestInterface $request): ResponseInterface
-    {
-        $this->init($request);
-        if ($response = $this->process()) {
-            return $response;
-        }
-
-        return new HtmlResponse($this->moduleTemplate->renderContent());
-    }
-
-    /**
-     * Initialize script class
-     *
-     * @param ServerRequestInterface $request
-     *
-     * @throws InsufficientFileAccessPermissionsException
-     */
-    protected function init(ServerRequestInterface $request): void
-    {
-        $parsedBody = $request->getParsedBody();
-        $queryParams = $request->getQueryParams();
-
-        // Setting target, which must be a file reference to a file within the mounts.
-        $this->target = $this->origTarget = $parsedBody['target'] ?? $queryParams['target'] ?? '';
-        $this->returnUrl = GeneralUtility::sanitizeLocalUrl($parsedBody['returnUrl'] ?? $queryParams['returnUrl'] ?? '');
-        // create the file object
-        if ($this->target) {
-            $this->fileObject = ResourceFactory::getInstance()
-                ->retrieveFileOrFolderObject($this->target);
-        }
-        // Cleaning and checking target directory
-        if (!$this->fileObject) {
-            $title = $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:paramError');
-            $message = $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:targetNoDir');
-            throw new \RuntimeException($title . ': ' . $message, 1294586841);
-        }
-        if ($this->fileObject->getStorage()->getUid() === 0) {
-            throw new InsufficientFileAccessPermissionsException(
-                'You are not allowed to access files outside your storages',
-                1375889832
-            );
-        }
-
-        // Setting template object
-        $this->moduleTemplate->addJavaScriptCode(
-            'FileEditBackToList',
-            'function backToList() {
-                               top.goToModule("file_FilelistList");
-                       }'
+        trigger_error(
+            'Using \TYPO3\CMS\Backend\Controller\File\EditFileController is deprecated and internal, please use an own controller.',
+            E_USER_DEPRECATED
         );
-    }
-
-    /**
-     * Main function, rendering the actual content of the editing page
-     *
-     * @return ResponseInterface|null Possible redirect response
-     */
-    protected function process(): ?ResponseInterface
-    {
-        $dataColumnDefinition = [
-            'label' => htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:file'))
-                . ' ' . htmlspecialchars($this->target),
-            'config' => [
-                'type' => 'text',
-                'cols' => 48,
-                'wrap' => 'OFF',
-            ],
-            'defaultExtras' => 'fixed-font: enable-tab'
-        ];
-
-        $this->getButtonsInternal();
-        // Hook: before compiling the output
-        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/file_edit.php']['preOutputProcessingHook'] ?? [] as $hookFunction) {
-            $hookParameters = [
-                'content' => &$this->content,
-                'target' => &$this->target,
-                'dataColumnDefinition' => &$dataColumnDefinition,
-            ];
-            GeneralUtility::callUserFunction($hookFunction, $hookParameters, $this);
-        }
-
-        $assigns = [];
-        $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
-        $assigns['moduleUrlTceFile'] = (string)$uriBuilder->buildUriFromRoute('tce_file');
-        $assigns['fileName'] = $this->fileObject->getName();
-
-        $extList = $GLOBALS['TYPO3_CONF_VARS']['SYS']['textfile_ext'];
-        try {
-            if (!$extList || !GeneralUtility::inList($extList, $this->fileObject->getExtension())) {
-                // @todo throw a minor exception here, not the global one
-                throw new \Exception('Files with that extension are not editable. Allowed extensions are: ' . $extList, 1476050135);
-            }
-
-            // Making the formfields
-            $hValue = (string)$uriBuilder->buildUriFromRoute('file_edit', [
-                'target' => $this->origTarget,
-                'returnUrl' => $this->returnUrl
-            ]);
-
-            $formData = [
-                'databaseRow' => [
-                    'uid' => 0,
-                    'data' => $this->fileObject->getContents(),
-                    'target' => $this->fileObject->getUid(),
-                    'redirect' => $hValue,
-                ],
-                'tableName' => 'editfile',
-                'processedTca' => [
-                    'columns' => [
-                        'data' => $dataColumnDefinition,
-                        'target' => [
-                            'config' => [
-                                'type' => 'input',
-                                'renderType' => 'hidden',
-                            ],
-                        ],
-                        'redirect' => [
-                            'config' => [
-                                'type' => 'input',
-                                'renderType' => 'hidden',
-                            ],
-                        ],
-                    ],
-                    'types' => [
-                        1 => [
-                            'showitem' => 'data,target,redirect',
-                        ],
-                    ],
-                ],
-                'recordTypeValue' => 1,
-                'inlineStructure' => [],
-                'renderType' => 'fullRecordContainer',
-            ];
-
-            $resultArray = GeneralUtility::makeInstance(NodeFactory::class)->create($formData)->render();
-            $formResultCompiler = GeneralUtility::makeInstance(FormResultCompiler::class);
-            $formResultCompiler->mergeResult($resultArray);
-
-            $form = $formResultCompiler->addCssFiles()
-                . $resultArray['html']
-                . $formResultCompiler->printNeededJSFunctions();
-
-            $assigns['form'] = $form;
-        } catch (\Exception $e) {
-            // @todo catch dedicated exceptions, not the global one, if possible
-            $flashMessage = GeneralUtility::makeInstance(FlashMessage::class, $e->getMessage(), '', FlashMessage::ERROR, true);
-
-            $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
-            $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
-            $defaultFlashMessageQueue->enqueue($flashMessage);
-
-            return new RedirectResponse($this->returnUrl, 500);
-        }
-
-        // Rendering of the output via fluid
-        $view = GeneralUtility::makeInstance(StandaloneView::class);
-        $view->setTemplateRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates')]);
-        $view->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Partials')]);
-        $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName(
-            'EXT:backend/Resources/Private/Templates/File/EditFile.html'
-        ));
-        $view->assignMultiple($assigns);
-        $pageContent = $view->render();
-
-        // Hook: after compiling the output
-        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/file_edit.php']['postOutputProcessingHook'] ?? [] as $hookFunction) {
-            $hookParameters = [
-                'pageContent' => &$pageContent,
-                'target' => &$this->target
-            ];
-            GeneralUtility::callUserFunction($hookFunction, $hookParameters, $this);
-        }
-
-        $this->content .= $pageContent;
-        $this->moduleTemplate->setContent($this->content);
-        return null;
-    }
-
-    /**
-     * Builds the buttons for the docheader
-     */
-    protected function getButtonsInternal(): void
-    {
-        $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
-
-        $lang = $this->getLanguageService();
-        // CSH button
-        $helpButton = $buttonBar->makeHelpButton()
-            ->setFieldName('file_edit')
-            ->setModuleName('xMOD_csh_corebe');
-        $buttonBar->addButton($helpButton);
-
-        // Save button
-        $saveButton = $buttonBar->makeInputButton()
-            ->setName('_save')
-            ->setValue('1')
-            ->setForm('EditFileController')
-            ->setTitle($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_edit.php.submit'))
-            ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save', Icon::SIZE_SMALL));
-
-        // Save and Close button
-        $saveAndCloseButton = $buttonBar->makeInputButton()
-            ->setName('_saveandclosedok')
-            ->setValue('1')
-            ->setForm('EditFileController')
-            ->setOnClick(
-                'document.editform.elements.namedItem("data[editfile][0][redirect]").value='
-                . GeneralUtility::quoteJSvalue($this->returnUrl)
-                . ';'
-            )
-            ->setTitle($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_edit.php.saveAndClose'))
-            ->setIcon($this->moduleTemplate->getIconFactory()->getIcon(
-                'actions-document-save-close',
-                Icon::SIZE_SMALL
-            ));
-
-        $splitButton = $buttonBar->makeSplitButton()
-            ->addItem($saveButton)
-            ->addItem($saveAndCloseButton);
-        $buttonBar->addButton($splitButton, ButtonBar::BUTTON_POSITION_LEFT, 20);
-
-        // Cancel button
-        $closeButton = $buttonBar->makeLinkButton()
-            ->setHref('#')
-            ->setOnClick('backToList(); return false;')
-            ->setTitle($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.cancel'))
-            ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-close', Icon::SIZE_SMALL));
-        $buttonBar->addButton($closeButton, ButtonBar::BUTTON_POSITION_LEFT, 10);
-
-        // Make shortcut:
-        $shortButton = $buttonBar->makeShortcutButton()
-            ->setModuleName('file_edit')
-            ->setGetVariables(['target']);
-        $buttonBar->addButton($shortButton);
-    }
-
-    /**
-     * Returns LanguageService
-     *
-     * @return LanguageService
-     */
-    protected function getLanguageService(): LanguageService
-    {
-        return $GLOBALS['LANG'];
-    }
-
-    /**
-     * Returns the current BE user.
-     *
-     * @return BackendUserAuthentication
-     */
-    protected function getBackendUser(): BackendUserAuthentication
-    {
-        return $GLOBALS['BE_USER'];
+        parent::__construct();
     }
 }
index 784d042..056f7ec 100644 (file)
@@ -18,6 +18,7 @@ namespace TYPO3\CMS\Backend\Controller\File;
 use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\ServerRequestInterface;
 use TYPO3\CMS\Backend\Clipboard\Clipboard;
+use TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException;
 use TYPO3\CMS\Backend\Routing\UriBuilder;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
@@ -92,6 +93,7 @@ class FileController
      *
      * @param ServerRequestInterface $request the current request
      * @return ResponseInterface the response with the content
+     * @throws \TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException
      */
     public function mainAction(ServerRequestInterface $request): ResponseInterface
     {
@@ -256,7 +258,12 @@ class FileController
             $urlParameters['returnUrl'] = $this->redirect;
         }
         $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
-        return (string)$uriBuilder->buildUriFromRoute('file_edit', $urlParameters);
+        try {
+            return (string)$uriBuilder->buildUriFromRoute('file_edit', $urlParameters);
+        } catch (RouteNotFoundException $exception) {
+            // no route for editing files available
+            return '';
+        }
     }
 
     /**
index a4c52de..d557aff 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 declare(strict_types = 1);
+
 namespace TYPO3\CMS\Backend\Controller\File;
 
 /*
@@ -15,198 +16,18 @@ namespace TYPO3\CMS\Backend\Controller\File;
  * The TYPO3 project - inspiring people to share!
  */
 
-use Psr\Http\Message\ResponseInterface;
-use Psr\Http\Message\ServerRequestInterface;
-use TYPO3\CMS\Backend\Template\ModuleTemplate;
-use TYPO3\CMS\Core\Http\HtmlResponse;
-use TYPO3\CMS\Core\Imaging\Icon;
-use TYPO3\CMS\Core\Localization\LanguageService;
-use TYPO3\CMS\Core\Resource\Exception\InsufficientFolderAccessPermissionsException;
-use TYPO3\CMS\Core\Resource\ResourceFactory;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-
 /**
- * Script Class for display up to 10 upload fields
- * @internal This class is a specific Backend controller implementation and is not considered part of the Public TYPO3 API.
+ * Class FileUploadController
+ *
+ * @deprecated see \TYPO3\CMS\Filelist\Controller\File\FileUploadController
  */
-class FileUploadController
+class FileUploadController extends \TYPO3\CMS\Filelist\Controller\File\FileUploadController
 {
-    /**
-     * Set with the target path inputted in &target
-     *
-     * @var string
-     */
-    protected $target;
-
-    /**
-     * Return URL of list module.
-     *
-     * @var string
-     */
-    protected $returnUrl;
-
-    /**
-     * Accumulating content
-     *
-     * @var string
-     */
-    protected $content;
-
-    /**
-     * The folder object which is the target directory for the upload
-     *
-     * @var \TYPO3\CMS\Core\Resource\Folder $folderObject
-     */
-    protected $folderObject;
-
-    /**
-     * ModuleTemplate object
-     *
-     * @var ModuleTemplate
-     */
-    protected $moduleTemplate;
-
-    /**
-     * Processes the request, currently everything is handled and put together via "renderContent()"
-     *
-     * @param ServerRequestInterface $request the current request
-     * @return ResponseInterface the response with the content
-     */
-    public function mainAction(ServerRequestInterface $request): ResponseInterface
-    {
-        $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
-        $this->getLanguageService()->includeLLFile('EXT:core/Resources/Private/Language/locallang_misc.xlf');
-        $this->init($request);
-        $this->renderContent();
-        return new HtmlResponse($this->moduleTemplate->renderContent());
-    }
-
-    /**
-     * Initialize
-     *
-     * @param ServerRequestInterface $request
-     * @throws InsufficientFolderAccessPermissionsException
-     */
-    protected function init(ServerRequestInterface $request): void
-    {
-        $parsedBody = $request->getParsedBody();
-        $queryParams = $request->getQueryParams();
-
-        /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
-        $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
-        // Initialize GPvars:
-        $this->target = $parsedBody['target'] ?? $queryParams['target'] ?? null;
-        $this->returnUrl = GeneralUtility::sanitizeLocalUrl($parsedBody['returnUrl'] ?? $queryParams['returnUrl'] ?? '');
-        if (!$this->returnUrl) {
-            $this->returnUrl = (string)$uriBuilder->buildUriFromRoute('file_list', [
-                'id' => rawurlencode($this->target)
-            ]);
-        }
-        // Create the folder object
-        if ($this->target) {
-            $this->folderObject = ResourceFactory::getInstance()
-                ->retrieveFileOrFolderObject($this->target);
-        }
-        if ($this->folderObject->getStorage()->getUid() === 0) {
-            throw new InsufficientFolderAccessPermissionsException(
-                'You are not allowed to access folders outside your storages',
-                1375889834
-            );
-        }
-
-        // Cleaning and checking target directory
-        if (!$this->folderObject) {
-            $title = $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:paramError');
-            $message = $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:targetNoDir');
-            throw new \RuntimeException($title . ': ' . $message, 1294586843);
-        }
-
-        // Setting up the context sensitive menu
-        $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
-
-        // building pathInfo for metaInformation
-        $pathInfo = [
-            'combined_identifier' => $this->folderObject->getCombinedIdentifier(),
-        ];
-        $this->moduleTemplate->getDocHeaderComponent()->setMetaInformation($pathInfo);
-    }
-
-    /**
-     * Render module content
-     */
-    protected function renderContent(): void
-    {
-        $lang = $this->getLanguageService();
-        /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
-        $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
-
-        // set page title
-        $this->moduleTemplate->setTitle($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_upload.php.pagetitle'));
-
-        $pageContent = '<form action="'
-            . htmlspecialchars((string)$uriBuilder->buildUriFromRoute('tce_file'))
-            . '" method="post" id="FileUploadController" name="editform" enctype="multipart/form-data">';
-        // Make page header:
-        $pageContent .= '<h1>' . $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_upload.php.pagetitle') . '</h1>';
-        $pageContent .= $this->renderUploadFormInternal();
-
-        // Header Buttons
-        $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
-
-        // csh button
-        $cshButton = $buttonBar->makeHelpButton()
-            ->setModuleName('xMOD_csh_corebe')
-            ->setFieldName('file_upload');
-        $buttonBar->addButton($cshButton);
-
-        // back button
-        if ($this->returnUrl) {
-            $backButton = $buttonBar->makeLinkButton()
-                ->setHref($this->returnUrl)
-                ->setTitle($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.goBack'))
-                ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-view-go-back', Icon::SIZE_SMALL));
-            $buttonBar->addButton($backButton);
-        }
-
-        $pageContent .= '</form>';
-        $this->content .= '<div>' . $pageContent . '</div>';
-        $this->moduleTemplate->setContent($this->content);
-    }
-
-    /**
-     * This function renders the upload form
-     *
-     * @return string The HTML form as a string, ready for outputting
-     */
-    protected function renderUploadFormInternal(): string
-    {
-        $content = '
-            <div class="form-group">
-                <input type="file" multiple="multiple" class="form-control" name="upload_1[]" />
-                <input type="hidden" name="data[upload][1][target]" value="' . htmlspecialchars($this->folderObject->getCombinedIdentifier()) . '" />
-                <input type="hidden" name="data[upload][1][data]" value="1" />
-            </div>
-            <div class="checkbox">
-                <label for="overwriteExistingFiles">
-                <input type="checkbox" name="overwriteExistingFiles" id="overwriteExistingFiles" value="replace" /> ' . htmlspecialchars($this->getLanguageService()->getLL('overwriteExistingFiles')) . '</label>
-            </div>
-            <div>
-                <input type="hidden" name="data[upload][1][redirect]" value="' . $this->returnUrl . '" />
-                <input class="btn btn-primary" type="submit" value="' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_upload.php.submit')) . '" />
-            </div>
-            <div class="callout callout-warning">
-              ' . htmlspecialchars($this->getLanguageService()->getLL('uploadMultipleFilesInfo')) . '
-            </div>
-        ';
-
-        return $content;
-    }
-
-    /**
-     * @return LanguageService
-     */
-    protected function getLanguageService(): LanguageService
+    public function __construct()
     {
-        return $GLOBALS['LANG'];
+        trigger_error(
+            'Using \TYPO3\CMS\Backend\Controller\File\FileUploadController is deprecated and internal, please use an own controller.',
+            E_USER_DEPRECATED
+        );
     }
 }
index ddf0643..b4f6d03 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 declare(strict_types = 1);
+
 namespace TYPO3\CMS\Backend\Controller\File;
 
 /*
@@ -15,208 +16,18 @@ namespace TYPO3\CMS\Backend\Controller\File;
  * The TYPO3 project - inspiring people to share!
  */
 
-use Psr\Http\Message\ResponseInterface;
-use Psr\Http\Message\ServerRequestInterface;
-use TYPO3\CMS\Backend\Template\Components\ButtonBar;
-use TYPO3\CMS\Backend\Template\ModuleTemplate;
-use TYPO3\CMS\Core\Http\HtmlResponse;
-use TYPO3\CMS\Core\Imaging\Icon;
-use TYPO3\CMS\Core\Localization\LanguageService;
-use TYPO3\CMS\Core\Resource\DuplicationBehavior;
-use TYPO3\CMS\Core\Resource\Exception\InsufficientFileAccessPermissionsException;
-use TYPO3\CMS\Core\Resource\File;
-use TYPO3\CMS\Core\Resource\Folder;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Fluid\View\StandaloneView;
-
 /**
- * Script Class for the rename-file form.
- * @internal This class is a specific Backend controller implementation and is not considered part of the Public TYPO3 API.
+ * Class RenameFileController
+ *
+ * @deprecated see \TYPO3\CMS\Filelist\Controller\File\RenameFileController
  */
-class RenameFileController
+class RenameFileController extends \TYPO3\CMS\Filelist\Controller\File\RenameFileController
 {
-    /**
-     * Target path
-     *
-     * @var string
-     * @internal
-     */
-    protected $target;
-
-    /**
-     * The file or folder object that should be renamed
-     *
-     * @var File|Folder $fileOrFolderObject
-     */
-    protected $fileOrFolderObject;
-
-    /**
-     * Return URL of list module.
-     *
-     * @var string
-     */
-    protected $returnUrl;
-
-    /**
-     * ModuleTemplate object
-     *
-     * @var ModuleTemplate
-     */
-    protected $moduleTemplate;
-
-    /**
-     * Processes the request, currently everything is handled and put together via "renderContent()"
-     *
-     * @param ServerRequestInterface $request
-     * @return ResponseInterface the response with the content
-     */
-    public function mainAction(ServerRequestInterface $request): ResponseInterface
+    public function __construct()
     {
-        $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
-        $this->init($request);
-        $this->renderContent();
-        return new HtmlResponse($this->moduleTemplate->renderContent());
-    }
-
-    /**
-     * Initialize
-     *
-     * @param ServerRequestInterface $request
-     * @throws InsufficientFileAccessPermissionsException
-     */
-    protected function init(ServerRequestInterface $request): void
-    {
-        $parsedBody = $request->getParsedBody();
-        $queryParams = $request->getQueryParams();
-
-        // Initialize GPvars:
-        $this->target = $parsedBody['target'] ?? $queryParams['target'] ?? null;
-        $this->returnUrl = GeneralUtility::sanitizeLocalUrl($parsedBody['returnUrl'] ?? $queryParams['returnUrl'] ?? '');
-        // Cleaning and checking target
-        if ($this->target) {
-            $this->fileOrFolderObject = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->retrieveFileOrFolderObject($this->target);
-        }
-        if (!$this->fileOrFolderObject) {
-            $title = $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:paramError');
-            $message = $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:targetNoDir');
-            throw new \RuntimeException($title . ': ' . $message, 1294586844);
-        }
-        if ($this->fileOrFolderObject->getStorage()->getUid() === 0) {
-            throw new InsufficientFileAccessPermissionsException('You are not allowed to access files outside your storages', 1375889840);
-        }
-
-        // If a folder should be renamed, AND the returnURL should go to the old directory name, the redirect is forced
-        // so the redirect will NOT end in an error message
-        // this case only happens if you select the folder itself in the foldertree and then use the clickmenu to
-        // rename the folder
-        if ($this->fileOrFolderObject instanceof Folder) {
-            $parsedUrl = parse_url($this->returnUrl);
-            $queryParts = GeneralUtility::explodeUrl2Array(urldecode($parsedUrl['query']));
-            if ($queryParts['id'] === $this->fileOrFolderObject->getCombinedIdentifier()) {
-                $this->returnUrl = str_replace(
-                    urlencode($queryParts['id']),
-                    urlencode($this->fileOrFolderObject->getStorage()->getRootLevelFolder()->getCombinedIdentifier()),
-                    $this->returnUrl
-                );
-            }
-        }
-
-        // building pathInfo for metaInformation
-        $pathInfo = [
-            'combined_identifier' => $this->fileOrFolderObject->getCombinedIdentifier(),
-        ];
-        $this->moduleTemplate->getDocHeaderComponent()->setMetaInformation($pathInfo);
-
-        // Setting up the context sensitive menu
-        $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
-        $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/RenameFile');
-
-        // Add javaScript
-        $this->moduleTemplate->addJavaScriptCode(
-            'RenameFileInlineJavaScript',
-            'function backToList() {top.goToModule("file_FilelistList");}'
+        trigger_error(
+            'Using \TYPO3\CMS\Backend\Controller\File\RenameFileController is deprecated and internal, please use an own controller.',
+            E_USER_DEPRECATED
         );
     }
-
-    /**
-     * Render module content
-     */
-    protected function renderContent(): void
-    {
-        $assigns = [];
-        /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
-        $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
-        $assigns['moduleUrlTceFile'] = (string)$uriBuilder->buildUriFromRoute('tce_file');
-        $assigns['returnUrl'] = $this->returnUrl;
-
-        if ($this->fileOrFolderObject instanceof Folder) {
-            $fileIdentifier = $this->fileOrFolderObject->getCombinedIdentifier();
-            $targetLabel = 'file_rename.php.label.target.folder';
-        } else {
-            $fileIdentifier = $this->fileOrFolderObject->getUid();
-            $targetLabel = 'file_rename.php.label.target.file';
-            $assigns['conflictMode'] = DuplicationBehavior::cast(DuplicationBehavior::RENAME);
-            $assigns['destination'] = $this->fileOrFolderObject->getParentFolder()->getCombinedIdentifier();
-        }
-
-        $assigns['fileName'] = $this->fileOrFolderObject->getName();
-        $assigns['fileIdentifier'] = $fileIdentifier;
-        $assigns['fieldLabel'] = $targetLabel;
-
-        // Create buttons
-        $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
-
-        // csh button
-        $cshButton = $buttonBar->makeHelpButton()
-            ->setModuleName('xMOD_csh_corebe')
-            ->setFieldName('file_rename');
-        $buttonBar->addButton($cshButton);
-
-        // back button
-        if ($this->returnUrl) {
-            $backButton = $buttonBar->makeLinkButton()
-                ->setHref($this->returnUrl)
-                ->setTitle($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.goBack'))
-                ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-close', Icon::SIZE_SMALL));
-            $buttonBar->addButton($backButton);
-        }
-
-        // Save and Close button
-        $saveAndCloseButton = $buttonBar->makeInputButton()
-            ->setName('_saveandclose')
-            ->setValue('1')
-            ->setShowLabelText(true)
-            ->setClasses('t3js-submit-file-rename')
-            ->setForm('RenameFileController')
-            ->setTitle($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_edit.php.saveAndClose'))
-            ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save-close', Icon::SIZE_SMALL));
-
-        $buttonBar->addButton($saveAndCloseButton, ButtonBar::BUTTON_POSITION_LEFT, 20);
-
-        $this->moduleTemplate->getPageRenderer()->addInlineLanguageLabelArray([
-            'file_rename.actions.cancel' => $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_rename.actions.cancel'),
-            'file_rename.actions.rename' => $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_rename.actions.rename'),
-            'file_rename.actions.override' => $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_rename.actions.override'),
-            'file_rename.exists.title' => $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_rename.exists.title'),
-            'file_rename.exists.description' => $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_rename.exists.description'),
-        ]);
-
-        // Rendering of the output via fluid
-        $view = GeneralUtility::makeInstance(StandaloneView::class);
-        $view->setTemplateRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates')]);
-        $view->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Partials')]);
-        $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName(
-            'EXT:backend/Resources/Private/Templates/File/RenameFile.html'
-        ));
-        $view->assignMultiple($assigns);
-        $this->moduleTemplate->setContent($view->render());
-    }
-
-    /**
-     * @return LanguageService
-     */
-    protected function getLanguageService(): LanguageService
-    {
-        return $GLOBALS['LANG'];
-    }
 }
index cbefc8f..be9b12e 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 declare(strict_types = 1);
+
 namespace TYPO3\CMS\Backend\Controller\File;
 
 /*
@@ -15,173 +16,18 @@ namespace TYPO3\CMS\Backend\Controller\File;
  * The TYPO3 project - inspiring people to share!
  */
 
-use Psr\Http\Message\ResponseInterface;
-use Psr\Http\Message\ServerRequestInterface;
-use TYPO3\CMS\Backend\Routing\UriBuilder;
-use TYPO3\CMS\Backend\Template\ModuleTemplate;
-use TYPO3\CMS\Core\Http\HtmlResponse;
-use TYPO3\CMS\Core\Imaging\Icon;
-use TYPO3\CMS\Core\Localization\LanguageService;
-use TYPO3\CMS\Core\Resource\Exception\InsufficientFileAccessPermissionsException;
-use TYPO3\CMS\Core\Resource\Folder;
-use TYPO3\CMS\Core\Resource\ResourceFactory;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Fluid\View\StandaloneView;
-
 /**
- * Script Class for the replace-file form
- * @internal This class is a specific Backend controller implementation and is not considered part of the Public TYPO3 API.
+ * Class ReplaceFileController
+ *
+ * @deprecated see \TYPO3\CMS\Filelist\Controller\File\ReplaceFileController
  */
-class ReplaceFileController
+class ReplaceFileController extends \TYPO3\CMS\Filelist\Controller\File\ReplaceFileController
 {
-    /**
-     * sys_file uid
-     *
-     * @var int
-     */
-    protected $uid;
-
-    /**
-     * The file or folder object that should be renamed
-     *
-     * @var \TYPO3\CMS\Core\Resource\ResourceInterface $fileOrFolderObject
-     */
-    protected $fileOrFolderObject;
-
-    /**
-     * Return URL of list module.
-     *
-     * @var string
-     */
-    protected $returnUrl;
-
-    /**
-     * ModuleTemplate object
-     *
-     * @var ModuleTemplate
-     */
-    protected $moduleTemplate;
-
-    /**
-     * Processes the request, currently everything is handled and put together via "main()"
-     *
-     * @param ServerRequestInterface $request the current request
-     * @return ResponseInterface the response with the content
-     */
-    public function mainAction(ServerRequestInterface $request): ResponseInterface
-    {
-        $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
-        $this->init($request);
-        $this->renderContent();
-        return new HtmlResponse($this->moduleTemplate->renderContent());
-    }
-
-    /**
-     * Init
-     *
-     * @param ServerRequestInterface $request
-     * @throws \RuntimeException
-     * @throws InsufficientFileAccessPermissionsException
-     */
-    protected function init(ServerRequestInterface $request): void
+    public function __construct()
     {
-        $parsedBody = $request->getParsedBody();
-        $queryParams = $request->getQueryParams();
-        $lang = $this->getLanguageService();
-
-        // Initialize GPvars:
-        $this->uid = (int)($parsedBody['uid'] ?? $queryParams['uid'] ?? 0);
-        $this->returnUrl = GeneralUtility::sanitizeLocalUrl($parsedBody['returnUrl'] ?? $queryParams['returnUrl'] ?? '');
-
-        // Cleaning and checking uid
-        if ($this->uid > 0) {
-            $this->fileOrFolderObject = ResourceFactory::getInstance()
-                ->retrieveFileOrFolderObject('file:' . $this->uid);
-        }
-        if (!$this->fileOrFolderObject) {
-            $title = $lang->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:paramError');
-            $message = $lang->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:targetNoDir');
-            throw new \RuntimeException($title . ': ' . $message, 1436895930);
-        }
-        if ($this->fileOrFolderObject->getStorage()->getUid() === 0) {
-            throw new InsufficientFileAccessPermissionsException(
-                'You are not allowed to access files outside your storages',
-                1436895931
-            );
-        }
-
-        // If a folder should be renamed, AND the returnURL should go to the old directory name, the redirect is forced
-        // so the redirect will NOT end in an error message
-        // this case only happens if you select the folder itself in the foldertree and then use the clickmenu to
-        // rename the folder
-        if ($this->fileOrFolderObject instanceof Folder) {
-            $parsedUrl = parse_url($this->returnUrl);
-            $queryParts = GeneralUtility::explodeUrl2Array(urldecode($parsedUrl['query']));
-            if ($queryParts['id'] === $this->fileOrFolderObject->getCombinedIdentifier()) {
-                $this->returnUrl = str_replace(
-                    urlencode($queryParts['id']),
-                    urlencode($this->fileOrFolderObject->getStorage()->getRootLevelFolder()->getCombinedIdentifier()),
-                    $this->returnUrl
-                );
-            }
-        }
-
-        $pathInfo = [
-            'combined_identifier' => $this->fileOrFolderObject->getCombinedIdentifier(),
-        ];
-        $this->moduleTemplate->getDocHeaderComponent()->setMetaInformation($pathInfo);
-        $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
-        $this->moduleTemplate->addJavaScriptCode(
-            'ReplaceFileOnlineJavaScript',
-            'function backToList() {top.goToModule("file_FilelistList");}'
+        trigger_error(
+            'Using \TYPO3\CMS\Backend\Controller\File\ReplaceFileController is deprecated and internal, please use an own controller.',
+            E_USER_DEPRECATED
         );
     }
-
-    /**
-     * Render module content
-     */
-    protected function renderContent(): void
-    {
-        // Assign variables used by the fluid template
-        $assigns = [];
-        /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
-        $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
-        $assigns['moduleUrlTceFile'] = (string)$uriBuilder->buildUriFromRoute('tce_file');
-        $assigns['uid'] = $this->uid;
-        $assigns['returnUrl'] = $this->returnUrl;
-
-        $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
-        // csh button
-        $cshButton = $buttonBar->makeHelpButton()
-            ->setModuleName('xMOD_csh_corebe')
-            ->setFieldName('file_rename');
-        $buttonBar->addButton($cshButton);
-
-        // Back button
-        if ($this->returnUrl) {
-            $returnButton = $buttonBar->makeLinkButton()
-                ->setHref($this->returnUrl)
-                ->setTitle($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.goBack'))
-                ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-view-go-back', Icon::SIZE_SMALL));
-            $buttonBar->addButton($returnButton);
-        }
-
-        // Rendering of the output via fluid
-        $view = GeneralUtility::makeInstance(StandaloneView::class);
-        $view->setTemplateRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates')]);
-        $view->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Partials')]);
-        $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName(
-            'EXT:backend/Resources/Private/Templates/File/ReplaceFile.html'
-        ));
-        $view->assignMultiple($assigns);
-        $this->moduleTemplate->setContent($view->render());
-    }
-
-    /**
-     * @return LanguageService
-     */
-    protected function getLanguageService(): LanguageService
-    {
-        return $GLOBALS['LANG'];
-    }
 }
index 84d8330..3f02d1b 100644 (file)
@@ -67,7 +67,7 @@ return [
     // Register link wizard
     'wizard_link' => [
         'path' => '/wizard/link/browse',
-        'target' => \TYPO3\CMS\Backend\Controller\LinkBrowserController::class . '::mainAction'
+        'target' => Controller\LinkBrowserController::class . '::mainAction'
     ],
 
     /** File- and folder-related routes */
@@ -78,36 +78,6 @@ return [
         'target' => Controller\FileSystemNavigationFrameController::class . '::mainAction'
     ],
 
-    // Editing the contents of a file
-    'file_edit' => [
-        'path' => '/file/editcontent',
-        'target' => Controller\File\EditFileController::class . '::mainAction'
-    ],
-
-    // Create a new folder
-    'file_newfolder' => [
-        'path' => '/file/new',
-        'target' => Controller\File\CreateFolderController::class . '::mainAction'
-    ],
-
-    // Rename a file
-    'file_rename' => [
-        'path' => '/file/rename',
-        'target' => Controller\File\RenameFileController::class . '::mainAction'
-    ],
-
-    // Replace a file with a different one
-    'file_replace' => [
-        'path' => '/file/replace',
-        'target' => Controller\File\ReplaceFileController::class . '::mainAction'
-    ],
-
-    // Upload new files
-    'file_upload' => [
-        'path' => '/file/upload',
-        'target' => Controller\File\FileUploadController::class . '::mainAction'
-    ],
-
     // Add new online media
     'online_media' => [
         'path' => '/online-media',
diff --git a/typo3/sysext/backend/Resources/Private/Templates/File/CreateFolder.html b/typo3/sysext/backend/Resources/Private/Templates/File/CreateFolder.html
deleted file mode 100644 (file)
index 8875a05..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-<div>
-    <h1><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_newfolder.php.pagetitle" /></h1>
-    <f:if condition="{moduleUrlTceFile}">
-        <h3><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_newfolder.php.newfolders" /></h3>
-        <div>
-            <form role="form" action="{moduleUrlTceFile}" method="post" name="editform">
-                <div class="form-group">
-                    <div class="form-section">
-                        <div class="form-group">
-                            <label for="number-of-new-folders"><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_newfolder.php.number_of_folders" /></label> {cshFileNewFolder -> f:format.raw()}
-                            <div class="form-control-wrap">
-                                <div class="input-group">
-                                    <select class="form-control form-control-adapt" name="number" id="number-of-new-folders" onchange="reload(this.options[this.selectedIndex].value);">';
-                                        <f:for each="{options}" as="option">
-                                            <option value="{option.value}"{option.selected}>{option.value}</option>
-                                        </f:for>
-                                    </select>
-                                </div>
-                            </div>
-                        </div>
-                    </div>
-                    <f:for each="{folders}" as="folder">
-                        <div class="form-section">
-                            <div class="form-group">
-                                <label for="folder_new_{folder.this}"><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_newfolder.php.label_newfolder" /> {folder.next}:</label>
-                                <div class="form-control-wrap">
-                                    <input type="text" class="form-control" id="folder_new_{folder.this}" name="data[newfolder][{folder.this}][data]" onchange="changed=true;" />
-                                    <input type="hidden" name="data[newfolder][{folder.this}][target]" value="{target}" />
-                                </div>
-                            </div>
-                        </div>
-                    </f:for>
-                </div>
-                <div class="form-group">
-                    <input class="btn btn-default" type="submit" value="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_newfolder.php.submit')}" />
-                    <input type="hidden" name="data[newfolder][0][redirect]" value="{returnUrl}" />
-                </div>
-            </form>
-        </div>
-    </f:if>
-    <f:if condition="{moduleUrlOnlineMedia}">
-        <f:if condition="{fileExtList -> f:count()} > 0">
-            <form action="{moduleUrlOnlineMedia}" method="post" name="editform2">
-                <h3><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media" /></h3>
-                <div>
-                    <div class="form-group">
-                        <div class="form-section">
-                            <div class="form-group">
-                                <label for="newMedia"><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media.label" /></label> {cshFileNewMedia -> f:format.raw()}
-                                <div class="form-control-wrap">
-                                    <input class="form-control" type="text" id="newMedia" name="data[newMedia][0][url]"
-                                           placeholder="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media.placeholder')}" />
-                                    <input type="hidden" name="data[newMedia][0][target]" value="{target}" />
-                                </div>
-                                <div class="help-block">
-                                    <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media.allowedProviders" /><br>
-                                        <f:for each="{fileExtList}" as="fileExt">
-                                            <span class="label label-success">{fileExt}</span>
-                                        </f:for>
-                                </div>
-                            </div>
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <input class="btn btn-default" type="submit" value="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media.submit')}" />
-                        <input type="hidden" name="redirect" value="{returnUrl}" />
-                    </div>
-                </div>
-            </form>
-        </f:if>
-        <f:if condition="{txtFileExtList -> f:count()} > 0">
-            <form action="{moduleUrlTceFile}" method="post" name="editform3">
-                <h3><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_newfolder.php.newfile" /></h3>
-                <div>
-                    <div class="form-group">
-                        <div class="form-section">
-                            <div class="form-group">
-                                <label for="newfile"><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_newfolder.php.label_newfile" /></label> {cshFileNewFile -> f:format.raw()}
-                                <div class="form-control-wrap">
-                                    <input class="form-control" type="text" id="newfile" name="data[newfile][0][data]" onchange="changed=true;" />
-                                    <input type="hidden" name="data[newfile][0][target]" value="{target}" />
-                                </div>
-                                <div class="help-block">
-                                    <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.allowedEditableTextFileExtensions" /><br>
-                                    <f:for each="{txtFileExtList}" as="fileExt">
-                                        <span class="label label-success">{fileExt}</span>
-                                    </f:for>
-                                </div>
-                            </div>
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <button class="btn btn-default" name="edit" type="submit" value="1"><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_newfolder.php.newfile_submit" /></button>
-                        <input type="hidden" name="data[newfile][0][redirect]" value="{returnUrl}" />
-                    </div>
-                </div>
-            </form>
-        </f:if>
-    </f:if>
-</div>
diff --git a/typo3/sysext/backend/Resources/Private/Templates/File/EditFile.html b/typo3/sysext/backend/Resources/Private/Templates/File/EditFile.html
deleted file mode 100644 (file)
index 268ba76..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<form action="{moduleUrlTceFile}" method="post" id="EditFileController" name="editform">
-    <h1><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_edit.php.pagetitle" /> {fileName}</h1>
-    <f:format.raw>{form}</f:format.raw>
-</form>
diff --git a/typo3/sysext/backend/Resources/Private/Templates/File/RenameFile.html b/typo3/sysext/backend/Resources/Private/Templates/File/RenameFile.html
deleted file mode 100644 (file)
index e7f2cb8..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-<form action="{moduleUrlTceFile}" method="post" name="editform" role="form" id="RenameFileController">
-    <fieldset class="form-section">
-        <div class="row">
-            <div class="form-group col-md-12">
-                <label class="t3js-formengine-label" for="rename_target">
-                    <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:{fieldLabel}" />
-                </label>
-                <div class="formengine-field-item">
-                    <div class="form-control-wrap">
-                        <div class="form-wizards-wrap">
-                            <div class="form-wizards-element">
-                                <input id="rename_target" class="form-control" type="text" name="data[rename][0][target]" value="{fileName}" data-original="{fileName}" />
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-    </fieldset>
-
-    <f:if condition="{destination}">
-        <input type="hidden" name="data[rename][0][destination]" value="{destination}"/>
-        <input type="hidden" name="data[rename][0][conflictMode]" value="{conflictMode}"/>
-    </f:if>
-    <input type="hidden" name="data[rename][0][data]" value="{fileIdentifier}"/>
-    <input type="hidden" name="data[rename][0][redirect]" value="{returnUrl}"/>
-</form>
diff --git a/typo3/sysext/backend/Resources/Private/Templates/File/ReplaceFile.html b/typo3/sysext/backend/Resources/Private/Templates/File/ReplaceFile.html
deleted file mode 100644 (file)
index 71cfe7d..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-<h1><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_replace.php.pagetitle" /></h1>
-<div>
-    <form action="{moduleUrlTceFile}" role="form" method="post" name="editform" enctype="multipart/form-data">
-    <div class="form-group">
-        <input type="checkbox" value="1" id="keepFilename" name="data[replace][1][keepFilename]">
-        <label for="keepFilename"><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_replace.php.keepfiletitle" /></label>
-    </div>
-
-    <div class="form-group">
-        <label for="file_replace"><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_replace.php.selectfile" /></label>
-        <div class="input-group col-xs-6">
-            <input type="text" name="fakefile" id="fakefile" class="form-control input-xlarge" readonly>
-            <a class="input-group-addon btn btn-primary" onclick="$('#file_replace').click();">
-                <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_replace.php.browse" />
-            </a>
-        </div>
-        <input class="form-control" type="file" id="file_replace" name="replace_1" style="visibility: hidden;" />
-    </div>
-
-    <script>
-      require(['jquery'], function($) {
-        $('#file_replace').change(function() {
-          $('#fakefile').val($(this).val());
-        });
-      });
-    </script>
-
-    <input type="hidden" name="overwriteExistingFiles" value="replace" />
-    <input type="hidden" name="data[replace][1][data]" value="1" />
-    <input type="hidden" name="data[replace][1][uid]" value="{uid}" />
-
-    <div class="form-group">
-        <input class="btn btn-primary" type="submit" value="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_replace.php.submit')}" />
-        <input class="btn btn-danger" type="submit" value="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.cancel')}"
-             onclick="backToList(); return false;" />
-        <input type="hidden" name="data[replace][1][redirect]" value="{returnUrl}" />
-    </div>
-    </form>
-</div>
diff --git a/typo3/sysext/backend/Resources/Private/TypeScript/RenameFile.ts b/typo3/sysext/backend/Resources/Private/TypeScript/RenameFile.ts
deleted file mode 100644 (file)
index a122c98..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-import {SeverityEnum} from './Enum/Severity';
-import * as $ from 'jquery';
-import Modal = require('./Modal');
-
-/**
- * Module: TYPO3/CMS/Backend/RenameFile
- * Modal to pick the required conflict strategy for colliding filenames
- * @exports TYPO3/CMS/Backend/RenameFile
- */
-class RenameFile {
-
-  constructor() {
-    this.initialize();
-  }
-
-  public initialize(): void {
-    $('.t3js-submit-file-rename').on('click', this.checkForDuplicate);
-  }
-
-  private checkForDuplicate(e: any): void {
-    e.preventDefault();
-
-    const form: any = $('#' + $(e.currentTarget).attr('form'));
-    const fileNameField: any = form.find('input[name="data[rename][0][target]"]');
-    const conflictModeField: any = form.find('input[name="data[rename][0][conflictMode]"]');
-    const ajaxUrl: string = TYPO3.settings.ajaxUrls.file_exists;
-
-    $.ajax({
-      cache: false,
-      data: {
-        fileName: fileNameField.val(),
-        fileTarget: form.find('input[name="data[rename][0][destination]"]').val(),
-      },
-      success: (response: any): void => {
-        const fileExists: boolean = typeof response.uid !== 'undefined';
-        const originalFileName: string = fileNameField.data('original');
-        const newFileName: string = fileNameField.val();
-
-        if (fileExists && originalFileName !== newFileName) {
-          const description: string = TYPO3.lang['file_rename.exists.description']
-                                           .replace('{0}', originalFileName).replace('{1}', newFileName);
-
-          const modal: JQuery = Modal.confirm(
-            TYPO3.lang['file_rename.exists.title'],
-            description,
-            SeverityEnum.warning,
-            [
-              {
-                active: true,
-                btnClass: 'btn-default',
-                name: 'cancel',
-                text: TYPO3.lang['file_rename.actions.cancel'],
-              },
-              {
-                btnClass: 'btn-primary',
-                name: 'rename',
-                text: TYPO3.lang['file_rename.actions.rename'],
-              },
-              {
-                btnClass: 'btn-default',
-                name: 'replace',
-                text: TYPO3.lang['file_rename.actions.override'],
-              },
-            ]);
-
-          modal.on('button.clicked', (event: any): void => {
-            if (event.target.name !== 'cancel') {
-              conflictModeField.val(event.target.name);
-              form.submit();
-            }
-            Modal.dismiss();
-          });
-        } else {
-          form.submit();
-        }
-      },
-      url: ajaxUrl,
-    });
-  }
-}
-
-export = new RenameFile();
diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/RenameFile.js b/typo3/sysext/backend/Resources/Public/JavaScript/RenameFile.js
deleted file mode 100644 (file)
index 4387687..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-define(["require","exports","./Enum/Severity","jquery","./Modal"],function(e,t,a,n,i){"use strict";return new(function(){function e(){this.initialize()}return e.prototype.initialize=function(){n(".t3js-submit-file-rename").on("click",this.checkForDuplicate)},e.prototype.checkForDuplicate=function(e){e.preventDefault();var t=n("#"+n(e.currentTarget).attr("form")),r=t.find('input[name="data[rename][0][target]"]'),l=t.find('input[name="data[rename][0][conflictMode]"]'),c=TYPO3.settings.ajaxUrls.file_exists;n.ajax({cache:!1,data:{fileName:r.val(),fileTarget:t.find('input[name="data[rename][0][destination]"]').val()},success:function(e){var n=void 0!==e.uid,c=r.data("original"),s=r.val();if(n&&c!==s){var o=TYPO3.lang["file_rename.exists.description"].replace("{0}",c).replace("{1}",s);i.confirm(TYPO3.lang["file_rename.exists.title"],o,a.SeverityEnum.warning,[{active:!0,btnClass:"btn-default",name:"cancel",text:TYPO3.lang["file_rename.actions.cancel"]},{btnClass:"btn-primary",name:"rename",text:TYPO3.lang["file_rename.actions.rename"]},{btnClass:"btn-default",name:"replace",text:TYPO3.lang["file_rename.actions.override"]}]).on("button.clicked",function(e){"cancel"!==e.target.name&&(l.val(e.target.name),t.submit()),i.dismiss()})}else t.submit()},url:c})},e}())});
\ No newline at end of file
index 76d7e00..ee3414d 100644 (file)
@@ -123,7 +123,7 @@ class FileControllerTest extends UnitTestCase
      */
     public function processAjaxRequestDeleteProcessActuallyDoesNotChangeFileData()
     {
-        $subject = $this->getAccessibleMock(FileController::class, ['init', 'main']);
+        $subject = $this->getAccessibleMock(\TYPO3\CMS\Backend\Controller\File\FileController::class, ['init', 'main']);
 
         $fileData = ['delete' => [true]];
         $subject->_set('fileProcessor', $this->mockFileProcessor);
@@ -140,7 +140,7 @@ class FileControllerTest extends UnitTestCase
      */
     public function processAjaxRequestEditFileProcessActuallyDoesNotChangeFileData()
     {
-        $subject = $this->getAccessibleMock(FileController::class, ['init', 'main']);
+        $subject = $this->getAccessibleMock(\TYPO3\CMS\Backend\Controller\File\FileController::class, ['init', 'main']);
 
         $fileData = ['editfile' => [true]];
         $subject->_set('fileProcessor', $this->mockFileProcessor);
@@ -157,7 +157,7 @@ class FileControllerTest extends UnitTestCase
      */
     public function processAjaxRequestReturnsStatus200IfNoErrorOccures()
     {
-        $subject = $this->getAccessibleMock(FileController::class, ['init', 'main']);
+        $subject = $this->getAccessibleMock(\TYPO3\CMS\Backend\Controller\File\FileController::class, ['init', 'main']);
 
         $fileData = ['editfile' => [true]];
         $subject->_set('fileProcessor', $this->mockFileProcessor);
index 628b391..6044fc9 100644 (file)
@@ -26,7 +26,7 @@ use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
 class ThumbnailControllerTest extends UnitTestCase
 {
     /**
-     * @var ThumbnailController|MockObject
+     * @var \TYPO3\CMS\Backend\Controller\File\ThumbnailController|MockObject
      */
     protected $subject;
 
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-87882-FileRelatedControllersMovedToEXTfilelist.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-87882-FileRelatedControllersMovedToEXTfilelist.rst
new file mode 100644 (file)
index 0000000..082070e
--- /dev/null
@@ -0,0 +1,42 @@
+.. include:: ../../Includes.txt
+
+====================================================================
+Deprecation: #87882 - File related controllers moved to EXT:filelist
+====================================================================
+
+See :issue:`87882`
+
+Description
+===========
+
+The following controllers have been moved to extension `filelist` as they are part of
+the filelist feature set:
+
+* :php:`CreateFolderController`
+* :php:`EditFileController`
+* :php:`FileUploadController`
+* :php:`RenameFileController`
+* :php:`ReplaceFileController`
+
+
+Impact
+======
+
+The namespace changed from :php:`TYPO3\CMS\Backend\Controller\File` to :php:`TYPO3\CMS\Filelist\Controller\File`. Using
+the old controllers will trigger a PHP :php:`E_USER_DEPRECATED` error.
+
+
+Affected Installations
+======================
+
+Installations accessing any of the above controllers.
+
+
+Migration
+=========
+
+When wanting to use any of the functionality in these controllers, you should build your own controllers as they are
+internal and might change at any time. Use the TYPO3 file abstraction layer as API and add your own functionality on top
+of it with an own controller instead of reusing these.
+
+.. index:: Backend, PHP-API, PartiallyScanned, ext:filelist
index a88561d..96a419b 100644 (file)
@@ -526,9 +526,6 @@ Do you want to continue WITHOUT saving?</source>
                        <trans-unit id="file_upload.php.submit">
                                <source>Upload files</source>
                        </trans-unit>
-                       <trans-unit id="file_upload.php.files">
-                               <source>files</source>
-                       </trans-unit>
                        <trans-unit id="file_upload.dropzonehint.title">
                                <source>Drag &amp; drop to upload files</source>
                        </trans-unit>
@@ -613,97 +610,6 @@ Do you want to continue WITHOUT saving?</source>
                        <trans-unit id="file_upload.button.continue">
                                <source>Continue with selected actions</source>
                        </trans-unit>
-                       <trans-unit id="file_upload.php.number_of_files">
-                               <source>Number of files</source>
-                       </trans-unit>
-                       <trans-unit id="file_rename.exists.title">
-                               <source>File exists already</source>
-                       </trans-unit>
-                       <trans-unit id="file_rename.exists.description">
-                               <source>You want to rename the file "{0}" to "{1}", but such a file already exists. How do you want to proceed?</source>
-                       </trans-unit>
-                       <trans-unit id="file_rename.actions.cancel">
-                               <source>Cancel</source>
-                       </trans-unit>
-                       <trans-unit id="file_rename.actions.rename">
-                               <source>Rename with unique name</source>
-                       </trans-unit>
-                       <trans-unit id="file_rename.actions.override">
-                               <source>Overwrite</source>
-                       </trans-unit>
-                       <trans-unit id="file_rename.php.pagetitle">
-                               <source>Rename</source>
-                       </trans-unit>
-                       <trans-unit id="file_rename.php.submit">
-                               <source>Rename</source>
-                               <note from="developer">This label is not used since TYPO3 v9.</note>
-                       </trans-unit>
-                       <trans-unit id="file_rename.php.label.target.file">
-                               <source>New file name</source>
-                       </trans-unit>
-                       <trans-unit id="file_rename.php.label.target.folder">
-                               <source>New folder name</source>
-                       </trans-unit>
-                       <trans-unit id="file_replace.php.pagetitle">
-                               <source>Replace</source>
-                       </trans-unit>
-                       <trans-unit id="file_replace.php.selectfile">
-                               <source>Select new file</source>
-                       </trans-unit>
-                       <trans-unit id="file_replace.php.keepfiletitle">
-                               <source>Keep the current filename?</source>
-                       </trans-unit>
-                       <trans-unit id="file_replace.php.browse">
-                               <source>Browse</source>
-                       </trans-unit>
-                       <trans-unit id="file_replace.php.submit">
-                               <source>Replace</source>
-                       </trans-unit>
-                       <trans-unit id="file_edit.php.pagetitle">
-                               <source>Edit</source>
-                       </trans-unit>
-                       <trans-unit id="file_edit.php.submit">
-                               <source>Save</source>
-                       </trans-unit>
-                       <trans-unit id="file_edit.php.saveAndClose">
-                               <source>Save and Close</source>
-                       </trans-unit>
-                       <trans-unit id="file_edit.php.coundNot">
-                               <source>This filetype cannot be edited.&lt;br /&gt;The file must have an extension like:&lt;br /&gt;&lt;br /&gt; &lt;b&gt;%s&lt;/b&gt;</source>
-                       </trans-unit>
-                       <trans-unit id="file_newfolder.php.pagetitle">
-                               <source>New file or folder</source>
-                       </trans-unit>
-                       <trans-unit id="file_newfolder.php.newfolders">
-                               <source>Create new folders</source>
-                       </trans-unit>
-                       <trans-unit id="file_newfolder.php.label_newfolder">
-                               <source>Folder</source>
-                       </trans-unit>
-                       <trans-unit id="file_newfolder.php.submit">
-                               <source>Create folders</source>
-                       </trans-unit>
-                       <trans-unit id="create_folder.title">
-                               <source>Create new folder</source>
-                       </trans-unit>
-                       <trans-unit id="create_folder.submit">
-                               <source>Create folder</source>
-                       </trans-unit>
-                       <trans-unit id="file_newfolder.php.folders">
-                               <source>folders</source>
-                       </trans-unit>
-                       <trans-unit id="file_newfolder.php.newfile_submit">
-                               <source>Create file</source>
-                       </trans-unit>
-                       <trans-unit id="file_newfolder.php.newfile">
-                               <source>Create new textfile</source>
-                       </trans-unit>
-                       <trans-unit id="file_newfolder.php.label_newfile">
-                               <source>File name</source>
-                       </trans-unit>
-                       <trans-unit id="file_newfolder.php.number_of_folders">
-                               <source>Number of folders</source>
-                       </trans-unit>
                        <trans-unit id="online_media.new_media">
                                <source>Add new media asset</source>
                        </trans-unit>
diff --git a/typo3/sysext/filelist/Classes/Controller/File/CreateFolderController.php b/typo3/sysext/filelist/Classes/Controller/File/CreateFolderController.php
new file mode 100644 (file)
index 0000000..a6b1831
--- /dev/null
@@ -0,0 +1,267 @@
+<?php
+declare(strict_types = 1);
+namespace TYPO3\CMS\Filelist\Controller\File;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use TYPO3\CMS\Backend\Routing\UriBuilder;
+use TYPO3\CMS\Backend\Template\ModuleTemplate;
+use TYPO3\CMS\Backend\Utility\BackendUtility;
+use TYPO3\CMS\Core\Http\HtmlResponse;
+use TYPO3\CMS\Core\Imaging\Icon;
+use TYPO3\CMS\Core\Localization\LanguageService;
+use TYPO3\CMS\Core\Resource\Exception\InsufficientFolderAccessPermissionsException;
+use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperRegistry;
+use TYPO3\CMS\Core\Resource\ResourceFactory;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\MathUtility;
+use TYPO3\CMS\Fluid\View\StandaloneView;
+
+/**
+ * Script class for the create-new script
+ *
+ * Displays forms for creating folders (1 to 10), a media asset or a new file.
+ * @internal This class is a specific Backend controller implementation and is not considered part of the Public TYPO3 API.
+ */
+class CreateFolderController
+{
+    /**
+     * @var int
+     */
+    protected $folderNumber = 10;
+
+    /**
+     * @var int
+     */
+    protected $number;
+
+    /**
+     * Set with the target path inputted in &target
+     *
+     * @var string
+     */
+    protected $target;
+
+    /**
+     * The folder object which is  the target directory
+     *
+     * @var \TYPO3\CMS\Core\Resource\Folder $folderObject
+     */
+    protected $folderObject;
+
+    /**
+     * Return URL of list module.
+     *
+     * @var string
+     */
+    protected $returnUrl;
+
+    /**
+     * @var array
+     */
+    protected $pathInfo;
+
+    /**
+     * ModuleTemplate object
+     *
+     * @var ModuleTemplate
+     */
+    protected $moduleTemplate;
+
+    /**
+     * Processes the request, currently everything is handled and put together via "main()"
+     *
+     * @param ServerRequestInterface $request the current request
+     * @return ResponseInterface the response with the content
+     */
+    public function mainAction(ServerRequestInterface $request): ResponseInterface
+    {
+        $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
+        $this->init($request);
+        $this->main();
+        return new HtmlResponse($this->moduleTemplate->renderContent());
+    }
+
+    /**
+     * @param ServerRequestInterface|null $request
+     *
+     * @throws InsufficientFolderAccessPermissionsException
+     * @throws \RuntimeException
+     */
+    protected function init(ServerRequestInterface $request): void
+    {
+        $parsedBody = $request->getParsedBody();
+        $queryParams = $request->getQueryParams();
+
+        $this->number = $parsedBody['number'] ?? $queryParams['number'] ?? 0;
+        $this->target = ($combinedIdentifier = $parsedBody['target'] ?? $queryParams['target'] ?? '');
+        $this->returnUrl = GeneralUtility::sanitizeLocalUrl($parsedBody['returnUrl'] ?? $queryParams['returnUrl'] ?? '');
+        // create the folder object
+        if ($combinedIdentifier) {
+            $this->folderObject = ResourceFactory::getInstance()
+                ->getFolderObjectFromCombinedIdentifier($combinedIdentifier);
+        }
+        // Cleaning and checking target directory
+        if (!$this->folderObject) {
+            $title = $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:paramError');
+            $message = $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:targetNoDir');
+            throw new \RuntimeException($title . ': ' . $message, 1294586845);
+        }
+        if ($this->folderObject->getStorage()->getUid() === 0) {
+            throw new InsufficientFolderAccessPermissionsException(
+                'You are not allowed to access folders outside your storages',
+                1375889838
+            );
+        }
+
+        $pathInfo = [
+            'combined_identifier' => $this->folderObject->getCombinedIdentifier(),
+        ];
+        $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
+
+        $this->moduleTemplate->getDocHeaderComponent()->setMetaInformation($pathInfo);
+        $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
+        $this->moduleTemplate->addJavaScriptCode(
+            'CreateFolderInlineJavaScript',
+            'var path = "' . $this->target . '";
+            var confirmTitle = '
+            . GeneralUtility::quoteJSvalue(
+                $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:pleaseConfirm')
+            )
+            . ';
+            var confirmText = '
+            . GeneralUtility::quoteJSvalue(
+                $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:mess.redraw')
+            )
+            . ';
+            function reload(a) {
+                var params = "&target="+encodeURIComponent(path)+"&number="+a+"&returnUrl=' . rawurlencode($this->returnUrl) . '";
+                var url = \'' . (string)$uriBuilder->buildUriFromRoute('file_newfolder') . '\';
+                if (!changed) {
+                    window.location.href = url + params;
+                } else {
+                    var modal = top.TYPO3.Modal.confirm(confirmTitle, confirmText);
+                    modal.on(\'confirm.button.cancel\', function(e) {
+                        top.TYPO3.Modal.currentModal.trigger(\'modal-dismiss\');
+                    });
+                    modal.on(\'confirm.button.ok\', function(e) {
+                        top.TYPO3.Modal.currentModal.trigger(\'modal-dismiss\');
+                        window.location.href = url + params;
+                    });
+                }
+            }
+            function backToList() {
+                top.goToModule("file_FilelistList");
+            }
+            var changed = 0;'
+        );
+    }
+
+    /**
+     * Main function, rendering the main module content
+     */
+    protected function main()
+    {
+        $lang = $this->getLanguageService();
+        $assigns = [];
+        $assigns['target'] = $this->target;
+        if ($this->folderObject->checkActionPermission('add')) {
+            $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
+            $assigns['moduleUrlTceFile'] = (string)$uriBuilder->buildUriFromRoute('tce_file');
+            $assigns['cshFileNewFolder'] = BackendUtility::cshItem('xMOD_csh_corebe', 'file_newfolder');
+            // Making the selector box for the number of concurrent folder-creations
+            $this->number = MathUtility::forceIntegerInRange($this->number, 1, 10);
+            for ($a = 1; $a <= $this->folderNumber; $a++) {
+                $options = [];
+                $options['value'] = $a;
+                $options['selected'] = ($this->number == $a ? ' selected="selected"' : '');
+                $assigns['options'][] = $options;
+            }
+            // Making the number of new-folder boxes needed:
+            for ($a = 0; $a < $this->number; $a++) {
+                $folder = [];
+                $folder['this'] = $a;
+                $folder['next'] = $a + 1;
+                $assigns['folders'][] = $folder;
+            }
+            // Making submit button for folder creation:
+            $assigns['returnUrl'] = $this->returnUrl;
+        }
+
+        if ($this->folderObject->getStorage()->checkUserActionPermission('add', 'File')) {
+            $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
+            $assigns['moduleUrlOnlineMedia'] = (string)$uriBuilder->buildUriFromRoute('online_media');
+            $assigns['cshFileNewMedia'] = BackendUtility::cshItem('xMOD_csh_corebe', 'file_newMedia');
+            // Create a list of allowed file extensions with the readable format "youtube, vimeo" etc.
+            $fileExtList = [];
+            $onlineMediaFileExt = OnlineMediaHelperRegistry::getInstance()->getSupportedFileExtensions();
+            foreach ($onlineMediaFileExt as $fileExt) {
+                if (GeneralUtility::verifyFilenameAgainstDenyPattern('.' . $fileExt)) {
+                    $fileExtList[] = strtoupper(htmlspecialchars($fileExt));
+                }
+            }
+            $assigns['fileExtList'] = $fileExtList;
+
+            $assigns['moduleUrlTceFile'] = (string)$uriBuilder->buildUriFromRoute('tce_file');
+            $assigns['cshFileNewFile'] = BackendUtility::cshItem('xMOD_csh_corebe', 'file_newfile');
+            // Create a list of allowed file extensions with a text format "*.txt, *.css" etc.
+            $fileExtList = [];
+            $textFileExt = GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['SYS']['textfile_ext'], true);
+            foreach ($textFileExt as $fileExt) {
+                if (GeneralUtility::verifyFilenameAgainstDenyPattern('.' . $fileExt)) {
+                    $fileExtList[] = strtoupper(htmlspecialchars($fileExt));
+                }
+            }
+            $assigns['txtFileExtList'] = $fileExtList;
+        }
+
+        $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
+        // CSH button
+        $helpButton = $buttonBar->makeHelpButton()
+            ->setFieldName('file_new')
+            ->setModuleName('xMOD_csh_corebe');
+        $buttonBar->addButton($helpButton);
+
+        // Back
+        if ($this->returnUrl) {
+            $backButton = $buttonBar->makeLinkButton()
+                ->setHref($this->returnUrl)
+                ->setTitle($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.goBack'))
+                ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-view-go-back', Icon::SIZE_SMALL));
+            $buttonBar->addButton($backButton);
+        }
+
+        // Rendering of the output via fluid
+        $view = GeneralUtility::makeInstance(StandaloneView::class);
+        $view->setTemplateRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates')]);
+        $view->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Partials')]);
+        $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName(
+            'EXT:filelist/Resources/Private/Templates/File/CreateFolder.html'
+        ));
+        $view->assignMultiple($assigns);
+        $this->moduleTemplate->setContent($view->render());
+    }
+
+    /**
+     * Returns LanguageService
+     *
+     * @return LanguageService
+     */
+    protected function getLanguageService(): LanguageService
+    {
+        return $GLOBALS['LANG'];
+    }
+}
diff --git a/typo3/sysext/filelist/Classes/Controller/File/EditFileController.php b/typo3/sysext/filelist/Classes/Controller/File/EditFileController.php
new file mode 100644 (file)
index 0000000..ecd205f
--- /dev/null
@@ -0,0 +1,354 @@
+<?php
+declare(strict_types = 1);
+namespace TYPO3\CMS\Filelist\Controller\File;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use TYPO3\CMS\Backend\Form\FormResultCompiler;
+use TYPO3\CMS\Backend\Form\NodeFactory;
+use TYPO3\CMS\Backend\Routing\UriBuilder;
+use TYPO3\CMS\Backend\Template\Components\ButtonBar;
+use TYPO3\CMS\Backend\Template\ModuleTemplate;
+use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
+use TYPO3\CMS\Core\Http\HtmlResponse;
+use TYPO3\CMS\Core\Http\RedirectResponse;
+use TYPO3\CMS\Core\Imaging\Icon;
+use TYPO3\CMS\Core\Localization\LanguageService;
+use TYPO3\CMS\Core\Messaging\FlashMessage;
+use TYPO3\CMS\Core\Messaging\FlashMessageService;
+use TYPO3\CMS\Core\Resource\Exception\InsufficientFileAccessPermissionsException;
+use TYPO3\CMS\Core\Resource\ResourceFactory;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Fluid\View\StandaloneView;
+
+/**
+ * Script Class for rendering the file editing screen
+ * @internal This class is a specific Backend controller implementation and is not considered part of the Public TYPO3 API.
+ */
+class EditFileController
+{
+    /**
+     * Module content accumulated.
+     *
+     * @var string
+     */
+    protected $content;
+
+    /**
+     * Original input target
+     *
+     * @var string
+     */
+    protected $origTarget;
+
+    /**
+     * The original target, but validated.
+     *
+     * @var string
+     */
+    protected $target;
+
+    /**
+     * Return URL of list module.
+     *
+     * @var string
+     */
+    protected $returnUrl;
+
+    /**
+     * the file that is being edited on
+     *
+     * @var \TYPO3\CMS\Core\Resource\AbstractFile
+     */
+    protected $fileObject;
+
+    /**
+     * ModuleTemplate object
+     *
+     * @var ModuleTemplate
+     */
+    protected $moduleTemplate;
+
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
+    }
+
+    /**
+     * Processes the request, currently everything is handled and put together via "process()"
+     *
+     * @param ServerRequestInterface $request the current request
+     * @return ResponseInterface the response with the content
+     */
+    public function mainAction(ServerRequestInterface $request): ResponseInterface
+    {
+        $this->init($request);
+        if ($response = $this->process()) {
+            return $response;
+        }
+
+        return new HtmlResponse($this->moduleTemplate->renderContent());
+    }
+
+    /**
+     * Initialize script class
+     *
+     * @param ServerRequestInterface $request
+     *
+     * @throws InsufficientFileAccessPermissionsException
+     */
+    protected function init(ServerRequestInterface $request): void
+    {
+        $parsedBody = $request->getParsedBody();
+        $queryParams = $request->getQueryParams();
+
+        // Setting target, which must be a file reference to a file within the mounts.
+        $this->target = $this->origTarget = $parsedBody['target'] ?? $queryParams['target'] ?? '';
+        $this->returnUrl = GeneralUtility::sanitizeLocalUrl($parsedBody['returnUrl'] ?? $queryParams['returnUrl'] ?? '');
+        // create the file object
+        if ($this->target) {
+            $this->fileObject = ResourceFactory::getInstance()
+                ->retrieveFileOrFolderObject($this->target);
+        }
+        // Cleaning and checking target directory
+        if (!$this->fileObject) {
+            $title = $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:paramError');
+            $message = $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:targetNoDir');
+            throw new \RuntimeException($title . ': ' . $message, 1294586841);
+        }
+        if ($this->fileObject->getStorage()->getUid() === 0) {
+            throw new InsufficientFileAccessPermissionsException(
+                'You are not allowed to access files outside your storages',
+                1375889832
+            );
+        }
+
+        // Setting template object
+        $this->moduleTemplate->addJavaScriptCode(
+            'FileEditBackToList',
+            'function backToList() {
+                               top.goToModule("file_FilelistList");
+                       }'
+        );
+    }
+
+    /**
+     * Main function, rendering the actual content of the editing page
+     *
+     * @return ResponseInterface|null Possible redirect response
+     */
+    protected function process(): ?ResponseInterface
+    {
+        $dataColumnDefinition = [
+            'label' => htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:file'))
+                . ' ' . htmlspecialchars($this->target),
+            'config' => [
+                'type' => 'text',
+                'cols' => 48,
+                'wrap' => 'OFF',
+            ],
+            'defaultExtras' => 'fixed-font: enable-tab'
+        ];
+
+        $this->getButtonsInternal();
+        // Hook: before compiling the output
+        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/file_edit.php']['preOutputProcessingHook'] ?? [] as $hookFunction) {
+            $hookParameters = [
+                'content' => &$this->content,
+                'target' => &$this->target,
+                'dataColumnDefinition' => &$dataColumnDefinition,
+            ];
+            GeneralUtility::callUserFunction($hookFunction, $hookParameters, $this);
+        }
+
+        $assigns = [];
+        $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
+        $assigns['moduleUrlTceFile'] = (string)$uriBuilder->buildUriFromRoute('tce_file');
+        $assigns['fileName'] = $this->fileObject->getName();
+
+        $extList = $GLOBALS['TYPO3_CONF_VARS']['SYS']['textfile_ext'];
+        try {
+            if (!$extList || !GeneralUtility::inList($extList, $this->fileObject->getExtension())) {
+                // @todo throw a minor exception here, not the global one
+                throw new \Exception('Files with that extension are not editable. Allowed extensions are: ' . $extList, 1476050135);
+            }
+
+            // Making the formfields
+            $hValue = (string)$uriBuilder->buildUriFromRoute('file_edit', [
+                'target' => $this->origTarget,
+                'returnUrl' => $this->returnUrl
+            ]);
+
+            $formData = [
+                'databaseRow' => [
+                    'uid' => 0,
+                    'data' => $this->fileObject->getContents(),
+                    'target' => $this->fileObject->getUid(),
+                    'redirect' => $hValue,
+                ],
+                'tableName' => 'editfile',
+                'processedTca' => [
+                    'columns' => [
+                        'data' => $dataColumnDefinition,
+                        'target' => [
+                            'config' => [
+                                'type' => 'input',
+                                'renderType' => 'hidden',
+                            ],
+                        ],
+                        'redirect' => [
+                            'config' => [
+                                'type' => 'input',
+                                'renderType' => 'hidden',
+                            ],
+                        ],
+                    ],
+                    'types' => [
+                        1 => [
+                            'showitem' => 'data,target,redirect',
+                        ],
+                    ],
+                ],
+                'recordTypeValue' => 1,
+                'inlineStructure' => [],
+                'renderType' => 'fullRecordContainer',
+            ];
+
+            $resultArray = GeneralUtility::makeInstance(NodeFactory::class)->create($formData)->render();
+            $formResultCompiler = GeneralUtility::makeInstance(FormResultCompiler::class);
+            $formResultCompiler->mergeResult($resultArray);
+
+            $form = $formResultCompiler->addCssFiles()
+                . $resultArray['html']
+                . $formResultCompiler->printNeededJSFunctions();
+
+            $assigns['form'] = $form;
+        } catch (\Exception $e) {
+            // @todo catch dedicated exceptions, not the global one, if possible
+            $flashMessage = GeneralUtility::makeInstance(FlashMessage::class, $e->getMessage(), '', FlashMessage::ERROR, true);
+
+            $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
+            $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
+            $defaultFlashMessageQueue->enqueue($flashMessage);
+
+            return new RedirectResponse($this->returnUrl, 500);
+        }
+
+        // Rendering of the output via fluid
+        $view = GeneralUtility::makeInstance(StandaloneView::class);
+        $view->setTemplateRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates')]);
+        $view->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Partials')]);
+        $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName(
+            'EXT:filelist/Resources/Private/Templates/File/EditFile.html'
+        ));
+        $view->assignMultiple($assigns);
+        $pageContent = $view->render();
+
+        // Hook: after compiling the output
+        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/file_edit.php']['postOutputProcessingHook'] ?? [] as $hookFunction) {
+            $hookParameters = [
+                'pageContent' => &$pageContent,
+                'target' => &$this->target
+            ];
+            GeneralUtility::callUserFunction($hookFunction, $hookParameters, $this);
+        }
+
+        $this->content .= $pageContent;
+        $this->moduleTemplate->setContent($this->content);
+        return null;
+    }
+
+    /**
+     * Builds the buttons for the docheader
+     */
+    protected function getButtonsInternal(): void
+    {
+        $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
+
+        $lang = $this->getLanguageService();
+        // CSH button
+        $helpButton = $buttonBar->makeHelpButton()
+            ->setFieldName('file_edit')
+            ->setModuleName('xMOD_csh_corebe');
+        $buttonBar->addButton($helpButton);
+
+        // Save button
+        $saveButton = $buttonBar->makeInputButton()
+            ->setName('_save')
+            ->setValue('1')
+            ->setForm('EditFileController')
+            ->setTitle($lang->sL('LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_edit.php.submit'))
+            ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save', Icon::SIZE_SMALL));
+
+        // Save and Close button
+        $saveAndCloseButton = $buttonBar->makeInputButton()
+            ->setName('_saveandclosedok')
+            ->setValue('1')
+            ->setForm('EditFileController')
+            ->setOnClick(
+                'document.editform.elements.namedItem("data[editfile][0][redirect]").value='
+                . GeneralUtility::quoteJSvalue($this->returnUrl)
+                . ';'
+            )
+            ->setTitle($lang->sL('LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_edit.php.saveAndClose'))
+            ->setIcon($this->moduleTemplate->getIconFactory()->getIcon(
+                'actions-document-save-close',
+                Icon::SIZE_SMALL
+            ));
+
+        $splitButton = $buttonBar->makeSplitButton()
+            ->addItem($saveButton)
+            ->addItem($saveAndCloseButton);
+        $buttonBar->addButton($splitButton, ButtonBar::BUTTON_POSITION_LEFT, 20);
+
+        // Cancel button
+        $closeButton = $buttonBar->makeLinkButton()
+            ->setHref('#')
+            ->setOnClick('backToList(); return false;')
+            ->setTitle($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.cancel'))
+            ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-close', Icon::SIZE_SMALL));
+        $buttonBar->addButton($closeButton, ButtonBar::BUTTON_POSITION_LEFT, 10);
+
+        // Make shortcut:
+        $shortButton = $buttonBar->makeShortcutButton()
+            ->setModuleName('file_edit')
+            ->setGetVariables(['target']);
+        $buttonBar->addButton($shortButton);
+    }
+
+    /**
+     * Returns LanguageService
+     *
+     * @return LanguageService
+     */
+    protected function getLanguageService(): LanguageService
+    {
+        return $GLOBALS['LANG'];
+    }
+
+    /**
+     * Returns the current BE user.
+     *
+     * @return BackendUserAuthentication
+     */
+    protected function getBackendUser(): BackendUserAuthentication
+    {
+        return $GLOBALS['BE_USER'];
+    }
+}
diff --git a/typo3/sysext/filelist/Classes/Controller/File/FileUploadController.php b/typo3/sysext/filelist/Classes/Controller/File/FileUploadController.php
new file mode 100644 (file)
index 0000000..7a88a32
--- /dev/null
@@ -0,0 +1,212 @@
+<?php
+declare(strict_types = 1);
+namespace TYPO3\CMS\Filelist\Controller\File;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use TYPO3\CMS\Backend\Template\ModuleTemplate;
+use TYPO3\CMS\Core\Http\HtmlResponse;
+use TYPO3\CMS\Core\Imaging\Icon;
+use TYPO3\CMS\Core\Localization\LanguageService;
+use TYPO3\CMS\Core\Resource\Exception\InsufficientFolderAccessPermissionsException;
+use TYPO3\CMS\Core\Resource\ResourceFactory;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+
+/**
+ * Script Class for display up to 10 upload fields
+ * @internal This class is a specific Backend controller implementation and is not considered part of the Public TYPO3 API.
+ */
+class FileUploadController
+{
+    /**
+     * Set with the target path inputted in &target
+     *
+     * @var string
+     */
+    protected $target;
+
+    /**
+     * Return URL of list module.
+     *
+     * @var string
+     */
+    protected $returnUrl;
+
+    /**
+     * Accumulating content
+     *
+     * @var string
+     */
+    protected $content;
+
+    /**
+     * The folder object which is the target directory for the upload
+     *
+     * @var \TYPO3\CMS\Core\Resource\Folder $folderObject
+     */
+    protected $folderObject;
+
+    /**
+     * ModuleTemplate object
+     *
+     * @var ModuleTemplate
+     */
+    protected $moduleTemplate;
+
+    /**
+     * Processes the request, currently everything is handled and put together via "renderContent()"
+     *
+     * @param ServerRequestInterface $request the current request
+     * @return ResponseInterface the response with the content
+     */
+    public function mainAction(ServerRequestInterface $request): ResponseInterface
+    {
+        $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
+        $this->getLanguageService()->includeLLFile('EXT:core/Resources/Private/Language/locallang_misc.xlf');
+        $this->init($request);
+        $this->renderContent();
+        return new HtmlResponse($this->moduleTemplate->renderContent());
+    }
+
+    /**
+     * Initialize
+     *
+     * @param ServerRequestInterface $request
+     * @throws InsufficientFolderAccessPermissionsException
+     */
+    protected function init(ServerRequestInterface $request): void
+    {
+        $parsedBody = $request->getParsedBody();
+        $queryParams = $request->getQueryParams();
+
+        /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
+        $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
+        // Initialize GPvars:
+        $this->target = $parsedBody['target'] ?? $queryParams['target'] ?? null;
+        $this->returnUrl = GeneralUtility::sanitizeLocalUrl($parsedBody['returnUrl'] ?? $queryParams['returnUrl'] ?? '');
+        if (!$this->returnUrl) {
+            $this->returnUrl = (string)$uriBuilder->buildUriFromRoute('file_list', [
+                'id' => rawurlencode($this->target)
+            ]);
+        }
+        // Create the folder object
+        if ($this->target) {
+            $this->folderObject = ResourceFactory::getInstance()
+                ->retrieveFileOrFolderObject($this->target);
+        }
+        if ($this->folderObject->getStorage()->getUid() === 0) {
+            throw new InsufficientFolderAccessPermissionsException(
+                'You are not allowed to access folders outside your storages',
+                1375889834
+            );
+        }
+
+        // Cleaning and checking target directory
+        if (!$this->folderObject) {
+            $title = $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:paramError');
+            $message = $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:targetNoDir');
+            throw new \RuntimeException($title . ': ' . $message, 1294586843);
+        }
+
+        // Setting up the context sensitive menu
+        $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
+
+        // building pathInfo for metaInformation
+        $pathInfo = [
+            'combined_identifier' => $this->folderObject->getCombinedIdentifier(),
+        ];
+        $this->moduleTemplate->getDocHeaderComponent()->setMetaInformation($pathInfo);
+    }
+
+    /**
+     * Render module content
+     */
+    protected function renderContent(): void
+    {
+        $lang = $this->getLanguageService();
+        /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
+        $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
+
+        // set page title
+        $this->moduleTemplate->setTitle($lang->sL('LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_upload.php.pagetitle'));
+
+        $pageContent = '<form action="'
+            . htmlspecialchars((string)$uriBuilder->buildUriFromRoute('tce_file'))
+            . '" method="post" id="FileUploadController" name="editform" enctype="multipart/form-data">';
+        // Make page header:
+        $pageContent .= '<h1>' . $lang->sL('LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_upload.php.pagetitle') . '</h1>';
+        $pageContent .= $this->renderUploadFormInternal();
+
+        // Header Buttons
+        $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
+
+        // csh button
+        $cshButton = $buttonBar->makeHelpButton()
+            ->setModuleName('xMOD_csh_corebe')
+            ->setFieldName('file_upload');
+        $buttonBar->addButton($cshButton);
+
+        // back button
+        if ($this->returnUrl) {
+            $backButton = $buttonBar->makeLinkButton()
+                ->setHref($this->returnUrl)
+                ->setTitle($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.goBack'))
+                ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-view-go-back', Icon::SIZE_SMALL));
+            $buttonBar->addButton($backButton);
+        }
+
+        $pageContent .= '</form>';
+        $this->content .= '<div>' . $pageContent . '</div>';
+        $this->moduleTemplate->setContent($this->content);
+    }
+
+    /**
+     * This function renders the upload form
+     *
+     * @return string The HTML form as a string, ready for outputting
+     */
+    protected function renderUploadFormInternal(): string
+    {
+        $content = '
+            <div class="form-group">
+                <input type="file" multiple="multiple" class="form-control" name="upload_1[]" />
+                <input type="hidden" name="data[upload][1][target]" value="' . htmlspecialchars($this->folderObject->getCombinedIdentifier()) . '" />
+                <input type="hidden" name="data[upload][1][data]" value="1" />
+            </div>
+            <div class="checkbox">
+                <label for="overwriteExistingFiles">
+                <input type="checkbox" name="overwriteExistingFiles" id="overwriteExistingFiles" value="replace" /> ' . htmlspecialchars($this->getLanguageService()->getLL('overwriteExistingFiles')) . '</label>
+            </div>
+            <div>
+                <input type="hidden" name="data[upload][1][redirect]" value="' . $this->returnUrl . '" />
+                <input class="btn btn-primary" type="submit" value="' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_upload.php.submit')) . '" />
+            </div>
+            <div class="callout callout-warning">
+              ' . htmlspecialchars($this->getLanguageService()->getLL('uploadMultipleFilesInfo')) . '
+            </div>
+        ';
+
+        return $content;
+    }
+
+    /**
+     * @return LanguageService
+     */
+    protected function getLanguageService(): LanguageService
+    {
+        return $GLOBALS['LANG'];
+    }
+}
diff --git a/typo3/sysext/filelist/Classes/Controller/File/RenameFileController.php b/typo3/sysext/filelist/Classes/Controller/File/RenameFileController.php
new file mode 100644 (file)
index 0000000..65c82c7
--- /dev/null
@@ -0,0 +1,222 @@
+<?php
+declare(strict_types = 1);
+namespace TYPO3\CMS\Filelist\Controller\File;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use TYPO3\CMS\Backend\Template\Components\ButtonBar;
+use TYPO3\CMS\Backend\Template\ModuleTemplate;
+use TYPO3\CMS\Core\Http\HtmlResponse;
+use TYPO3\CMS\Core\Imaging\Icon;
+use TYPO3\CMS\Core\Localization\LanguageService;
+use TYPO3\CMS\Core\Resource\DuplicationBehavior;
+use TYPO3\CMS\Core\Resource\Exception\InsufficientFileAccessPermissionsException;
+use TYPO3\CMS\Core\Resource\File;
+use TYPO3\CMS\Core\Resource\Folder;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Fluid\View\StandaloneView;
+
+/**
+ * Script Class for the rename-file form.
+ * @internal This class is a specific Backend controller implementation and is not considered part of the Public TYPO3 API.
+ */
+class RenameFileController
+{
+    /**
+     * Target path
+     *
+     * @var string
+     * @internal
+     */
+    protected $target;
+
+    /**
+     * The file or folder object that should be renamed
+     *
+     * @var File|Folder $fileOrFolderObject
+     */
+    protected $fileOrFolderObject;
+
+    /**
+     * Return URL of list module.
+     *
+     * @var string
+     */
+    protected $returnUrl;
+
+    /**
+     * ModuleTemplate object
+     *
+     * @var ModuleTemplate
+     */
+    protected $moduleTemplate;
+
+    /**
+     * Processes the request, currently everything is handled and put together via "renderContent()"
+     *
+     * @param ServerRequestInterface $request
+     * @return ResponseInterface the response with the content
+     */
+    public function mainAction(ServerRequestInterface $request): ResponseInterface
+    {
+        $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
+        $this->init($request);
+        $this->renderContent();
+        return new HtmlResponse($this->moduleTemplate->renderContent());
+    }
+
+    /**
+     * Initialize
+     *
+     * @param ServerRequestInterface $request
+     * @throws InsufficientFileAccessPermissionsException
+     */
+    protected function init(ServerRequestInterface $request): void
+    {
+        $parsedBody = $request->getParsedBody();
+        $queryParams = $request->getQueryParams();
+
+        // Initialize GPvars:
+        $this->target = $parsedBody['target'] ?? $queryParams['target'] ?? null;
+        $this->returnUrl = GeneralUtility::sanitizeLocalUrl($parsedBody['returnUrl'] ?? $queryParams['returnUrl'] ?? '');
+        // Cleaning and checking target
+        if ($this->target) {
+            $this->fileOrFolderObject = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->retrieveFileOrFolderObject($this->target);
+        }
+        if (!$this->fileOrFolderObject) {
+            $title = $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:paramError');
+            $message = $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:targetNoDir');
+            throw new \RuntimeException($title . ': ' . $message, 1294586844);
+        }
+        if ($this->fileOrFolderObject->getStorage()->getUid() === 0) {
+            throw new InsufficientFileAccessPermissionsException('You are not allowed to access files outside your storages', 1375889840);
+        }
+
+        // If a folder should be renamed, AND the returnURL should go to the old directory name, the redirect is forced
+        // so the redirect will NOT end in an error message
+        // this case only happens if you select the folder itself in the foldertree and then use the clickmenu to
+        // rename the folder
+        if ($this->fileOrFolderObject instanceof Folder) {
+            $parsedUrl = parse_url($this->returnUrl);
+            $queryParts = GeneralUtility::explodeUrl2Array(urldecode($parsedUrl['query']));
+            if ($queryParts['id'] === $this->fileOrFolderObject->getCombinedIdentifier()) {
+                $this->returnUrl = str_replace(
+                    urlencode($queryParts['id']),
+                    urlencode($this->fileOrFolderObject->getStorage()->getRootLevelFolder()->getCombinedIdentifier()),
+                    $this->returnUrl
+                );
+            }
+        }
+
+        // building pathInfo for metaInformation
+        $pathInfo = [
+            'combined_identifier' => $this->fileOrFolderObject->getCombinedIdentifier(),
+        ];
+        $this->moduleTemplate->getDocHeaderComponent()->setMetaInformation($pathInfo);
+
+        // Setting up the context sensitive menu
+        $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
+        $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Filelist/RenameFile');
+
+        // Add javaScript
+        $this->moduleTemplate->addJavaScriptCode(
+            'RenameFileInlineJavaScript',
+            'function backToList() {top.goToModule("file_FilelistList");}'
+        );
+    }
+
+    /**
+     * Render module content
+     */
+    protected function renderContent(): void
+    {
+        $assigns = [];
+        /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
+        $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
+        $assigns['moduleUrlTceFile'] = (string)$uriBuilder->buildUriFromRoute('tce_file');
+        $assigns['returnUrl'] = $this->returnUrl;
+
+        if ($this->fileOrFolderObject instanceof Folder) {
+            $fileIdentifier = $this->fileOrFolderObject->getCombinedIdentifier();
+            $targetLabel = 'file_rename.php.label.target.folder';
+        } else {
+            $fileIdentifier = $this->fileOrFolderObject->getUid();
+            $targetLabel = 'file_rename.php.label.target.file';
+            $assigns['conflictMode'] = DuplicationBehavior::cast(DuplicationBehavior::RENAME);
+            $assigns['destination'] = $this->fileOrFolderObject->getParentFolder()->getCombinedIdentifier();
+        }
+
+        $assigns['fileName'] = $this->fileOrFolderObject->getName();
+        $assigns['fileIdentifier'] = $fileIdentifier;
+        $assigns['fieldLabel'] = $targetLabel;
+
+        // Create buttons
+        $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
+
+        // csh button
+        $cshButton = $buttonBar->makeHelpButton()
+            ->setModuleName('xMOD_csh_corebe')
+            ->setFieldName('file_rename');
+        $buttonBar->addButton($cshButton);
+
+        // back button
+        if ($this->returnUrl) {
+            $backButton = $buttonBar->makeLinkButton()
+                ->setHref($this->returnUrl)
+                ->setTitle($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.goBack'))
+                ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-close', Icon::SIZE_SMALL));
+            $buttonBar->addButton($backButton);
+        }
+
+        // Save and Close button
+        $saveAndCloseButton = $buttonBar->makeInputButton()
+            ->setName('_saveandclose')
+            ->setValue('1')
+            ->setShowLabelText(true)
+            ->setClasses('t3js-submit-file-rename')
+            ->setForm('RenameFileController')
+            ->setTitle($this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_edit.php.saveAndClose'))
+            ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save-close', Icon::SIZE_SMALL));
+
+        $buttonBar->addButton($saveAndCloseButton, ButtonBar::BUTTON_POSITION_LEFT, 20);
+
+        $this->moduleTemplate->getPageRenderer()->addInlineLanguageLabelArray([
+            'file_rename.actions.cancel' => $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_rename.actions.cancel'),
+            'file_rename.actions.rename' => $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_rename.actions.rename'),
+            'file_rename.actions.override' => $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_rename.actions.override'),
+            'file_rename.exists.title' => $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_rename.exists.title'),
+            'file_rename.exists.description' => $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_rename.exists.description'),
+        ]);
+
+        // Rendering of the output via fluid
+        $view = GeneralUtility::makeInstance(StandaloneView::class);
+        $view->setTemplateRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates')]);
+        $view->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Partials')]);
+        $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName(
+            'EXT:filelist/Resources/Private/Templates/File/RenameFile.html'
+        ));
+        $view->assignMultiple($assigns);
+        $this->moduleTemplate->setContent($view->render());
+    }
+
+    /**
+     * @return LanguageService
+     */
+    protected function getLanguageService(): LanguageService
+    {
+        return $GLOBALS['LANG'];
+    }
+}
diff --git a/typo3/sysext/filelist/Classes/Controller/File/ReplaceFileController.php b/typo3/sysext/filelist/Classes/Controller/File/ReplaceFileController.php
new file mode 100644 (file)
index 0000000..9993df6
--- /dev/null
@@ -0,0 +1,187 @@
+<?php
+declare(strict_types = 1);
+namespace TYPO3\CMS\Filelist\Controller\File;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use TYPO3\CMS\Backend\Routing\UriBuilder;
+use TYPO3\CMS\Backend\Template\ModuleTemplate;
+use TYPO3\CMS\Core\Http\HtmlResponse;
+use TYPO3\CMS\Core\Imaging\Icon;
+use TYPO3\CMS\Core\Localization\LanguageService;
+use TYPO3\CMS\Core\Resource\Exception\InsufficientFileAccessPermissionsException;
+use TYPO3\CMS\Core\Resource\Folder;
+use TYPO3\CMS\Core\Resource\ResourceFactory;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Fluid\View\StandaloneView;
+
+/**
+ * Script Class for the replace-file form
+ * @internal This class is a specific Backend controller implementation and is not considered part of the Public TYPO3 API.
+ */
+class ReplaceFileController
+{
+    /**
+     * sys_file uid
+     *
+     * @var int
+     */
+    protected $uid;
+
+    /**
+     * The file or folder object that should be renamed
+     *
+     * @var \TYPO3\CMS\Core\Resource\ResourceInterface $fileOrFolderObject
+     */
+    protected $fileOrFolderObject;
+
+    /**
+     * Return URL of list module.
+     *
+     * @var string
+     */
+    protected $returnUrl;
+
+    /**
+     * ModuleTemplate object
+     *
+     * @var ModuleTemplate
+     */
+    protected $moduleTemplate;
+
+    /**
+     * Processes the request, currently everything is handled and put together via "main()"
+     *
+     * @param ServerRequestInterface $request the current request
+     * @return ResponseInterface the response with the content
+     */
+    public function mainAction(ServerRequestInterface $request): ResponseInterface
+    {
+        $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
+        $this->init($request);
+        $this->renderContent();
+        return new HtmlResponse($this->moduleTemplate->renderContent());
+    }
+
+    /**
+     * Init
+     *
+     * @param ServerRequestInterface $request
+     * @throws \RuntimeException
+     * @throws InsufficientFileAccessPermissionsException
+     */
+    protected function init(ServerRequestInterface $request): void
+    {
+        $parsedBody = $request->getParsedBody();
+        $queryParams = $request->getQueryParams();
+        $lang = $this->getLanguageService();
+
+        // Initialize GPvars:
+        $this->uid = (int)($parsedBody['uid'] ?? $queryParams['uid'] ?? 0);
+        $this->returnUrl = GeneralUtility::sanitizeLocalUrl($parsedBody['returnUrl'] ?? $queryParams['returnUrl'] ?? '');
+
+        // Cleaning and checking uid
+        if ($this->uid > 0) {
+            $this->fileOrFolderObject = ResourceFactory::getInstance()
+                ->retrieveFileOrFolderObject('file:' . $this->uid);
+        }
+        if (!$this->fileOrFolderObject) {
+            $title = $lang->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:paramError');
+            $message = $lang->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:targetNoDir');
+            throw new \RuntimeException($title . ': ' . $message, 1436895930);
+        }
+        if ($this->fileOrFolderObject->getStorage()->getUid() === 0) {
+            throw new InsufficientFileAccessPermissionsException(
+                'You are not allowed to access files outside your storages',
+                1436895931
+            );
+        }
+
+        // If a folder should be renamed, AND the returnURL should go to the old directory name, the redirect is forced
+        // so the redirect will NOT end in an error message
+        // this case only happens if you select the folder itself in the foldertree and then use the clickmenu to
+        // rename the folder
+        if ($this->fileOrFolderObject instanceof Folder) {
+            $parsedUrl = parse_url($this->returnUrl);
+            $queryParts = GeneralUtility::explodeUrl2Array(urldecode($parsedUrl['query']));
+            if ($queryParts['id'] === $this->fileOrFolderObject->getCombinedIdentifier()) {
+                $this->returnUrl = str_replace(
+                    urlencode($queryParts['id']),
+                    urlencode($this->fileOrFolderObject->getStorage()->getRootLevelFolder()->getCombinedIdentifier()),
+                    $this->returnUrl
+                );
+            }
+        }
+
+        $pathInfo = [
+            'combined_identifier' => $this->fileOrFolderObject->getCombinedIdentifier(),
+        ];
+        $this->moduleTemplate->getDocHeaderComponent()->setMetaInformation($pathInfo);
+        $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
+        $this->moduleTemplate->addJavaScriptCode(
+            'ReplaceFileOnlineJavaScript',
+            'function backToList() {top.goToModule("file_FilelistList");}'
+        );
+    }
+
+    /**
+     * Render module content
+     */
+    protected function renderContent(): void
+    {
+        // Assign variables used by the fluid template
+        $assigns = [];
+        /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
+        $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
+        $assigns['moduleUrlTceFile'] = (string)$uriBuilder->buildUriFromRoute('tce_file');
+        $assigns['uid'] = $this->uid;
+        $assigns['returnUrl'] = $this->returnUrl;
+
+        $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
+        // csh button
+        $cshButton = $buttonBar->makeHelpButton()
+            ->setModuleName('xMOD_csh_corebe')
+            ->setFieldName('file_rename');
+        $buttonBar->addButton($cshButton);
+
+        // Back button
+        if ($this->returnUrl) {
+            $returnButton = $buttonBar->makeLinkButton()
+                ->setHref($this->returnUrl)
+                ->setTitle($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.goBack'))
+                ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-view-go-back', Icon::SIZE_SMALL));
+            $buttonBar->addButton($returnButton);
+        }
+
+        // Rendering of the output via fluid
+        $view = GeneralUtility::makeInstance(StandaloneView::class);
+        $view->setTemplateRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates')]);
+        $view->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Partials')]);
+        $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName(
+            'EXT:filelist/Resources/Private/Templates/File/ReplaceFile.html'
+        ));
+        $view->assignMultiple($assigns);
+        $this->moduleTemplate->setContent($view->render());
+    }
+
+    /**
+     * @return LanguageService
+     */
+    protected function getLanguageService(): LanguageService
+    {
+        return $GLOBALS['LANG'];
+    }
+}
index ab8dd09..2fb4653 100644 (file)
@@ -39,6 +39,5 @@ class BackendControllerHook
         $pageRenderer->addInlineSetting('FileEdit', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('file_edit'));
         $pageRenderer->addInlineSetting('FileUpload', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('file_upload'));
         $pageRenderer->addInlineSetting('FileCreate', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('file_newfolder'));
-        $pageRenderer->addInlineSetting('FileCommit', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('tce_file'));
     }
 }
diff --git a/typo3/sysext/filelist/Configuration/Backend/Routes.php b/typo3/sysext/filelist/Configuration/Backend/Routes.php
new file mode 100644 (file)
index 0000000..acdb94b
--- /dev/null
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * Definitions for routes provided by EXT:backend
+ * Contains all "regular" routes for entry points
+ *
+ * Please note that this setup is preliminary until all core use-cases are set up here.
+ * Especially some more properties regarding modules will be added until TYPO3 CMS 7 LTS, and might change.
+ *
+ * Currently the "access" property is only used so no token creation + validation is made,
+ * but will be extended further.
+ */
+return [
+
+    // Editing the contents of a file
+    'file_edit' => [
+        'path' => '/file/editcontent',
+        'target' => \TYPO3\CMS\Filelist\Controller\File\EditFileController::class . '::mainAction'
+    ],
+
+    // Create a new folder
+    'file_newfolder' => [
+        'path' => '/file/new',
+        'target' => \TYPO3\CMS\Filelist\Controller\File\CreateFolderController::class . '::mainAction'
+    ],
+
+    // Rename a file
+    'file_rename' => [
+        'path' => '/file/rename',
+        'target' => \TYPO3\CMS\Filelist\Controller\File\RenameFileController::class . '::mainAction'
+    ],
+
+    // Replace a file with a different one
+    'file_replace' => [
+        'path' => '/file/replace',
+        'target' => \TYPO3\CMS\Filelist\Controller\File\ReplaceFileController::class . '::mainAction'
+    ],
+
+    // Upload new files
+    'file_upload' => [
+        'path' => '/file/upload',
+        'target' => \TYPO3\CMS\Filelist\Controller\File\FileUploadController::class . '::mainAction'
+    ],
+];
index 222f3fe..2aba067 100644 (file)
@@ -9,6 +9,107 @@
                        <trans-unit id="flashmessage.no_results">
                                <source>No results found</source>
                        </trans-unit>
+                       <trans-unit id="file_upload.php.pagetitle">
+                               <source>Upload files</source>
+                       </trans-unit>
+                       <trans-unit id="file_upload.php.submit">
+                               <source>Upload files</source>
+                       </trans-unit>
+                       <trans-unit id="file_upload.php.files">
+                               <source>files</source>
+                       </trans-unit>
+                       <trans-unit id="file_rename.exists.title">
+                               <source>File exists already</source>
+                       </trans-unit>
+                       <trans-unit id="file_rename.exists.description">
+                               <source>You want to rename the file "{0}" to "{1}", but such a file already exists. How do you want to
+                                       proceed?
+                               </source>
+                       </trans-unit>
+                       <trans-unit id="file_rename.actions.cancel">
+                               <source>Cancel</source>
+                       </trans-unit>
+                       <trans-unit id="file_rename.actions.rename">
+                               <source>Rename with unique name</source>
+                       </trans-unit>
+                       <trans-unit id="file_rename.actions.override">
+                               <source>Overwrite</source>
+                       </trans-unit>
+                       <trans-unit id="file_rename.php.pagetitle">
+                               <source>Rename</source>
+                       </trans-unit>
+                       <trans-unit id="file_rename.php.submit">
+                               <source>Rename</source>
+                               <note from="developer">This label is not used since TYPO3 v9.</note>
+                       </trans-unit>
+                       <trans-unit id="file_rename.php.label.target.file">
+                               <source>New file name</source>
+                       </trans-unit>
+                       <trans-unit id="file_rename.php.label.target.folder">
+                               <source>New folder name</source>
+                       </trans-unit>
+                       <trans-unit id="file_replace.php.pagetitle">
+                               <source>Replace</source>
+                       </trans-unit>
+                       <trans-unit id="file_replace.php.selectfile">
+                               <source>Select new file</source>
+                       </trans-unit>
+                       <trans-unit id="file_replace.php.keepfiletitle">
+                               <source>Keep the current filename?</source>
+                       </trans-unit>
+                       <trans-unit id="file_replace.php.browse">
+                               <source>Browse</source>
+                       </trans-unit>
+                       <trans-unit id="file_replace.php.submit">
+                               <source>Replace</source>
+                       </trans-unit>
+                       <trans-unit id="file_edit.php.pagetitle">
+                               <source>Edit</source>
+                       </trans-unit>
+                       <trans-unit id="file_edit.php.submit">
+                               <source>Save</source>
+                       </trans-unit>
+                       <trans-unit id="file_edit.php.saveAndClose">
+                               <source>Save and Close</source>
+                       </trans-unit>
+                       <trans-unit id="file_edit.php.coundNot">
+                               <source>This filetype cannot be edited.&lt;br /&gt;The file must have an extension like:&lt;br /&gt;&lt;br
+                                       /&gt; &lt;b&gt;%s&lt;/b&gt;
+                               </source>
+                       </trans-unit>
+                       <trans-unit id="file_newfolder.php.pagetitle">
+                               <source>New file or folder</source>
+                       </trans-unit>
+                       <trans-unit id="file_newfolder.php.newfolders">
+                               <source>Create new folders</source>
+                       </trans-unit>
+                       <trans-unit id="file_newfolder.php.label_newfolder">
+                               <source>Folder</source>
+                       </trans-unit>
+                       <trans-unit id="file_newfolder.php.submit">
+                               <source>Create folders</source>
+                       </trans-unit>
+                       <trans-unit id="create_folder.title">
+                               <source>Create new folder</source>
+                       </trans-unit>
+                       <trans-unit id="create_folder.submit">
+                               <source>Create folder</source>
+                       </trans-unit>
+                       <trans-unit id="file_newfolder.php.folders">
+                               <source>folders</source>
+                       </trans-unit>
+                       <trans-unit id="file_newfolder.php.newfile_submit">
+                               <source>Create file</source>
+                       </trans-unit>
+                       <trans-unit id="file_newfolder.php.newfile">
+                               <source>Create new textfile</source>
+                       </trans-unit>
+                       <trans-unit id="file_newfolder.php.label_newfile">
+                               <source>File name</source>
+                       </trans-unit>
+                       <trans-unit id="file_newfolder.php.number_of_folders">
+                               <source>Number of folders</source>
+                       </trans-unit>
                </body>
        </file>
 </xliff>
diff --git a/typo3/sysext/filelist/Resources/Private/Templates/File/CreateFolder.html b/typo3/sysext/filelist/Resources/Private/Templates/File/CreateFolder.html
new file mode 100644 (file)
index 0000000..c2fc5cc
--- /dev/null
@@ -0,0 +1,100 @@
+<div>
+    <h1><f:translate key="LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_newfolder.php.pagetitle" /></h1>
+    <f:if condition="{moduleUrlTceFile}">
+        <h3><f:translate key="LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_newfolder.php.newfolders" /></h3>
+        <div>
+            <form role="form" action="{moduleUrlTceFile}" method="post" name="editform">
+                <div class="form-group">
+                    <div class="form-section">
+                        <div class="form-group">
+                            <label for="number-of-new-folders"><f:translate key="LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_newfolder.php.number_of_folders" /></label> {cshFileNewFolder -> f:format.raw()}
+                            <div class="form-control-wrap">
+                                <div class="input-group">
+                                    <select class="form-control form-control-adapt" name="number" id="number-of-new-folders" onchange="reload(this.options[this.selectedIndex].value);">';
+                                        <f:for each="{options}" as="option">
+                                            <option value="{option.value}"{option.selected}>{option.value}</option>
+                                        </f:for>
+                                    </select>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                    <f:for each="{folders}" as="folder">
+                        <div class="form-section">
+                            <div class="form-group">
+                                <label for="folder_new_{folder.this}"><f:translate key="LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_newfolder.php.label_newfolder" /> {folder.next}:</label>
+                                <div class="form-control-wrap">
+                                    <input type="text" class="form-control" id="folder_new_{folder.this}" name="data[newfolder][{folder.this}][data]" onchange="changed=true;" />
+                                    <input type="hidden" name="data[newfolder][{folder.this}][target]" value="{target}" />
+                                </div>
+                            </div>
+                        </div>
+                    </f:for>
+                </div>
+                <div class="form-group">
+                    <input class="btn btn-default" type="submit" value="{f:translate(key: 'LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_newfolder.php.submit')}" />
+                    <input type="hidden" name="data[newfolder][0][redirect]" value="{returnUrl}" />
+                </div>
+            </form>
+        </div>
+    </f:if>
+    <f:if condition="{moduleUrlOnlineMedia}">
+        <f:if condition="{fileExtList -> f:count()} > 0">
+            <form action="{moduleUrlOnlineMedia}" method="post" name="editform2">
+                <h3><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media" /></h3>
+                <div>
+                    <div class="form-group">
+                        <div class="form-section">
+                            <div class="form-group">
+                                <label for="newMedia"><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media.label" /></label> {cshFileNewMedia -> f:format.raw()}
+                                <div class="form-control-wrap">
+                                    <input class="form-control" type="text" id="newMedia" name="data[newMedia][0][url]"
+                                           placeholder="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media.placeholder')}" />
+                                    <input type="hidden" name="data[newMedia][0][target]" value="{target}" />
+                                </div>
+                                <div class="help-block">
+                                    <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media.allowedProviders" /><br>
+                                        <f:for each="{fileExtList}" as="fileExt">
+                                            <span class="label label-success">{fileExt}</span>
+                                        </f:for>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <input class="btn btn-default" type="submit" value="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media.submit')}" />
+                        <input type="hidden" name="redirect" value="{returnUrl}" />
+                    </div>
+                </div>
+            </form>
+        </f:if>
+        <f:if condition="{txtFileExtList -> f:count()} > 0">
+            <form action="{moduleUrlTceFile}" method="post" name="editform3">
+                <h3><f:translate key="LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_newfolder.php.newfile" /></h3>
+                <div>
+                    <div class="form-group">
+                        <div class="form-section">
+                            <div class="form-group">
+                                <label for="newfile"><f:translate key="LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_newfolder.php.label_newfile" /></label> {cshFileNewFile -> f:format.raw()}
+                                <div class="form-control-wrap">
+                                    <input class="form-control" type="text" id="newfile" name="data[newfile][0][data]" onchange="changed=true;" />
+                                    <input type="hidden" name="data[newfile][0][target]" value="{target}" />
+                                </div>
+                                <div class="help-block">
+                                    <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.allowedEditableTextFileExtensions" /><br>
+                                    <f:for each="{txtFileExtList}" as="fileExt">
+                                        <span class="label label-success">{fileExt}</span>
+                                    </f:for>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <button class="btn btn-default" name="edit" type="submit" value="1"><f:translate key="LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_newfolder.php.newfile_submit" /></button>
+                        <input type="hidden" name="data[newfile][0][redirect]" value="{returnUrl}" />
+                    </div>
+                </div>
+            </form>
+        </f:if>
+    </f:if>
+</div>
diff --git a/typo3/sysext/filelist/Resources/Private/Templates/File/EditFile.html b/typo3/sysext/filelist/Resources/Private/Templates/File/EditFile.html
new file mode 100644 (file)
index 0000000..7410ca1
--- /dev/null
@@ -0,0 +1,4 @@
+<form action="{moduleUrlTceFile}" method="post" id="EditFileController" name="editform">
+    <h1><f:translate key="LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_edit.php.pagetitle" /> {fileName}</h1>
+    <f:format.raw>{form}</f:format.raw>
+</form>
diff --git a/typo3/sysext/filelist/Resources/Private/Templates/File/RenameFile.html b/typo3/sysext/filelist/Resources/Private/Templates/File/RenameFile.html
new file mode 100644 (file)
index 0000000..3ea4d1c
--- /dev/null
@@ -0,0 +1,27 @@
+<form action="{moduleUrlTceFile}" method="post" name="editform" role="form" id="RenameFileController">
+    <fieldset class="form-section">
+        <div class="row">
+            <div class="form-group col-md-12">
+                <label class="t3js-formengine-label" for="rename_target">
+                    <f:translate key="LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:{fieldLabel}" />
+                </label>
+                <div class="formengine-field-item">
+                    <div class="form-control-wrap">
+                        <div class="form-wizards-wrap">
+                            <div class="form-wizards-element">
+                                <input id="rename_target" class="form-control" type="text" name="data[rename][0][target]" value="{fileName}" data-original="{fileName}" />
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </fieldset>
+
+    <f:if condition="{destination}">
+        <input type="hidden" name="data[rename][0][destination]" value="{destination}"/>
+        <input type="hidden" name="data[rename][0][conflictMode]" value="{conflictMode}"/>
+    </f:if>
+    <input type="hidden" name="data[rename][0][data]" value="{fileIdentifier}"/>
+    <input type="hidden" name="data[rename][0][redirect]" value="{returnUrl}"/>
+</form>
diff --git a/typo3/sysext/filelist/Resources/Private/Templates/File/ReplaceFile.html b/typo3/sysext/filelist/Resources/Private/Templates/File/ReplaceFile.html
new file mode 100644 (file)
index 0000000..734caa4
--- /dev/null
@@ -0,0 +1,39 @@
+<h1><f:translate key="LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_replace.php.pagetitle" /></h1>
+<div>
+    <form action="{moduleUrlTceFile}" role="form" method="post" name="editform" enctype="multipart/form-data">
+    <div class="form-group">
+        <input type="checkbox" value="1" id="keepFilename" name="data[replace][1][keepFilename]">
+        <label for="keepFilename"><f:translate key="LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_replace.php.keepfiletitle" /></label>
+    </div>
+
+    <div class="form-group">
+        <label for="file_replace"><f:translate key="LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_replace.php.selectfile" /></label>
+        <div class="input-group col-xs-6">
+            <input type="text" name="fakefile" id="fakefile" class="form-control input-xlarge" readonly>
+            <a class="input-group-addon btn btn-primary" onclick="$('#file_replace').click();">
+                <f:translate key="LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_replace.php.browse" />
+            </a>
+        </div>
+        <input class="form-control" type="file" id="file_replace" name="replace_1" style="visibility: hidden;" />
+    </div>
+
+    <script>
+      require(['jquery'], function($) {
+        $('#file_replace').change(function() {
+          $('#fakefile').val($(this).val());
+        });
+      });
+    </script>
+
+    <input type="hidden" name="overwriteExistingFiles" value="replace" />
+    <input type="hidden" name="data[replace][1][data]" value="1" />
+    <input type="hidden" name="data[replace][1][uid]" value="{uid}" />
+
+    <div class="form-group">
+        <input class="btn btn-primary" type="submit" value="{f:translate(key: 'LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_replace.php.submit')}" />
+        <input class="btn btn-danger" type="submit" value="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.cancel')}"
+             onclick="backToList(); return false;" />
+        <input type="hidden" name="data[replace][1][redirect]" value="{returnUrl}" />
+    </div>
+    </form>
+</div>
diff --git a/typo3/sysext/filelist/Resources/Private/TypeScript/RenameFile.ts b/typo3/sysext/filelist/Resources/Private/TypeScript/RenameFile.ts
new file mode 100644 (file)
index 0000000..a731479
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+import {SeverityEnum} from 'TYPO3/CMS/Backend/Enum/Severity';
+import * as $ from 'jquery';
+import Modal = require('TYPO3/CMS/Backend/Modal');
+
+/**
+ * Module: TYPO3/CMS/Filelist/RenameFile
+ * Modal to pick the required conflict strategy for colliding filenames
+ * @exports TYPO3/CMS/Filelist/RenameFile
+ */
+class RenameFile {
+
+  constructor() {
+    this.initialize();
+  }
+
+  public initialize(): void {
+    $('.t3js-submit-file-rename').on('click', this.checkForDuplicate);
+  }
+
+  private checkForDuplicate(e: any): void {
+    e.preventDefault();
+
+    const form: any = $('#' + $(e.currentTarget).attr('form'));
+    const fileNameField: any = form.find('input[name="data[rename][0][target]"]');
+    const conflictModeField: any = form.find('input[name="data[rename][0][conflictMode]"]');
+    const ajaxUrl: string = TYPO3.settings.ajaxUrls.file_exists;
+
+    $.ajax({
+      cache: false,
+      data: {
+        fileName: fileNameField.val(),
+        fileTarget: form.find('input[name="data[rename][0][destination]"]').val(),
+      },
+      success: (response: any): void => {
+        const fileExists: boolean = typeof response.uid !== 'undefined';
+        const originalFileName: string = fileNameField.data('original');
+        const newFileName: string = fileNameField.val();
+
+        if (fileExists && originalFileName !== newFileName) {
+          const description: string = TYPO3.lang['file_rename.exists.description']
+                                           .replace('{0}', originalFileName).replace('{1}', newFileName);
+
+          const modal: JQuery = Modal.confirm(
+            TYPO3.lang['file_rename.exists.title'],
+            description,
+            SeverityEnum.warning,
+            [
+              {
+                active: true,
+                btnClass: 'btn-default',
+                name: 'cancel',
+                text: TYPO3.lang['file_rename.actions.cancel'],
+              },
+              {
+                btnClass: 'btn-primary',
+                name: 'rename',
+                text: TYPO3.lang['file_rename.actions.rename'],
+              },
+              {
+                btnClass: 'btn-default',
+                name: 'replace',
+                text: TYPO3.lang['file_rename.actions.override'],
+              },
+            ]);
+
+          modal.on('button.clicked', (event: any): void => {
+            if (event.target.name !== 'cancel') {
+              conflictModeField.val(event.target.name);
+              form.submit();
+            }
+            Modal.dismiss();
+          });
+        } else {
+          form.submit();
+        }
+      },
+      url: ajaxUrl,
+    });
+  }
+}
+
+export = new RenameFile();
diff --git a/typo3/sysext/filelist/Resources/Public/JavaScript/RenameFile.js b/typo3/sysext/filelist/Resources/Public/JavaScript/RenameFile.js
new file mode 100644 (file)
index 0000000..7b30540
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+define(["require","exports","TYPO3/CMS/Backend/Enum/Severity","jquery","TYPO3/CMS/Backend/Modal"],function(e,a,n,t,i){"use strict";return new(function(){function e(){this.initialize()}return e.prototype.initialize=function(){t(".t3js-submit-file-rename").on("click",this.checkForDuplicate)},e.prototype.checkForDuplicate=function(e){e.preventDefault();var a=t("#"+t(e.currentTarget).attr("form")),r=a.find('input[name="data[rename][0][target]"]'),l=a.find('input[name="data[rename][0][conflictMode]"]'),c=TYPO3.settings.ajaxUrls.file_exists;t.ajax({cache:!1,data:{fileName:r.val(),fileTarget:a.find('input[name="data[rename][0][destination]"]').val()},success:function(e){var t=void 0!==e.uid,c=r.data("original"),s=r.val();if(t&&c!==s){var o=TYPO3.lang["file_rename.exists.description"].replace("{0}",c).replace("{1}",s);i.confirm(TYPO3.lang["file_rename.exists.title"],o,n.SeverityEnum.warning,[{active:!0,btnClass:"btn-default",name:"cancel",text:TYPO3.lang["file_rename.actions.cancel"]},{btnClass:"btn-primary",name:"rename",text:TYPO3.lang["file_rename.actions.rename"]},{btnClass:"btn-default",name:"replace",text:TYPO3.lang["file_rename.actions.override"]}]).on("button.clicked",function(e){"cancel"!==e.target.name&&(l.val(e.target.name),a.submit()),i.dismiss()})}else a.submit()},url:c})},e}())});
\ No newline at end of file
index bfef59a..203637d 100644 (file)
@@ -1244,4 +1244,29 @@ return [
             'Important-87516-RemoveCoreHTTPRequestHandlerInterface.rst',
         ],
     ],
+    'TYPO3\CMS\Backend\Controller\File\CreateFolderController' => [
+        'restFiles' => [
+            'Deprecation-87882-FileRelatedControllersMovedToEXTfilelist.rst',
+        ],
+    ],
+    'TYPO3\CMS\Backend\Controller\File\EditFileController' => [
+        'restFiles' => [
+            'Deprecation-87882-FileRelatedControllersMovedToEXTfilelist.rst',
+        ],
+    ],
+    'TYPO3\CMS\Backend\Controller\File\FileUploadController' => [
+        'restFiles' => [
+            'Deprecation-87882-FileRelatedControllersMovedToEXTfilelist.rst'
+        ],
+    ],
+    'TYPO3\CMS\Backend\Controller\File\RenameFileController' => [
+        'restFiles' => [
+            'Deprecation-87882-FileRelatedControllersMovedToEXTfilelist.rst'
+        ],
+    ],
+    'TYPO3\CMS\Backend\Controller\File\ReplaceFileController' => [
+        'restFiles' => [
+            'Deprecation-87882-FileRelatedControllersMovedToEXTfilelist.rst'
+        ],
+    ],
 ];
index 2f92737..a5aa7a9 100644 (file)
@@ -15,9 +15,9 @@ namespace TYPO3\CMS\T3editor\Hook;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Backend\Controller\File\EditFileController;
 use TYPO3\CMS\Core\Resource\ResourceFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Filelist\Controller\File\EditFileController;
 use TYPO3\CMS\T3editor\Exception\InvalidModeException;
 use TYPO3\CMS\T3editor\Registry\ModeRegistry;
 use TYPO3\CMS\T3editor\T3editor;