[TASK] Allow Folder and Storage to recursively retrieve Files from Driver
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Resource / Driver / LocalDriver.php
index e442de9..48e85b6 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace TYPO3\CMS\Core\Resource\Driver;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /***************************************************************
  * Copyright notice
@@ -26,12 +27,11 @@ namespace TYPO3\CMS\Core\Resource\Driver;
  *
  * This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
+
 /**
  * Driver for the local file system
  *
  * @author Andreas Wolf <andreas.wolf@ikt-werk.de>
- * @package    TYPO3
- * @subpackage         t3lib
  */
 class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
 
@@ -91,7 +91,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
        public function initialize() {
                $this->determineBaseUrl();
                // The capabilities of this driver. See CAPABILITY_* constants for possible values
-               $this->capabilities = (\TYPO3\CMS\Core\Resource\ResourceStorage::CAPABILITY_BROWSABLE | \TYPO3\CMS\Core\Resource\ResourceStorage::CAPABILITY_PUBLIC) | \TYPO3\CMS\Core\Resource\ResourceStorage::CAPABILITY_WRITABLE;
+               $this->capabilities = \TYPO3\CMS\Core\Resource\ResourceStorage::CAPABILITY_BROWSABLE | \TYPO3\CMS\Core\Resource\ResourceStorage::CAPABILITY_PUBLIC | \TYPO3\CMS\Core\Resource\ResourceStorage::CAPABILITY_WRITABLE;
        }
 
        /**
@@ -115,11 +115,15 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
        /**
         * Calculates the absolute path to this drivers storage location.
         *
-        * @throws RuntimeException
+        * @throws \TYPO3\CMS\Core\Resource\Exception\InvalidConfigurationException
         * @param array $configuration
         * @return string
         */
        protected function calculateBasePath(array $configuration) {
+               if (!array_key_exists('basePath', $configuration) || empty($configuration['basePath'])) {
+                       throw new \TYPO3\CMS\Core\Resource\Exception\InvalidConfigurationException('Configuration must contain base path.', 1346510477);
+               }
+
                if ($configuration['pathType'] === 'relative') {
                        $relativeBasePath = $configuration['basePath'];
                        $absoluteBasePath = PATH_site . $relativeBasePath;
@@ -128,7 +132,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
                }
                $absoluteBasePath = rtrim($absoluteBasePath, '/') . '/';
                if (!is_dir($absoluteBasePath)) {
-                       throw new \TYPO3\CMS\Core\Resource\Exception\InvalidConfigurationException(('Base path "' . $absoluteBasePath) . '" does not exist or is no directory.', 1299233097);
+                       throw new \TYPO3\CMS\Core\Resource\Exception\InvalidConfigurationException('Base path "' . $absoluteBasePath . '" does not exist or is no directory.', 1299233097);
                }
                return $absoluteBasePath;
        }
