[TASK] Use enumeration for handling conflicts in file names 94/42794/20
authorDaniel Goerz <ervaude@gmail.com>
Thu, 20 Aug 2015 22:11:11 +0000 (00:11 +0200)
committerMarkus Klein <markus.klein@typo3.org>
Wed, 2 Sep 2015 12:13:08 +0000 (14:13 +0200)
Conflicts in file names are handled with a list of plain
text values in the code. This patch adds a DuplicationBehavior
enumeration to improve the situation. It also streamlines the
redundant use of different strings for the same thing.

Change-Id: If07cacc77a4737bf52e6978dba79c22d72b7209c
Resolves: #55419
Releases: master
Reviewed-on: http://review.typo3.org/42794
Reviewed-by: Alexander Opitz <opitz.alexander@googlemail.com>
Tested-by: Alexander Opitz <opitz.alexander@googlemail.com>
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Tested-by: Markus Klein <markus.klein@typo3.org>
Reviewed-by: Frans Saris <franssaris@gmail.com>
15 files changed:
typo3/sysext/backend/Classes/Controller/File/FileController.php
typo3/sysext/backend/Resources/Public/JavaScript/DragUploader.js
typo3/sysext/core/Classes/Html/RteHtmlParser.php
typo3/sysext/core/Classes/Resource/AbstractFile.php
typo3/sysext/core/Classes/Resource/DuplicationBehavior.php [new file with mode: 0644]
typo3/sysext/core/Classes/Resource/Folder.php
typo3/sysext/core/Classes/Resource/InaccessibleFolder.php
typo3/sysext/core/Classes/Resource/ResourceStorage.php
typo3/sysext/core/Classes/Utility/File/ExtendedFileUtility.php
typo3/sysext/core/Documentation/Changelog/7.4/Deprecation-63603-ExtendedFileUtilitydontCheckForUniqueIsDeprecated.rst
typo3/sysext/core/Documentation/Changelog/7.4/Deprecation-63603-FileControllerAndFileListControllerOverwriteExistingFilesChangedToStringValue.rst
typo3/sysext/core/Documentation/Changelog/master/Deprecation-55419-StreamlineFileConflictModeHandling.rst [new file with mode: 0644]
typo3/sysext/filelist/Classes/Controller/FileListController.php
typo3/sysext/impexp/Classes/Controller/ImportExportController.php
typo3/sysext/impexp/Classes/ImportExport.php

index 79eb0fd..31eb3d3 100644 (file)
@@ -17,6 +17,7 @@ namespace TYPO3\CMS\Backend\Controller\File;
 use Psr\Http\Message\ServerRequestInterface;
 use TYPO3\CMS\Core\Http\AjaxRequestHandler;
 use TYPO3\CMS\Core\Http\Response;
+use TYPO3\CMS\Core\Resource\DuplicationBehavior;
 use TYPO3\CMS\Core\Resource\Folder;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
