From e6878c490509979a758e7d5fbfbf402ccf20a812 Mon Sep 17 00:00:00 2001 From: Andreas Fernandez <a.fernandez@scripting-base.de> Date: Mon, 5 Jun 2017 21:09:34 +0200 Subject: [PATCH] [!!!][TASK] Migrate file edit form to FormEngine To simplify the overhaul of EXT:t3editor, the form to change a file's content is based on FormEngine now. Additionally, the file rename form has been streamlined to the overall backend visual appearance. Resolves: #81763 Releases: master Change-Id: Ifb9bc5513bff923a6d4cdbcb6046e87f4dcf3626 Reviewed-on: https://review.typo3.org/53129 Tested-by: TYPO3com <no-reply@typo3.com> Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de> Reviewed-by: Georg Ringer <georg.ringer@gmail.com> Tested-by: Georg Ringer <georg.ringer@gmail.com> Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch> Tested-by: Christian Kuhn <lolli@schwarzbu.ch> --- .../Controller/File/EditFileController.php | 86 +++++++++++-- .../Controller/File/FileController.php | 11 +- .../Controller/File/FileUploadController.php | 4 +- .../Controller/File/RenameFileController.php | 26 +++- .../Private/Templates/File/CreateFolder.html | 18 +-- .../Private/Templates/File/EditFile.html | 12 +- .../Private/Templates/File/RenameFile.html | 49 ++++---- .../Private/TypeScript/RenameFile.ts | 8 +- .../Public/JavaScript/DragUploader.js | 4 +- .../Resources/Public/JavaScript/RenameFile.js | 8 +- ..._editphppreOutputProcessingHookChanged.rst | 35 ++++++ ...3-DeprecatedLanguageLabelForFileRename.rst | 26 ++++ .../Public/JavaScript/ContextMenuActions.js | 2 +- .../Resources/Public/JavaScript/FileDelete.js | 6 +- .../Private/Partials/Import/Upload.html | 4 +- .../Private/Language/locallang_core.xlf | 7 ++ .../Classes/View/FolderUtilityRenderer.php | 4 +- .../t3editor/Classes/Hook/FileEditHook.php | 119 ++++++------------ .../Resources/Public/JavaScript/FileEdit.js | 60 --------- typo3/sysext/t3editor/ext_localconf.php | 4 - 20 files changed, 264 insertions(+), 229 deletions(-) create mode 100644 typo3/sysext/core/Documentation/Changelog/master/Breaking-81763-HookParametersOfTypo3file_editphppreOutputProcessingHookChanged.rst create mode 100644 typo3/sysext/core/Documentation/Changelog/master/Deprecation-81763-DeprecatedLanguageLabelForFileRename.rst delete mode 100644 typo3/sysext/t3editor/Resources/Public/JavaScript/FileEdit.js diff --git a/typo3/sysext/backend/Classes/Controller/File/EditFileController.php b/typo3/sysext/backend/Classes/Controller/File/EditFileController.php index 6ca34b4f01e9..09d151a34ba2 100644 --- a/typo3/sysext/backend/Classes/Controller/File/EditFileController.php +++ b/typo3/sysext/backend/Classes/Controller/File/EditFileController.php @@ -16,14 +16,19 @@ namespace TYPO3\CMS\Backend\Controller\File; 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\Module\AbstractModule; use TYPO3\CMS\Backend\Template\Components\ButtonBar; use TYPO3\CMS\Backend\Template\DocumentTemplate; use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Core\Imaging\Icon; +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\Core\Utility\HttpUtility; use TYPO3\CMS\Fluid\View\StandaloneView; /** @@ -138,10 +143,21 @@ class EditFileController extends AbstractModule } /** - * Main function, redering the actual content of the editing page + * Main function, rendering the actual content of the editing page */ public function main() { + $dataColumnDefinition = [ + 'label' => htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:file')) + . ' ' . htmlspecialchars($this->target), + 'config' => [ + 'type' => 'text', + 'cols' => 48, + 'wrap' => 'OFF', + ], + 'defaultExtras' => 'fixed-font: enable-tab' + ]; + $this->getButtons(); // Hook: before compiling the output if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/file_edit.php']['preOutputProcessingHook'])) { @@ -149,7 +165,8 @@ class EditFileController extends AbstractModule if (is_array($preOutputProcessingHook)) { $hookParameters = [ 'content' => &$this->content, - 'target' => &$this->target + 'target' => &$this->target, + 'dataColumnDefinition' => &$dataColumnDefinition, ]; foreach ($preOutputProcessingHook as $hookFunction) { GeneralUtility::callUserFunction($hookFunction, $hookParameters, $this); @@ -164,22 +181,67 @@ class EditFileController extends AbstractModule $extList = $GLOBALS['TYPO3_CONF_VARS']['SYS']['textfile_ext']; try { if (!$extList || !GeneralUtility::inList($extList, $this->fileObject->getExtension())) { - throw new \Exception('Files with that extension are not editable.', 1476050135); + throw new \Exception('Files with that extension are not editable. Allowed extensions are: ' . $extList, 1476050135); } - // Read file content to edit: - $fileContent = $this->fileObject->getContents(); - // Making the formfields $hValue = BackendUtility::getModuleUrl('file_edit', [ 'target' => $this->origTarget, 'returnUrl' => $this->returnUrl ]); - $assigns['uid'] = $this->fileObject->getUid(); - $assigns['fileContent'] = $fileContent; - $assigns['hValue'] = $hValue; + + $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) { - $assigns['extList'] = $extList; + $flashMessage = GeneralUtility::makeInstance(FlashMessage::class, $e->getMessage(), '', FlashMessage::ERROR, true); + + $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class); + $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier(); + $defaultFlashMessageQueue->enqueue($flashMessage); + + HttpUtility::redirect($this->returnUrl, HttpUtility::HTTP_STATUS_500); } // Rendering of the output via fluid @@ -227,8 +289,6 @@ class EditFileController extends AbstractModule /** * Builds the buttons for the docheader and returns them as an array - * - * @return array */ public function getButtons() { @@ -246,6 +306,7 @@ class EditFileController extends AbstractModule ->setName('_save') ->setValue('1') ->setOnClick('document.editform.submit();') + ->setForm('EditFileController') ->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:file_edit.php.submit')) ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save', Icon::SIZE_SMALL)); @@ -253,6 +314,7 @@ class EditFileController extends AbstractModule $saveAndCloseButton = $buttonBar->makeInputButton() ->setName('_saveandclose') ->setValue('1') + ->setForm('EditFileController') ->setOnClick( 'document.editform.redirect.value=' . GeneralUtility::quoteJSvalue($this->returnUrl) diff --git a/typo3/sysext/backend/Classes/Controller/File/FileController.php b/typo3/sysext/backend/Classes/Controller/File/FileController.php index 49be98ca727f..e61d290a9280 100644 --- a/typo3/sysext/backend/Classes/Controller/File/FileController.php +++ b/typo3/sysext/backend/Classes/Controller/File/FileController.php @@ -92,8 +92,16 @@ class FileController protected function init() { // Set the GPvars from outside - $this->file = GeneralUtility::_GP('file'); + $this->file = GeneralUtility::_GP('data'); + if ($this->file === null) { + // This happens in clipboard mode only + $this->redirect = GeneralUtility::sanitizeLocalUrl(GeneralUtility::_GP('redirect')); + } else { + $mode = key($this->file); + $this->redirect = GeneralUtility::sanitizeLocalUrl($this->file[$mode][0]['redirect']); + } $this->CB = GeneralUtility::_GP('CB'); + if (isset($this->file['rename'][0]['conflictMode'])) { $conflictMode = $this->file['rename'][0]['conflictMode']; unset($this->file['rename'][0]['conflictMode']); @@ -101,7 +109,6 @@ class FileController } else { $this->overwriteExistingFiles = DuplicationBehavior::cast(GeneralUtility::_GP('overwriteExistingFiles')); } - $this->redirect = GeneralUtility::sanitizeLocalUrl(GeneralUtility::_GP('redirect')); $this->initClipboard(); $this->fileProcessor = GeneralUtility::makeInstance(ExtendedFileUtility::class); } diff --git a/typo3/sysext/backend/Classes/Controller/File/FileUploadController.php b/typo3/sysext/backend/Classes/Controller/File/FileUploadController.php index c7ef406ac102..a1788bd4b712 100644 --- a/typo3/sysext/backend/Classes/Controller/File/FileUploadController.php +++ b/typo3/sysext/backend/Classes/Controller/File/FileUploadController.php @@ -180,8 +180,8 @@ class FileUploadController extends AbstractModule // Adding 'size="50" ' for the sake of Mozilla! $content .= ' <input type="file" multiple="multiple" name="upload_1[]" /> - <input type="hidden" name="file[upload][1][target]" value="' . htmlspecialchars($this->folderObject->getCombinedIdentifier()) . '" /> - <input type="hidden" name="file[upload][1][data]" value="1" /><br /> + <input type="hidden" name="data[upload][1][target]" value="' . htmlspecialchars($this->folderObject->getCombinedIdentifier()) . '" /> + <input type="hidden" name="data[upload][1][data]" value="1" /><br /> '; $content .= ' </div> diff --git a/typo3/sysext/backend/Classes/Controller/File/RenameFileController.php b/typo3/sysext/backend/Classes/Controller/File/RenameFileController.php index 3a1d718fef81..2026258dac41 100644 --- a/typo3/sysext/backend/Classes/Controller/File/RenameFileController.php +++ b/typo3/sysext/backend/Classes/Controller/File/RenameFileController.php @@ -17,9 +17,12 @@ namespace TYPO3\CMS\Backend\Controller\File; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use TYPO3\CMS\Backend\Module\AbstractModule; +use TYPO3\CMS\Backend\Template\Components\ButtonBar; use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Core\Imaging\Icon; use TYPO3\CMS\Core\Resource\DuplicationBehavior; +use TYPO3\CMS\Core\Resource\File; +use TYPO3\CMS\Core\Resource\Folder; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Fluid\View\StandaloneView; @@ -46,7 +49,7 @@ class RenameFileController extends AbstractModule /** * The file or folder object that should be renamed * - * @var \TYPO3\CMS\Core\Resource\File|\TYPO3\CMS\Core\Resource\Folder $fileOrFolderObject + * @var File|Folder $fileOrFolderObject */ protected $fileOrFolderObject; @@ -102,7 +105,7 @@ class RenameFileController extends AbstractModule // 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 \TYPO3\CMS\Core\Resource\Folder) { + if ($this->fileOrFolderObject instanceof Folder) { $parsedUrl = parse_url($this->returnUrl); $queryParts = GeneralUtility::explodeUrl2Array(urldecode($parsedUrl['query'])); if ($queryParts['id'] === $this->fileOrFolderObject->getCombinedIdentifier()) { @@ -138,16 +141,19 @@ class RenameFileController extends AbstractModule $assigns['moduleUrlTceFile'] = BackendUtility::getModuleUrl('tce_file'); $assigns['returnUrl'] = $this->returnUrl; - if ($this->fileOrFolderObject instanceof \TYPO3\CMS\Core\Resource\Folder) { + 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'] = substr($this->fileOrFolderObject->getCombinedIdentifier(), 0, -strlen($this->fileOrFolderObject->getName())); } $assigns['fileName'] = $this->fileOrFolderObject->getName(); $assigns['fileIdentifier'] = $fileIdentifier; + $assigns['fieldLabel'] = $targetLabel; // Create buttons $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar(); @@ -163,10 +169,22 @@ class RenameFileController extends AbstractModule $backButton = $buttonBar->makeLinkButton() ->setHref($this->returnUrl) ->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.goBack')) - ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-view-go-back', Icon::SIZE_SMALL)); + ->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:lang/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:lang/Resources/Private/Language/locallang_core.xlf:file_rename.actions.cancel'), 'file_rename.actions.rename' => $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:file_rename.actions.rename'), diff --git a/typo3/sysext/backend/Resources/Private/Templates/File/CreateFolder.html b/typo3/sysext/backend/Resources/Private/Templates/File/CreateFolder.html index a0ee00cd9187..b4045c5fbe37 100644 --- a/typo3/sysext/backend/Resources/Private/Templates/File/CreateFolder.html +++ b/typo3/sysext/backend/Resources/Private/Templates/File/CreateFolder.html @@ -24,8 +24,8 @@ <div class="form-group"> <label for="folder_new_{folder.this}"><f:translate key="LLL:EXT:lang/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="file[newfolder][{folder.this}][data]" onchange="changed=true;" /> - <input type="hidden" name="file[newfolder][{folder.this}][target]" value="{target}" /> + <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> @@ -33,7 +33,7 @@ </div> <div class="form-group"> <input class="btn btn-default" type="submit" value="{f:translate(key: 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:file_newfolder.php.submit')}" /> - <input type="hidden" name="redirect" value="{returnUrl}" /> + <input type="hidden" name="data[newfolder][0][redirect]" value="{returnUrl}" /> </div> </form> </div> @@ -47,9 +47,9 @@ <div class="form-group"> <label for="newMedia"><f:translate key="LLL:EXT:lang/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="file[newMedia][0][url]" + <input class="form-control" type="text" id="newMedia" name="data[newMedia][0][url]" placeholder="{f:translate(key: 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:online_media.new_media.placeholder')}" /> - <input type="hidden" name="file[newMedia][0][target]" value="{target}" /> + <input type="hidden" name="data[newMedia][0][target]" value="{target}" /> </div> <div class="help-block"> <f:translate key="LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:online_media.new_media.allowedProviders" /><br> @@ -62,7 +62,7 @@ </div> <div class="form-group"> <input class="btn btn-default" type="submit" value="{f:translate(key: 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:online_media.new_media.submit')}" /> - <input type="hidden" name="redirect" value="{returnUrl}" /> + <input type="hidden" name="data[newMedia][0][redirect]" value="{returnUrl}" /> </div> </div> </form> @@ -74,8 +74,8 @@ <div class="form-group"> <label for="newfile"><f:translate key="LLL:EXT:lang/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="file[newfile][0][data]" onchange="changed=true;" /> - <input type="hidden" name="file[newfile][0][target]" value="{target}" /> + <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:lang/Resources/Private/Language/locallang_core.xlf:cm.allowedFileExtensions" /><br> @@ -88,7 +88,7 @@ </div> <div class="form-group"> <button class="btn btn-default" name="edit" type="submit" value="1"><f:translate key="LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:file_newfolder.php.newfile_submit" /></button> - <input type="hidden" name="redirect" value="{returnUrl}" /> + <input type="hidden" name="data[newfile][0][redirect]" value="{returnUrl}" /> </div> </div> </form> diff --git a/typo3/sysext/backend/Resources/Private/Templates/File/EditFile.html b/typo3/sysext/backend/Resources/Private/Templates/File/EditFile.html index d763dee5a1c1..544fd006b5a6 100644 --- a/typo3/sysext/backend/Resources/Private/Templates/File/EditFile.html +++ b/typo3/sysext/backend/Resources/Private/Templates/File/EditFile.html @@ -1,14 +1,4 @@ <form action="{moduleUrlTceFile}" method="post" id="EditFileController" name="editform"> <h1><f:translate key="LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:file_edit.php.pagetitle" /> {fileName}</h1> - <div id="c-edit"> - <textarea rows="30" name="file[editfile][0][data]" wrap="off" class="form-control text-monospace t3js-enable-tab">{fileContent}</textarea> - <input type="hidden" name="file[editfile][0][target]" value="{uid}" /> - <input type="hidden" name="redirect" value="{hValue}" /> - </div> - <br /> - <f:if condition="{extList}"> - <f:format.raw> - <f:translate key="LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:file_edit.php.coundNot" arguments="{0: extList}" /> - </f:format.raw> - </f:if> + <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 index 531a156d2d60..e0e321cbca20 100644 --- a/typo3/sysext/backend/Resources/Private/Templates/File/RenameFile.html +++ b/typo3/sysext/backend/Resources/Private/Templates/File/RenameFile.html @@ -1,24 +1,27 @@ -<h1> - <f:translate key="LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:file_rename.php.pagetitle"/> -</h1> -<div> - <form action="{moduleUrlTceFile}" method="post" name="editform" role="form"> - <div class="form-group"> - <input class="form-control" type="text" name="file[rename][0][target]" value="{fileName}" - data-original="{fileName}" style="width:384px;"/> - <input type="hidden" name="file[rename][0][data]" value="{fileIdentifier}"/> - <f:if condition="{destination}"> - <input type="hidden" name="file[rename][0][destination]" value="{destination}"/> - <input type="hidden" name="file[rename][0][conflictMode]" value="{conflictMode}"/> - </f:if> +<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:lang/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> - <div class="form-group"> - <input class="btn btn-primary t3js-submit-file-rename" type="submit" - value="{f:translate(key: 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:file_rename.php.submit')}"/> - <input class="btn btn-danger" type="submit" - value="{f:translate(key: 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.cancel')}" - onclick="backToList(); return false;"/> - <input type="hidden" name="redirect" value="{returnUrl}"/> - </div> - </form> -</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> \ No newline at end of file diff --git a/typo3/sysext/backend/Resources/Private/TypeScript/RenameFile.ts b/typo3/sysext/backend/Resources/Private/TypeScript/RenameFile.ts index ac9bb01c1db2..d05ac012fc8c 100644 --- a/typo3/sysext/backend/Resources/Private/TypeScript/RenameFile.ts +++ b/typo3/sysext/backend/Resources/Private/TypeScript/RenameFile.ts @@ -33,16 +33,16 @@ class RenameFile { private checkForDuplicate(e: any): void { e.preventDefault(); - const form: any = $(e.currentTarget).closest('form'); - const fileNameField: any = form.find('input[name="file[rename][0][target]"]'); - const conflictModeField: any = form.find('input[name="file[rename][0][conflictMode]"]'); + 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="file[rename][0][destination]"]').val(), + fileTarget: form.find('input[name="data[rename][0][destination]"]').val(), }, success: (response: any): void => { const fileExists: boolean = response !== false; diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/DragUploader.js b/typo3/sysext/backend/Resources/Public/JavaScript/DragUploader.js index 9e575dd2e1a7..e2dc9ddae0cc 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/DragUploader.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/DragUploader.js @@ -562,8 +562,8 @@ define(['jquery', me.updateMessage('- ' + DragUploader.fileSizeAsString(me.file.size)); var formData = new FormData(); - formData.append('file[upload][1][target]', me.dragUploader.target); - formData.append('file[upload][1][data]', '1'); + formData.append('data[upload][1][target]', me.dragUploader.target); + formData.append('data[upload][1][data]', '1'); formData.append('overwriteExistingFiles', me.override); formData.append('redirect', ''); formData.append('upload_1', me.file); diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/RenameFile.js b/typo3/sysext/backend/Resources/Public/JavaScript/RenameFile.js index 59b38b9923ca..5350e22cdee6 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/RenameFile.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/RenameFile.js @@ -26,15 +26,15 @@ define(["require", "exports", "jquery", "TYPO3/CMS/Backend/Modal", "TYPO3/CMS/Ba }; RenameFile.prototype.checkForDuplicate = function (e) { e.preventDefault(); - var form = $(e.currentTarget).closest('form'); - var fileNameField = form.find('input[name="file[rename][0][target]"]'); - var conflictModeField = form.find('input[name="file[rename][0][conflictMode]"]'); + var form = $('#' + $(e.currentTarget).attr('form')); + var fileNameField = form.find('input[name="data[rename][0][target]"]'); + var conflictModeField = form.find('input[name="data[rename][0][conflictMode]"]'); var ajaxUrl = TYPO3.settings.ajaxUrls.file_exists; $.ajax({ cache: false, data: { fileName: fileNameField.val(), - fileTarget: form.find('input[name="file[rename][0][destination]"]').val(), + fileTarget: form.find('input[name="data[rename][0][destination]"]').val(), }, success: function (response) { var fileExists = response !== false; diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-81763-HookParametersOfTypo3file_editphppreOutputProcessingHookChanged.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-81763-HookParametersOfTypo3file_editphppreOutputProcessingHookChanged.rst new file mode 100644 index 000000000000..8223fdd1f9be --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Breaking-81763-HookParametersOfTypo3file_editphppreOutputProcessingHookChanged.rst @@ -0,0 +1,35 @@ +.. include:: ../../Includes.txt + +================================================================================================ +Breaking: #81763 - Hook parameters of ['typo3/file_edit.php']['preOutputProcessingHook'] changed +================================================================================================ + +See :issue:`81763` + +Description +=========== + +The hook parameters passed into :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/file_edit.php']['preOutputProcessingHook']` +have been changed due to rewriting the edit file form to use FormEngine. + + +Impact +====== + +Any information added to modify the output may have no effect anymore. + + +Affected Installations +====================== + +Every installation using an extension that hooks into :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/file_edit.php']['preOutputProcessingHook']` +to modify the form's output is affected. + + +Migration +========= + +As the form is based on FormEngine now, you may want to adjust the newly introduced hook parameter :php:`$dataColumnDefinition`, +representing the definition of the `data` field which contains the file content. An example can be found in EXT:t3editor. + +.. index:: Backend \ No newline at end of file diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-81763-DeprecatedLanguageLabelForFileRename.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-81763-DeprecatedLanguageLabelForFileRename.rst new file mode 100644 index 000000000000..491a5145364f --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-81763-DeprecatedLanguageLabelForFileRename.rst @@ -0,0 +1,26 @@ +.. include:: ../../Includes.txt + +=============================================================== +Deprecation: #81763 - Deprecated language label for file rename +=============================================================== + +See :issue:`81763` + +Description +=========== + +The language label `file_rename.php.submit` in `EXT:lang/Resources/Private/Language/locallang_core.xlf` has been marked as deprecated. + + +Affected Installations +====================== + +Any TYPO3 extension using the deprecated label is affected. + + +Migration +========= + +Add the label to the `locallang.xlf` of your extension and adjust the usage of the label. + +.. index:: Backend \ No newline at end of file diff --git a/typo3/sysext/filelist/Resources/Public/JavaScript/ContextMenuActions.js b/typo3/sysext/filelist/Resources/Public/JavaScript/ContextMenuActions.js index 799bb6615a4f..def7f5fe0726 100644 --- a/typo3/sysext/filelist/Resources/Public/JavaScript/ContextMenuActions.js +++ b/typo3/sysext/filelist/Resources/Public/JavaScript/ContextMenuActions.js @@ -71,7 +71,7 @@ define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity'], func var $anchorElement = $(this); var performDelete = function () { top.TYPO3.Backend.ContentContainer.setUrl( - top.TYPO3.settings.FileCommit.moduleUrl + '&file[delete][0][data]=' + top.rawurlencode(uid) + '&redirect=' + ContextMenuActions.getReturnUrl() + top.TYPO3.settings.FileCommit.moduleUrl + '&data[delete][0][data]=' + top.rawurlencode(uid) + '&data[delete][0][redirect]=' + ContextMenuActions.getReturnUrl() ); }; if (!$anchorElement.data('title')) { diff --git a/typo3/sysext/filelist/Resources/Public/JavaScript/FileDelete.js b/typo3/sysext/filelist/Resources/Public/JavaScript/FileDelete.js index 41facd9c1a39..0dd2ec469639 100644 --- a/typo3/sysext/filelist/Resources/Public/JavaScript/FileDelete.js +++ b/typo3/sysext/filelist/Resources/Public/JavaScript/FileDelete.js @@ -28,7 +28,7 @@ define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity'], func } var identifier = $anchorElement.data('identifier'); var deleteType = $anchorElement.data('deleteType'); - var deleteUrl = $anchorElement.data('deleteUrl') + '&file[delete][0][data]=' + encodeURIComponent(identifier); + var deleteUrl = $anchorElement.data('deleteUrl') + '&data[delete][0][data]=' + encodeURIComponent(identifier); if ($anchorElement.data('check')) { var $modal = Modal.confirm($anchorElement.data('title'), $anchorElement.data('content'), Severity.warning, [ { @@ -48,11 +48,11 @@ define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity'], func Modal.dismiss(); } else if (e.target.name === 'yes') { Modal.dismiss(); - top.list_frame.location.href = deleteUrl + '&redirect=' + redirectUrl; + top.list_frame.location.href = deleteUrl + '&data[delete][0][redirect]=' + redirectUrl; } }); } else { - top.list_frame.location.href = deleteUrl + '&redirect=' + redirectUrl; + top.list_frame.location.href = deleteUrl + '&data[delete][0][redirect]=' + redirectUrl; } }); diff --git a/typo3/sysext/impexp/Resources/Private/Partials/Import/Upload.html b/typo3/sysext/impexp/Resources/Private/Partials/Import/Upload.html index b69b578bf77b..06b41ddf37a7 100644 --- a/typo3/sysext/impexp/Resources/Private/Partials/Import/Upload.html +++ b/typo3/sysext/impexp/Resources/Private/Partials/Import/Upload.html @@ -6,8 +6,8 @@ </h4> <div class="form-group"> <f:form.upload name="upload_1" /> - <f:form.hidden name="file[upload][1][target]" value="{tempFolder}" /> - <f:form.hidden name="file[upload][1][data]" value="1" /> + <f:form.hidden name="data[upload][1][target]" value="{tempFolder}" /> + <f:form.hidden name="data[upload][1][data]" value="1" /> </div> <div class="form-group"> <f:form.submit class="btn btn-default" name="_upload" value="{f:translate(key: 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:file_upload.php.submit')}" /> diff --git a/typo3/sysext/lang/Resources/Private/Language/locallang_core.xlf b/typo3/sysext/lang/Resources/Private/Language/locallang_core.xlf index 333ecb8d6769..19e57272059a 100644 --- a/typo3/sysext/lang/Resources/Private/Language/locallang_core.xlf +++ b/typo3/sysext/lang/Resources/Private/Language/locallang_core.xlf @@ -633,6 +633,13 @@ Do you want to continue WITHOUT saving?</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> diff --git a/typo3/sysext/recordlist/Classes/View/FolderUtilityRenderer.php b/typo3/sysext/recordlist/Classes/View/FolderUtilityRenderer.php index 79fe7a63b5d6..232765eb3d8e 100644 --- a/typo3/sysext/recordlist/Classes/View/FolderUtilityRenderer.php +++ b/typo3/sysext/recordlist/Classes/View/FolderUtilityRenderer.php @@ -144,9 +144,9 @@ class FolderUtilityRenderer $markup[] = '<input type="file" multiple="multiple" name="upload_' . $a . '[]" size="50" />'; $markup[] = '</span>'; $markup[] = '</div>'; - $markup[] = '<input type="hidden" name="file[upload][' . $a . '][target]" value="' + $markup[] = '<input type="hidden" name="data[upload][' . $a . '][target]" value="' . htmlspecialchars($combinedIdentifier) . '" />'; - $markup[] = '<input type="hidden" name="file[upload][' . $a . '][data]" value="' . $a . '" />'; + $markup[] = '<input type="hidden" name="data[upload][' . $a . '][data]" value="' . $a . '" />'; } $redirectValue = $this->parameterProvider->getScriptUrl() . GeneralUtility::implodeArrayForUrl( '', diff --git a/typo3/sysext/t3editor/Classes/Hook/FileEditHook.php b/typo3/sysext/t3editor/Classes/Hook/FileEditHook.php index 939ea392707f..564037332221 100644 --- a/typo3/sysext/t3editor/Classes/Hook/FileEditHook.php +++ b/typo3/sysext/t3editor/Classes/Hook/FileEditHook.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); namespace TYPO3\CMS\T3editor\Hook; /* @@ -14,8 +15,9 @@ namespace TYPO3\CMS\T3editor\Hook; * The TYPO3 project - inspiring people to share! */ -use TYPO3\CMS\Core\Page\PageRenderer; -use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Backend\Controller\File\EditFileController; +use TYPO3\CMS\Core\Resource\ResourceFactory; +use TYPO3\CMS\T3editor\Form\Element\T3editorElement; /** * File edit hook for t3editor @@ -23,106 +25,55 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; class FileEditHook { /** - * @var \TYPO3\CMS\T3editor\T3editor - */ - protected $t3editor = null; - - /** - * @var string - */ - protected $ajaxSaveType = 'TypoScriptTemplateInformationModuleFunctionController'; - - /** - * @return \TYPO3\CMS\T3editor\T3editor + * Editor mode to file extension mapping. This is just temporarily in place and will be removed after refactoring + * EXT:t3editor. + * + * @var array */ - protected function getT3editor() - { - if ($this->t3editor === null) { - $this->t3editor = GeneralUtility::makeInstance(\TYPO3\CMS\T3editor\T3editor::class)->setAjaxSaveType($this->ajaxSaveType); - } - return $this->t3editor; - } + protected $fileExtensions = [ + T3editorElement::MODE_CSS => ['css'], + T3editorElement::MODE_HTML => ['htm', 'html'], + T3editorElement::MODE_JAVASCRIPT => ['js'], + T3editorElement::MODE_PHP => ['php', 'php5', 'php7', 'phps'], + T3editorElement::MODE_SPARQL => ['rq'], + T3editorElement::MODE_TYPOSCRIPT => ['ts', 'typoscript', 'txt'], + T3editorElement::MODE_XML => ['xml'], + ]; /** * Hook-function: inject t3editor JavaScript code before the page is compiled * called in file_edit module * * @param array $parameters - * @param \TYPO3\CMS\Backend\Controller\File\EditFileController $pObj + * @param EditFileController $pObj */ - public function preOutputProcessingHook($parameters, $pObj) + public function preOutputProcessingHook(array $parameters, EditFileController $pObj) { - $t3editor = $this->getT3editor(); - $t3editor->setModeByFile($parameters['target']); - if (!$t3editor->getMode()) { - return; + $target = ''; + if (isset($parameters['target']) && is_string($parameters['target'])) { + $target = $parameters['target']; } - $t3editor->getJavascriptCode(); - $this->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/T3editor/FileEdit'); + $parameters['dataColumnDefinition']['config']['renderType'] = 't3editor'; + $parameters['dataColumnDefinition']['config']['format'] = $this->determineFormatByExtension($target); } /** - * Hook-function: inject t3editor JavaScript code before the page is compiled - * called in \TYPO3\CMS\Backend\Template\DocumentTemplate:startPage - * - * @see \TYPO3\CMS\Backend\Template\DocumentTemplate::startPage + * @param string $fileIdentifier + * @return string */ - public function preStartPageHook() + protected function determineFormatByExtension(string $fileIdentifier): string { - // @todo: this is a workaround. Ideally the document template holds the current request so we can match the route - // against the name of the route and not the GET parameter - if (GeneralUtility::_GET('route') === '/file/editcontent') { - $t3editor = $this->getT3editor(); - $t3editor->getJavascriptCode(); - $this->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/T3editor/FileEdit'); + $fileExtension = ResourceFactory::getInstance()->retrieveFileOrFolderObject($fileIdentifier)->getExtension(); + if (empty($fileExtension)) { + return T3editorElement::MODE_MIXED; } - } - /** - * Hook-function: - * called in file_edit module - * - * @param array $parameters - * @param \TYPO3\CMS\Backend\Controller\File\EditFileController $pObj - */ - public function postOutputProcessingHook($parameters, $pObj) - { - $t3editor = $this->getT3editor(); - if (!$t3editor->getMode()) { - return; + foreach ($this->fileExtensions as $format => $extensions) { + if (in_array($fileExtension, $extensions, true)) { + return $format; + } } - $attributes = 'rows="30" wrap="off" style="width:98%;height:60%"'; - $title = $GLOBALS['LANG']->getLL('file') . ' ' . htmlspecialchars($pObj->target); - $outCode = $t3editor->getCodeEditor('file[editfile][0][data]', 'text-monospace enable-tab', '$1', $attributes, $title, [ - 'target' => (int)$pObj->target - ]); - $parameters['pageContent'] = preg_replace('/\\<textarea .*name="file\\[editfile\\]\\[0\\]\\[data\\]".*\\>([^\\<]*)\\<\\/textarea\\>/mi', $outCode, $parameters['pageContent']); - } - /** - * @param array $parameters - * @param mixed $pObj - * - * @return bool TRUE if successful - */ - public function save($parameters, $pObj) - { - $savingsuccess = false; - if ($parameters['type'] === $this->ajaxSaveType) { - /** @var \TYPO3\CMS\Backend\Controller\File\FileController $tceFile */ - $tceFile = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Controller\File\FileController::class); - $response = $tceFile->processAjaxRequest($parameters['request'], $parameters['response']); - $result = json_decode((string)$response->getBody(), true); - $savingsuccess = is_array($result) && $result['editfile'][0]; - } - return $savingsuccess; - } - - /** - * @return PageRenderer - */ - protected function getPageRenderer() - { - return GeneralUtility::makeInstance(PageRenderer::class); + return T3editorElement::MODE_MIXED; } } diff --git a/typo3/sysext/t3editor/Resources/Public/JavaScript/FileEdit.js b/typo3/sysext/t3editor/Resources/Public/JavaScript/FileEdit.js deleted file mode 100644 index 7ef510af416d..000000000000 --- a/typo3/sysext/t3editor/Resources/Public/JavaScript/FileEdit.js +++ /dev/null @@ -1,60 +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! - */ - -/** - * Module: TYPO3/CMS/T3editor/FileEdit - * File edit for ext:t3editor - * @exports TYPO3/CMS/T3editor/FileEdit - */ -define(['jquery', 'TYPO3/CMS/T3editor/T3editor'], function ($, T3editor) { - 'use strict'; - - $(function() { - - // Remove document.editform.submit from save and close onclick - // Form will be submitted by the new on click handler - var $saveAndCloseButton = $('[data-name="_saveandclose"], [name="_saveandclose"]'), - $saveButton = $('[data-name="_save"], [name="_save"]'); - - var onClick = $saveAndCloseButton.attr('onclick'); - $saveAndCloseButton.attr('onclick', onClick.replace('document.editform.submit();', '')); - - // Remove onclick for save icon, saving is done by an AJAX-call - $saveButton.removeAttr('onclick'); - - $saveButton.on('click', function(e) { - e.preventDefault(); - - if (!T3editor || !T3editor.instances[0]) { - document.editform.submit(); - return false; - } - - T3editor.saveFunction(T3editor.instances[0]); - return false; - }); - - $saveAndCloseButton.on('click', function(e) { - e.preventDefault(); - - if (!T3editor || !T3editor.instances[0]) { - document.editform.submit(); - return false; - } - T3editor.updateTextarea(T3editor.instances[0]); - document.editform.submit(); - return false; - }); - - }); -}); diff --git a/typo3/sysext/t3editor/ext_localconf.php b/typo3/sysext/t3editor/ext_localconf.php index 52b52792bc3e..be6045987d28 100644 --- a/typo3/sysext/t3editor/ext_localconf.php +++ b/typo3/sysext/t3editor/ext_localconf.php @@ -2,11 +2,7 @@ defined('TYPO3_MODE') or die(); if (TYPO3_MODE === 'BE') { - // Register hooks for tstemplate module - $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/t3editor/classes/class.tx_t3editor.php']['ajaxSaveCode']['file_edit'] = \TYPO3\CMS\T3editor\Hook\FileEditHook::class . '->save'; - $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/template.php']['preStartPageHook'][] = \TYPO3\CMS\T3editor\Hook\FileEditHook::class . '->preStartPageHook'; $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/file_edit.php']['preOutputProcessingHook'][] = \TYPO3\CMS\T3editor\Hook\FileEditHook::class . '->preOutputProcessingHook'; - $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/file_edit.php']['postOutputProcessingHook'][] = \TYPO3\CMS\T3editor\Hook\FileEditHook::class . '->postOutputProcessingHook'; } $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'][1433089350] = [ -- GitLab