@@ -143,7 +147,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
         */
        public function getPublicUrl(\TYPO3\CMS\Core\Resource\ResourceInterface $fileOrFolder, $relativeToCurrentScript = FALSE) {
                if ($this->configuration['pathType'] === 'relative' && rtrim($this->configuration['basePath'], '/') !== '') {
-                       $publicUrl = (rtrim($this->configuration['basePath'], '/') . '/') . ltrim($fileOrFolder->getIdentifier(), '/');
+                       $publicUrl = rtrim($this->configuration['basePath'], '/') . '/' . ltrim($fileOrFolder->getIdentifier(), '/');
                } elseif (isset($this->baseUri)) {
                        $publicUrl = $this->baseUri . ltrim($fileOrFolder->getIdentifier(), '/');
                } else {
@@ -207,15 +211,17 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
        public function getFileInfoByIdentifier($fileIdentifier) {
                // Makes sure the Path given as parameter is valid
                $this->checkFilePath($fileIdentifier);
-               $dirPath = dirname($fileIdentifier);
+               $dirPath = \TYPO3\CMS\Core\Utility\GeneralUtility::fixWindowsFilePath(
+                       dirname($fileIdentifier)
+               );
                if ($dirPath !== '' && $dirPath !== '/') {
-                       $dirPath = ('/' . trim($dirPath, '/')) . '/';
+                       $dirPath = '/' . trim($dirPath, '/') . '/';
                }
                $absoluteFilePath = $this->absoluteBasePath . ltrim($fileIdentifier, '/');
                // don't use $this->fileExists() because we need the absolute path to the file anyways, so we can directly
                // use PHP's filesystem method.
                if (!file_exists($absoluteFilePath)) {
-                       throw new \InvalidArgumentException(('File ' . $fileIdentifier) . ' does not exist.', 1314516809);
+                       throw new \InvalidArgumentException('File ' . $fileIdentifier . ' does not exist.', 1314516809);
                }
                return $this->extractFileInformation($absoluteFilePath, $dirPath);
        }
@@ -252,11 +258,8 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
                        if (!$charset) {
                                if (TYPO3_MODE === 'FE') {
                                        $charset = $GLOBALS['TSFE']->renderCharset;
-                               } elseif (is_object($GLOBALS['LANG'])) {
-                                       // BE assumed:
-                                       $charset = $GLOBALS['LANG']->charSet;
                                } else {
-                                       // best guess
+                                       // default for Backend
                                        $charset = 'utf-8';
                                }
                        }
@@ -270,7 +273,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
                // Strip trailing dots and return
                $cleanFileName = preg_replace('/\\.*$/', '', $cleanFileName);
                if (!$cleanFileName) {
-                       throw new \TYPO3\CMS\Core\Resource\Exception\InvalidFileNameException(('File name ' . $cleanFileName) . ' is invalid.', 1320288991);
+                       throw new \TYPO3\CMS\Core\Resource\Exception\InvalidFileNameException('File name ' . $cleanFileName . ' is invalid.', 1320288991);
                }
                return $cleanFileName;
        }
@@ -285,13 +288,14 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
         * @param array $filterMethods The filter methods used to filter the directory items
         * @param string $itemHandlerMethod The method (in this class) that handles the single iterator elements.
         * @param array $itemRows
+        * @param boolean $recursive
         * @return array
         */
        // TODO add unit tests
-       protected function getDirectoryItemList($path, $start, $numberOfItems, array $filterMethods, $itemHandlerMethod, $itemRows = array()) {
+       protected function getDirectoryItemList($path, $start, $numberOfItems, array $filterMethods, $itemHandlerMethod, $itemRows = array(), $recursive = FALSE) {
                $realPath = rtrim(($this->absoluteBasePath . trim($path, '/')), '/') . '/';
                if (!is_dir($realPath)) {
-                       throw new \InvalidArgumentException(('Cannot list items in directory ' . $path) . ' - does not exist or is no directory', 1314349666);
+                       throw new \InvalidArgumentException('Cannot list items in directory ' . $path . ' - does not exist or is no directory', 1314349666);
                }
                if ($start > 0) {
                        $start--;
@@ -299,7 +303,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
                // Fetch the files and folders and sort them by name; we have to do
                // this here because the directory iterator does return them in
                // an arbitrary order
-               $items = $this->getFileAndFoldernamesInPath($realPath);
+               $items = $this->getFileAndFoldernamesInPath($realPath, $recursive);
                natcasesort($items);
                $iterator = new \ArrayIterator($items);
                if ($iterator->count() == 0) {
@@ -307,7 +311,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
                }
                $iterator->seek($start);
                if ($path !== '' && $path !== '/') {
-                       $path = ('/' . trim($path, '/')) . '/';
+                       $path = '/' . trim($path, '/') . '/';
                }
                // $c is the counter for how many items we still have to fetch (-1 is unlimited)
                $c = $numberOfItems > 0 ? $numberOfItems : -1;
@@ -373,7 +377,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
                        return array('', array());
                }
                // also don't show hidden files
-               if ((($folderName === '..' || $folderName === '.') || $folderName === '') || \TYPO3\CMS\Core\Utility\GeneralUtility::isFirstPartOfStr($folderName, '.') === TRUE) {
+               if ($folderName === '..' || $folderName === '.' || $folderName === '') {
                        return array('', array());
                }
                // remove the trailing slash from the folder name (the trailing slash comes from the DirectoryIterator)
@@ -397,7 +401,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
                }
                $directoryEntries = array();
                while ($iterator->valid()) {
-                       /** @var $entry SplFileInfo */
+                       /** @var $entry \SplFileInfo */
                        $entry = $iterator->current();
                        // skip non-files/non-folders, and empty entries
                        if (!$entry->isFile() && !$entry->isDir() || $entry->getFilename() == '') {
@@ -409,7 +413,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
                                $iterator->next();
                                continue;
                        }
-                       $entryPath = substr($entry->getPathname(), strlen($path));
+                       $entryPath = GeneralUtility::fixWindowsFilePath(substr($entry->getPathname(), strlen($path)));
                        if ($entry->isDir()) {
                                $entryPath .= '/';
                        }
@@ -428,13 +432,12 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
         */
        protected function extractFileInformation($filePath, $containerPath) {
                $fileName = basename($filePath);
-               $fileMimeInformation = new \finfo(FILEINFO_MIME_TYPE);
                $fileInformation = array(
                        'size' => filesize($filePath),
                        'atime' => fileatime($filePath),
                        'mtime' => filemtime($filePath),
                        'ctime' => filectime($filePath),
-                       'mimetype' => $fileMimeInformation->file($filePath),
+                       'mimetype' => $this->getMimeTypeOfFile($filePath),
                        'name' => $fileName,
                        'identifier' => $containerPath . $fileName,
                        'storage' => $this->storage->getUid()
@@ -455,7 +458,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
                        'ctime' => filectime($folderPath),
                        'mtime' => filemtime($folderPath),
                        'name' => $folderName,
-                       'identifier' => ($containerPath . $folderName) . '/',
+                       'identifier' => $containerPath . $folderName . '/',
                        'storage' => $this->storage->getUid()
                );
                return $folderInformation;
@@ -473,7 +476,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
        /**
         * Returns the absolute path of a file or folder.
         *
-        * @param t3lib_file_FileInterface|t3lib_file_Folder|string $file
+        * @param \TYPO3\CMS\Core\Resource\FileInterface|\TYPO3\CMS\Core\Resource\Folder|string $file
         * @return string
         */
        public function getAbsolutePath($file) {
@@ -485,7 +488,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
                } elseif (is_string($file)) {
                        $path = $this->absoluteBasePath . ltrim($file, '/');
                } else {
-                       throw new \RuntimeException(('Type "' . gettype($file)) . '" is not supported.', 1325191178);
+                       throw new \RuntimeException('Type "' . gettype($file) . '" is not supported.', 1325191178);
                }
                return $path;
        }
@@ -500,22 +503,34 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
                // TODO define which data should be returned
                // TODO write unit test
                // TODO cache this info. Registry?
+               // TODO merge with extractFolderInformation() above?!
                $filePath = $this->getAbsolutePath($file);
                $fileStat = stat($filePath);
-               $fileInfo = new \finfo();
+               $mimeType = $this->getMimeTypeOfFile($filePath);
                $stat = array(
                        'size' => filesize($filePath),
                        'atime' => $fileStat['atime'],
                        'mtime' => $fileStat['mtime'],
                        'ctime' => $fileStat['ctime'],
                        'nlink' => $fileStat['nlink'],
-                       'type' => $fileInfo->file($filePath, FILEINFO_MIME_TYPE),
-                       'mimetype' => $fileInfo->file($filePath, FILEINFO_MIME_TYPE)
+                       'type' => $mimeType,
+                       'mimetype' => $mimeType
                );
                return $stat;
        }
 
        /**
+        * Get mime type of file.
+        *
+        * @param string $absoluteFilePath Absolute path to file
+        * @return string Mime type. eg, text/html
+        */
+       protected function getMimeTypeOfFile($absoluteFilePath) {
+               $fileInfo = new \finfo();
+               return $fileInfo->file($absoluteFilePath, FILEINFO_MIME_TYPE);
+       }
+
+       /**
         * Creates a (cryptographic) hash for a file.
         *
         * @param \TYPO3\CMS\Core\Resource\FileInterface $file
@@ -524,7 +539,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
         */
        public function hash(\TYPO3\CMS\Core\Resource\FileInterface $file, $hashAlgorithm) {
                if (!in_array($hashAlgorithm, $this->getSupportedHashAlgorithms())) {
-                       throw new \InvalidArgumentException(('Hash algorithm "' . $hashAlgorithm) . '" is not supported.', 1304964032);
+                       throw new \InvalidArgumentException('Hash algorithm "' . $hashAlgorithm . '" is not supported.', 1304964032);
                }
                switch ($hashAlgorithm) {
                case 'sha1':
@@ -534,7 +549,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
                        $hash = md5_file($this->getAbsolutePath($file));
                        break;
                default:
-                       throw new \RuntimeException(('Hash algorithm ' . $hashAlgorithm) . ' is not implemented.', 1329644451);
+                       throw new \RuntimeException('Hash algorithm ' . $hashAlgorithm . ' is not implemented.', 1329644451);
                }
                return $hash;
        }
@@ -548,7 +563,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
         * @param \TYPO3\CMS\Core\Resource\Folder $targetFolder
         * @param string $fileName The name to add the file under
         * @param \TYPO3\CMS\Core\Resource\AbstractFile $updateFileObject File object to update (instead of creating a new object). With this parameter, this function can be used to "populate" a dummy file object with a real file underneath.
-        * @todo t3lib_file_File $updateFileObject should be t3lib_file_FileInterface, but indexer logic is only in t3lib_file_File
+        * @todo \TYPO3\CMS\Core\Resource\File $updateFileObject should be \TYPO3\CMS\Core\Resource\FileInterface, but indexer logic is only in \TYPO3\CMS\Core\Resource\File
         * @return \TYPO3\CMS\Core\Resource\FileInterface
         */
        public function addFile($localFilePath, \TYPO3\CMS\Core\Resource\Folder $targetFolder, $fileName, \TYPO3\CMS\Core\Resource\AbstractFile $updateFileObject = NULL) {
@@ -566,7 +581,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
                        $moveResult = rename($localFilePath, $targetPath);
                }
                if ($moveResult !== TRUE) {
-                       throw new \RuntimeException(((('Moving file ' . $localFilePath) . ' to ') . $targetPath) . ' failed.', 1314803096);
+                       throw new \RuntimeException('Moving file ' . $localFilePath . ' to ' . $targetPath . ' failed.', 1314803096);
                }
                clearstatcache();
                // Change the permissions of the file
@@ -646,7 +661,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
         * @return \TYPO3\CMS\Core\Resource\Folder
         */
        public function getFolderInFolder($name, \TYPO3\CMS\Core\Resource\Folder $parentFolder) {
-               $folderIdentifier = ($parentFolder->getIdentifier() . $name) . '/';
+               $folderIdentifier = $parentFolder->getIdentifier() . $name . '/';
                return $this->getFolder($folderIdentifier);
        }
 
@@ -661,7 +676,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
                $filePath = $this->getAbsolutePath($file);
                $result = rename($localFilePath, $filePath);
                if ($result === FALSE) {
-                       throw new \RuntimeException(((('Replacing file ' . $filePath) . ' with ') . $localFilePath) . ' failed.', 1315314711);
+                       throw new \RuntimeException('Replacing file ' . $filePath . ' with ' . $localFilePath . ' failed.', 1315314711);
                }
                $fileInfo = $this->getFileInfoByIdentifier($file->getIdentifier());
                $file->updateProperties($fileInfo);
@@ -682,7 +697,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
                $absoluteFilePath = $this->absoluteBasePath . $fileIdentifier;
                $result = copy($localFilePath, $absoluteFilePath);
                if ($result === FALSE || !file_exists($absoluteFilePath)) {
-                       throw new \RuntimeException(((('Adding file ' . $localFilePath) . ' at ') . $fileIdentifier) . ' failed.');
+                       throw new \RuntimeException('Adding file ' . $localFilePath . ' at ' . $fileIdentifier . ' failed.');
                }
                return $fileIdentifier;
        }
@@ -700,7 +715,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
                $targetPath = $this->absoluteBasePath . ltrim($identifier, '/');
                $result = unlink($targetPath);
                if ($result === FALSE || file_exists($targetPath)) {
-                       throw new \RuntimeException(('Deleting file ' . $identifier) . ' failed.', 1320381534);
+                       throw new \RuntimeException('Deleting file ' . $identifier . ' failed.', 1320381534);
                }
                return TRUE;
        }
@@ -738,7 +753,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
                $targetIdentifier = $targetFolder->getIdentifier() . $fileName;
                $result = rename($sourcePath, $this->absoluteBasePath . $targetIdentifier);
                if ($result === FALSE) {
-                       throw new \RuntimeException(((('Moving file ' . $sourcePath) . ' to ') . $targetIdentifier) . ' failed.', 1315314712);
+                       throw new \RuntimeException('Moving file ' . $sourcePath . ' to ' . $targetIdentifier . ' failed.', 1315314712);
                }
                return $targetIdentifier;
        }