@@ -46,9 +47,10 @@ class FileController implements \TYPO3\CMS\Core\Http\ControllerInterface {
        protected $CB;
 
        /**
-        * Defines behaviour when uploading files with names that already exist; possible value are 'cancel', 'replace', 'changeName'
+        * Defines behaviour when uploading files with names that already exist; possible values are
+        * the values of the \TYPO3\CMS\Core\Resource\DuplicationBehavior enumeration
         *
-        * @var string
+        * @var \TYPO3\CMS\Core\Resource\DuplicationBehavior
         */
        protected $overwriteExistingFiles;
 
@@ -99,13 +101,7 @@ class FileController implements \TYPO3\CMS\Core\Http\ControllerInterface {
                // Set the GPvars from outside
                $this->file = GeneralUtility::_GP('file');
                $this->CB = GeneralUtility::_GP('CB');
-               $this->overwriteExistingFiles = GeneralUtility::_GP('overwriteExistingFiles');
-
-               if ((string)$this->overwriteExistingFiles === '1') {
-                       GeneralUtility::deprecationLog('overwriteExitingFiles = 1 is deprecated. Use overwriteExitingFiles = "replace". Support for old behavior will be removed in TYPO3 CMS 8.');
-                       $this->overwriteExistingFiles = 'replace';
-               }
-
+               $this->overwriteExistingFiles = DuplicationBehavior::cast(GeneralUtility::_GP('overwriteExistingFiles'));
                $this->vC = GeneralUtility::_GP('vC');
                $this->redirect = GeneralUtility::sanitizeLocalUrl(GeneralUtility::_GP('redirect'));
                $this->initClipboard();
@@ -142,16 +138,7 @@ class FileController implements \TYPO3\CMS\Core\Http\ControllerInterface {
                // Initializing:
                $this->fileProcessor->init(array(), $GLOBALS['TYPO3_CONF_VARS']['BE']['fileExtensions']);
                $this->fileProcessor->setActionPermissions();
-               switch ($this->overwriteExistingFiles) {
-                       case 'replace':
-                       case 'changeName':
-                               $conflictMode = $this->overwriteExistingFiles;
-                               break;
-                       default:
-                               $conflictMode = 'cancel';
-                               break;
-               }
-               $this->fileProcessor->setExistingFilesConflictMode($conflictMode);
+               $this->fileProcessor->setExistingFilesConflictMode($this->overwriteExistingFiles);
                // Checking referrer / executing:
                $refInfo = parse_url(GeneralUtility::getIndpEnv('HTTP_REFERER'));
                $httpHost = GeneralUtility::getIndpEnv('TYPO3_HOST_ONLY');
index 47176c6..9486049 100644 (file)
@@ -30,7 +30,7 @@ define('TYPO3/CMS/Backend/DragUploader', ['jquery', 'moment', 'nprogress', 'TYPO
         */
        var actions = {
                OVERRIDE: 'replace',
-               RENAME: 'changeName',
+               RENAME: 'rename',
                SKIP: 'cancel',
                USE_EXISTING: 'useExisting'
        };
index c49ef73..1132992 100644 (file)
@@ -451,7 +451,7 @@ class RteHtmlParser extends \TYPO3\CMS\Core\Html\HtmlParser {
                                                        }
                                                }
                                        }
-                                       // Remove width and heigth from style attribute
+                                       // Remove width and height from style attribute
                                        $attribArray['style'] = preg_replace('/((?:^|)\\s*(?:width|height)\\s*:[^;]*(?:$|;))/si', '', $attribArray['style']);
                                        // Must have alt attribute
                                        if (!isset($attribArray['alt'])) {
index df4a68d..5ea409e 100644 (file)
@@ -452,12 +452,12 @@ abstract class AbstractFile implements FileInterface {
         *
         * @param Folder $targetFolder Folder to copy file into.
         * @param string $targetFileName an optional destination fileName
-        * @param string $conflictMode overrideExistingFile", "renameNewFile", "cancel
+        * @param string $conflictMode a value of the \TYPO3\CMS\Core\Resource\DuplicationBehavior enumeration
         *
         * @throws \RuntimeException
         * @return File The new (copied) file.
         */
-       public function copyTo(Folder $targetFolder, $targetFileName = NULL, $conflictMode = 'renameNewFile') {
+       public function copyTo(Folder $targetFolder, $targetFileName = NULL, $conflictMode = DuplicationBehavior::RENAME) {
                if ($this->deleted) {
                        throw new \RuntimeException('File has been deleted.', 1329821483);
                }
@@ -469,12 +469,12 @@ abstract class AbstractFile implements FileInterface {
         *
         * @param Folder $targetFolder Folder to move file into.
         * @param string $targetFileName an optional destination fileName
-        * @param string $conflictMode overrideExistingFile", "renameNewFile", "cancel
+        * @param string $conflictMode a value of the \TYPO3\CMS\Core\Resource\DuplicationBehavior enumeration
         *
         * @throws \RuntimeException
         * @return File This file object, with updated properties.
         */
-       public function moveTo(Folder $targetFolder, $targetFileName = NULL, $conflictMode = 'renameNewFile') {
+       public function moveTo(Folder $targetFolder, $targetFileName = NULL, $conflictMode = DuplicationBehavior::RENAME) {
                if ($this->deleted) {
                        throw new \RuntimeException('File has been deleted.', 1329821484);
                }
diff --git a/typo3/sysext/core/Classes/Resource/DuplicationBehavior.php b/typo3/sysext/core/Classes/Resource/DuplicationBehavior.php
new file mode 100644 (file)
index 0000000..341e04f
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+namespace TYPO3\CMS\Core\Resource;
+
+/*
+ * 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 TYPO3\CMS\Core\Utility\GeneralUtility;
+
+/**
+ * Enumeration object for DuplicationBehavior
+ */
+class DuplicationBehavior extends \TYPO3\CMS\Core\Type\Enumeration {
+
+       const __default = self::CANCEL;
+
+       /**
+        * If a file is uploaded and another file with
+        * the same name already exists, the new file
+        * is renamed.
+        */
+       const RENAME = 'rename';
+
+       /**
+        * If a file is uploaded and another file with
+        * the same name already exists, the old file
+        * gets overwritten by the new file.
+        */
+       const REPLACE = 'replace';
+
+       /**
+        * If a file is uploaded and another file with
+        * the same name already exists, the process is
+        * aborted.
+        */
+       const CANCEL = 'cancel';
+
+       /**
+        * Mapping of some legacy values, to assure BC
+        *
+        * @var string[]
+        * @deprecated
+        */
+       static protected $legacyValueMap = array(
+               '1' => self::REPLACE,
+               'overrideExistingFile' => self::REPLACE,
+               'renameNewFile' => self::RENAME,
+               'changeName' => self::RENAME
+       );
+
+       /**
+        * @param mixed $value
+        */
+       public function __construct($value = NULL) {
+               if (isset(static::$legacyValueMap[$value])) {
+                       GeneralUtility::deprecationLog('Using ' . $value . ' for resolving conflicts in file names is deprecated. Make use of the enumeration "\TYPO3\CMS\Core\Resource\DuplicationBehavior" instead.');
+                       $value = static::$legacyValueMap[$value];
+               }
+               parent::__construct($value);
+       }
+
+}
index 9038756..ff96a92 100644 (file)
@@ -263,10 +263,10 @@ class Folder implements FolderInterface {
         *
         * @param string $localFilePath
         * @param string $fileName
-        * @param string $conflictMode possible value are 'cancel', 'replace', 'changeName'
+        * @param string $conflictMode a value of the \TYPO3\CMS\Core\Resource\DuplicationBehavior enumeration
         * @return File The file object
         */
-       public function addFile($localFilePath, $fileName = NULL, $conflictMode = 'cancel') {
+       public function addFile($localFilePath, $fileName = NULL, $conflictMode = DuplicationBehavior::CANCEL) {
                $fileName = $fileName ? $fileName : PathUtility::basename($localFilePath);
                return $this->storage->addFile($localFilePath, $this, $fileName, $conflictMode);
        }
@@ -275,10 +275,10 @@ class Folder implements FolderInterface {
         * Adds an uploaded file into the Storage.
         *
         * @param array $uploadedFileData contains information about the uploaded file given by $_FILES['file1']
-        * @param string $conflictMode possible value are 'cancel', 'replace'
+        * @param string $conflictMode a value of the \TYPO3\CMS\Core\Resource\DuplicationBehavior enumeration
         * @return File The file object
         */
-       public function addUploadedFile(array $uploadedFileData, $conflictMode = 'cancel') {
+       public function addUploadedFile(array $uploadedFileData, $conflictMode = DuplicationBehavior::CANCEL) {
                return $this->storage->addUploadedFile($uploadedFileData, $this, $uploadedFileData['name'], $conflictMode);
        }
 
@@ -327,10 +327,10 @@ class Folder implements FolderInterface {
         *
         * @param Folder $targetFolder Target folder to copy to.
         * @param string $targetFolderName an optional destination fileName
-        * @param string $conflictMode "overrideExistingFile", "renameNewFile" or "cancel
+        * @param string $conflictMode a value of the \TYPO3\CMS\Core\Resource\DuplicationBehavior enumeration
         * @return Folder New (copied) folder object.
         */
-       public function copyTo(Folder $targetFolder, $targetFolderName = NULL, $conflictMode = 'renameNewFile') {
+       public function copyTo(Folder $targetFolder, $targetFolderName = NULL, $conflictMode = DuplicationBehavior::RENAME) {
                return $targetFolder->getStorage()->copyFolder($this, $targetFolder, $targetFolderName, $conflictMode);
        }
 
@@ -339,10 +339,10 @@ class Folder implements FolderInterface {
         *
         * @param Folder $targetFolder Target folder to move to.
         * @param string $targetFolderName an optional destination fileName
-        * @param string $conflictMode "overrideExistingFile", "renameNewFile" or "cancel
+        * @param string $conflictMode a value of the \TYPO3\CMS\Core\Resource\DuplicationBehavior enumeration
         * @return Folder New (copied) folder object.
         */
-       public function moveTo(Folder $targetFolder, $targetFolderName = NULL, $conflictMode = 'renameNewFile') {
+       public function moveTo(Folder $targetFolder, $targetFolderName = NULL, $conflictMode = DuplicationBehavior::RENAME) {
                return $targetFolder->getStorage()->moveFolder($this, $targetFolder, $targetFolderName, $conflictMode);
        }
 
index c882678..d176df2 100644 (file)
@@ -123,10 +123,10 @@ class InaccessibleFolder extends Folder {
         *
         * @param string $localFilePath
         * @param string $fileName
-        * @param string $conflictMode possible value are 'cancel', 'replace'
+        * @param string $conflictMode a value of the \TYPO3\CMS\Core\Resource\DuplicationBehavior enumeration
         * @return File The file object
         */
-       public function addFile($localFilePath, $fileName = NULL, $conflictMode = 'cancel') {
+       public function addFile($localFilePath, $fileName = NULL, $conflictMode = DuplicationBehavior::CANCEL) {
                $this->throwInaccessibleException();
        }
 
@@ -134,10 +134,10 @@ class InaccessibleFolder extends Folder {
         * Adds an uploaded file into the Storage.
         *
         * @param array $uploadedFileData contains information about the uploaded file given by $_FILES['file1']
-        * @param string $conflictMode possible value are 'cancel', 'replace'
+        * @param string $conflictMode a value of the \TYPO3\CMS\Core\Resource\DuplicationBehavior enumeration
         * @return File The file object
         */
-       public function addUploadedFile(array $uploadedFileData, $conflictMode = 'cancel') {
+       public function addUploadedFile(array $uploadedFileData, $conflictMode = DuplicationBehavior::CANCEL) {
                $this->throwInaccessibleException();
        }
 
@@ -186,10 +186,10 @@ class InaccessibleFolder extends Folder {
         *
         * @param Folder $targetFolder Target folder to copy to.
         * @param string $targetFolderName an optional destination fileName
-        * @param string $conflictMode "overrideExistingFile", "renameNewFile" or "cancel
+        * @param string $conflictMode a value of the \TYPO3\CMS\Core\Resource\DuplicationBehavior enumeration
         * @return Folder New (copied) folder object.
         */
-       public function copyTo(Folder $targetFolder, $targetFolderName = NULL, $conflictMode = 'renameNewFile') {
+       public function copyTo(Folder $targetFolder, $targetFolderName = NULL, $conflictMode = DuplicationBehavior::RENAME) {
                $this->throwInaccessibleException();
        }
 
@@ -198,10 +198,10 @@ class InaccessibleFolder extends Folder {
         *
         * @param Folder $targetFolder Target folder to move to.
         * @param string $targetFolderName an optional destination fileName
-        * @param string $conflictMode "overrideExistingFile", "renameNewFile" or "cancel
+        * @param string $conflictMode a value of the \TYPO3\CMS\Core\Resource\DuplicationBehavior enumeration
         * @return Folder New (copied) folder object.
         */
-       public function moveTo(Folder $targetFolder, $targetFolderName = NULL, $conflictMode = 'renameNewFile') {
+       public function moveTo(Folder $targetFolder, $targetFolderName = NULL, $conflictMode = DuplicationBehavior::RENAME) {
                $this->throwInaccessibleException();
        }
 
index 1752076..13f310d 100644 (file)
@@ -1089,27 +1089,27 @@ class ResourceStorage implements ResourceStorageInterface {
         * @param string $localFilePath The file on the server's hard disk to add
         * @param Folder $targetFolder The target folder where the file should be added
         * @param string $targetFileName The name of the file to be add, If not set, the local file name is used
-        * @param string $conflictMode possible value are 'cancel', 'replace', 'changeName'
+        * @param string $conflictMode a value of the \TYPO3\CMS\Core\Resource\DuplicationBehavior enumeration
         *
         * @throws \InvalidArgumentException
         * @throws Exception\ExistingTargetFileNameException
         * @return FileInterface
         */
-       public function addFile($localFilePath, Folder $targetFolder, $targetFileName = '', $conflictMode = 'changeName') {
+       public function addFile($localFilePath, Folder $targetFolder, $targetFileName = '', $conflictMode = DuplicationBehavior::RENAME) {
                $localFilePath = PathUtility::getCanonicalPath($localFilePath);
                if (!file_exists($localFilePath)) {
                        throw new \InvalidArgumentException('File "' . $localFilePath . '" does not exist.', 1319552745);
                }
+               $conflictMode = DuplicationBehavior::cast($conflictMode);
                $targetFolder = $targetFolder ?: $this->getDefaultFolder();
                $targetFileName = $this->sanitizeFileName($targetFileName ?: PathUtility::basename($localFilePath), $targetFolder);
 
                $targetFileName = $this->emitPreFileAddSignal($targetFileName, $targetFolder, $localFilePath);
 
                $this->assureFileAddPermissions($targetFolder, $targetFileName);
-
-               if ($conflictMode === 'cancel' && $this->driver->fileExistsInFolder($targetFileName, $targetFolder->getIdentifier())) {
+               if ($conflictMode->equals(DuplicationBehavior::CANCEL) && $this->driver->fileExistsInFolder($targetFileName, $targetFolder->getIdentifier())) {
                        throw new Exception\ExistingTargetFileNameException('File "' . $targetFileName . '" already exists in folder ' . $targetFolder->getIdentifier(), 1322121068);
-               } elseif ($conflictMode === 'changeName') {
+               } elseif ($conflictMode->equals(DuplicationBehavior::RENAME)) {
                        $targetFileName = $this->getUniqueName($targetFolder, $targetFileName);
                }
 
@@ -1637,13 +1637,14 @@ class ResourceStorage implements ResourceStorageInterface {
         * @param FileInterface $file
         * @param Folder $targetFolder
         * @param string $targetFileName an optional destination fileName
-        * @param string $conflictMode "overrideExistingFile", "renameNewFile", "cancel
+        * @param string $conflictMode a value of the \TYPO3\CMS\Core\Resource\DuplicationBehavior enumeration
         *
         * @throws \Exception|Exception\AbstractFileOperationException
         * @throws Exception\ExistingTargetFileNameException
         * @return FileInterface
         */
-       public function copyFile(FileInterface $file, Folder $targetFolder, $targetFileName = NULL, $conflictMode = 'renameNewFile') {
+       public function copyFile(FileInterface $file, Folder $targetFolder, $targetFileName = NULL, $conflictMode = DuplicationBehavior::RENAME) {
+               $conflictMode = DuplicationBehavior::cast($conflictMode);
                if ($targetFileName === NULL) {
                        $targetFileName = $file->getName();
                }
@@ -1651,11 +1652,11 @@ class ResourceStorage implements ResourceStorageInterface {
                $this->assureFileCopyPermissions($file, $targetFolder, $sanitizedTargetFileName);
                $this->emitPreFileCopySignal($file, $targetFolder);
                // File exists and we should abort, let's abort
-               if ($conflictMode === 'cancel' && $targetFolder->hasFile($sanitizedTargetFileName)) {
+               if ($conflictMode->equals(DuplicationBehavior::CANCEL) && $targetFolder->hasFile($sanitizedTargetFileName)) {
                        throw new Exception\ExistingTargetFileNameException('The target file already exists.', 1320291064);
                }
                // File exists and we should find another name, let's find another one
-               if ($conflictMode === 'renameNewFile' && $targetFolder->hasFile($sanitizedTargetFileName)) {
+               if ($conflictMode->equals(DuplicationBehavior::RENAME) && $targetFolder->hasFile($sanitizedTargetFileName)) {
                        $sanitizedTargetFileName = $this->getUniqueName($targetFolder, $sanitizedTargetFileName);
                }
                $sourceStorage = $file->getStorage();
@@ -1681,13 +1682,14 @@ class ResourceStorage implements ResourceStorageInterface {
         * @param FileInterface $file
         * @param Folder $targetFolder
         * @param string $targetFileName an optional destination fileName
-        * @param string $conflictMode "overrideExistingFile", "renameNewFile", "cancel
+        * @param string $conflictMode a value of the \TYPO3\CMS\Core\Resource\DuplicationBehavior enumeration
         *
         * @throws Exception\ExistingTargetFileNameException
         * @throws \RuntimeException
         * @return FileInterface
         */
-       public function moveFile($file, $targetFolder, $targetFileName = NULL, $conflictMode = 'renameNewFile') {
+       public function moveFile($file, $targetFolder, $targetFileName = NULL, $conflictMode = DuplicationBehavior::RENAME) {
+               $conflictMode = DuplicationBehavior::cast($conflictMode);
                if ($targetFileName === NULL) {
                        $targetFileName = $file->getName();
                }
@@ -1696,9 +1698,9 @@ class ResourceStorage implements ResourceStorageInterface {
                $this->assureFileMovePermissions($file, $targetFolder, $sanitizedTargetFileName);
                if ($targetFolder->hasFile($sanitizedTargetFileName)) {
                        // File exists and we should abort, let's abort
-                       if ($conflictMode === 'renameNewFile') {
+                       if ($conflictMode->equals(DuplicationBehavior::RENAME)) {
                                $sanitizedTargetFileName = $this->getUniqueName($targetFolder, $sanitizedTargetFileName);
-                       } elseif ($conflictMode === 'cancel') {
+                       } elseif ($conflictMode->equals(DuplicationBehavior::CANCEL)) {
                                throw new Exception\ExistingTargetFileNameException('The target file already exists', 1329850997);
                        }
                }
@@ -1800,10 +1802,11 @@ class ResourceStorage implements ResourceStorageInterface {
         * @param array $uploadedFileData contains information about the uploaded file given by $_FILES['file1']
         * @param Folder $targetFolder the target folder
         * @param string $targetFileName the file name to be written
-        * @param string $conflictMode possible value are 'cancel', 'replace'
+        * @param string $conflictMode a value of the \TYPO3\CMS\Core\Resource\DuplicationBehavior enumeration
         * @return FileInterface The file object
         */
-       public function addUploadedFile(array $uploadedFileData, Folder $targetFolder = NULL, $targetFileName = NULL, $conflictMode = 'cancel') {
+       public function addUploadedFile(array $uploadedFileData, Folder $targetFolder = NULL, $targetFileName = NULL, $conflictMode = DuplicationBehavior::CANCEL) {
+               $conflictMode = DuplicationBehavior::cast($conflictMode);
                $localFilePath = $uploadedFileData['tmp_name'];
                if ($targetFolder === NULL) {
                        $targetFolder = $this->getDefaultFolder();
@@ -1814,11 +1817,11 @@ class ResourceStorage implements ResourceStorageInterface {
                $targetFileName = $this->driver->sanitizeFileName($targetFileName);
 
                $this->assureFileUploadPermissions($localFilePath, $targetFolder, $targetFileName, $uploadedFileData['size']);
-               if ($this->hasFileInFolder($targetFileName, $targetFolder) && $conflictMode === 'replace') {
+               if ($this->hasFileInFolder($targetFileName, $targetFolder) && $conflictMode->equals(DuplicationBehavior::REPLACE)) {
                        $file = $this->getFileInFolder($targetFileName, $targetFolder);
                        $resultObject = $this->replaceFile($file, $localFilePath);
                } else {
-                       $resultObject = $this->addFile($localFilePath, $targetFolder, $targetFileName, $conflictMode);
+                       $resultObject = $this->addFile($localFilePath, $targetFolder, $targetFileName, (string)$conflictMode);
                }
                return $resultObject;
        }
@@ -1856,14 +1859,14 @@ class ResourceStorage implements ResourceStorageInterface {
         * @param Folder $folderToMove The folder to move.
         * @param Folder $targetParentFolder The target parent folder
         * @param string $newFolderName
-        * @param string $conflictMode How to handle conflicts; one of "overrideExistingFile", "renameNewFolder", "cancel
+        * @param string $conflictMode a value of the \TYPO3\CMS\Core\Resource\DuplicationBehavior enumeration
         *
         * @throws \Exception|\TYPO3\CMS\Core\Exception
         * @throws \InvalidArgumentException
         * @throws InvalidTargetFolderException
         * @return Folder
         */
-       public function moveFolder(Folder $folderToMove, Folder $targetParentFolder, $newFolderName = NULL, $conflictMode = 'renameNewFolder') {
+       public function moveFolder(Folder $folderToMove, Folder $targetParentFolder, $newFolderName = NULL, $conflictMode = DuplicationBehavior::RENAME) {
                // @todo add tests
                $originalFolder = $folderToMove->getParentFolder();
                $this->assureFolderMovePermissions($folderToMove, $targetParentFolder);
@@ -1920,11 +1923,11 @@ class ResourceStorage implements ResourceStorageInterface {
         * @param FolderInterface $folderToCopy The folder to copy
         * @param FolderInterface $targetParentFolder The target folder
         * @param string $newFolderName
-        * @param string $conflictMode "overrideExistingFolder", "renameNewFolder", "cancel
+        * @param string $conflictMode a value of the \TYPO3\CMS\Core\Resource\DuplicationBehavior enumeration
         * @return Folder The new (copied) folder object
         * @throws InvalidTargetFolderException
         */
-       public function copyFolder(FolderInterface $folderToCopy, FolderInterface $targetParentFolder, $newFolderName = NULL, $conflictMode = 'renameNewFolder') {
+       public function copyFolder(FolderInterface $folderToCopy, FolderInterface $targetParentFolder, $newFolderName = NULL, $conflictMode = DuplicationBehavior::RENAME) {
                // @todo implement the $conflictMode handling
                $this->assureFolderCopyPermissions($folderToCopy, $targetParentFolder);
                $returnObject = NULL;
index cf36884..ba5f648 100644 (file)
@@ -18,6 +18,7 @@ use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Backend\Utility\IconUtility;
 use TYPO3\CMS\Core\Messaging\FlashMessage;
 use TYPO3\CMS\Core\Messaging\FlashMessageService;
+use TYPO3\CMS\Core\Resource\DuplicationBehavior;
 use TYPO3\CMS\Core\Resource\Exception;
 use TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException;
 use TYPO3\CMS\Core\Resource\File;
@@ -26,6 +27,7 @@ use TYPO3\CMS\Core\Resource\ResourceFactory;
 use TYPO3\CMS\Core\Resource\ResourceStorage;
 use TYPO3\CMS\Core\Utility\CommandUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Type\Exception\InvalidEnumerationValueException;
 
 /**
  * Contains functions for performing file operations like copying, pasting, uploading, moving,
@@ -73,9 +75,10 @@ class ExtendedFileUtility extends BasicFileUtility {
        public $dontCheckForUnique = 0;
 
        /**
-        * Defines behaviour when uploading files with names that already exist; possible value are 'cancel', 'replace', 'changeName'
+        * Defines behaviour when uploading files with names that already exist; possible values are
+        * the values of the \TYPO3\CMS\Core\Resource\DuplicationBehavior enumeration
         *
-        * @var string
+        * @var \TYPO3\CMS\Core\Resource\DuplicationBehavior
         */
        protected $existingFilesConflictMode;
 
@@ -151,20 +154,28 @@ class ExtendedFileUtility extends BasicFileUtility {
         * @return string
         */
        public function getExistingFilesConflictMode() {
-               return $this->existingFilesConflictMode;
+               return (string)$this->existingFilesConflictMode;
        }
 
        /**
         * Set existingFilesConflictMode
         *
-        * @param string $existingFilesConflictMode
+        * @param \TYPO3\CMS\Core\Resource\DuplicationBehavior|string $existingFilesConflictMode Instance or constant of \TYPO3\CMS\Core\Resource\DuplicationBehavior
+        * @return void
         * @throws Exception
         */
        public function setExistingFilesConflictMode($existingFilesConflictMode) {
-               if (!in_array($existingFilesConflictMode, array('cancel', 'replace', 'changeName'))) {
-                       throw new Exception(sprintf('Invalid argument, received: "%s", expected: "cancel", "replace" or "changeName"', $existingFilesConflictMode));
+               try {
+                       $this->existingFilesConflictMode = DuplicationBehavior::cast($existingFilesConflictMode);
+               } catch (InvalidEnumerationValueException $e) {
+                       throw new Exception(
+                               sprintf(
+                                       'Invalid argument, received: "%s", expected a value from enumeration \TYPO3\CMS\Core\Resource\DuplicationBehavior (%s)',
+                                       $existingFilesConflictMode,
+                                       implode(', ', DuplicationBehavior::getConstants())
+                               )
+                       );
                }
-               $this->existingFilesConflictMode = $existingFilesConflictMode;
        }
 
        /**
@@ -191,6 +202,7 @@ class ExtendedFileUtility extends BasicFileUtility {
         * If no argument is given, permissions of the currently logged in backend user are taken into account.
         *
         * @param array $permissions File Permissions.
+        * @return void
         */
        public function setActionPermissions(array $permissions = array()) {
                if (empty($permissions)) {
@@ -609,10 +621,10 @@ class ExtendedFileUtility extends BasicFileUtility {
                // If this is TRUE, we append _XX to the file name if
                $appendSuffixOnConflict = (string)$cmds['altName'];
                $resultObject = NULL;
+               $conflictMode = $appendSuffixOnConflict !== '' ? DuplicationBehavior::RENAME : DuplicationBehavior::CANCEL;
                // Copying the file
                if ($sourceFileObject instanceof File) {
                        try {
-                               $conflictMode = $appendSuffixOnConflict !== '' ? 'renameNewFile' : 'cancel';
                                $resultObject = $sourceFileObject->copyTo($targetFolderObject, NULL, $conflictMode);
                        } catch (\TYPO3\CMS\Core\Resource\Exception\InsufficientUserPermissionsException $e) {
                                $this->writelog(2, 1, 114, 'You are not allowed to copy files', '');
@@ -634,7 +646,6 @@ class ExtendedFileUtility extends BasicFileUtility {
                        // Else means this is a Folder
                        $sourceFolderObject = $sourceFileObject;
                        try {
-                               $conflictMode = $appendSuffixOnConflict !== '' ? 'renameNewFile' : 'cancel';
                                $resultObject = $sourceFolderObject->copyTo($targetFolderObject, NULL, $conflictMode);
                        } catch (\TYPO3\CMS\Core\Resource\Exception\InsufficientUserPermissionsException $e) {
                                $this->writelog(2, 1, 125, 'You are not allowed to copy directories', '');
@@ -689,10 +700,10 @@ class ExtendedFileUtility extends BasicFileUtility {
                        try {
                                if ($alternativeName !== '') {
                                        // Don't allow overwriting existing files, but find a new name
-                                       $resultObject = $sourceFileObject->moveTo($targetFolderObject, $alternativeName, 'renameNewFile');
+                                       $resultObject = $sourceFileObject->moveTo($targetFolderObject, $alternativeName, DuplicationBehavior::RENAME);
                                } else {
                                        // Don't allow overwriting existing files
-                                       $resultObject = $sourceFileObject->moveTo($targetFolderObject, NULL, 'cancel');
+                                       $resultObject = $sourceFileObject->moveTo($targetFolderObject, NULL, DuplicationBehavior::CANCEL);
                                }
                                $this->writelog(3, 0, 1, 'File "%s" moved to "%s"', array($sourceFileObject->getIdentifier(), $resultObject->getIdentifier()));
                        } catch (\TYPO3\CMS\Core\Resource\Exception\InsufficientUserPermissionsException $e) {
@@ -714,10 +725,10 @@ class ExtendedFileUtility extends BasicFileUtility {
                        try {
                                if ($alternativeName !== '') {
                                        // Don't allow overwriting existing files, but find a new name
-                                       $resultObject = $sourceFolderObject->moveTo($targetFolderObject, $alternativeName, 'renameNewFile');
+                                       $resultObject = $sourceFolderObject->moveTo($targetFolderObject, $alternativeName, DuplicationBehavior::RENAME);
                                } else {
                                        // Don't allow overwriting existing files
-                                       $resultObject = $sourceFolderObject->moveTo($targetFolderObject, NULL, 'renameNewFile');
+                                       $resultObject = $sourceFolderObject->moveTo($targetFolderObject, NULL, DuplicationBehavior::RENAME);
                                }
                                $this->writelog(3, 0, 2, 'Directory "%s" moved to "%s"', array($sourceFolderObject->getIdentifier(), $targetFolderObject->getIdentifier()));
                        } catch (\TYPO3\CMS\Core\Resource\Exception\InsufficientUserPermissionsException $e) {
@@ -972,14 +983,14 @@ class ExtendedFileUtility extends BasicFileUtility {
                        try {
 
                                if ((int)$this->dontCheckForUnique === 1) {
-                                       GeneralUtility::deprecationLog('dontCheckForUnique = 1 is deprecated. Use setExistingFilesConflictMode(\'replace\');. Support for dontCheckForUnique will be removed in TYPO3 CMS 8.');
-                                       $this->existingFilesConflictMode = 'replace';
+                                       GeneralUtility::deprecationLog('dontCheckForUnique = 1 is deprecated. Use setExistingFilesConflictMode(DuplicationBehavior::REPLACE);. Support for dontCheckForUnique will be removed in TYPO3 CMS 8.');
+                                       $this->existingFilesConflictMode = DuplicationBehavior::cast(DuplicationBehavior::REPLACE);
                                }
 
                                /** @var $fileObject File */
-                               $fileObject = $targetFolderObject->addUploadedFile($fileInfo, $this->existingFilesConflictMode);
+                               $fileObject = $targetFolderObject->addUploadedFile($fileInfo, (string)$this->existingFilesConflictMode);
                                $fileObject = ResourceFactory::getInstance()->getFileObjectByStorageAndIdentifier($targetFolderObject->getStorage()->getUid(), $fileObject->getIdentifier());
-                               if ($this->existingFilesConflictMode === 'replace') {
+                               if ($this->existingFilesConflictMode->equals(DuplicationBehavior::REPLACE)) {
                                        $this->getIndexer($fileObject->getStorage())->updateIndexEntry($fileObject);
                                }
                                $resultObjects[] = $fileObject;
@@ -1088,7 +1099,7 @@ class ExtendedFileUtility extends BasicFileUtility {
                        $folder = $fileObjectToReplace->getParentFolder();
                        $resourceStorage = $fileObjectToReplace->getStorage();
 
-                       $fileObject = $resourceStorage->addUploadedFile($fileInfo, $folder, $fileObjectToReplace->getName(), 'replace');
+                       $fileObject = $resourceStorage->addUploadedFile($fileInfo, $folder, $fileObjectToReplace->getName(), DuplicationBehavior::REPLACE);
 
                        // Check if there is a file that is going to be uploaded that has a different name as the replacing one
                        // but exists in that folder as well.
@@ -1096,7 +1107,7 @@ class ExtendedFileUtility extends BasicFileUtility {
                        if ($keepFileName === FALSE) {
                                // if a file with the same name already exists, we need to change it to _01 etc.
                                // if the file does not exist, we can do a simple rename
-                               $resourceStorage->moveFile($fileObject, $folder, $fileInfo['name'], 'renameNewFile');
+                               $resourceStorage->moveFile($fileObject, $folder, $fileInfo['name'], DuplicationBehavior::RENAME);
                        }
 
                        $resultObjects[] = $fileObject;
index be0e632..63e54e1 100644 (file)
@@ -6,7 +6,7 @@ Description
 ===========
 
 The ExtendedFileUtility ``$dontCheckForUnique`` flag has been marked as deprecated and replaced by
-``$fileUtility->setExistingFileConflictMode()`` with the possible options ``cancel``, ``replace`` and ``changeName``.
+``$fileUtility->setExistingFileConflictMode()`` with the possible options of the ``\TYPO3\CMS\Core\Resource\DuplicationBehavior`` enumeration.
 
 
 Impact
@@ -24,4 +24,4 @@ All installations with extensions that use ``ExtendedFileUtility::$dontCheckForU
 Migration
 =========
 
-Change the ``$fileUtility->dontCheckForUnique = TRUE`` to ``$fileUtility->setExistingFileConflictMode('replace')``.
\ No newline at end of file
+Change the ``$fileUtility->dontCheckForUnique = TRUE`` to ``$fileUtility->setExistingFileConflictMode(DuplicationBehavior::REPLACE)``.
index a8333e3..158e58f 100644 (file)
@@ -6,7 +6,7 @@ Description
 ===========
 
 The GET/POST param to tell the FileController and FileListController whether to override a file or not switched from a bool
-value to a string with the possibilities ``cancel``, ``replace`` and ``changeName``.
+value to a string with the possibilities of the ``\TYPO3\CMS\Core\Resource\DuplicationBehavior`` enumeration.
 
 
 Impact
@@ -24,4 +24,4 @@ All installations with extensions that use the BE upload functionality and suppl
 Migration
 =========
 
-Change the ``<input name="overwriteExistingFiles" value="1">`` to ``<input name="overwriteExistingFiles" value="replace">``.
\ No newline at end of file
+Change the ``<input name="overwriteExistingFiles" value="1">`` to ``<input name="overwriteExistingFiles" value="replace">``.
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-55419-StreamlineFileConflictModeHandling.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-55419-StreamlineFileConflictModeHandling.rst
new file mode 100644 (file)
index 0000000..c7e949e
--- /dev/null
@@ -0,0 +1,53 @@
+============================================================
+Deprecation: #55419 - Streamline file conflict mode handling
+============================================================
+
+
+Description
+===========
+
+Conflicts in file names and folder names when uploading new files or creating new folders are now handled
+uniformly with constants within the core. Therefore a new enumeration was introduced to provide the available
+values: ``\TYPO3\CMS\Core\Resource\DuplicationBehavior``.
+
+Provided constants are:
+ * DuplicationBehavior::RENAME
+ * DuplicationBehavior::REPLACE
+ * DuplicationBehavior::CANCEL
+
+Before this change there were two sets of strings used to define the behavior upon conflicts.
+ * Set1: ``cancel``, ``replace`` and ``changeName``
+ * Set2: ``cancel``, ``overrideExistingFile`` and ``renameNewFile``
+
+As they are redundant they are now represented by a new set of constants:
+
+ * ``cancel``, ``replace`` and ``rename``
+
+All usages of strings of the former sets have been replaced with their counterparts from the new set. In the enumeration
+the former values are mapped to the new values and have been marked for deprecation.
+
+
+Impact
+======
+
+Using ``changeName``, ``overrideExistingFile`` or ``renameNewFile`` for file conflict handling will result in a deprecation log entry.
+
+
+Affected Installations
+======================
+
+All third party code that calls one of the listed methods with ``$conflictMode`` either set to ``changeName``, ``overrideExistingFile`` or ``renameNewFile``.
+
+
+Migration
+=========
+
+Use the provided enumeration ``\TYPO3\CMS\Core\Resource\DuplicationBehavior`` instead.
+
+
+Example
+=======
+
+.. code-block:: php
+
+       $resourceStorage->copyFile($file, $targetFolder, 'target-file-name', DuplicationBehavior::RENAME);
index cfc27ef..4a81e0e 100644 (file)
@@ -21,6 +21,7 @@ use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
 use TYPO3\CMS\Core\Messaging\FlashMessage;
 use TYPO3\CMS\Core\Page\PageRenderer;
+use TYPO3\CMS\Core\Resource\DuplicationBehavior;
 use TYPO3\CMS\Core\Resource\Exception;
 use TYPO3\CMS\Core\Resource\Folder;
 use TYPO3\CMS\Core\Resource\ResourceFactory;
@@ -105,9 +106,10 @@ class FileListController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionControl
        public $cmd;
 
        /**
-        * Defines behaviour when uploading files with names that already exist; possible value are 'cancel', 'replace', 'changeName'
+        * Defines behaviour when uploading files with names that already exist; possible values are
+        * the values of the \TYPO3\CMS\Core\Resource\DuplicationBehavior enumeration
         *
-        * @var string
+        * @var \TYPO3\CMS\Core\Resource\DuplicationBehavior
         */
        protected $overwriteExistingFiles;
 
@@ -144,12 +146,7 @@ class FileListController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionControl
                $this->table = GeneralUtility::_GP('table');
                $this->imagemode = GeneralUtility::_GP('imagemode');
                $this->cmd = GeneralUtility::_GP('cmd');
-               $this->overwriteExistingFiles = GeneralUtility::_GP('overwriteExistingFiles');
-
-               if ($this->overwriteExistingFiles === '1') {
-                       GeneralUtility::deprecationLog('overwriteExitingFiles = 1 is deprecated. Use overwriteExitingFiles = "replace". Support for old behavior will be removed in TYPO3 CMS 8.');
-                       $this->overwriteExistingFiles = 'replace';
-               }
+               $this->overwriteExistingFiles = DuplicationBehavior::cast(GeneralUtility::_GP('overwriteExistingFiles'));
 
                try {
                        if ($combinedIdentifier) {
@@ -329,22 +326,12 @@ class FileListController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionControl
                                        foreach ($items as $v) {
                                                $FILE['delete'][] = array('data' => $v);
                                        }
-                                       switch ($this->overwriteExistingFiles) {
-                                               case 'replace':
-                                               case 'changeName':
-                                                       $conflictMode = $this->overwriteExistingFiles;
-                                                       break;
-                                               default:
-                                                       $conflictMode = 'cancel';
-                                                       break;
-                                       }
-
                                        // Init file processing object for deleting and pass the cmd array.
                                        /** @var ExtendedFileUtility $fileProcessor */
                                        $fileProcessor = GeneralUtility::makeInstance(ExtendedFileUtility::class);
                                        $fileProcessor->init(array(), $GLOBALS['TYPO3_CONF_VARS']['BE']['fileExtensions']);
                                        $fileProcessor->setActionPermissions();
-                                       $fileProcessor->setExistingFilesConflictMode($conflictMode);
+                                       $fileProcessor->setExistingFilesConflictMode($this->overwriteExistingFiles);
                                        $fileProcessor->start($FILE);
                                        $fileProcessor->processData();
                                        $fileProcessor->pushErrorMessagesToFlashMessageQueue();
index bba3a33..7dcccb1 100644 (file)
@@ -21,6 +21,7 @@ use TYPO3\CMS\Core\Http\Response;
 use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
 use TYPO3\CMS\Core\Page\PageRenderer;
+use TYPO3\CMS\Core\Resource\DuplicationBehavior;
 use TYPO3\CMS\Core\Resource\ResourceFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
@@ -1391,7 +1392,7 @@ class ImportExportController extends \TYPO3\CMS\Backend\Module\BaseScriptClass i
                $this->fileProcessor = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Utility\File\ExtendedFileUtility::class);
                $this->fileProcessor->init(array(), $GLOBALS['TYPO3_CONF_VARS']['BE']['fileExtensions']);
                $this->fileProcessor->setActionPermissions();
-               $this->fileProcessor->setExistingFilesConflictMode((int)GeneralUtility::_GP('overwriteExistingFiles') === 1 ? 'replace' : 'cancel');
+               $this->fileProcessor->setExistingFilesConflictMode((int)GeneralUtility::_GP('overwriteExistingFiles') === 1 ? DuplicationBehavior::REPLACE : DuplicationBehavior::CANCEL);
                // Checking referer / executing:
                $refInfo = parse_url(GeneralUtility::getIndpEnv('HTTP_REFERER'));
                $httpHost = GeneralUtility::getIndpEnv('TYPO3_HOST_ONLY');
index 2953ac7..31e6af5 100644 (file)
@@ -19,6 +19,7 @@ use TYPO3\CMS\Core\DataHandling\DataHandler;
 use TYPO3\CMS\Core\Exception;
 use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
+use TYPO3\CMS\Core\Resource\DuplicationBehavior;
 use TYPO3\CMS\Core\Resource\ResourceFactory;
 use TYPO3\CMS\Core\Utility\File\ExtendedFileUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -2308,7 +2309,7 @@ class ImportExport {
 
                                                                                        if ($fileObject === NULL) {
                                                                                                try {
-                                                                                                       $fileObject = $this->legacyImportFolder->addFile($tempFile, $fileName, 'changeName');
+                                                                                                       $fileObject = $this->legacyImportFolder->addFile($tempFile, $fileName, DuplicationBehavior::RENAME);
                                                                                                } catch (\TYPO3\CMS\Core\Exception $e) {
                                                                                                        $this->error('Error: no file could be added to the storage for file name' . $this->alternativeFileName[$tempFile]);
                                                                                                }
@@ -2996,7 +2997,7 @@ class ImportExport {
 
                if ($fileObject === NULL) {
                        try {
-                               $fileObject = $importFolder->addFile($temporaryFile, $fileName, 'changeName');
+                               $fileObject = $importFolder->addFile($temporaryFile, $fileName, DuplicationBehavior::RENAME);
                        } catch (\TYPO3\CMS\Core\Exception $e) {
                                $this->error('Error: no file could be added to the storage for file name ' . $this->alternativeFileName[$temporaryFile]);
                        }