101 if ($this->baseUri === NULL) {
128 if ($temporaryBaseUri !==
'') {
129 $uriParts = explode(
'/', $temporaryBaseUri);
130 $uriParts = array_map(
'rawurlencode', $uriParts);
131 $temporaryBaseUri = implode(
'/', $uriParts) .
'/';
133 $this->baseUri = $temporaryBaseUri;
135 $this->baseUri = rtrim($this->configuration[
'baseUri'],
'/') .
'/';
148 if (!array_key_exists(
'basePath', $configuration) || empty($configuration[
'basePath'])) {
149 throw new \TYPO3\CMS\Core\Resource\Exception\InvalidConfigurationException(
150 'Configuration must contain base path.',
155 if ($configuration[
'pathType'] ===
'relative') {
156 $relativeBasePath = $configuration[
'basePath'];
164 throw new \TYPO3\CMS\Core\Resource\Exception\InvalidConfigurationException(
182 if ($this->baseUri !== NULL) {
183 $uriParts = explode(
'/', ltrim($identifier,
'/'));
184 $uriParts = array_map(
'rawurlencode', $uriParts);
185 $identifier = implode(
'/', $uriParts);
186 $publicUrl = $this->baseUri . $identifier;
206 $identifier =
'/user_upload/';
208 if ($createFolder === TRUE) {
223 public function createFolder($newFolderName, $parentFolderIdentifier =
'', $recursive = FALSE) {
225 $newFolderName = trim($newFolderName,
'/');
226 if ($recursive == FALSE) {
228 $newIdentifier = $parentFolderIdentifier . $newFolderName .
'/';
232 $parts = array_map(array($this,
'sanitizeFileName'), $parts);
233 $newFolderName = implode(
'/', $parts);
234 $newIdentifier = $parentFolderIdentifier . $newFolderName .
'/';
237 return $newIdentifier;
255 if (!file_exists($absoluteFilePath) || !is_file($absoluteFilePath)) {
256 throw new \InvalidArgumentException(
'File ' . $fileIdentifier .
' does not exist.', 1314516809);
272 throw new \TYPO3\CMS\Core\Resource\Exception\FolderDoesNotExistException(
273 'File ' . $folderIdentifier .
' does not exist.',
278 'identifier' => $folderIdentifier,
280 'storage' => $this->storageUid
298 if (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SYS'][
'UTF8filesystem']) {
300 $cleanFileName = preg_replace(
'/[' . self::UNSAFE_FILENAME_CHARACTER_EXPRESSION .
']/u',
'_', trim($fileName));
305 $charset =
$GLOBALS[
'TSFE']->renderCharset;
316 $cleanFileName = preg_replace(
'/[' . self::UNSAFE_FILENAME_CHARACTER_EXPRESSION .
'\\xC0-\\xFF]/',
'_', trim($fileName));
319 $cleanFileName = rtrim($cleanFileName,
'.');
320 if ($cleanFileName ===
'') {
321 throw new \TYPO3\CMS\Core\Resource\Exception\InvalidFileNameException(
322 'File name ' . $fileName .
' is invalid.',
326 return $cleanFileName;
343 protected function getDirectoryItemList($folderIdentifier, $start = 0, $numberOfItems = 0, array $filterMethods, $includeFiles = TRUE, $includeDirs = TRUE, $recursive = FALSE) {
346 if (!is_dir($realPath)) {
347 throw new \InvalidArgumentException(
348 'Cannot list items in directory ' . $folderIdentifier .
' - does not exist or is no directory',
356 $items = $this->retrieveFileAndFoldersInPath($realPath, $recursive, $includeFiles, $includeDirs);
359 array(
'\\TYPO3\\CMS\\Core\\Utility\\ResourceUtility',
'recursiveFileListSortingHelper')
362 $iterator = new \ArrayIterator($items);
363 if ($iterator->count() === 0) {
368 $c = $numberOfItems > 0 ? $numberOfItems : - 1;
370 while ($iterator->valid() && ($numberOfItems === 0 || $c > 0)) {
372 $iteratorItem = $iterator->current();
379 $iteratorItem[
'name'],
380 $iteratorItem[
'identifier'],
390 $items[$iteratorItem[
'identifier']] = $iteratorItem[
'identifier'];
412 foreach ($filterMethods as $filter) {
413 if (is_callable($filter)) {
414 $result = call_user_func($filter, $itemName, $itemIdentifier, $parentIdentifier, array(), $this);
420 throw new \RuntimeException(
'Could not apply file/folder name filter ' . $filter[0] .
'::' . $filter[1]);
438 public function getFilesInFolder($folderIdentifier, $start = 0, $numberOfItems = 0, $recursive = FALSE, array $filenameFilterCallbacks = array()) {
439 return $this->
getDirectoryItemList($folderIdentifier, $start, $numberOfItems, $filenameFilterCallbacks, TRUE, FALSE, $recursive);
453 public function getFoldersInFolder($folderIdentifier, $start = 0, $numberOfItems = 0, $recursive = FALSE, array $folderNameFilterCallbacks = array()) {
454 return $this->
getDirectoryItemList($folderIdentifier, $start, $numberOfItems, $folderNameFilterCallbacks, FALSE, TRUE, $recursive);
466 protected function retrieveFileAndFoldersInPath($path, $recursive = FALSE, $includeFiles = TRUE, $includeDirs = TRUE) {
468 $iteratorMode = \FilesystemIterator::UNIX_PATHS | \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::FOLLOW_SYMLINKS;
470 $iterator = new \RecursiveIteratorIterator(
471 new \RecursiveDirectoryIterator($path, $iteratorMode),
472 \RecursiveIteratorIterator::SELF_FIRST
475 $iterator = new \RecursiveDirectoryIterator($path, $iteratorMode);
478 $directoryEntries = array();
479 while ($iterator->valid()) {
481 $entry = $iterator->current();
483 if ((!$entry->isFile() && !$entry->isDir()) || $entry->getFilename() ==
'' ||
484 ($entry->isFile() && !$includeFiles) || ($entry->isDir() && !$includeDirs)) {
488 $entryIdentifier =
'/' . substr($entry->getPathname(), $pathLength);
490 if ($entry->isDir()) {
491 $entryIdentifier .=
'/';
494 'identifier' => $entryIdentifier,
495 'name' => $entryName,
496 'type' => $entry->isDir() ?
'dir' :
'file' 498 $directoryEntries[$entryIdentifier] = $entryArray;
501 return $directoryEntries;
513 if (count($propertiesToExtract) === 0) {
514 $propertiesToExtract = array(
515 'size',
'atime',
'atime',
'mtime',
'ctime',
'mimetype',
'name',
516 'identifier',
'identifier_hash',
'storage',
'folder_hash' 519 $fileInformation = array();
520 foreach ($propertiesToExtract as $property) {
523 return $fileInformation;
542 return filesize($fileIdentifier);
544 return fileatime($fileIdentifier);
546 return filemtime($fileIdentifier);
548 return filectime($fileIdentifier);
557 case 'identifier_hash':
562 throw new \InvalidArgumentException(sprintf(
'The information "%s" is not available.', $property));
585 $path = $this->absoluteBasePath . $relativeFilePath;
596 if (function_exists(
'finfo_file')) {
597 $fileInfo = new \finfo();
598 return $fileInfo->file($absoluteFilePath, FILEINFO_MIME_TYPE);
599 } elseif (function_exists(
'mime_content_type')) {
600 return mime_content_type($absoluteFilePath);
614 public function hash($fileIdentifier, $hashAlgorithm) {
615 if (!in_array($hashAlgorithm, $this->supportedHashAlgorithms)) {
616 throw new \InvalidArgumentException(
'Hash algorithm "' . $hashAlgorithm .
'" is not supported.', 1304964032);
618 switch ($hashAlgorithm) {
626 throw new \RuntimeException(
'Hash algorithm ' . $hashAlgorithm .
' is not implemented.', 1329644451);
644 public function addFile($localFilePath, $targetFolderIdentifier, $newFileName =
'', $removeOriginal = TRUE) {
650 throw new \InvalidArgumentException(
'Cannot add a file that is already part of this storage.', 1314778269);
656 if ($removeOriginal) {
657 if (is_uploaded_file($localFilePath)) {
658 $result = move_uploaded_file($localFilePath, $targetPath);
660 $result = rename($localFilePath, $targetPath);
663 $result = copy($localFilePath, $targetPath);
665 if (
$result === FALSE || !file_exists($targetPath)) {
666 throw new \RuntimeException(
'Adding file ' . $localFilePath .
' at ' . $newFileIdentifier .
' failed.');
671 return $newFileIdentifier;
683 return is_file($absoluteFilePath);
694 $identifier = $folderIdentifier .
'/' . $fileName;
708 return is_dir($absoluteFilePath);
719 $identifier = $folderIdentifier .
'/' . $folderName;
734 return $folderIdentifier;
747 $result = rename($localFilePath, $filePath);
750 throw new \RuntimeException(
'Replacing file ' . $fileIdentifier .
' with ' . $localFilePath .
' failed.', 1315314711);
767 $newIdentifier = $targetFolderIdentifier .
'/' . $fileName;
771 copy($sourcePath, $absoluteFilePath);
773 return $newIdentifier;
790 $targetIdentifier = $targetFolderIdentifier .
'/' . $newFileName;
794 throw new \RuntimeException(
'Moving file ' . $sourcePath .
' to ' . $targetIdentifier .
' failed.', 1315314712);
796 return $targetIdentifier;
809 $result = copy($sourcePath, $temporaryPath);
810 touch($temporaryPath, filemtime($sourcePath));
812 throw new \RuntimeException(
'Copying file ' . $fileIdentifier .
' to temporary path failed.', 1320577649);
814 return $temporaryPath;
828 protected function createIdentifierMap(array $filesAndFolders, $sourceFolderIdentifier, $targetFolderIdentifier) {
829 $identifierMap = array();
830 $identifierMap[$sourceFolderIdentifier] = $targetFolderIdentifier;
831 foreach ($filesAndFolders as $oldItem) {
832 if ($oldItem[
'type'] ==
'dir') {
833 $oldIdentifier = $oldItem[
'identifier'];
835 str_replace($sourceFolderIdentifier, $targetFolderIdentifier, $oldItem[
'identifier'])
838 $oldIdentifier = $oldItem[
'identifier'];
840 str_replace($sourceFolderIdentifier, $targetFolderIdentifier, $oldItem[
'identifier'])
844 throw new \TYPO3\CMS\Core\Resource\Exception\FileOperationErrorException(
845 sprintf(
'File "%1$s" was not found (should have been copied/moved from "%2$s").', $newIdentifier, $oldIdentifier),
849 $identifierMap[$oldIdentifier] = $newIdentifier;
851 return $identifierMap;
869 $filesAndFolders = $this->retrieveFileAndFoldersInPath($sourcePath, TRUE);
870 $result = rename($sourcePath, $targetPath);
872 throw new \RuntimeException(
'Moving folder ' . $sourcePath .
' to ' . $targetPath .
' failed.', 1320711817);
875 $identifierMap = $this->
createIdentifierMap($filesAndFolders, $sourceFolderIdentifier, $relativeTargetPath);
876 return $identifierMap;
896 mkdir($targetFolderPath);
898 $iterator = new \RecursiveIteratorIterator(
899 new \RecursiveDirectoryIterator($sourceFolderPath),
900 \RecursiveIteratorIterator::SELF_FIRST
904 while ($iterator->valid()) {
906 $current = $iterator->current();
907 $fileName = $current->getFilename();
909 if ($current->isDir() && !($fileName ===
'..' || $fileName ===
'.')) {
911 } elseif ($current->isFile()) {
912 $result = copy($sourceFolderPath .
'/' . $itemSubPath, $targetFolderPath .
'/' . $itemSubPath);
916 throw new \TYPO3\CMS\Core\Resource\Exception\FileOperationErrorException(
917 'Copying file "' . $sourceFolderPath . $itemSubPath .
'" to "' . $targetFolderPath . $itemSubPath .
'" failed.',
945 throw new \TYPO3\CMS\Core\Resource\Exception\ExistingTargetFileNameException(
'The target file already exists.', 1320291063);
949 $result = rename($sourcePath, $targetPath);
951 throw new \RuntimeException(
'Renaming file ' . $sourcePath .
' to ' . $targetPath .
' failed.', 1320375115);
953 return $newIdentifier;
975 $filesAndFolders = $this->retrieveFileAndFoldersInPath($sourcePath, TRUE);
976 $result = rename($sourcePath, $targetPath);
978 throw new \RuntimeException(sprintf(
'Renaming folder "%1$s" to "%2$s" failed."', $sourcePath, $targetPath), 1320375116);
982 $identifierMap = $this->
createIdentifierMap($filesAndFolders, $folderIdentifier, $newIdentifier);
984 rename($targetPath, $sourcePath);
985 throw new \RuntimeException(
987 'Creating filename mapping after renaming "%1$s" to "%2$s" failed. Reverted rename operation.\\n\\nOriginal error: %3$s"',
988 $sourcePath, $targetPath, $e->getMessage()
993 return $identifierMap;
1009 throw new \RuntimeException(
'Deletion of file ' . $fileIdentifier .
' failed.', 1320855304);
1023 public function deleteFolder($folderIdentifier, $deleteRecursively = FALSE) {
1027 throw new \TYPO3\CMS\Core\Resource\Exception\FileOperationErrorException(
1028 'Deleting folder "' . $folderIdentifier .
'" failed.',
1043 $dirHandle = opendir($path);
1044 while ($entry = readdir($dirHandle)) {
1045 if ($entry !==
'.' && $entry !==
'..') {
1046 closedir($dirHandle);
1050 closedir($dirHandle);
1065 if ($writable === FALSE) {
1082 $permissionBits = fileperms($path);
1083 if ($permissionBits === FALSE) {
1084 throw new \TYPO3\CMS\Core\Resource\Exception\ResourcePermissionsUnavailableException(
1085 'Error while fetching permissions for ' . $path,
1090 'r' => (
bool)is_readable($path),
1091 'w' => (
bool)is_writable($path)
1104 public function isWithin($folderIdentifier, $identifier) {
1107 if ($folderIdentifier === $entryIdentifier) {
1112 if ($folderIdentifier !==
'/') {
1113 $folderIdentifier .=
'/';
1129 throw new \TYPO3\CMS\Core\Resource\Exception\InvalidFileNameException(
1130 'Invalid characters in fileName "' . $fileName .
'"',
1139 $result = touch($absoluteFilePath);
1143 throw new \RuntimeException(
'Creating file ' . $fileIdentifier .
' failed.', 1320569854);
1145 return $fileIdentifier;
1159 return file_get_contents($filePath);
1172 $result = file_put_contents($filePath, $contents);
1175 clearstatcache(TRUE, $filePath);
1178 throw new \RuntimeException(
'Setting contents of file "' . $fileIdentifier .
'" failed.', 1325419305);
1189 if (!isset($this->charsetConversion)) {
1191 $this->charsetConversion =
$GLOBALS[
'TSFE']->csConvObj;
1192 } elseif (is_object(
$GLOBALS[
'LANG'])) {
1194 $this->charsetConversion =
$GLOBALS[
'LANG']->csConvObj;
1211 $role = $this->mappingFolderNameToRole[$name];
extractFileInformation($filePath, $containerPath, array $propertiesToExtract=array())
getParentFolderIdentifierOfIdentifier($fileIdentifier)
getFoldersInFolder($folderIdentifier, $start=0, $numberOfItems=0, $recursive=FALSE, array $folderNameFilterCallbacks=array())
static mkdir_deep($directory, $deepDirectory='')
isValidFilename($fileName)
getFileContents($fileIdentifier)
applyFilterMethodsToDirectoryItem(array $filterMethods, $itemName, $itemIdentifier, $parentIdentifier)
static isFirstPartOfStr($str, $partStr)
getSpecificFileInformation($fileIdentifier, $containerPath, $property)
getFolderInfoByIdentifier($folderIdentifier)
copyFolderWithinStorage($sourceFolderIdentifier, $targetFolderIdentifier, $newFolderName)
getPermissions($identifier)
deleteFolder($folderIdentifier, $deleteRecursively=FALSE)
static rmdir($path, $removeNonEmpty=FALSE)
getAbsolutePath($fileIdentifier)
isFolderEmpty($folderIdentifier)
canonicalizeAndCheckFolderIdentifier($folderPath)
static fixPermissions($path, $recursive=FALSE)
copyFileToTemporaryPath($fileIdentifier)
hasCapability($capability)
static makeInstance($className)
hash($fileIdentifier, $hashAlgorithm)
const CAPABILITY_WRITABLE
moveFileWithinStorage($fileIdentifier, $targetFolderIdentifier, $newFileName)
static trimExplode($delim, $string, $removeEmptyValues=FALSE, $limit=0)
canonicalizeAndCheckFileIdentifier($fileIdentifier)
renameFolder($folderIdentifier, $newName)
moveFolderWithinStorage($sourceFolderIdentifier, $targetFolderIdentifier, $newFolderName)
const UNSAFE_FILENAME_CHARACTER_EXPRESSION
const CAPABILITY_BROWSABLE
getDirectoryItemList($folderIdentifier, $start=0, $numberOfItems=0, array $filterMethods, $includeFiles=TRUE, $includeDirs=TRUE, $recursive=FALSE)
getFileForLocalProcessing($fileIdentifier, $writable=TRUE)
addFile($localFilePath, $targetFolderIdentifier, $newFileName='', $removeOriginal=TRUE)
if($list_of_literals) if(!empty($literals)) if(!empty($literals)) $result
Analyse literals to prepend the N char to them if their contents aren't numeric.
createFile($fileName, $parentFolderIdentifier)
__construct(array $configuration=array())
folderExistsInFolder($folderName, $folderIdentifier)
calculateBasePath(array $configuration)
setFileContents($fileIdentifier, $contents)
static fixWindowsFilePath($theFile)
getPublicUrl($identifier)
createFolder($newFolderName, $parentFolderIdentifier='', $recursive=FALSE)
canonicalizeAndCheckFilePath($filePath)
getFolderInFolder($folderName, $folderIdentifier)
getFileInfoByIdentifier($fileIdentifier, array $propertiesToExtract=array())
getFilesInFolder($folderIdentifier, $start=0, $numberOfItems=0, $recursive=FALSE, array $filenameFilterCallbacks=array())
mergeConfigurationCapabilities($capabilities)
deleteFile($fileIdentifier)
hashIdentifier($identifier)
dumpFileContents($identifier)
replaceFile($fileIdentifier, $localFilePath)
copyFileWithinStorage($fileIdentifier, $targetFolderIdentifier, $fileName)
getRole($folderIdentifier)
if(!defined('TYPO3_MODE')) $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_pre_processing'][]
folderExists($folderIdentifier)
renameFile($fileIdentifier, $newName)
static stripPathSitePrefix($path)
fileExistsInFolder($fileName, $folderIdentifier)
fileExists($fileIdentifier)
isWithin($folderIdentifier, $identifier)
getTemporaryPathForFile($fileIdentifier)
sanitizeFileName($fileName, $charset='')
createIdentifierMap(array $filesAndFolders, $sourceFolderIdentifier, $targetFolderIdentifier)
getMimeTypeOfFile($absoluteFilePath)