@@ -754,7 +769,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
                $temporaryPath = $this->getTemporaryPathForFile($file);
                $result = copy($sourcePath, $temporaryPath);
                if ($result === FALSE) {
-                       throw new \RuntimeException(('Copying file ' . $file->getIdentifier()) . ' to temporary path failed.', 1320577649);
+                       throw new \RuntimeException('Copying file ' . $file->getIdentifier() . ' to temporary path failed.', 1320577649);
                }
                return $temporaryPath;
        }
@@ -793,13 +808,13 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
        public function moveFolderWithinStorage(\TYPO3\CMS\Core\Resource\Folder $folderToMove, \TYPO3\CMS\Core\Resource\Folder $targetFolder, $newFolderName) {
                $relativeSourcePath = $folderToMove->getIdentifier();
                $sourcePath = $this->getAbsolutePath($relativeSourcePath);
-               $relativeTargetPath = ($targetFolder->getIdentifier() . $newFolderName) . '/';
+               $relativeTargetPath = $targetFolder->getIdentifier() . $newFolderName . '/';
                $targetPath = $this->getAbsolutePath($relativeTargetPath);
                // get all files and folders we are going to move, to have a map for updating later.
                $filesAndFolders = $this->getFileAndFoldernamesInPath($sourcePath, TRUE);
                $result = rename($sourcePath, $targetPath);
                if ($result === FALSE) {
-                       throw new \RuntimeException(((('Moving folder ' . $sourcePath) . ' to ') . $targetPath) . ' failed.', 1320711817);
+                       throw new \RuntimeException('Moving folder ' . $sourcePath . ' to ' . $targetPath . ' failed.', 1320711817);
                }
                // Create a mapping from old to new identifiers
                $identifierMap = $this->createIdentifierMap($filesAndFolders, $relativeSourcePath, $relativeTargetPath);
@@ -817,7 +832,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
        public function copyFolderWithinStorage(\TYPO3\CMS\Core\Resource\Folder $folderToCopy, \TYPO3\CMS\Core\Resource\Folder $targetFolder, $newFolderName) {
                // This target folder path already includes the topmost level, i.e. the folder this method knows as $folderToCopy.
                // We can thus rely on this folder being present and just create the subfolder we want to copy to.
-               $targetFolderPath = ($this->getAbsolutePath($targetFolder) . $newFolderName) . '/';
+               $targetFolderPath = $this->getAbsolutePath($targetFolder) . $newFolderName . '/';
                mkdir($targetFolderPath);
                $sourceFolderPath = $this->getAbsolutePath($folderToCopy);
                /** @var $iterator RecursiveDirectoryIterator */
@@ -831,7 +846,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
                        } elseif ($current->isFile()) {
                                $result = copy($sourceFolderPath . $itemSubPath, $targetFolderPath . $itemSubPath);
                                if ($result === FALSE) {
-                                       throw new \TYPO3\CMS\Core\Resource\Exception\FileOperationErrorException(((((('Copying file "' . $sourceFolderPath) . $itemSubPath) . '" to "') . $targetFolderPath) . $itemSubPath) . '" failed.', 1330119452);
+                                       throw new \TYPO3\CMS\Core\Resource\Exception\FileOperationErrorException('Copying file "' . $sourceFolderPath . $itemSubPath . '" to "' . $targetFolderPath . $itemSubPath . '" failed.', 1330119452);
                                }
                        }
                        $iterator->next();
@@ -849,16 +864,16 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
        public function renameFile(\TYPO3\CMS\Core\Resource\FileInterface $file, $newName) {
                // Makes sure the Path given as parameter is valid
                $newName = $this->sanitizeFileName($newName);
-               $newIdentifier = (rtrim(dirname($file->getIdentifier()), '/') . '/') . $newName;
+               $newIdentifier = rtrim(GeneralUtility::fixWindowsFilePath(dirname($file->getIdentifier())), '/') . '/' . $newName;
                // The target should not exist already
                if ($this->fileExists($newIdentifier)) {
                        throw new \TYPO3\CMS\Core\Resource\Exception\ExistingTargetFileNameException('The target file already exists.', 1320291063);
                }
                $sourcePath = $this->getAbsolutePath($file);
-               $targetPath = ($this->absoluteBasePath . '/') . ltrim($newIdentifier, '/');
+               $targetPath = $this->absoluteBasePath . '/' . ltrim($newIdentifier, '/');
                $result = rename($sourcePath, $targetPath);
                if ($result === FALSE) {
-                       throw new \RuntimeException(((('Renaming file ' . $sourcePath) . ' to ') . $targetPath) . ' failed.', 1320375115);
+                       throw new \RuntimeException('Renaming file ' . $sourcePath . ' to ' . $targetPath . ' failed.', 1320375115);
                }
                return $newIdentifier;
        }
@@ -872,7 +887,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
        protected function checkFilePath($filePath) {
                // filePath must be valid
                if (!$this->isPathValid($filePath)) {
-                       throw new \TYPO3\CMS\Core\Resource\Exception\InvalidPathException(('File ' . $filePath) . ' is not valid (".." and "//" is not allowed in path).', 1320286857);
+                       throw new \TYPO3\CMS\Core\Resource\Exception\InvalidPathException('File ' . $filePath . ' is not valid (".." and "//" is not allowed in path).', 1320286857);
                }
        }
 
@@ -882,14 +897,14 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
         * @param \TYPO3\CMS\Core\Resource\Folder $folder
         * @param string $newName The target path (including the file name!)
         * @return array A map of old to new file identifiers
-        * @throws RuntimeException if renaming the folder failed
+        * @throws \RuntimeException if renaming the folder failed
         */
        public function renameFolder(\TYPO3\CMS\Core\Resource\Folder $folder, $newName) {
                // Makes sure the path given as parameter is valid
                $newName = $this->sanitizeFileName($newName);
                $relativeSourcePath = $folder->getIdentifier();
                $sourcePath = $this->getAbsolutePath($relativeSourcePath);
-               $relativeTargetPath = ((rtrim(dirname($relativeSourcePath), '/') . '/') . $newName) . '/';
+               $relativeTargetPath = rtrim(GeneralUtility::fixWindowsFilePath(dirname($relativeSourcePath)), '/') . '/' . $newName . '/';
                $targetPath = $this->getAbsolutePath($relativeTargetPath);
                // get all files and folders we are going to move, to have a map for updating later.
                $filesAndFolders = $this->getFileAndFoldernamesInPath($sourcePath, TRUE);
@@ -917,7 +932,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
                $filePath = $this->getAbsolutePath($file);
                $result = unlink($filePath);
                if ($result === FALSE) {
-                       throw new \RuntimeException(('Deletion of file ' . $file->getIdentifier()) . ' failed.', 1320855304);
+                       throw new \RuntimeException('Deletion of file ' . $file->getIdentifier() . ' failed.', 1320855304);
                }
                return $result;
        }
@@ -933,7 +948,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
                $folderPath = $this->getAbsolutePath($folder);
                $result = \TYPO3\CMS\Core\Utility\GeneralUtility::rmdir($folderPath, $deleteRecursively);
                if ($result === FALSE) {
-                       throw new \TYPO3\CMS\Core\Resource\Exception\FileOperationErrorException(('Deleting folder "' . $folder->getIdentifier()) . '" failed.', 1330119451);
+                       throw new \TYPO3\CMS\Core\Resource\Exception\FileOperationErrorException('Deleting folder "' . $folder->getIdentifier() . '" failed.', 1330119451);
                }
                return $result;
        }
@@ -980,7 +995,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
         *
         * @param \TYPO3\CMS\Core\Resource\FileInterface $file The file object to check
         * @return array
-        * @throws RuntimeException If fetching the permissions failed
+        * @throws \RuntimeException If fetching the permissions failed
         */
        public function getFilePermissions(\TYPO3\CMS\Core\Resource\FileInterface $file) {
                $filePath = $this->getAbsolutePath($file);
@@ -992,7 +1007,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
         *
         * @param \TYPO3\CMS\Core\Resource\Folder $folder
         * @return array
-        * @throws RuntimeException If fetching the permissions failed
+        * @throws \RuntimeException If fetching the permissions failed
         */
        public function getFolderPermissions(\TYPO3\CMS\Core\Resource\Folder $folder) {
                $folderPath = $this->getAbsolutePath($folder);
@@ -1004,7 +1019,7 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
         *
         * @param string $path
         * @return array
-        * @throws RuntimeException If fetching the permissions failed
+        * @throws \RuntimeException If fetching the permissions failed
         */
        protected function getPermissions($path) {
                $permissionBits = fileperms($path);
@@ -1047,14 +1062,14 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
         */
        public function createFile($fileName, \TYPO3\CMS\Core\Resource\Folder $parentFolder) {
                if (!$this->isValidFilename($fileName)) {
-                       throw new \TYPO3\CMS\Core\Resource\Exception\InvalidFileNameException(('Invalid characters in fileName "' . $fileName) . '"', 1320572272);
+                       throw new \TYPO3\CMS\Core\Resource\Exception\InvalidFileNameException('Invalid characters in fileName "' . $fileName . '"', 1320572272);
                }
                $filePath = $parentFolder->getIdentifier() . ltrim($fileName, '/');
                // TODO set permissions of new file
                $result = touch($this->absoluteBasePath . $filePath);
                clearstatcache();
                if ($result !== TRUE) {
-                       throw new \RuntimeException(('Creating file ' . $filePath) . ' failed.', 1320569854);
+                       throw new \RuntimeException('Creating file ' . $filePath . ' failed.', 1320569854);
                }
                $fileInfo = $this->getFileInfoByIdentifier($filePath);
                return $this->getFileObject($fileInfo);
@@ -1080,13 +1095,13 @@ class LocalDriver extends \TYPO3\CMS\Core\Resource\Driver\AbstractDriver {
         * @param \TYPO3\CMS\Core\Resource\FileInterface $file
         * @param string $contents
         * @return integer The number of bytes written to the file
-        * @throws RuntimeException if the operation failed
+        * @throws \RuntimeException if the operation failed
         */
        public function setFileContents(\TYPO3\CMS\Core\Resource\FileInterface $file, $contents) {
                $filePath = $this->getAbsolutePath($file);
                $result = file_put_contents($filePath, $contents);
                if ($result === FALSE) {
-                       throw new \RuntimeException(('Setting contents of file "' . $file->getIdentifier()) . '" failed.', 1325419305);
+                       throw new \RuntimeException('Setting contents of file "' . $file->getIdentifier() . '" failed.', 1325419305);
                }
                return $result;
        }